此文章主要讲解 springcloud 中负责服务调用和负载均衡的工具 Ribbon 的相关知识。
前言
前面的章节中,我们已经实现了服务的注册和服务发现。当启动某个服务的时候,可以通过 HTTP 的形式将信息注册到注册中心,并且可以通过 SpringCloud 提供的工具获取注册中心的服务列表。但是服务之间的调用还存在很多问题:如何更加方便的调用微服务,多个微服务的提供者如何选择,如何负载均衡
等等。
Ribbon 基础
什么是 Ribbon?
Ribbon 是 Netflix 公司发布的一个负载均衡器,有助于控制 HTTP 和 TCP 的
客户端
行为。在 SpringCloud 中,Eureka 一般配合 Ribbon 进行使用,Ribbon 提供了客户端负载均衡的功能,Ribbon 利用从 Eureka 中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载均衡。在 SpringCloud 中可以将注册中心 Eureka 和 Ribbon 配合使用,Ribbon 自动的从注册中心获取服务提供者的列表新,并基于内置的负载均衡算法,请求服务。
Ribbon 的作用
服务调用:基于 Ribbon 实现服务调用,是通过拉取到的所有服务列表组成(服务名-请求路径的)映射关系。
借助于RestTemplate最终进行调用
。负载均衡:当有多个服务提供者时,Ribbon 可以根据
负载均衡的算法
自动的选择需要调用的服务地址。
简介
Ribbon 的使用
我们这里提前启动好之前在搭建的 eureka Server 集群(5 个模块)
- cloud-eureka-server7001
- cloud-eureka-server7002
- cloud-provider-payment8001
- cloud-provider-payment8002
- cloud-consumer-order80
上面在eureka时,确实实现了负载均衡机制,那是因为 netflix-eureka-client 包里面自带着 ribbon,在使用Eureka作为注册中心的时候,不需要再导入Ribbon的相关依赖,因为Eureka内部集成了Ribbon了。
RestTemplate 说明
有两种请求方式:post 和 get ,还有两种返回类型:object 和 Entity
RestTemplate 的 ForEntity 相比 ForObject 特殊的地方:
就是说如果使用 ForObject 得到的就是提供者返回的对象,而如果要使用 ForEntity
得到时 ResponstEntity
对象,使用 getBody()
才能得到提供者返回的数据。
1 | //使用forEnriry示例: |
负载均衡
什么是负载均衡
在搭建网站的时候,如果单节点的 web 服务性能和可靠性都无法达到要求;或者是在使用外网服务的时候,经常担心被人攻破,一不小心就会有打开外网端口的请求,通常这个时候加入负载均衡就能有效解决服务问题。
负载均衡是一种基础的网络服务,其原理是通过运行在前面的负载均衡服务,按照指定的负载均衡算法,将流量分配到后端服务集群上,从而为系统提供并行扩展的能力。
负载均衡的应用场景包括流量包、转发规则以及后端服务,由于该服务有内外网个例、健康检查等功能,能够有效提供系统的安全性和可用性。
客户端负载均衡和服务端负载均衡
客户端负载均衡
客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,进行访问;即在客户端进行负载均衡算法分配。
典型应用:Ribbon 是客户端负载均衡。
服务端负载均衡
先发送请求到负载均衡服务器或软件,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端进行负载均衡算法分配。
典型应用:
硬件:F5 等。
软件:Nginx 等。
Ribbon 内置的负载均衡策略
Ribbon 内置了多种负载均衡策略,内部负责复杂均衡的顶层接口为com.netflix.loadbalancer.IRule
,实现方式如下:
Ribbon 负载均衡规则类型
(IRule接口
的实现)
1 | com.netflix.loadbalancer.RoundRobinRule:# 以轮询的方式进行负载均衡。 |
配置负载均衡规则
Ribbon 内置的负载均衡策略的使用一
在服务消费者的 application.yml 中修改负载均衡策略
1 | # 修改ribbon的负载均衡策略 服务名 - ribbon - NFLoadBalancerRuleClassName :负载均衡策略 |
Ribbon 内置的负载均衡策略的使用二
注意上面说的,而Springboot主启动类上的 @SpringBootApplication 注解,相当于加了@ComponentScan注解,会自动扫描当前包及子包,所以注意不要放在SpringBoot主启动类的包内。
修改 cloud-consumer-order80,新建包 myrule
在这个包下新建 MySelfRule 类
1 |
|
然后在主启动类上添加注解 @RibbonClient
1 |
|
测试访问 http://localhost/consumer/payment/1 ,查看结果
Ribbon 的策略选择
如果每个机器配置一样,建议不修改策略(推荐)。
如果部分机器配置强,则可以改为 WeightedResponseTimeRule。
请求重试机制
在实际生产环境中,Ribbon 做客户端负载均衡的时候,Ribbon 默认的负载均衡算法是轮询,一旦访问到的那台微服务提供者突然宕机了,此时就会出现 404 的情况,这时可以使用 Ribbon 的请求重试机制,Ribbon 的请求重试机制基于 Spring 的 retry(Spring 的重试框架)。
使用
在微服务消费者导入 spring-retry 的 Maven 坐标:
1 | <dependency> |
修改微服务消费者的 application.yml:
1 | # Ribbon的重试机制 |
Ribbon 中负载均衡的源码分析
参考文章:https://www.yuque.com/sunxiaping/yg511q/kxmrqz#b7025e02
轮询算法原理
手写负载算法
原理+JUC(CAS+自旋锁的复习)
启动 Eureka 集群,7001 和 7002
8001 和 8002 微服务改造
在这两个提供者的 Controller 中加入以下代码,便于测试
1 | "/payment/lb") (value = |
服务提供者 80 改造
配置类
去掉 @LoadBalanced 注解
LoadBalancer 接口
1 | package com.itjing.springcloud.lb; |
LoadBalancer 接口实现类
1 | package com.itjing.springcloud.lb; |
OrderController
加入以下内容
1 |
|
启动访问测试
http://localhost/consumer/payment/lb
发布时间: 2021-01-16
最后更新: 2024-06-24
本文标题: SpringCloud Alibaba入门到精通(五)- 负载均衡Ribbon(不过时,但推荐使用Spring Cloud Loadbalancer)
本文链接: https://blog-yilia.xiaojingge.com/posts/a65be2d5.html
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可。转载请注明出处!
