服务的消费的两种方式:一种使用:rest+ribbon,一种是Feign
一.第二种客户端调用方式 — 服务消费者(Feign)
-
Feign简介
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。
使用Feign,只需要创建一个接口并注解。
它具有可插拔的注解特性,可使用Feign注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。
Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
简单来说:
Feign采用的是基于接口 + 注解;Feign整合了ribbon -
引入依赖
spring-cloud-starter-eureka
spring-cloud-starter-feign
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--引入client的feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
- 在调用的应用中创建 调用接口 并加入调用服务注解
@FeignClient
@FeignClient("HELLO-SERVICE") //明确该接口所对应eureka中哪个服务
public interface HelloServiceInterface {
@RequestMapping("/hello/hello") //指定调用哪个url(一般是:应用名/类名/方法名)
public String hello(@RequestParam("name") String name); //对应上参数
}
- 开发入口类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
开发Controller
@RestController
@RequestMapping("/hello")
public class HelloController {
//注入
@Autowired
private HelloServiceInterface helloServiceInterface;
@RequestMapping("/hello")
public String hello(String name){
String hello = helloServiceInterface.hello(name);
return hello;
}
}
- 配置application.yml
①指定服务端口、②、指定注册中心地址、③指定应用名
spring:
application:
name: springcloud-feign-client #指定应用名
server:
port: 9091 #端口
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
- 请求结果如图
两种客户端调用掌握一种即可,Feign的复用更好,所以更推荐Feign形式
二.断路器(Hystrix)
微服务架构中,根据业务拆分成各个服务,服务间相互调用(RPC),在SpringCloud可以用RestTemplate+Ribbon和Feign来调用。为保证其高可用,单个服务通常会集群部署。
由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。
服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
- 断路器简介
Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下架构所展示一样:
如果较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到到个阀值(Hystric 是5秒 2 0 次) 断路器将会被打开。如下图所示:
注意:此时断路器打开后,可以避免连锁故障,fallback方法可以直接返回一个固定值。
- restTemplate+ribbon 的断路器使用示例
①.引入断路器依赖
spring-cloud-starter-hystrix
<!--引入断路器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
②.开启断路器
入口类加入@EnableHystrix
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
③.使用断路器
开发一个断路器开发
@RestController
@RequestMapping("/show")
@DefaultProperties(defaultFallback = "defaultError")
public class ShowHelloController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/hello")
@HystrixCommand(fallbackMethod = "errorHello" )
//该注解对该方法创建熔断器功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串
//fallbackMethod触发节点:服务器节点都宕机或都阻塞时,才会触发。
public String showHello(String name){
String forObject = restTemplate.getForObject("http://HELLO-SERVICE/hello/hello?name=" + name, String.class);
return forObject;
}
public String errorHello(String name){
return "servers is shutdown, name: " + name;
}
public String defaultError(String name){
return "servers is shutdown, name: " + name;
}
}
④.启动客户端调用,测试断路器
这就说明当服务不可用时,service-ribbon调用服务的API接口时,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞 。
- Feign 的断路器使用示例
使用更为简便,默认集成了Hystrix组件
①.打开断路器
Feign是自带断路器的,在低版本的Springcloud中,它没有默认打开。需要在配置文件件中配置打开它,在配置文件加以下代码:
feign:
hystrix:
enabled: true
②.在FeignClient的服务接口加入如下实现类:
通过实现client接口中的方法,将实现方法作为调用的断路器方法用来返回具体的值
@FeignClient(value = "HELLO-SERVICE",fallback = HelloServiceHystrixImpl.class)
//明确该接口对应eureka中的哪个服务
//fallback用来指定断路器的实现 类的对象
public interface HelloServiceInterface {
@RequestMapping("/hello/hello/")
public String hello(@RequestParam("name") String name);
}
@Component
public class HelloServiceHystrixImpl implements HelloServiceInterface{
@Override
public String hello(String name) {
return "servers is : "+name;
}
}
③.启动测试
三.扩展信息/新闻
1、首先Hystix是什么?
单词中文名称“豪猪”,因为周身长满刺,能保护自己,代表一种防御机制,这与Hystix功能不谋而合。
在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等。如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。
Hystrix提供了熔断、隔离、Fallback、Cache、监控等功能,能够在一个或多个依赖同时出现问题时保证系统依然可用。
一个服务挂了后续的服务跟着不能用了,这就是雪崩效应!
2、Hystrix停止更新,Eureka停止更新
六年的时间说散就散,还来不及学一下原理,就不更新了!一声惋惜,几声叹息!
很多国内的中小公司,没有技术能力更新维护的,基本也都在找替代的技术方案,相继的转向Consul、ZooKeeper、Etcd 等开源中间件上去了。
3、Hystrix官方推荐的替代产品
Hystrix官方同时也推荐我们使用新一代熔断器神器Resilience4j。
Resilience4j有很多优势,比如轻量级、依赖少、模块化程度较好、函数式编程等优势。
4、Spring Cloud该何去何从?
Spring Cloud生态正经历着一些变化,前有Eureka闭源,后有Hystrix停止开发新功能。
同时,Spring Cloud也从依赖生态伙伴提供关键组件,演变到自己开发适配关键组件,例如提供了srpingcloud Zuul、springcloud Config、springcloud Loadbalance等开源产品,逐渐的整合,才能为更多的开发者提供舒心的服务。
5、Dubbo
Dubbo是阿里巴巴公司一个开源的高性能服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案,使得应用可通过高性能RPC实现服务的输出、输入功能和Spring框架无缝集成。
-
Dubbo特性一览
-
一张RPC完整的调用链图
参考资料: https://mp.weixin.qq.com/s/uW5x5wS8XsSPQn7uBm8eDQ