Spring Cloud构建微服务架构之六 断路器

在微服务架构中,存在着许许多多的服务单元,若一个服务出现故障,就会因依赖关系形成故障蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构就更加的不稳定。为了解决这样的问题,因此产生了断路器模式。

什么是断路器
断路器模式源于Martin Fowler的Circuit Breaker一文。“断路器”本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“断路器”能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。
在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

Netflix Hystrix
在Spring Cloud中使用了Hystrix 来实现断路器的功能。Hystrix是Netflix开源的微服务框架套件之一,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。

准备工作
在开始加入断路器之前,我们先拿之前构建两个微服务为基础进行下面的操作,主要使用下面几个工程:
eureka-servereureka-server工程:服务注册中心,端口1111
person-service工程:person-service服务,端口2222
eureka-ribbon
eureka-ribbon:通过ribbon实现的服务单元,依赖person-service的服务,端口4444
eureka-feign
eureka-feign:通过feign实现的服务单元,依赖person-service的服务,端口5555

Ribbon中引入Hystrix
依次启动eureka-server、person-service、eureka-ribbon工程
访问http://localhost:1111/可以看到注册中心的状态

图片.png

访问http://localhost:4444/person,调用eureka-ribbon的服务,该服务会去调用person-service的服务,页面显示结果。

图片.png

关闭person-service服务,访问http://localhost:4444/person,我们获得了下面的报错信息:

图片.png

pom.xml中引入依赖hystrix依赖

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

在eureka-ribbon的主类RibbonApplication中使用@EnableCircuitBreaker注解开启断路器功能:

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class EurekaRibbonApplication {
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

改造服务消费方式,增加PersonService类,在使用ribbon消费服务的函数上增加@HystrixCommand注解来指定回调方法。

@Service
public class PersonService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "personServiceFallback")
    public String personService() {
        return restTemplate.getForEntity("http://PERSON-SERVICE/person?firstname=William&lastname=Sun", String.class).getBody();
    }

    public String personServiceFallback() {
        return "error";
    }
}

提供rest接口的Controller改为调用PersonService的personService

@RestController
public class ConsumerController {
    @Autowired
    private PersonService personService;
    @RequestMapping(value = "/person", method = RequestMethod.GET)
    public String person() {
        return personService.personService();
    }
}

然后验证断路器的回调
依次启动eureka-server、person-service、eureka-ribbon工程
访问http://localhost:1111/可以看到注册中心的状态
访问http://localhost:4444/person,页面显示正常。
关闭person-service服务后再访问http://localhost:4444/person,页面显示:

图片.png
图片.png

Feign使用Hystrix
不需要在Feigh工程中引入Hystix,Feign中已经依赖了Hystrix.
application.properties,做以下修改:

spring.application.name=feign-consumer
server.port=5555
feign.hystrix.enabled=true
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

增加了feign.hystrix.enabled=true
然后尝试下面你的操作:
依次启动eureka-server、person-service、eureka-feign工程
访问http://localhost:1111/可以看到注册中心的状态
访问http://localhost:5555/person,调用eureka-feign的服务,该服务会去调用person-service的服务,页面显示正常结果。
关闭person-service服务,访问http://localhost:5555/person,我们获得了下面的报错信息:

图片.png

使用@FeignClient注解中的fallback属性指定回调类

@FeignClient(value = "person-service", fallback = PersonClientHystrix.class)
public interface PersonClient {
    @RequestMapping(method = RequestMethod.GET, value = "/person")
    String person(@RequestParam(value = "firstname") String firstname, @RequestParam(value = "lastname") String lastname);
}

创建回调类PersonClientHystrix,实现@FeignClient的接口,此时实现的方法就是对应@FeignClient接口中映射的fallback函数。

@Component
public class PersonClientHystrix implements PersonClient {
    @Override
    public String person( @RequestParam(value = "firstname") String firstname, @RequestParam(value = "lastname") String lastname) {
        // TODO Auto-generated method stub
        return "Error!";
    }
}

再次验证一下,在person-service服务不可用的情况下,页面返回:

图片.png

工程可参见:hystrix

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

推荐阅读更多精彩内容