这篇文章主要介绍了春云假装组件实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
采用春云微服务框架后,经常会涉及到服务间调用,服务间调用采用了假装组件。
由于之前有使用达博经验.dubbo的负载均衡策略(轮训,最小连接数,随机轮训,加权轮训),达博失败策略(快速失败,失败重试等等),
所以假装负载均衡策略的是什么?失败后是否会重试,重试策略又是什么?带这个疑问,查了一些资料,最后还是看了下代码。毕竟代码就是一切
弹簧引导集成装的大概流程:
1,利用FeignAutoConfiguration自动配置,并根据EnableFeignClients自动注册产生假装的代理类。
2,注册方式利用FeignClientFactoryBean,熟悉知春道FactoryBean产生豆的工厂,有个重要方法getObject产生FeignClient容器bean
3,同时代理类中使用hystrix做资源隔离,假装代理类中构造RequestTemplate, RequestTemlate要做的向负载均衡选中的服务器发送http请求,并进行编码和解码一系列操作。
下面只是粗略的看了下整体流程,先有整体再有细节吧,下面利用想法看下细节:
<强>一、假装失败重试强>
SynchronousMethodHandler的方法中的处理逻辑:
@Override 公共对象调用(Object [] argv)抛出Throwable { RequestTemplate模板=buildTemplateFromArgs.create (argv); 重试重试=this.retryer.clone (); 而(真){ 尝试{ 返回executeAndDecode(模板); }捕捉(RetryableException e) { retryer.continueOrPropagate (e); 如果(logLevel !=Logger.Level.NONE) { logger.logRetry (metadata.configKey (), logLevel); } 继续; } } }
-
<李>上面的逻辑很简单。构造模板并去进行服务间的http调用,然后对返回结果进行解码李>
<李>当抛出RetryableException后,异常逻辑是否重试?重试多少次?带这个问题,看了retryer.continueOrPropagate (e);李>
具体逻辑如下:
公共空间continueOrPropagate (RetryableException e) { 如果尝试+ +祝辞=maxAttempts) { 把e; } 长时间间隔; 如果(e.retryAfter () !=null) { .getTime间隔=e.retryAfter () ()——currentTimeMillis (); 如果(间隔比;maxPeriod) { 间隔=maxPeriod; } 如果(间隔& lt;0){ 返回; } 其他}{ 间隔=nextMaxInterval (); } 尝试{ thread . sleep(间隔); }捕捉(InterruptedException忽略){ .interrupt Thread.currentThread () (); } sleptForMillis +=间隔; }
-
<李>当重试次数大于默认次数5时候,直接抛出异常,不在重试李>
<李>否则每隔一段时间默认值最大1毫秒后重试一次。李>
这就假装这块的重试这块的粗略逻辑,由于之前工作中一直使用达博。同样是否需要将生产环境中重试操作关闭?
思考:之前达博生产环境的重试操作都会关闭。原因有几个:
-
<李>一般第一次失败,重试也会失败,极端情况下不断的重试,会占用大量达博连接池,造成连接池被打满,影响核心功能李>
<李>也是比较重要的一点原因,重试带来的业务逻辑的影响,即如果接口不是幂等的,重试会带来业务逻辑的错误,引发问题李>
<强>二,假装负载均衡策略强>
那么负载均衡的策略又是什么呢?由上图中可知executeAndDecode(模板)
对象executeAndDecode (RequestTemplate模板)抛出Throwable { 请求请求=targetRequest(模板); 如果(logLevel !=Logger.Level.NONE) { logLevel logger.logRequest (metadata.configKey(),请求); } 响应响应; 长开始=system . nanotime (); 尝试{ 响应=客户机。执行(请求,选项);//设置确保请求。TODO:删除假装10 response.toBuilder () .request(请求).build (); }捕捉(IOException e) { 如果(logLevel !=Logger.Level.NONE) { logLevel logger.logIOException (metadata.configKey (), e, elapsedTime(开始); } 把errorExecuting(请求,e); } 长elapsedTime=TimeUnit.NANOSECONDS.toMillis (system . nanotime()——开始); 布尔shouldClose=true; 尝试{ 如果(logLevel !=Logger.Level.NONE) { 响应=logLevel logger.logAndRebufferResponse (metadata.configKey(),响应,elapsedTime);//设置确保请求。TODO:删除假装10 response.toBuilder () .request(请求).build (); } 如果响应。类==metadata.returnType ()) { 如果(response.body ()==null) { 返回响应; } 如果(response.body () . length ()==null | | response.body () . length()比;MAX_RESPONSE_BUFFER_SIZE) { shouldClose=false; 返回响应; }//确保响应身体是分离的 byte [] bodyData=https://www.yisu.com/zixun/Util.toByteArray (response.body () .asInputStream ()); 返回response.toBuilder () .body (bodyData) .build (); } 如果(response.status ()>=200 & & response.status ()春云假装组件实例解析