疯狂Spring Cloud连载(21)Feign与Hystrix整合

本文介绍如何在Spring Cloud微服务架构中整合Feign与Hystrix,实现服务调用的熔断机制。通过配置Feign客户端启用Hystrix,并设置超时及断路器阈值,演示了服务调用超时后的熔断效果。
摘要由CSDN通过智能技术生成

本文节选自《疯狂Spring Cloud微服务架构实战》

京东购买地址:https://item.jd.com/12256011.html

当当网购买地址:http://product.dangdang.com/25201393.html

Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

Spring Cloud电子书:https://my.oschina.net/JavaLaw/blog/1570383

Feign与Hystrix整合

        Feign对Hystrix提供了支持,为“服务调用者”加入以下Feign依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>

        在application.yml中打开Feign的Hystrix开关,请见以下配置:

feign:
  hystrix:
    enabled: true

        在应用启动类里面,加入开Feign的开关,本小节的“服务调用者”应用启动类,所使用的注解如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@ServletComponentScan
@EnableFeignClients

        新建Feign接口,调用“服务提供者(spring-hystrix-provider)”的“/hello”服务,请见代码清单6-24。

        代码清单6-24:

        codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\feign\HelloClient.java

@FeignClient(name = "spring-hystrix-provider", fallback = HelloClientFallback.class)
public interface HelloClient {

    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    public String hello();

    @Component
    static class HelloClientFallback implements HelloClient {

        public String hello() {
            System.out.println("hello 方法的回退");
            return "error hello";
        }
    }
}

        与普通的Feign客户端无异,仅仅设置了处理回退的类,回退类实现了客户端接口。为了能测试效果,修改服务器端的“/hello”服务,让其有800毫秒的延时。根据前面章节可知,默认情况下,Hystrix的超时时间为1秒,因此,还需要修改配置超时配置。代码清单6-25,在application.yml中修改命令配置。

        代码清单6-25:codes\06\6.4\spring-hystrix-invoker\src\main\resources\application.yml

hystrix:
  command:
    HelloClient#hello():
      execution:
        isolation:
          thread: 
            timeoutInMilliseconds: 500
      circuitBreaker:
        requestVolumeThreshold: 3

        注意,如果是针对全局配置,则使用与下面类似的配置片断:

hystrix.command.default.circuitBreaker.requestVolumeThreshold // 默认时间段内发生的请求数
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds // 超时时间

        如果针对某个客户端,如使用下面的配置片断:

hystrix.command.CommandKey.circuitBreaker.requestVolumeThreshold

        Feign与Hystrix整合使用时,会自动帮我们生成CommandKey,格式为:“Feign客户端接口名#方法名()”。例如本例中的客户端为HelloClient,方法为hello,生成的CommandKey为“HelloClient#hello()”。而默认情况下,生成的GroupKey为@FeignClient注解的name属性。

        以上的配置中,我们针对了hello方法,设置了超时时间为500毫秒,而“/hello”服务超时时间为800毫秒,换言之,hello方法总会超时。另外,如果请求超过3次并且失败率超过50%,断路器将被打开。编写控制器,调用hello服务,并查看断路器的情况,请见代码清单6-26。

        代码清单6-26:HelloController.java

@RestController
public class HelloController {

    @Autowired
    HelloClient helloClient;

    @RequestMapping(value = "/feign/hello", method = RequestMethod.GET)
    public String feignHello() {
        // hello方法会超时
        String helloResult = helloClient.hello();
        // 获取断路器
        HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory
                .getInstance(HystrixCommandKey.Factory
                        .asKey("HelloClient#hello()"));        
        System.out.println("断路器状态:" + breaker.isOpen());
        return helloResult;
    }
}

        控制器的方法中,获取了hello方法的断路器,并输出其状态。接下来,编写一个测试客户端,多线程访问:http://localhost:9000/feign/hello/{index},也就是控制器的feignHello方法,客户端请见代码清单6-27。

        代码清单6-27:

        06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\feign\TestFeignClient.java

public class TestFeignClient {
    
    public static void main(String[] args) throws Exception {
        // 创建默认的HttpClient
        final CloseableHttpClient httpclient = HttpClients.createDefault();        
        // 调用多次服务并输出结果
        for(int i = 0; i < 6; i++) {
            // 建立线程访问接口
            Thread t = new Thread() {
                public void run() {
                    try {
                        String url = "http://localhost:9000/feign/hello";
                        // 调用 GET 方法请求服务
                        HttpGet httpget = new HttpGet(url);
                        // 获取响应
                        HttpResponse response = httpclient.execute(httpget);
                        // 根据 响应解析出字符串
                        System.out.println(EntityUtils.toString(response.getEntity()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            t.start();
        }
        // 等待完成
        Thread.sleep(15000);
    }
}

        完成后,依次启动Eureka服务器、服务提供者、服务调用者,运行代码清单6-27,可看到“服务计用者”的控制台输出如下:

断路器状态:false
断路器状态:false
断路器状态:false
断路器状态:false
断路器状态:true
断路器状态:true

        根据输出可知,断路器已经被打开。

本文节选自《疯狂Spring Cloud微服务架构实战》

Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

Spring Cloud电子书:https://my.oschina.net/JavaLaw/blog/1570383

本书代码共享地址:https://gitee.com/yangenxiong/SpringCloud

140509_5TSO_3665821.png

转载于:https://my.oschina.net/JavaLaw/blog/1575850

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值