Spring Cloud Ribbon
Ribbon是什么?
- (Spring Cloud Netflix) -->大量使用了Netflix公司的开源项目
- (Spring Cloud Alibaba)-->大量使用了Alibaba公司的开源项目
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡器;
我们通常说的负载均衡是指将一个请求均匀地分摊到不同的节点单元上执行,负载均衡分为硬件负载均衡和软件负载均衡:
- 硬件负载均衡:比如 F5、深信服、Array 等;
- 软件负载均衡:比如 Nginx、LVS、HAProxy 等;(是一个服务器实现的)
Ribbon是Netflix公司发布的开源项目(组件、框架、jar包),主要功能是提供客户端的软件负载均衡算法,它会从eureka中获取一个可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可以正常访问的服务端节点。
当客户端发送请求,则ribbon负载均衡器按某种算法(比如轮询、权重、 最小连接数等)从维护的可用服务端清单中取出一台服务端的地址,然后进行请求;
Ribbon非常简单,可以说就是一个jar包,这个jar包实现了负载均衡算法,Spring Cloud 对 Ribbon 做了二次封装,可以让我们使用 RestTemplate 的服务请求,自动转换成客户端负载均衡的服务调用。
Ribbon 支持多种负载均衡算法,还支持自定义的负载均衡算法。
客户端负载均衡 vs 服务端负载均衡
采用Ribbon实现服务调用
首先加入ribbon的依赖,但是eureka已经依赖了ribbon,所以这里不需要再引用ribbon的依赖;
要使用ribbon,只需要一个注解:
- @Bean
- @LoadBalanced
- public RestTemplate restTemplate(){
- RestTemplate restTemplate = new RestTemplate();
- return restTemplate;
- }
在RestTemplate上面加入@LoadBalanced注解,这样就可以实现RestTemplate 在调用时自动负载均衡;
我们这里现在启动了eureka集群(3个eureka) 和服务提供者集群(2个service-goods) 和一个服务调用者(service-portal)
#告诉服务端,服务实例的唯一ID
eureka.instance.instance-id=34-sprinGCloud-service-portal
Ribbon 负载均衡策略
Ribbon 的负载均衡策略是由 IRule 接口定义, 该接口由如下实现:
在jar包:com.netflix.ribbon#ribbon-loadbalancer中;
要使用ribbon实现负载均衡,在Spring 的配置类里面把对应的负载均衡接口实现类作为一个Bean配置一下就行了;
负载均衡的入口:ILoadBalancer接口
如果要切换负载均衡策略:
- @Bean
- public IRule iRule(){
- return new RoundRobinRule();
- }
如果我们没有指定负载均衡策略,ribbon默认的负载均衡是ZoneAvoidanceRule;(新版本,G版本)
Spring Cloud Feign
Feign是什么?
Feign 是 Netflix 公司开发的一个声明式的 REST 调用客户端; (调用远程的restful风格的http接口的一个组件)
调用组件其实很多,比如:
Httpclient(apache)
Httpurlconnection (jdk)
restTemplate(spring)
OkHttp(android)
Feign (Netflix) --> 实现非常优雅
Spring Cloud Feign 对 Ribbon 负载均衡进行了简化,在其基础上进行了进一步的封装,在配置上大大简化了开发工作,它是一种声明式的调用方式,它的使用方法是定义一个接口,然后在接口上添加注解,使其支持了Spring MVC标准注解和HttpMessageConverters,Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
Feign能干什么?
Feign旨在简化微服务消费方(调用者,客户端)代码的开发,前面在使用Ribbon+RestTemplate进行服务调用时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方式,但是在实际开发中,由于服务提供者提供的接口非常多,一个接口也可能会被多处调用,Feign在Ribbon+RestTemplate的基础上做了进一步封装,在Feign封装之后,我们只需创建一个接口并使用注解的方式来配置,即可完成对服务提供方的接口绑定,简化了使用Ribbon + RestTemplate的调用,自动封装服务调用客户端,减少代码开发量;
使用Feign实现消费者
使用 Feign 实现消费者,我们通过下面步骤进行:
创建普通 Spring Boot 工程
把接口放在通用的接口层、常量类、model的项目中
添加依赖
要 添 加 的 依 赖 主 要 是
spring-cloud-starter-netflix-eureka-client 和 spring-cloud-starter-feign,如下:
- -- spring-cloud-starter-openfeign -->
-
org.springframework.cloud -
spring-cloud-starter-openfeign -
第三步:声明服务
定义一个 GoodsRemoteClient 接口,通过@FeignClient 注解来指定服务名称,进而绑定服务,然后再通过 SpringMVC 中提供的注解来绑定服务提供者提供的接口, 如下:
- @FeignClient("34-SPRINGCLOUD-SERVICE-GOODS")
- public interface GoodsService {
- @RequestMapping("/service/goods")
- public String goods();
- }
这相当于绑定了一个名叫34-SPRINGCLOUD-SERVICE-GOODS (这里34-SPRINGCLOUD-SERVICE-GOODS大小写34-sprinGCloud-service-goods都可以 ) 的服务提供者提供的/service/goods 接口;
添加注解
在项目入口类上添加@EnableFeignClients 注解表示开启 Spring Cloud Feign的支持功能;
使用 Controller 中调用服务
接着来创建一个 Controller 来调用上面的服务,如下:
- public class GoodsController {
- @Autowired
- private GoodsService goodsService;
-
- @RequestMapping("/cloud/goodsFeign")
- public ResultObject goodsFeign() {
- //调用远程的一个controller, restful的调用
- return goodsService.goods();
- }
- }
第六步:属性配置
在 application.properties 中指定服务注册中心、端口号等信息,如下:
server.port=8090
#打开所有的web访问端点
management.endpoints.web.exposure.include=*
#此实例注册到eureka服务端的name
spring.application.name=34-sprinGCloud-service-feign
#不注册自己,我是一个消费者,别人如果不调用我的话,我就不用注册
eureka.client.register-with-eureka=false
#每间隔2s,向服务端发送一次心跳,证明自己依然"存活"
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,如果我10s之内没有给你发心跳,就代表我故障了,将我踢出掉
eureka.instance.lease-expiration-duration-in-seconds=10
#告诉服务端,服务实例以IP作为链接,而不是取机器名
eureka.instance.prefer-ip-address=true
#告诉服务端,服务实例的唯一ID
eureka.instance.instance-id=34-sprinGCloud-service-feign
#eureka注册中心的连接地址
#eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka
#eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka
eureka.client.service-url.defaultZone=http://192.168.10.128:8761/eureka,http://192.168.10.128:8762/eureka,http://192.168.10.128:8763/eureka
测试
依次启动注册中心、服务提供者和 feign 实现服务消费者,然后访问如下地址:
http://localhost:8090/cloud/goodsFeign
使用Feign实现消费者的测试
负载均衡:
我们知道,Spring Cloud 提供了 Ribbon 来实现负载均衡,使用 Ribbo 直接注入一个 RestTemplate 对象即可,RestTemplate 已经做好了负载均衡的配置;
在 Spring Cloud 下,使用 Feign 也是直接可以实现负载均衡的,定义一个有@FeignClient 注解的接口,然后使用@RequestMapping 注解到方法上映射远程的 REST 服务,此方法也是做好负载均衡配置的;
通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用;