前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloud入门(4)Hystrix

SpringCloud入门(4)Hystrix

作者头像
用户8902830
发布2021-08-12 11:04:20
5790
发布2021-08-12 11:04:20
举报
文章被收录于专栏:CodeNoneCodeNone

经过前3节的SpringCloud学习,了解了服务的提供者可能不止有一个端口,在以后的真正的工作中可能还不止有一个微服务来提供服务。如果服务崩掉,如果没有措施,会导致很严重的损失。

就比如如果提供的是购物服务,总不可能让顾客不买东西。还有生活中最常见的例子是当家庭某个电器短路的时候,为了保护整体电器,保险丝就会进行熔断。

Hystrix的诞生就是为了解决这个问题。

1 引入Hystrix

建立hystrix父模块,修改父模块pom文件使其子模块都导入了依赖,方便以后操作。

代码语言:javascript
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
</dependencies>

随后在父模块下新建一个hystrix-consume9301 子模块,最后的项目结构目录如下:

2 主启动类和配置文件

配置文件:

代码语言:javascript
复制
spring:
  application:
    name: hystrix-consume9301
server:
  port: 9301

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://localhost:8001/eureka/
  instance:
    instance-id: hystrix-consume9301

其实配置文件简单来说都是一样的,一直重复写出来就是为了大家方便cv复现

主启动类:

代码语言:javascript
复制
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix  //开启Hystrix
@RestController  //开启业务类
public class HystrixConsume9301 {
    
    public static void main(String[] args) {
        SpringApplication.run(HystrixConsume9301.class, args);
    }

}

3 业务类

再次强调是为了方便入门,直接在主启动类中编写业务类,这是「不规范」的。

为了能够进行服务间的调用,在入门Eureka的时候也说到了利用RestTemplate 即可,所以需要添加一个config类把RestTemplate 注入到Spring容器中。

代码语言:javascript
复制
@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced  //开启负载均衡功能,加了此注解才能通过服务名来访问服务
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

}

回过来看主启动类

代码语言:javascript
复制
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix  //开启Hystrix
@RestController  //开启业务类
public class HystrixConsume9301 {
    
    public static void main(String[] args) {
        SpringApplication.run(HystrixConsume9301.class, args);
    }
 
    //服务名字
    final String PROVIDE_URL = "http://eureka-provide";

    RestTemplate restTemplate;

    public HystrixConsume9301(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/hystrix/consume")
    @HystrixCommand(fallbackMethod = "getInfoFallback") //开启降级服务
    public String getInfo() {
        return "i am hystrix consumer, but actually invoke provide service: [" + restTemplate.getForObject(PROVIDE_URL + "/eureka/provide", String.class) + "]";
    }

    public String getInfoFallback() {
        return "hello, something wrong, i am getInfo fallback method";
    }


}

其它一切都一样,只不过是在相应的业务方法中添加了@HystrixCommand 注解,该注解中的fallbackMethod 声明的是服务降级后回调的是哪个方法。

4 测试

开启Eureka服务注册中心EurekaServer8001,服务提供者EurekaProvide7001,[7002, 7003],开启HystrixConsume9301

访问http://localhost:9301/hystrix/consume,正常情况下如图所示

但是当我们「把所有的服务提供者EurekaProvide7001停掉以模拟服务挂掉的情况」,测试结果如图所示。可以看到服务并没有报错,确实降级调用我们想要调用的方法。

5 扩展

对于扩展方面,这里就稍微提下@HystrixProperty 注解,直接看例子。

通过sleep() 函数来模拟服务提供端延迟提供服务

首先需要修改的是「服务提供端的代码,服务提供端的代码,服务提供端的代码」「也就是本系列第一篇文章中的eureka-client-provide7001子模块项目」

代码语言:javascript
复制
@SpringBootApplication
@RestController
@EnableEurekaClient
public class EurekaProvide7001 {

    @Value("${server.port}")
    int port;

    @GetMapping("/eureka/provide")
    public String getInfo() {
        return "hello, i am eureka provide, the provide service. My port: " + port;
    }
 
    //下面是添加的内容
    @GetMapping("/eureka/delayProvide")
    public String delayGetInfo() throws InterruptedException {
        Thread.sleep(3000);
        //延迟3秒才执行真正的业务逻辑
        return "hello, delay to do something";
    }
    public static void main(String[] args) {
        SpringApplication.run(EurekaProvide7001.class, args);
    }
}

然后修改「Hystrix消费端的代码」

代码语言:javascript
复制
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@RestController
public class HystrixConsume9301 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixConsume9301.class, args);
    }

    final String PROVIDE_URL = "http://eureka-provide";

    RestTemplate restTemplate;

    public HystrixConsume9301(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    //省略一部分

    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
    }, fallbackMethod = "getPropFallback")
    @GetMapping("hystrix/normalConsume")
    public String getNormalConsumeInfo() {
        long start = System.currentTimeMillis();
        String res = restTemplate.getForObject(PROVIDE_URL + "/eureka/delayProvide", String.class);
        long end = System.currentTimeMillis();
        res += "[cost time: " + (end - start) + "]";
        return res;
    }

    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    }, fallbackMethod = "getPropFallback")
    @GetMapping("hystrix/timeoutConsume")
    public String getTimeoutConsumeInfo() {
        long start = System.currentTimeMillis();
        String res = restTemplate.getForObject(PROVIDE_URL + "/eureka/delayProvide", String.class);
        long end = System.currentTimeMillis();
        res += "[cost time: " + (end - start) + "]";
        return res;
    }

    public String  getPropFallback() {
        return "timeout, fallback method, do something.";
    }

}

@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000" 主要表示的是在规定的时间(5000)如果能调用服务,那么就不fallback。

上面的服务是延迟了3000ms执行业务,然后我设置了一个回调阈值是5000ms,一个是2000ms。

开始测试前注意「把刚才停掉的服务提供者EurekaProvide7001开启」 ,模拟的是延迟调用服务,并不是服务挂掉了。首先访问http://localhost:9301/hystrix/normalConsume:

可以看到转圈圈是大概3s后有响应,同时通过消耗的时间也可以看出。

那么当访问「超时接口」后http://localhost:9301/hystrix/timeoutConsume:

可以看到转圈圈是大概2s后有响应,并且调用的是fallback方法,并不是服务提供方法。上种情况转3s是因为服务调用是3s,这种情况转2s是因为我们设置了回调阈值是2s,到2s后还没调用服务就调用fallback。

6 Hystrix Dashboard

这是一款可视化的监控,主要是帮助我们直观地看到了Hystrix Command有关响应的一些指标

引入依赖

「修改hystrix-consume9301子模块下的pom文件」 ,往其中添加依赖

代码语言:javascript
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
</dependencies>
修改主启动类,增加Bean
代码语言:javascript
复制
@SpringBootApplication
@EnableEurekaClient
@EnableHystrixDashboard  //开启可视化界面,其实就是多加了这个注解
@EnableHystrix
@RestController
public class HystrixConsume9301 {
    
}

此时可以启动主启动类来访问http://localhost:9301/hystrix

看到这个界面说明配置成功,值得注意的是我们还需要增加一个Bean的配置类才能够正确运行,在config包下新建一个类ServletRegisterBeanConfig

代码语言:javascript
复制
@Configuration
public class ServletRegisterBeanConfig {
    @Bean(name = "registerBean")
    public ServletRegistrationBean getServlet(){

        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();

        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);

        registrationBean.setLoadOnStartup(1);

        registrationBean.addUrlMappings("/actuator/hystrix.stream");

        registrationBean.setName("HystrixMetricsStreamServlet");


        return registrationBean;
    }
}

最后重新启动HystrixConsume9301主启动类,再次访问http://localhost:9301/hystrix,然后填入需要监控的stream

当点击监控流后,会发现dashboard界面和控制台同时报错

修改配置文件

按照控制台报错修改控制文件,加入

代码语言:javascript
复制
hystrix:
  dashboard:
    proxy-stream-allow-list: localhost

重启项目,此时重复上述操作可以看到正确运行,等待连接

测试

开启Eureka服务注册中心EurekaServer8001,服务提供者EurekaProvide7001,[7002, 7003],开启HystrixConsume9301 。访问消费接口http://localhost:9301/hystrix/consume ,http://localhost:9301/hystrix/normalConsume ,http://localhost:9301/hystrix/timeoutConsume,看下能不能监控到。

可以看到确实能够实时监控到请求,并且有对应的指标。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CodeNone 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 引入Hystrix
  • 2 主启动类和配置文件
  • 3 业务类
  • 4 测试
  • 5 扩展
  • 6 Hystrix Dashboard
    • 引入依赖
      • 修改主启动类,增加Bean
        • 修改配置文件
          • 测试
          相关产品与服务
          微服务引擎 TSE
          微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档