Spring cloud微服务架构-Ribbon(负载均衡)

Spring cloud微服务架构-Ribbon(负载均衡)

前言

首先我们先了解Ribbon是什么,Ribbon是一个负载均衡客户端,给我们更多控制的HTTP和TCP调用的行为。Feign默认集成了ribbon,Ribbon是Netflix的子项目,提供客户端实现负载均衡算法。Ribbon客户端组件提供如连接超时,重试等。Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。上篇讲了Eureka注册中心,本文将Ribbon结合Eureka注册中心做消费端的负载均衡调用。如下图,Ribbon可以结合Eureka使用,也可以单独使用Ribbon。

Spring cloud微服务架构-Ribbon(负载均衡)

Ribbon简单使用

以上篇文章的Eureka-client模块作为Provider,新建Ribbon-client作为消费者,首先Ribbon-client引入ribbon,eureka,在pom文件引入

<dependency>
<groupid>org.springframework.cloud/<groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.cloud/<groupid>
<artifactid>spring-cloud-starter-netflix-ribbon/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
/<dependency>

在application.yml 文件引入相关配置

server:
port: 8768
spring:
application:
name: ribbon-client
eureka:
client:
serviceUrl:
defaultZone: http://eureka-server1:8761/eureka/

新建 RibbonConfig配置类

@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

新建controller调用(eureka-client为之前模块的应用名,以该名在注册中心注册的 )

@RestController
public class RibbonClientController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/getEurekaServer")
public String getEurekaServer(String name){
return this.restTemplate.getForObject("http://eureka-client/ribbon?name=" + name, String.class);
}
}

启动类

@SpringBootApplication
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}

经过以上几步,默认的Ribbon客户完成,很简单。分别启动Eureka-server,Eureka-client,Ribbon-client。请求http://localhost:8768/getEurekaServer?name=Ribbon,会请求到Eureka-client模块的接口。上面的几步都是使用Ribbon默认的配置,一般微服务中,Provider会有多个,consumer也会有多个,默认情况下是轮询的方式去调用。当然我们也可以根据我们的需求去定义它。默认情况下,Ribbon自动帮我们做了如下配置

Spring cloud微服务架构-Ribbon(负载均衡)

Ribbon自定义客户端

自定义Ribbon意思就是说自定义上图中六个Ribbon组件的默认配置,首先我们新建CustomRibbonConfig配置类

@Configuration
public class CustomRibbonConfig {
@Bean
public IRule ribbonRule() {
// 自定义为随机规则
return new RandomRule();
}
@Bean
public IPing ribbonPing() {
// 如果调用成功,则认为本次心跳成功,表示此服务活着
return new PingUrl();
}
}

上面的代码我们重新定义负载均衡算法和与Provider端的心跳方式

然后我们的启动类加上

@SpringBootApplication
@RibbonClient(name = "eureka-client",configuration = CustomRibbonConfig.class)
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}

经过上面两步,自定义Ribbon的负载均衡客户端完成

但是在官方的文档上有这样的一段话

The CustomConfiguration clas must be a @Configuration class, but take care that it is not in a @ComponentScanfor the main application context. Otherwise, it is shared by all the @RibbonClients. If you use @ComponentScan(or @SpringBootApplication), you need to take steps to avoid it being included (for instance, you can put it in a separate, non-overlapping package or specify the packages to scan explicitly in the @ComponentScan)

意思是当我们Spring Boot @ComponentScan的时候应该明确的排除Ribbon自定义客户端的配置类,也就是要排除CustomRibbonConfig类

所以我们新建一个注解

public @interface Exclude {
}

注解加到CustomRibbonConfig配置类上

@Configuration
@Exclude
public class CustomRibbonConfig

启动类则变成

@SpringBootApplication
@RibbonClient(name = "eureka-client",configuration = CustomRibbonConfig.class)
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Exclude.class)})
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}

值得注意的是 上面的自定义配置只对服务名为 eureka-client 的provider有效

Ribbon不使用Eureka单独使用

Eureka是用于服务发现和服务注册、以及使用服务名来解决服务消费者和服务提供者通信时地址的硬编码问题的。如果Ribbon脱离了Eureka,那么在服务消费者端就无法根据服务名通过心跳机制从EurekaServer端获取对应服务提供者的IP以及端口号。这时就需要在服务消费者端配置对应服务提供者的地址列表,然后Ribbon才能通过配置文件或者自定义的RibbonClient或者默认的配置获取负载均衡的轮询策略进行请求分发。

我们需要把Ribbon-client 的application.yml 改成

server:
port: 8768
spring:
application:
name: ribbon-client
#eureka:
# client:
# serviceUrl:
# defaultZone: http://eureka-server1:8761/eureka/
ribbon:
eureka:
enabled: false
eureka-client:
ribbon:
listOfServers: localhost:8764,localhost:8765

其中 eureka-client是Provider端的服务名

Ribbon相关配置详解

Ribbon主要包含如下组件:

  • IRule

根据特定算法中从服务列表中选取一个要访问的服务

  • IPing

在后台运行的一个组件,用于检查服务列表是否都活

  • ServerList

存储服务列表。分为静态和动态。如果是动态的,后台有个线程会定时刷新和过滤服务列表

  • ServerListFilter

该接口允许过滤配置或动态获取的具有所需特性的服务器列表。ServerListFilter是DynamicServerListLoadBalancer用于过滤从ServerList实现返回的服务器的组件。

  • ServerListUpdater

被DynamicServerListLoadBalancer用于动态的更新服务列表

  • IClientConfig

定义各种配置信息,用来初始化ribbon客户端和负载均衡器

  • ILoadBalancer

定义软件负载平衡器操作的接口。动态更新一组服务列表及根据指定算法从现有服务器列表中选择一个服务


分享到:


相關文章: