hystrix是微服务中用于做熔断、降级的工具。

作用:防止因为一个服务的调用失败、调用延时导致多个请求的阻塞以及多个请求的调用失败。

1、pom.xml(引入hystrix-core包)

1          <!-- hystrix -->
2         <dependency>
3             <groupId>com.netflix.hystrix</groupId>
4             <artifactId>hystrix-core</artifactId>
5             <version>1.5.2</version>
6         </dependency>

2、application.properties

1 #hystrix
2 hystrix.timeoutInMillions = 3000

说明:设置hystrix属性,如上是"服务调用超时时间",其他属性设置见:https://github.com/Netflix/Hystrix/wiki/Configuration

3、HyStrixProperties

package com.xxx.firstboot.hystrix;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;

@Getter @Setter
@Component
@ConfigurationProperties(prefix = "hystrix")
public class HyStrixProperties {
    private int timeoutInMillions;
}

4、MyHyStrixCommand

package com.xxx.firstboot.hystrix;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netflix.hystrix.HystrixCommand;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

public class MyHystrixCommand extends HystrixCommand<Response> {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyHystrixCommand.class);
    private String url;

    public MyHystrixCommand(Setter setter, String url) {
        super(setter);
        this.url = url;
    }

    @Override
    protected Response run() throws Exception {
        LOGGER.info("服务正被调用,当前线程:'{}'", Thread.currentThread().getName());
        Request request = new Request.Builder().url(url).build();
        return new OkHttpClient().newCall(request).execute();
    }

    @Override
    public Response getFallback() {
        LOGGER.error("服务调用失败,service:'{}'");
        return null;
    }
}

说明:

  • 该类是最关键的一个类。
  • 继承HystrixCommand<T>
  • 添加构造器,注意:无法添加无参构造器,因此该类无法作为spring的bean来进行管理
  • 程序开始时执行run(),当执行发生错误或超时时,执行getFallback()

5、HyStrixUtil

package com.xxx.firstboot.hystrix;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.netflix.hystrix.HystrixCommand.Setter;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.squareup.okhttp.Response;

@Component
public class HystrixUtil {

    @Autowired
    private HyStrixProperties hp;

    public Response execute(String hotelServiceName,
                            String hotelServiceMethodGetHotelInfo,
                            String url) throws InterruptedException, ExecutionException {
        Setter setter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(hotelServiceName));//被调用服务
        setter.andCommandKey(HystrixCommandKey.Factory.asKey(hotelServiceMethodGetHotelInfo));//被调用服务的一个被调用方法
        setter.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(hp.getTimeoutInMillions()));
        return new MyHystrixCommand(setter, url).execute();//同步执行
//        Future<Response> future = new MyHystrixCommand(setter, url).queue();//异步执行
//        return future.get();//需要时获取
    }

}

说明:

  • hystrix的执行方式

    • 同步执行:超时时间起作用
    • 异步执行:超时时间不起作用(1.4.0之前的版本,在调用get()的时候开始计时起作用)
  • hystrix的隔离级别
    • HystrixCommandGroupKey:这个的名称设置为一个被调用的服务,eg.hotelService,所有这个服务下的方法都用同一个线程池(前提是没有配置ThreadPoolKey)
    • HystrixCommandKey:这个名称通常是被调用服务的一个方法的名字(实际上就是被调用服务某一个controller中的一个对外方法),eg.getHotelInfo()
    • ThreadPoolKey:这个用的很少,除非一个被调用服务中的有些被调用方法快、有的被调用方法慢,这样的话,就需要分别使用一个ThreadPoolKey,为每一个方法单独分配线程池

6、application.properties

1 service.hotel.name = hotelService
2 service.hotel.method.getHotelInfo = getHotelInfo 

说明:定义被调用服务的服务名和被调用方法名,当然服务名也可以使用被调用服务的controller的简单类名。

7、HystrixController

package com.xxx.firstboot.web;

import java.io.IOException;
import java.util.concurrent.ExecutionException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.squareup.okhttp.Response;
import com.xxx.firstboot.hystrix.HystrixUtil;

@RestController
@RequestMapping("/hystrix")
public class HystrixController {

    @Value("${service.hotel.url}")
    private String HOTEL_URL;

    @Value("${service.hotel.name}")
    private String hotelServiceName;

    @Value("${service.hotel.method.getHotelInfo}")
    private String hotelServiceMethodGetHotelInfo;

    @Autowired
    private HystrixUtil hystrixUtil;

    @RequestMapping(value = "/firstHystrix", method = RequestMethod.GET)
    public String getHotelInfo(@RequestParam("id") int id, @RequestParam("name") String name) {
        String url = String.format(HOTEL_URL, id, name);
        Response response = null;
        try {
            response = hystrixUtil.execute(hotelServiceName, hotelServiceMethodGetHotelInfo, url);
            if (response != null) {
                return response.body().string();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } finally {
            if (response != null && response.body() != null) {
                try {
                    response.body().close();// 资源关闭
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "获取酒店信息失败";
    }

}

说明:

  • 使用@value做属性注入,假设我们是在consul上配置了application.properties内容,当修改了属性文件的内容后,该服务也必须重启,因为@value只读一次(没测过,同事说的)
  • 使用spring的Environment进行注入,当修改了属性文件的内容后,服务不需要重启,会每五分钟重新刷一次(没测过,同事说的)
  • 使用boot构建一个属性收集类,如上边的HyStrixProperties类,不知道是否需要重启(没测过)

有测过的朋友和我讲一下,我有时间也会测一下。

下边是被调用服务的代码:

8、HotelController

@RestController
@RequestMapping("/hotel")
@Api("HotelController相关api")
public class HotelController {
    @ApiOperation("获取酒店Hotel信息:getHotelInfo")
    @RequestMapping(value="/getHotelInfo",method=RequestMethod.GET)
    public Hotel getHotelInfo(@RequestParam("id") int id, @RequestParam("name") String name) {
//        try {
//            TimeUnit.MILLISECONDS.sleep(2000);//用于测试超时
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return new Hotel(id, name);
    }
}

测试:启动被调用服务-->启动调用服务

参考:

http://blog.csdn.net/xiaoyu411502/article/details/50601687 官方的中文总结

https://stonetingxin.gitbooks.io/hystrix/content/ 基本上是官方的中文翻译

https://github.com/Netflix/Hystrix/wiki/Configuration hystrix配置介绍

http://blog.vicoder.com/hystrix-configuration/ 配置介绍

http://www.insaneprogramming.be/blog/2014/08/19/hystrix-spring-boot/ boot集成hystrix

【第十九章】 springboot + hystrix(1)的更多相关文章

  1. 第十九章 springboot + hystrix(1)

    hystrix是微服务中用于做熔断.降级的工具. 作用:防止因为一个服务的调用失败.调用延时导致多个请求的阻塞以及多个请求的调用失败. 1.pom.xml(引入hystrix-core包) <! ...

  2. 第二十九章 springboot + zipkin + mysql

    zipkin的数据存储可以存在4个地方: 内存(仅用于测试,数据不会持久化,zipkin-server关掉,数据就没有了) 这也是之前使用的 mysql 可能是最熟悉的方式 es Cassandra ...

  3. 第二十五章 springboot + hystrixdashboard

    注意: hystrix基本使用:第十九章 springboot + hystrix(1) hystrix计数原理:附6 hystrix metrics and monitor 一.hystrixdas ...

  4. Python之路【第十九章】:Django进阶

    Django路由规则 1.基于正则的URL 在templates目录下创建index.html.detail.html文件 <!DOCTYPE html> <html lang=&q ...

  5. 第十九章——使用资源调控器管理资源(1)——使用SQLServer Management Studio 配置资源调控器

    原文:第十九章--使用资源调控器管理资源(1)--使用SQLServer Management Studio 配置资源调控器 本系列包含: 1. 使用SQLServer Management Stud ...

  6. 第十九章——使用资源调控器管理资源(2)——使用T-SQL配置资源调控器

    原文:第十九章--使用资源调控器管理资源(2)--使用T-SQL配置资源调控器 前言: 在前一章已经演示了如何使用SSMS来配置资源调控器.但是作为DBA,总有需要写脚本的时候,因为它可以重用及扩展. ...

  7. 第十九章 Django的ORM映射机制

    第十九章 Django的ORM映射机制 第一课 Django获取多个数据以及文件上传 1.获取多选的结果(checkbox,select/option)时: req.POST.getlist('fav ...

  8. Gradle 1.12用户指南翻译——第四十九章. Build Dashboard 插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  9. Gradle 1.12翻译——第十九章. Gradle 守护进程

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  10. Gradle 1.12用户指南翻译——第二十九章. Checkstyle 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

随机推荐

  1. oracle显示转换字段类型cast()函数

    今天遇到一个查询类型转换的问题:表的字段是varchar2类型,然后查询到的结果要转换为number(20,2),刚开始的时候使用to_number()函数,发现不能满足需求.后来才知道,原来还有ca ...

  2. Sql Server索引的原理与应用

    SqlServer索引的原理与应用 转自:http://www.cnblogs.com/knowledgesea/p/3672099.html   索引的概念 索引的用途:我们对数据查询及处理速度已成 ...

  3. 空类指针为什么可以调用类的成员函数 以及 A(){}和A();

    1. 代码及问题 #include <iostream> using namespace std; class A { public: A() {} //A *p = new A()时:此 ...

  4. 计算auc-python/awk

    1.自己写的计算auc的代码,用scikit-learn的auc计算函数sklearn.metrics.auc(x, y, reorder=False)做了一些测试,结果是一样的,如有错误,欢迎指正. ...

  5. LeetCode--53 最大连续子序列(总结)

    # 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. # 示例:# 输入: [-2,1,-3,4,-1,2,1,-5,4],# 输出: 6# 解释 ...

  6. js全选反选

    <style type="text/css"> table { width: 800px; text-align: left; border-collapse: col ...

  7. Dapper Extensions中修改Dialect

    如果是MySql数据库,则修改为:DapperExtensions.DapperExtensions.SqlDialect = new MySqlDialect(); DapperExtensions ...

  8. Object-C-系统类型对象归档

    系统类型主要是指NSString NSDictionary,NSArray,NSData,NSNumber 类型数据(包括对应可变类型); 这些类型已经实现了NSCoding协议,支持归档, 写入方法 ...

  9. UVA 475

    /* 通过这题 学会了 两个词组 immediately to the left 是左邻的意思 immediately to the right 这个是右邻的意思 */ #include <io ...

  10. centos infiniband网卡安装配置

    硬件:Mellanox InfiniBand,主要包括 HCA(主机通道适配器)和交换机两部分 软件:CentOS 6.4 MLNX_OFED_LINUX-2.1-1.0.0-rhel6.4-x86_ ...