1.Ribbon是什么?
- Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套 客户端 负载均衡 的工具
- 3个关键词,表明了Ribbon 是与客户端相关的,所以我们在使用它的时候需要在客户端的中使用;并且它是实现客户端负载均衡的一个工具;
- 对于负载均衡就是对于集群技术中每个站点使用不均衡的情况,简单的解决办法可以使用轮询解决集群中的服务器均摊客户端请求,除了使用轮询我们还可以使用hash随机算法,每次随机选中一个集群服务器处理客户端的请求
- 简单的说,Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Ribbon 的客户端组件提供一系列完整的配置项,如:连接超时、重试等。简单的说,就是在配置文件中列出 LoadBalancer (简称LB:负载均衡) 后面所有的集群服务器,Ribbon 会自动的帮助你基于某种规则 (如简单轮询,随机连接等等) 去连接这些服务器,我们也容易使用 Ribbon 实现自定义的负载均衡算法!
- 面试造飞机,工作拧螺丝
2.Ribbon的作用
- LB,即负载均衡 (LoadBalancer) ,在微服务或分布式集群中经常用的一种应用。
- 负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高可用)
- 常见的负载均衡软件有 Nginx、Lvs 等等
- Dubbo、SpringCloud 中均给我们提供了负载均衡,SpringCloud 的负载均衡算法可以自定义。
- 负载均衡简单分类:
- 集中式LB(在消费者请求到达服务器集群之前,首先通过服务器集群前面运行着负载均衡程序的服务器,由它来决定消费者的这个请求发送到服务器集群中的哪一台服务器上进行处理)
- 即在服务的提供方和消费方之间使用独立的LB设施,如Nginx:反向代理服务器,由该设施负责把访问请求通过某种策略转发至服务的提供方!
- 进程式LB(将负载均衡的处理交给用户,即消费者在本地发送请求的时候就已经知道了自己应该将这个请求发送到集群服务器中的那一台具体的服务器进行处理,这是由集成在客户端的负载均衡算法实现的)
- 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用(负载均衡的依据),然后自己再从这些地址中选出一个合适的服务器
- Ribbon 就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址
- 集中式LB(在消费者请求到达服务器集群之前,首先通过服务器集群前面运行着负载均衡程序的服务器,由它来决定消费者的这个请求发送到服务器集群中的哪一台服务器上进行处理)
3. 集成Ribbon
- 导入依赖,首先是要继承ribbon,所以它的依赖一定需要,再者是ribbon需要连接eureka的注册中心获取已经注册的服务列表,所以我们还需要eureka的依赖
<!-- Ribbon --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!--eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.7.RELEASE</version> </dependency>
- 编写消费者微服务中的配置文件,配置eureka
#eureka配置 eureka: client: register-with-eureka: false #表示不向eureka中注册自己,即表明自己是一个消费者 service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #配置可以连接的eureka注册中心的url
- 启动eureka客户端,即加上注解@EnableEurekaClient
- 上面的操作只是使得客户端可以连接eureka获取并消费服务提供者提供的服务,真正的负载均衡要怎么配置呢?在前面我们说过了ribbon是将负载均衡集成在了客户端,在客户端发出请求的时候进行负载均衡,所以要实现负载均衡,我们只需要修改消费者发出服务请求的代码即可
- 在前面我们讲解了,在spring cloud中消费者请求可以消费的服务依赖的是spring的一个工具类RestTemplate,通过它模拟浏览器向注册中心发送服务请求,所以我们只需要对这个类进行改造,使得它在发送请求之前进行负载均衡即可;实现方法很简单,只需要在将这个类装配到spring容器中的方法上添加一个注解@LoadBalanced即可
@Configuration //spring容器的配置类 public class ConfigBean { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
- 在前面搭建消费者环境的时候,还没有使用注册中心,所以消费者的controller代码中我们将服务者的请求地址写死在了代码中
private static final String REST_URL_PREFIX = "http://localhost:8001/"; //请求服务者提供的服务的url的固定前缀,就是服务者程序的主机名+端口名。它的后面还应该接上对应服务的请求url/映射的地址
- 但是现在我们使用了注册中心,并且已经将服务提供者提供的服务成功的注册到了注册中心中,我们的消费者就不应该再使用写死的url进行拼接来获取服务提供者提供的服务,而是应该通过注册中心获取服务进行消费
- 消费者从注册中心获取指定服务的方法就是通过服务名称/注册的服务的application字段的值来获取该服务
- 测试
- 先启动注册中心集群,再启动服务提供者微服务,最后启动服务消费者
- 先启动注册中心集群,再启动服务提供者微服务,最后启动服务消费者
4.小结
- 通过上面的例子,我们可以发现,消费者在请求服务的时候是通过服务者提供的服务名称实现的,这样做的好处在于客户端不需要关心服务提供者的主机名、服务运行的端口号,只需要知道自己想要消费的服务在注册中心的名称,及这个获取具体服务的API(即服务提供者在controller中暴露的API)即可消费服务
- 但是上面的好处只是eureka作为注册中心实现的,与我们使用的ribbon没有显式的关系,原因就是我们的服务提供者只有一个,所以ribbon并不能进行负载均衡,为了测试ribbon的作用,我们应该实现服务提供者的集群,具体做法在下一篇博客中讲述