Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。
在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。
负载均衡是一种基础的网络服务,其原理是通过运行在前面的负载均衡服务,按照指定的负载均衡算法,将流量分配到后端服务集群上,从而为系统提供并行扩展的能力;
负载均衡分为两种:
Ribbon为客户端负载均衡!
1:新建Spring Boot项目EurekaServer,添加依赖Eureka Server
2:启动类
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
3:配置文件application.yml
server:
port: 8761
eureka:
client:
registerWithEureka: false #是否将自己注册到Eureka Server,默认为True。由于当前应用就是Eureka Server,故false
fetchRegistry: false #是否从Eureka Server获取注册信息,默认True。因为这是一个单节点的Eureka Server,不需要同步其他的Eureka Server节点,故false
serviceUrl:
defaultZone: http://localhost:8761/eureka/
4:新建Spring Boot项目EurekaClient,添加依赖Eureka Client
5:启动类
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
6:配置文件application.yml
server:
port: 8020
spring:
application:
name: EurekaClinet
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
7:新建Spring Boot项目EurekaRibbon,添加依赖Eureka Client、Ribbon、Web
添加Ribbon依赖时要注意Spring Boot版本!
8:启动类
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonApplication.class, args);
}
}
9:配置文件application.yml
server:
port: 8010
spring:
application:
name: EurekaRabbon
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
10:MyController
@RestController
public class MyController {
private static final Logger LOGGER = LoggerFactory.getLogger(MyController.class);
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/log-user-instance")
public void logUserInstance() {
ServiceInstance serviceInstance = this.loadBalancerClient.choose("EurekaClinet");
// 打印当前选择的是哪个节点
MyController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort());
}
}
11:运行测试
启动项目EurekaServer
启动项目EurekaClient(服务提供者1- - -以8020端口启动)
启动项目EurekaClient(服务提供者2- - -以8030端口启动)
启动项目EurekaRibbon(这里我省略了客户端,直接从负载均衡服务发起调用)
访问:http://localhost:8010/log-user-instance
EurekaRibbon控制台会打印:
可以看到请求是均匀分布到两个用户微服务节点上的,说明已经实现了负载均衡!
Spring Cloud Camden允许使用Java代码或属性自定义Ribbon的配置,两种方式是等价的。
1:EurekaRibbon项目添加Ribbon配置类:RibbonConfiguration.java
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule() {
// 负载均衡规则,改为随机
return new RandomRule();
}
}
2:EurekaRibbon项目空类TestConfiguration.java
/**
* @RibbonClient的configuration属性指定自定义Ribbon配置
* @author yangdong
* @date 2021-01-20
*/
@Configuration
@RibbonClient(name = "EurekaClinet", configuration = RibbonConfiguration.class)
public class TestConfiguration {
}
4:运行测试
此时请求会随机分布到两个用户微服务节点上,说明已经实现了Ribbon的自定义配置。
Ribbon内置了多种负载均衡策略,内部负责复杂均衡的顶级接口为com.netflix.loadbalancer.IRule,实现方式如下:
从Spring Cloud Netflix1.2.0开始,Ribbon支持使用属性自定义Ribbon客户端,配置的前缀是< ClientName >.ribbon。在EurekaRibbonClient的application.yml配置文件中可以修改负载均衡策略;
application.yml添加:
##需要调用的微服务名称
EurekaClinet:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
##从Ribbon中的关键组件小节中,可以知道配置负载均衡策略的配置类是NFLoadBalancerRuleClassName
1:新建Spring Boot项目RibbonWithOutEureka,添加依赖Ribbon、Web
2:启动类
@SpringBootApplication
public class RibbonWithOutEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonWithOutEurekaApplication.class, args);
}
}
3:MyController
@RestController
public class MyController {
private static final Logger LOGGER = LoggerFactory.getLogger(MyController.class);
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/log-user-instance")
public void logUserInstance() {
ServiceInstance serviceInstance = this.loadBalancerClient.choose("EurekaClinet");
// 打印当前选择的是哪个节点
MyController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort());
}
}
4:application.yml
server:
port: 8010
spring:
application:
name: RibbonWithOutEureka
EurekaClinet:
ribbon:
listOfServers: localhost:8020,localhost:8030
5:运行测试
启动项目RibbonWithOutEureka
访问:http://localhost:8010/log-user-instance
尽管此时没有注册到Eureka上,Ribbon仍可正常工作,请求依旧会均匀分摊到两个微服务节点上。
参考书籍:Spring Cloud与Docker微服务架构实战
以上只是学习所做的笔记,以供日后参考!!!