一、断路器介绍
在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,为了解决这个问题,业界提出了断路器模型。
hystrxi是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等待,hystrix能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提供分布式系统的弹性。hystrix能够进行服务降级,服务熔断,服务限流,接近实时的监控。
上图中的请求需要调用A,P,H,I四个服务,如果一切顺利则没有什么问题,关键是如果I服务超时会出现雪崩效应。
什么是服务雪崩?
多个微服务之间调用的时候,假设服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的雪崩效应。
二、在ribbon中使用断路器
在此之前注册中心以及需要用到的服务都已启动好了。同学们根据自己本身的项目来吧
1、在pom.xml中添加依赖
<!-- 继承spring-boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<!-- 继承spring-cloud -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring-boot每一个框架的集成都是一个starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加ribbon的依赖jar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!-- 客户端用来发送送请求到注册中心 依赖的jar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- 添加hystrix的依赖jar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
2、配置application.yml
server:
# 指定一个端口
port: 8092
spring:
application:
# 指定一个服务名
name: ribbon-center
eureka:
client:
service-url:
# 指定注册中心的地址
defaultZone: http://10.0.1.65:8081/eureka/
3、在启动类上加上注解(@EnableHystrix)
package cn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@RibbonClient(name = "mail-center")
@Configuration
public class RibbonApplication {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class,args);
}
}
4、在需要使用熔断器的方法上加上一个注解(@HystrixCommand)fallbackMethod 指向的是如果发生异常触发的方法
package cn.et;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@RestController
public class RibbonController {
@RequestMapping("test3")
@HystrixCommand(fallbackMethod = "error")
public String test3(String name){
String forObject = restTemplate.getForObject("http://mail-center/test2/{name}", String.class,name);
return forObject;
}
public String error(String name){
return name +" 测试Ribbon断开服务器";
}
}
5、启动mail-center服务,当我们访问http://localhost:8092/test3?name=123,浏览器显示:
123
6、关闭mail-center服务,当我们再次访问http://localhost:8092/test3?name=123,浏览器显示:
123 测试Ribbon断开服务器
这就说明当 mail-center服务不可用的时候,ribbon-center服务调用 mail-center的API接口时,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。
三、在feign中使用断路器
1、Feign是自带断路器的,在Spring Cloud中,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下代码
默认是 false 关闭的
#配置Feign自带的断路器
feign:
hystrix:
enabled: true
2、只需要在FeignClient加上fallback属性,然后指定这个类所在的位置
package cn.et.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@FeignClient(value = "mail-center",fallback = HystrixServiceImpl.class)
public interface SendMailService {
@RequestMapping("test1")
String send(Map map);
@RequestMapping("test2")
String test2(String name);
}
3、实现类需要实现这个接口类,在这个实现类里面就可以做一些操作
package cn.et.service;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class HystrixServiceImpl implements SendMailService {
@Override
public String send(Map map) {
return "测试Feign调用断路器";
}
@Override
public String test2(String name) {
return name +" 测试Feign调用断路器";
}
}
4、编写一个测试类
package cn.et.controller;
import cn.et.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class FeignController {
@Autowired
SendMailService sendMailService;
@RequestMapping("test2")
public String test2(String name){
return sendMailService.test2(name);
}
}
5、启动feign-center服务,浏览器打开http://localhost:8093/test2?name=111,注意此时mail-center服务没有启动,网页显示:
111 测试Feign调用断路器
6、启动mail-center服务,网页显示:
SUCCESS
由此可见,断路器起到作用了。
四、断路器仪表盘(Hystrix Dashboard)
仪表盘是统计流信息的可视化界面(web界面)
1、添加maven依赖
<!--断路器仪表盘依赖jar包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<!--健康监测包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、在启动类上加上注解
@EnableHystrixDashboard
3、测试访问
启动后访问:http://localhost:8092/hystrix
第一个文本框中 输入统计流信息地址
title自己定义一个标题
点击 monitor stream (必须先访问一次被保护的方法 http://localhost:8092/test3?name=456 否则 一致阻塞)
hystrixdashboard 只能在开始界面输入一个监控地址 检测某个客户端的调用 不能检测多个
tubine可以对整个eurreka集群上的断路器调用进行检测
关注我,下一章节讲解Tubine用来监控服务间的调用和熔断相关指标。。。。。