一、如果只想加入feign,不要载入hystrix,则在引包时排除掉hystrix的包。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId><exclusions><exclusion><groupId>io.github.openfeign</groupId><artifactId>feign-hystrix</artifactId></exclusion></exclusions>
</dependency>

并且去掉//@EnableHystrix和

@FeignClient(name = "ACCOUNT-SERVICE"/*,fallback = AccountFeignClientHystrix.class*/)
public interface AccountFeignClient {

的配置,以及application中的hystrix配置

feign.hystrix.enabled=false#任务执行超时时间
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=400
#
#hystrix.command.default.circuitBreaker.requestVolumeThreshold=2
#
##设置统计的时间窗口值的毫秒值
#hystrix.command.default.metrics.rollingStats.timeInMilliseconds=5000
#
#hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5000
#
#hystrix.command.default.circuitBreaker.enabled=true
#
## 错误比率阀值,如果错误率>=该值,circuit会被打开,并短路所有请求触发fallback。默认50
#hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
#
## 线程池大小
#hystrix.threadpool.default.coreSize=3
## 缓冲区大小, 如果为-1,则不缓冲,直接进行降级 fallback
#hystrix.threadpool.default.maxQueueSize=5
## 缓冲区大小超限的阈值,超限就直接降级
#hystrix.threadpool.default.queueSizeRejectionThreshold=2
#
## fallback执行并发量
#hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=2ribbon.ReadTimeout=30000
ribbon.ConnectTimeout=30000
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.simplemall.micro.serv</groupId><artifactId>simplemall-proj</artifactId><version>0.0.1-SNAPSHOT</version></parent><groupId>com.simplemall.micro.serv.page</groupId><artifactId>front-app</artifactId><name>frontPage</name><description>前端页面及服务调用</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.7</java.version></properties><dependencies><!--        <dependency>-->
<!--         <groupId>org.springframework.cloud</groupId>-->
<!--         <artifactId>spring-cloud-starter-config</artifactId>-->
<!--     </dependency>--><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>1.4.6</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zipkin</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!--        <dependency>-->
<!--         <groupId>org.springframework.cloud</groupId>-->
<!--         <artifactId>spring-cloud-starter-hystrix</artifactId>-->
<!--     </dependency>--><!--        <dependency>-->
<!--         <groupId>org.springframework.boot</groupId>-->
<!--         <artifactId>spring-boot-starter-actuator</artifactId>-->
<!--     </dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency>
<!--     <dependency>-->
<!--         <groupId>org.springframework.boot</groupId>-->
<!--         <artifactId>spring-boot-devtools</artifactId>-->
<!--         <optional>true</optional>-->
<!--     </dependency>--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-joda</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.module</groupId><artifactId>jackson-module-parameter-names</artifactId></dependency><!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.6.1</version></dependency><!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.6.1</version></dependency><dependency><groupId>com.simplemall.micro.serv.common</groupId><artifactId>common-module</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- client request framework --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId><exclusions><exclusion><groupId>io.github.openfeign</groupId><artifactId>feign-hystrix</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId></dependency><!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.7.0</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.10</version></dependency><!--        <dependency>-->
<!--         <groupId>org.springframework.cloud</groupId>-->
<!--         <artifactId>spring-cloud-starter-bus-amqp</artifactId>-->
<!--     </dependency>--><!--        <dependency>-->
<!--         <groupId>org.springframework.cloud</groupId>-->
<!--         <artifactId>spring-cloud-starter-netflix-turbine</artifactId>-->
<!--     </dependency>--></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Camden.SR5</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

二、调试接口,查看代码

package com.simplemall.micro.serv.page.client;import java.util.List;//import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
//import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
//import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import com.simplemall.micro.serv.page.client.hystrix.AccountFeignClientHystrix;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import com.simplemall.micro.serv.common.bean.account.AccAddress;
import com.simplemall.micro.serv.common.bean.account.Account;/*** feign与@RequestParam配合使用时,一定要写value值。* feign方法的@RequestMapping,务必与服务端方法保持一致,请求类型,请求参数,返回值等等* * TODO 可以从服务端定义一个接口层,服务实现层实现接口,调用方扩展此接口,即可完成接口定义的复用,而无须在此重新复制一次。* 但此举会导致服务端接口变动后,调用方就会直接受影响,建议事先约定好规则* * @author guooo**/
@FeignClient(name = "ACCOUNT-SERVICE"/*,fallback = AccountFeignClientHystrix.class*/)
public interface AccountFeignClient {/*** 登录* * @param phone* @param password* @return*/@RequestMapping("/acc/login")public Account login(@RequestParam("phone") String phone, @RequestParam("password") String password);/*** 注册* * @param phone* @param password* @return*/@RequestMapping("/acc/signup")
//      @HystrixCommand(groupKey="test-thread-quarantine",
//          commandKey = "testThreadQuarantine",
//          threadPoolKey="test-thread-quarantine",
//          threadPoolProperties = {
//                  @HystrixProperty(name="coreSize", value="30"),
//                  @HystrixProperty(name="maxQueueSize", value="100"),
//                  @HystrixProperty(name="keepAliveTimeMinutes", value="2"),
//                  @HystrixProperty(name="queueSizeRejectionThreshold", value="15")
//          },
//          fallbackMethod = "threadQuarantineFallback")public String signup(@RequestParam("phone") String phone, @RequestParam("password") String password);/*** get address list* * @param accountTid* @return*/@RequestMapping("/address/list/{accountTid}")// @HystrixCommand(fallbackMethod="semaphoreQuarantineFallback",
//          commandProperties={
//                  @HystrixProperty(
//                          name= HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY,
//                          value="SEMAPHORE"), // 信号量隔离
//                  @HystrixProperty(
//                          name=HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS,
//                          value="100") // 信号量最大并发数
//          })public List<AccAddress> getList(@RequestParam(value = "accountTid", required = true) @PathVariable("accountTid") String accountTid);
}
@Slf4j
@Api(value = "用户服务", tags = "用户服务接口")
@RestController
@RefreshScope // 使用该注解的类,会在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。需要重新触发加载动作可以使用POST方式请求/refresh接口,该接口位于spring-boot-starter-actuator依赖,调用前需添加否则404。
public class APIAccountController {private Logger logger = LoggerFactory.getLogger(APIAccountController.class);/*** 短信开关*/
//  @Value("${switch.sms}")private boolean switchSMS = true;@Autowiredprivate AccountFeignClient accountFeignClient;@ApiOperation(value = "用户登陆")@RequestMapping(value = "acc/login", method = { RequestMethod.POST,RequestMethod.GET })public RestAPIResult<String> login(@ApiParam(value = "手机号") @RequestParam(required = true) String phone,@ApiParam(value = "密码") @RequestParam(required = true) String password, HttpSession session) {RestAPIResult<String> restAPIResult = new RestAPIResult<>();try{Account account = accountFeignClient.login(phone, password);log.info(" account:{}", JSONObject.toJSONString(account));if (StringUtils.isEmpty(account.getTid())) {restAPIResult = new RestAPIResult<String>("登陆失败,用户名或密码不正确!");restAPIResult.setRespData("kkk");} else {if (account.getTid().equalsIgnoreCase("hystrix")){restAPIResult = new RestAPIResult<String>("hystrix!");restAPIResult.setRespData("触发熔断");}else{try {// 正常情况返回jwtJSONObject subject = new JSONObject(true);subject.put("tid", account.getTid());// token此处定义12小时有效,据实际应用场景确定有效性,也可以定义刷新机制,保持用户token的使用时限String accessToken = JWTUtils.createJWT(UUIDUtils.getUUID(), subject.toJSONString(),12 * 60 * 60 * 1000);restAPIResult.setRespData(accessToken);} catch (Exception e) {logger.error("生成jwt异常{}", e);}}}logger.info("login result = {}", restAPIResult.getRespData());}catch (Exception e){restAPIResult = new RestAPIResult<String>("登陆异常!");restAPIResult.setRespData(e.getMessage());}return restAPIResult;}

查看调用堆栈,我们可以看到feignClient的代理对象为FeignInvocationHandler,真正的处理类为

SynchronousMethodHandler

然后client为LoadBalancerFeignClient, 这里通过LoadBalancerContext获取负载均衡器的健康实例

ILoadBalancer lb = getLoadBalancer();
Server svc = lb.chooseServer(loadBalancerKey);

然后在AbstractLoadBalancerAwareClient.executeWithLoadBalancer进行URL中的HOST服务名替换为真实IP端口。

public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, requestConfig);LoadBalancerCommand<T> command = LoadBalancerCommand.<T>builder().withLoadBalancerContext(this).withRetryHandler(handler).withLoadBalancerURI(request.getUri()).build();try {return command.submit(new ServerOperation<T>() {@Overridepublic Observable<T> call(Server server) {URI finalUri = reconstructURIWithServer(server, request.getUri());S requestForServer = (S) request.replaceUri(finalUri);try {return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));} catch (Exception e) {return Observable.error(e);}}}).toBlocking().single();} catch (Exception e) {Throwable t = e.getCause();if (t instanceof ClientException) {throw (ClientException) t;} else {throw new ClientException(e);}}}

替换完是这样

接着跳到FeignLoadBalancer.execute

这里配置超时,就是ribbon的超时,然后通过RetryTemplate进行一个重试框架的调用

现在进到真正的client调用

这里有一个TraceFeignClient,用来做链路追踪的。

 最终调用这个代理client对象真正完成HTTP请求。

Response response = this.delegate.execute(modifiedRequest, options);

代理对象源码


package feign;/*** Submits HTTP {@link Request requests}. Implementations are expected to be thread-safe.*/
public interface Client {Response execute(Request request, Options options) throws IOException;public static class Default implements Client {@Overridepublic Response execute(Request request, Options options) throws IOException {HttpURLConnection connection = convertAndSend(request, options);return convertResponse(connection).toBuilder().request(request).build();}

执行堆栈 

这里已经返回结果了

HttpResponse

最后外层返回结果

spring cloud feign 加载流程相关推荐

  1. Spring的bean加载流程

    IOC容器就像是一个工厂,里面有很多流水线生产出一个个产品(bean).bean的加载流程大概分为: 容器启动阶段 bean加载阶段 容器启动阶段: 1.配置元信息 当你生产物品的时候总得知道产品得规 ...

  2. spring ioc加载流程

    一.总框架加载流程 1.applicationContext创建beanFactory-> 2.beanFactory通过XMLbeandefineReader解析文件,获取BeanDefini ...

  3. spring启动加载流程

    上次看了spring的加载流程,今天发现或多都忘记了,今天又看了一下,顺便总结一下: 标题spring的web项目启动: 1.首先web容器(比如Tomcat)会读取配置在web.xml中的监听器,从 ...

  4. Spring初始化加载流程分析

    关于Spring框架的介绍,网上有很多非常好的详细的文章,如果在本篇博客中没有了解到自己想要的东西,个人能力有限,只能使用博客记录一下自己目前了解的知识点了! 本篇博客将大致介绍一下Spring框架的 ...

  5. Spring Cloud Feign使用详解

     通过前面两章对Spring Cloud Ribbon和Spring Cloud Hystrix的介绍,我们已经掌握了开发微服务应用时,两个重要武器,学会了如何在微服务架构中实现客户端负载均衡的服务调 ...

  6. Spring解析,加载及实例化Bean的顺序(零配置)

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 作者:jb_hz blog.csdn.net/qq_2752 ...

  7. Spring框架—SpringBean加载过程

    原文作者:RunAlgorithm 原文地址:图文并茂,揭秘 Spring 的 Bean 的加载过程 1. 概述 Spring 作为 Ioc 框架,实现了依赖注入,由一个中心化的 Bean 工厂来负责 ...

  8. Dubbo(十)之配置加载流程

    转载自  Dubbo配置加载流程 Dubbo 中的配置加载流程介绍 此篇文档主要讲在应用启动阶段,Dubbo框架如何将所需要的配置采集起来(包括应用配置.注册中心配置.服务配置等),以完成服务的暴露和 ...

  9. Spring Boot : 资源加载器

    1.美图 2.概述 前言参考: 源码:Spring boot 主程序的功能(启动流程) ResourceLoader接口,在 Spring 中用于加载资源,通过它可以获取一个Resouce 对象.使用 ...

最新文章

  1. PoPo数据可视化第8期
  2. 2019.7.29学习整理python
  3. android 动态申请权限_你真的了解Android权限机制吗?
  4. zabbix使用ICMP ping监控网络状态
  5. php安装sphinx扩展,安装php的sphinx扩展模块
  6. Tomcat JMX
  7. ofo显示服务器故障,ofo服务器超时
  8. python三维转换教程_Python科学计算三维可视化【完结】
  9. 深度学习入门:手写体识别
  10. java程序员必备---2020年idea官方最新版ideaIU-2020.1.1.exe
  11. PCAN Explorer之plot插件导出数据时间格式转换
  12. html自动播放音乐
  13. 衡山湘大学计算机学校,南岳衡山烧香求学业显灵感恩南岳大庙祈福考上985双一流重点大学...
  14. App-UI自动化测试(Airtest+Pycharm)
  15. 《NVMe-over-Fabrics-1_0a-2018.07.23-Ratified》阅读笔记(1)
  16. js实现局部刷新数据
  17. 如何使用谷歌浏览器远程调试安卓/ios真机H5应用?
  18. android开发沉浸式标题栏_android实现沉浸式状态栏
  19. 2024中山大学计算机考研信息汇总
  20. java 回滚异常_Java异常与事物回滚探究

热门文章

  1. 会计记忆总结之二:会计要素和会计科目
  2. SD--关于销售环节的折扣、折让、回扣、佣金的介绍
  3. 2020年什么名字最受欢迎?前面“奕辰”你别走
  4. 从“连锁”到“新联锁”,尚美生活如何引领酒店行业变革?
  5. 从“电商合伙人”到“品牌掌柜”,快手电商“军训”进行时
  6. C语言加取址符的作用,C语言中指针和取地址符的关系
  7. mysql tcp ip_通过TCP/IP连接Mysql数据库
  8. apache的es的原理_Elasticsearch的原理简介
  9. 计算机组成原理we指什么,计算机组成原理课后习题答案一到九章
  10. oracle gsd,晕死:11203GSD死活起不来