荐 SpringCloud(3)--服务调用(Ribbon、OpenFeign)
文章目录
系列链接:
- GitHub:源码
- SpringCloud(1)–入门、版本、环境搭建
- SpringCloud(2)–服务注册与发现(Eureka、Zookeeper、Consul)
- SpringCloud(3)–服务调用(Ribbon、OpenFeign)
- …
服务调用
Ribbon
Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端,主要功能是提供客户端的软件负载均衡算法和服务调用。
注:Ribbon虽然大规模运用,但目前也进入维护,基本上不准备更新了
负载均衡:将用户的请求平摊的分配到多个服务上,常见的负载均衡软件有Nginx等。
Ribbon本地负载均衡客户端与Nginx服务端负载均衡的区别:
-
Nginx是服务器负载均衡,客户端所有请求交给 Nginx,然后由 Nginx 实现转发请求。
-
Ribbon是本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到 JVM 本地,从而在本地实现 RPC 远程服务调用技术。
由上面的区别可以将负载均衡分为两种:
- 集中式LB:在服务的消费方和提供方之间使用独立的LB设施(Nginx)
- 进程内LB:将LB的逻辑继承到消费方,消费方从服务注册中心获知哪些提供方地址可用,然后自己进行选择(Ribbon)
Ribbon就是一个软负载均衡的客户端组件,就是负载均衡+RestTemplate调用,与Eureka结合的架构如下:
Ribbon的使用
-
我们之前实现了负载均衡就是基于 Ribbon,其实在使用eureka的新版本时,默认就集成了Ribbon。
<!--eureka client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
-
RestTemplate类
- xxxForObject()方法:返回的是响应体中的数据
- xxxForEntity()方法:返回的是entity对象,包含响应体数据、响应体信息(状态码等)
Ribbon常用负载均衡算法
Riboon使用 IRule 接口,根据特定算法从所有服务中,选择一个服务。而I Rule 接口有7个实现类。每个实现类代表一个负载均衡算法:
- com.netflix.loadbalancer.RoundRobinRule:轮询
- com.netflix.loadbalancer.RandomRule:随机
- com.netflix.loadbalancer.RetryRule:先轮询,失败则在指定时间内进行重试
- WeightedResponseTimeRule:对轮询的扩展,响应速度越快权重越大
- BestAvailableRule:先过滤处于断路状态的服务,选择一个并发量最小的服务
- AvailabilityFilteringRule:先过滤故障实例,再选择并发较小的实例
- ZoneAvoidanceRule:默认规则,根据Server所在区域的性能和可用性选择服务器。
修改Order模块
有两点需要注意:
-
这里使用 Eureka 的相关服务
-
IRule 自定义配置类不能放在@ComponentScan所扫描的当前包以及子包下
(有@SpringBootApplication注解的Main所在的包)
-
额外创建一个包
-
创建配置类,指定负载均衡算法
@Configuration public class MySelfRule { @Bean public IRule myRule(){ return new RandomRule();//随机负载均衡算法 } }
-
在主启动类上加@RibbonClient注解,表示访问CLOUD-PAYMENT-SERVICE服务时,使用我们自定义的负载均衡算法
@SpringBootApplication @EnableEurekaClient @RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class) public class OrderMain80 { public static void main(String[] args){ SpringApplication.run(OrderMain80.class,args); } }
自定义负载均衡算法
ribbon的轮询算法原理
rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务器重启计数从1开始。
自定义负载均衡算法
实现轮询方式的负载均衡算法。
-
给pay模块(8001,8002)的controller方法添加一个方法,返回当前节点端口
@GetMapping("/lb") public String getPaymentLB(){ return serverPort; }
-
修改order模块,去掉ApplicationContextConfig中的 @LoadBalanced 注解,以及Main上的@RibbonClient注解
-
自定义接口
public interface LoadBalancer { //从服务列表中选取一个服务 ServiceInstance instances(List<ServiceInstance> serviceInstances); }
-
接口实现类
@Component public class MyLB implements LoadBalancer { private AtomicInteger atomicInteger = new AtomicInteger(0); private final int getAndIncrement(){ int current; int next; do{ current = this.atomicInteger.get(); next = current >= Integer.MAX_VALUE ? 0 : current+1; }while(!this.atomicInteger.compareAndSet(current,next)); System.out.println("****next: "+next); return next; } @Override public ServiceInstance instances(List<ServiceInstance> serviceInstances) { int index = getAndIncrement() % serviceInstances.size(); return serviceInstances.get(index); } }
-
修改controller:
@Resource private LoadBalancer loadBalancer;//自定义的 @Resource private DiscoveryClient discoveryClient;
@GetMapping("/payment/lb") public String getPaymentLB(){ List<ServiceInstance> serviceInstances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE"); if(serviceInstances == null || serviceInstances.size() <= 0){ return null; } ServiceInstance instance = loadBalancer.instances(serviceInstances); URI url = instance.getUri(); return restTemplate.getForObject(url+"/payment/lb",String.class); }
-
启动服务,测试接口
OpenFeign
Feign是一个声明式WebService客户端,服务调用只需在自己的接口上添加相应的注解。其简化了使用 Spring Cloud Ribbon 时,自动封装服务调用客户端的开发过程,其实 Feign 底层集成了 Ribbon 和 RestTemplate。
Feign与OpenFeign区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HNbFY4C1-1594459297952)(https://hw.mokespace.cn/images/2020/07/11/242dd143bf8a766ead4941bef46bf3b0.png)]
OpenFeign的使用
-
新建一个order项目,用于feign测试,名称为 cloud-consumer-feign-order80
-
pom文件,比原始的多一个openfeign依赖
<!-- openfeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
配置文件
server: port: 80 eureka: client: register-with-eureka: false service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
-
主启动类
@SpringBootApplication @EnableFeignClients //开启 public class OrderFeginMain80 { public static void main(String[] args){ SpringApplication.run(OrderFeginMain80.class,args); } }
-
fegin需要调用的其他的服务的接口
@FeignClient(value = "CLOUD-PAYMENT-SERVICE") public interface PaymentService { @GetMapping("/payment/get/{id}") public CommonResult getPaymentById(@PathVariable("id") Long id); }
-
controller
@RestController @Slf4j @RequestMapping("/consumer") public class OrderFeginController { @Resource private PaymentService paymentService; @GetMapping("/payment/get/{id}") public CommonResult<Payment> getPyamentById(@PathVariable("id")Long id){ return paymentService.getPaymentById(id); } }
-
测试:启动两个erueka(7001,7002)、两个pay(8001,8002)、当前的order模块
OpenFeign超时机制
首先,OpenFeign 默认等待时间是1秒,超过1秒会直接报错,如下图:
设置超时时间,修改配置文件
因为OpenFeign的底层是ribbon进行负载均衡,所以它的超时时间是由ribbon控制,所以在配置文件对 ribbon 进行配置:
ribbon:
# 建立连接后,在服务端读取数据的时间
ReadTimeout: 5000
# 建立连接所需的时间
ConnetTimeout: 5000
OpenFeign日志
Feign提供了日志打印的功能,可以调整日志级别来了解接口的调用情况。
OpenFeign的日志级别有:
- NOEE:默认,不显示日志
- BASIC:仅记录请求方法、URL、响应状态码以及执行时间
- HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息
- FULL:除了 HEADERS 中定义的信息外,还有请求和响应的正文以及元数据
使用OpenFeign的日志:
-
实现在配置类中添加OpenFeign的日志类
@Configuration public class FeignConfig { @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.FULL;//日志级别 } }
-
为指定类设置日志级别,配置文件中
logging: level: # feign 日志以什么级别监控哪个接口 com.moke.springcloud.service.PaymentService: debug
-
启动服务即可
本文地址:https://blog.csdn.net/MOKEXFDGH/article/details/107287927
上一篇: 90后有演技的年轻演员:刘昊然上榜,第四是童星出身
下一篇: 注解实现Spring IOC与事务控制
推荐阅读
-
SpringCloud学习笔记(3):使用Feign实现声明式服务调用
-
[SpringCloud学习笔记3]SpringCloud服务调用(ribbon,openFeign)
-
SpringCloud_4Ribbon负载均衡服务调用和OpenFeign服务接口调用学习笔记
-
荐 SpringCloud(3)--服务调用(Ribbon、OpenFeign)
-
用SpringCloud Alibaba搭建属于自己的微服务(十四)~基础搭建~使用springcloud openfeign实现rpc调用
-
springcloud【六】OpenFeign服务调用
-
聊聊SpringCloud中的Ribbon进行服务调用的问题
-
springcloud使用nacos作为注册中心用openfeign调用服务
-
SpringCloud 服务调用 - OpenFeign
-
SpringCloud学习笔记(3):使用Feign实现声明式服务调用