springcloud feign远程调用熔断详解

最近学习springcloud搭建微服务,各个模块单元之间要互相进行调用。博主原有是通过httpclient的方式进行调用,但是不得不每次都需要暴露url进行调用,feign提供本地调用的方式,不需要暴露url,t提供类似本地调用实现,并且配合hystrix熔断策略进行使用。

1.maven添加包引用

<!--添加feign 提供服务调用-->  

<dependency>  

    <groupId>org.springframework.cloud</groupId>  

    <artifactId>spring-cloud-starter-feign</artifactId>  

</dependency>  

<!-- ApacheHttpClient 实现这个类,替换httpclient线程池-->  

<dependency>  

    <groupId>io.github.openfeign</groupId>  

    <artifactId>feign-httpclient</artifactId>  

    <version>9.5.0</version>  

</dependency>  


<!-- 添加熔断器,提供服务熔断操作 -->  

<dependency>  

    <groupId>org.springframework.cloud</groupId>  

    <artifactId>spring-cloud-starter-hystrix</artifactId>  

</dependency>

2.配置文件需要填写eureka等相关配置文件

<dependencies>  

            <dependency>  

                <groupId>org.springframework.cloud</groupId>  

                <artifactId>spring-cloud-dependencies</artifactId>  

                <version>${spring-cloud.version}</version>  

                <type>pom</type>  

                <scope>import</scope>  

            </dependency>  

        </dependencies> 

spring-cloud的版本有Brixton.RELEASE和Dalston.RELEASE,现在创建的新项目应该是引用Dalston.RELEASE这个版本,该版本下默认hystrix是关闭的,所以需要在属性文件中进行打开,如果没有设置为true,在后面的调试过程会发现熔断机制不生效

#开启hystrix熔断机制  

feign.hystrix.enabled=true

feign简单调用,如以下实例,假如现在在同一个eureka下有一个项目A需要调用项目message-api项目,而message-api项目有一个接口为/example/hello,那么在A项目做以下配置:

1.建立远程调用客户端

@FeignClient(value = "message-api")  

public interface MessageApiFeignClient {  

    @RequestMapping(value = "/example/hello",method = RequestMethod.GET)  

    public String getMessage(@RequestParam("name") String name);  

本地方法直接调用该接口

@RequestMapping(value="/hello3",method = RequestMethod.GET)  

public void hello3(String name){  

    String result = messageApiFeignClient.getMessage("zhangsan");  

    System.out.println(result);  

运行起来会发现成功调用。

通常feign和hystrix一起配合使用的,什么是hystrix,hystrix是分布式系统互相调用超时处理和容错的机制。例如著名的雪崩,通常A->B->C互相依次调用,但是很可能C项目出现问题,流量过大或者报错等,导致线程一直进行等待,导致拖垮整个链路层,线程资源耗尽。

工作原理:

1.隔离机制:

线程隔离:hystrix为每个依赖调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,默认不采用排队,加速判定时间

信号隔离:信号隔离也可以限制并发访问,防止阻塞扩散,与线程隔离最大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请,如果客户端是可信的且可以快速返回,可以使用信号隔离),springcloud zuul就是采用的是信号隔离的方式

2.熔断:

如果某个目标服务调用慢或者大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用

以下通过代码的方式进行详细讲解

hystrix通过设置fallback和fallbackFactory属性触发请求容灾降级

1.fallback

首先设置接口服务方一个简单的方法

@RestController  

@RequestMapping("/example")  

public class ExampleController {  


    public static final Logger logger = LoggerFactory.getLogger(ExampleController.class);  


    @RequestMapping(value = "/hello")  

    @ResponseBody  

    public String helloFeign(String name) throws Exception {  

        logger.info("进入服务端:"+name);  

        if("zhangsan".equals(name)){  

            int i = 1/0;  

        }else if("lisi".equals(name)){  

            throw new Exception("服务端报错");  

        }else{  

        }  

        return "hello!"+name;  

    }  

在feignclient上添加fallback

@FeignClient(value = "message-api",fallback = MessageApiFailBack.class)  

public interface MessageApiFeignClient {  


    @RequestMapping(value = "/example/hello",method = RequestMethod.GET)  

    public String getMessage(@RequestParam("name") String name);  

定义MessageApiFeignClient类

@Component  

public class MessageApiFailBack implements MessageApiFeignClient{  

    @Override  

    public String getMessage(String name) {  

        return "出错啦!";  

    }  

}

调用方进行本地调用

messageApiFeignClient.getMessage("zhangsan");

运行后

服务调用方打印:出错啦!

服务提供方打印:java.lang.ArithmeticException: / by zero

2.fallbackFactory与fallback不同的是可以打印详细的错误信息

将原来的fallback替换成fallbackFactory

@FeignClient(value = "message-api",fallbackFactory = MessageApiFailFactory.class)  

public interface MessageApiFeignClient {  

    @RequestMapping(value = "/example/hello",method = RequestMethod.GET)  

    public String getMessage(@RequestParam("name") String name);  

}

public interface MessageApiFeignFallBackFactoryClient extends MessageApiFeignClient{  

}

@Component  

public class MessageApiFailFactory implements FallbackFactory<MessageApiFeignClient> {  


    public static final Logger logger = LoggerFactory.getLogger(MessageApiFailFactory.class);  

    @Override  

    public MessageApiFeignClient create(Throwable throwable) {  

        logger.info("fallback; reason was: {}",throwable.getMessage());  

        return new MessageApiFeignFallBackFactoryClient(){  


            @Override  

            public String getMessage(String name) {  

                return "错误原因:"+throwable.getMessage();  

            }  

        };  

    }  

}

同样进行本地调用

messageApiFeignClient.getMessage("zhangsan");

运行后服务调用方打印:

错误原因:status 500 reading MessageApiFeignClient#getMessage(String); content:

{"timestamp":1508681203932,"status":500,"error":"Internal Server Error","exception":"java.lang.ArithmeticException","message":"/ by zero","path":"/example/hello"}

另外配置文件下可以设置hystrix服务超时机制

#开启hystrix请求超时机制   也可以设置成永久不超时hystrix.command.default.execution.timeout.enabled=false  

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000  

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容