SpringCloud集成Resilience4j实现熔断器( 二 )


// after Hystrix is removed from SpringCloud2021.0.1, the fallback is ineffective//@FeignClient(name = "${codeman.service.name:codeman}", url = "${codeman.service.address:}", fallback = CodeManFallbackImpl.class)public interface CodeManFeign extends CodeManService {@RequestLine("GET /codeman/info/version")public String getVersion();@RequestLine("GET /codeman/info/author")public String getAuthor();@RequestLine("GET /codeman/info/author/{userid}")//对应请求方式和路径public String requestLine(@Param("userid") String userid);} 
通过上面的代码可以看到在Feign的定义接口里 ,  不再使用SpringMVC里的标准Post/Get/Delete/Request等; 而是使用Feign标准的注解RequestLine;这个估计大多数做过Feign的朋友 , 还不知道这个才是Feign的标准Annotation; 由于上一步 , 我们修改了Consract不再使用SpringMVCConstract;所以Post/Get/Delete/Request等这些在SpringMVC里的Annotation不能使用;必须替换;
 
业务调用 
上一段代码 , 我们定义出了RPC的remote调用接口;在service层 , 我们使用已定义的Feign接口 , 完成业务上的调用;
 
@Componentpublic class CodeManServiceImpl implements CodeManService{//@Autowired//CodeManFeign codeManFeign;@Value("${codeman.service.address:http://${codeman.service.name:codeman}}")private String url;@Value("${codeman.service.name:codeman}")private String name;CircuitBreaker circuitBreaker;CodeManFeign codeManFeign;@PostConstructpublic void init(){circuitBreaker = CircuitBreaker.ofDefaults("backendA");FeignDecorators decorators = FeignDecorators.builder().withFallback(new CodeManFallbackImpl(), FeignException.class).build();codeManFeign = Resilience4jFeign.builder(decorators).target(new Target.HardCodedTarget<>(CodeManFeign.class,name, url));}@Overridepublic String getVersion() {return codeManFeign.getVersion();}@Overridepublic String getAuthor() {return codeManFeign.getAuthor();}@Overridepublic String requestLine(String userid) {return codeManFeign.requestLine(userid);}} 
上面的业务调用的代码;和我们经常使用OpenFeign进行调用上有点差别;在与对CodeManFeign的IOC的获取上;可以看到代码里
 
注释掉了通过IOC的方式
 

//@Autowired
//CodeManFeign codeManFeign;
 
而是通过
 
@PostConstruct
public void init(){
}
 
的方式 , 在init里通过FeignDecorators.builder()去实例化了Resilience4jFeign.builder(decorators).target()的方式去实例化了这个; 这里也是不解的地方;为什么不去类似Hystrix的哦方式 。在Feign接口定义的时候 , 也去做一些绑定 , 而是要手工在这里通过API进行绑定; 对这个不解:个人的感觉;可能还是在产品设计的时候 , 让这个设置更加的细化吧 。
 
在我们自己的项目里 , 在这里是自己做了处理的 , 其实这个处理的目的就省略掉Init里的代码
 
定义Fallback的实现 
public class CodeManFallbackImpl implements CodeManService {@Overridepublic String getVersion() {return "N/A";}@Overridepublic String getAuthor() {return "SpringCloud";}@Overridepublic String requestLine(String userid){return "Kill team‘s poison";}} 
通过以上的步骤 , 就可以实现Resilience4j的熔断器的实现了 。题外话 , 由于我们自己的项目都是使用的springcloud来实现微服务;并且都是在springcloud的基础上结合公司项目的特点 , 封装了自己的springcloud的开发框架 , 在springcloud的ioc是个好东西 , 但是在spring里的ioc到处都是 , 不仅增加了调试问题和追踪问题的复杂程度;而且更让人不放心的就是ioc都是使用反射或者动态代理的方式进行处理的 ,  这样的实现方式真的存在着很大的隐患;不过由于我们使用SpringCloud实现的微服务大多数都是来处理业务应用 , 反射的性能低下相对于业务应用往往性能的瓶颈而言 , 基本上都可以忽略不计了 , 这样的隐患也就藏起来了 。当然在学习了Go语言以后 , 深深地体会到了 , 做服务和做业务对设计模式的取舍点的不同;
 
结束语 
本文主要介绍的是在SpringCloud微服务开发中 , 如何使用Resilience4j实现熔断器功能的实现方式; 也可以直接通过resilience4j的API , 在自己的Java程序里实现熔断器功能 ,  说实在的 , SpringCloud的微服务体系真的和Service Mesh的体系一比较 , 真的就是一个小孩和大人的比较 , 熔断是业务需求吗 , 既然不是 , 为什么springCloude的开发中 , 微服务的代码却要揉入熔断器的开发代码; 别扭吧; 这就是Service Mesh为什么会是未来的原因 。


推荐阅读