spring cloud hystrix的隔离策略和dashboard

    随着服务的拆分,各个服务有着明确的职责,服务之间通过轻量级的协议进行通讯。但有时候我们完成一个功能需要同时调用多个微服务,比如完成订单的创建,那么获取用户信息需要调用用户微服务,获取商品信息需要调用商品微服务,给用户增加积分需要调用积分微服务。假如用户微服务调用此时响应慢,就会导致调用线程(tomcat线程或jetty线程等)被占用,降低系统的处理能力如果用户微服务被隔离了,使用是自己的线程,那么就不会占用调用线程,系统的处理能力就会提高。 下面是官网隔离的图

从上面可以看到隔离机制分成2种左侧是线程池隔离右侧是信号量隔离。上方蓝色的线是调用线程(tomcat线程...),黄色的线是hystrixCommand线程
   线程池隔离:
      1、调用线程和hystrixCommand线程不是同一个线程,并发请求数受到线程池(不是容器tomcat的线程池,而是hystrixCommand所属于线程组的线程池)中的线程数限制,默认是10。
      2、这个是默认的隔离机制
      3、hystrixCommand线程无法获取到调用线程中的ThreadLocal中的值
   信号量隔离:
      1、调用线程和hystrixCommand线程是同一个线程,默认最大并发请求数是10
      2、调用数度快,开销小,由于和调用线程是处于同一个线程,所以必须确保调用的微服务可用性足够高并且返回快才用
 

需求:

    1、修改默认的隔离策略为线程隔离
    2、为具体的某个方法设置信号量隔离
    3、对线程隔离和信号量隔离其余的参数进行配置
    4、fallback最大的并发设置,超出直接抛出异常(即同时调用fallback的上限,超出抛出异常)

代码结构:
    eureka-server
        |- 服务注册中心
    hystrix
        product-provider-8091
            |- 服务提供者,返回商品信息
        product-consumer-feign-hystrix-isolation-dashboard-8094
            |- 服务消费者,实现服务隔离和dashboard查看

代码实现

一、注册中心和服务提供者的实现(和上一节的代码一样或见最下方的代码连接)

二、服务消费者

    1、引入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>8.17.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    引入依赖:

           spring-cloud-starter-netflix-hystrix

           spring-cloud-starter-netflix-hystrix-dashboard
 

  2、启动类上增加注解@EnableHystrixDashboard 图表监控注解

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
public class ApplicationProductConsumer8094 {

	public static void main(String[] args) {
		SpringApplication.run(ApplicationProductConsumer8094.class, args);
	}
}

 

    3、远程调用feign的实现和yml的配置

        注意需要记住这个类名selectByProductIdAndName这个方法名,下方yml配置中使用信号量隔离用到了。

     注意:

            1、注意上面yml 中隔离的写法以及其他的参数的含义。

            2、hystrix.command.default              ===> 全局配置

            3、hystrix.command.commandKey  ===> 局部配置

         

    4、控制层写法

/**
 * 商品控制器
 *
 * @author huan.fu
 * @date 2018/5/30 - 16:52
 */
@RestController
@RequestMapping("product")
public class ProductController {

	@Autowired
	private ProductService01Feign productService01Feign;

	/**
	 * 获取商品信息
	 *
	 * @param productId
	 * @return
	 */
	@GetMapping("/01/selectOne/{productId}")
	public Map<String, Object> select01ByProductId(@PathVariable String productId) {
		try {
			MDC.put("productId", productId);
			return productService01Feign.selectByProductId(productId);
		} finally {
			MDC.clear();
		}
	}

	@GetMapping("/01/selectByProductIdAndName")
	public Map<String, Object> selectByProductIdAndName(String productId, String productName) {
		return productService01Feign.selectByProductIdAndName(productId, productName);
	}
}

        访问路径
            http://localhost:8094/product/01/selectOne/p0001 -> 访问的是信号量隔离方法
            http://localhost:8094/product/01/selectByProductIdAndName?productId=p0001&productName=Mac%20Book -> 访问的是线程池隔离的方法
        运行结果,看下方的运行结果图。

 

    5、运行结果


        监控页面:
            1、访问 http://localhost:8094
            2、因为我们是单机的,所以访问路径是:http://localhost:8094/hystrix.stream
        从运行结果的最后的监控页面上我们可以看到,当访问http://localhost:8094/product/01/selectByProductIdAndName?productId=p0001&productName=Mac%20Book链接时,监控页面上
        出现了线程池监控,且pool size的最大值为6,说明这个使用的是线程池隔离,访问另外的一个没有出现,说明是使用的是信号量隔离
 

三、完整代码

    https://gitee.com/huan1993/spring-cloud-parent/tree/master/hystrix
    hystrix隔离代码:https://gitee.com/huan1993/spring-cloud-parent/tree/master/hystrix/product-consumer-feign-hystrix-isolation-dashboard-8094

posted @ 2018-06-05 21:06  huan1993  阅读(71)  评论(0编辑  收藏  举报