springcloud demo入门篇(二)
springcloud demo入门篇(二)
整合feign和hystrix组件
上篇我们已经完成了对eureka组件的整合,这篇继续整合springcloud的另外两个重要组件——feign和hystrix。
先来介绍下feign的基本概念:
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。
Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
简而言之:
- Feign 采用的是基于接口的注解
- Feign 整合了ribbon,具有负载均衡的能力
- 整合了Hystrix,具有熔断的能力
feign的大概实现原理是在Feign 底层,通过基于面向接口的动态代理方式生成实现类,将请求调用委托到动态代理实现类,具体原理可参考博客https://www.jianshu.com/p/8c7b92b4396c,博主讲的非常详细。
下面开始feign的具体整合,先说下,一般使用feign是在privoder提供业务的具体实现,consumer端编写feign接口,加上@FeignClient注解指定服务,consumer直接调用即可。这样可以实现,但感觉Feign可以单独抽出作个服务会减少耦合性,代码逻辑也会清晰不少。结构图如下:
shop-feign模块的pom.xml内容:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
但这里要注意,shop-feign作为公共模块供provider和consumer引用,所以相当于是个公共的api模块,可以不是springboot项目,所以springboot的启动类可以删掉,pom里的maven-plugin也不能要,不然会报错。
shop-feign里编写feign接口:@FeignClient(name="privoder服务名"),@GetMapping注解不能少,路由路径倒无关紧要,随便写,因为我们会在provider端实现这个接口,consumer去调用stockWebFeign的duduct()方法时,其实会直接指向这个接口的实现类(也是feign底层动态代理思想的体现)。
@FeignClient(name="shop-stock")
public interface StockWebFeign {
@GetMapping("/stock/deduct")
void deduct();
}
provider端实现这个feign接口:
shop-stock pom.xml添加shop-feign服务的依赖,并新建StockWebFeignController(@RestController注解不能少,少了会报错)实现公共feign接口,接下来就引入本服务下的ShopStockService,直接调用其减库存的duduct()方法就ok了。
shop-stock pom.xml
<!--依赖feign服务-->
<dependency>
<groupId>com.gjn</groupId>
<artifactId>shop-feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
consumer端的pom中同样添加对shop-feign模块的依赖,启动类上增加@EnableFeignClients(basePackages = "com.gjn.shopfeign.*")注解并指定feign接口所在的包(必须指定,因为shop-feign作为公共模块引入consumer端,springboot的启动类并扫描不到@FeignClient注解,所以要手动指定feign接口所在位置),业务代码中引入feign接口,调用其方法即可。
此刻即可测试feign功能是否生效,启动所有服务,stock服务启动两个端口8080和8081,浏览器多次访问消费端,可以看到feign功能正常且负载均衡也已生效。
hystrix相关概念:
在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。为了解决这个问题,业界提出了断路器模型,hystrix就是该模型组件。
接下来整合hystrix,shop-stock端添加hystrix的依赖,启动类添加@EnableHystrix注解,业务方法上添加注解并指定方法名@HystrixCommand(fallbackMethod = "方法名"),编写降级逻辑即可。重启相关服务,经测试,hystrix的fallback生效。
<!--依赖hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
@Service
public class ShopStockServiceImpl implements ShopStockService {
@Override
@HystrixCommand(fallbackMethod = "deductError")
public void deduct() {
//添加异常代码,看fallback是否生效
int i = 1/0;
System.out.println("=========stock 8081=========");
}
public void deductError() {
System.out.println("=========stock error 8081=========");
}
}