一、概念部分
1.什么是熔断器?
熔断,就是断开与服务器的连接,熔断器是在服务不可用的时候主动断开,以免造成更多的雪崩效应,他是保护服务高可用的最后一道防线。
2.为什么需要熔断器?
为保证服务高可用,最先想到的是服务集群,但集群并不能完全的保证服务高可用,
当某个服务出现故障时,在负载均衡的时候可能多次被调用到,调用方由于无法得到调用结果,会出现请求超时会其他异常,这时候如果不及时的熔断服务,就有可能会有更多的调用者去调用已经出现故障的服务节点,造成大量调用失败,甚至引发联级故障的雪崩。
在分布式系统中,通常会有很多的服务调用,比如服务调用关系:AB->C->D。
基础服务的故障可能会导致联级故障,如下图所示:
我们需要一个熔断机制,当某个节点出现故障时,及时的做熔断处理,防止更多的服务调用失败。
二:代码实例
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml #mybatis所在路径
type-aliases-package: com.atguigu.springcloud.entities #entity别名类
mapper-locations:
- classpath:mybatis/mapper/**/*.xml #mapper映射文件
spring:
application:
name: microservicecloud-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/cloudDB01
username: root
password: 123456
dbcp2:
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://:7001/eureka/,http://:7002/eureka/,http://:7003/eureka/
instance:
instance-id: microservicecloud-dept8001-hystrix #自定义hystrix相关的服务名称信息
prefer-ip-address: true #访问路径可以显示IP地址
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: $project.artifactId$
build.version: $project.version$
接口
package com.atguigu.springcloud.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.atguigu.springcloud.entities.Dept;
/**
*
* @Description: 修改microservicecloud-api工程,根据已经有的DeptClientService接口
新建
一个实现了FallbackFactory接口的类DeptClientServiceFallbackFactory
* @author zzyy
* @date 2018年4月21日
*/
//@FeignClient(value = "MICROSERVICECLOUD-DEPT")
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class)
public interface DeptClientService
{
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") long id);
@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List<Dept> list();
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(Dept dept);
}
在每个接口上定义熔断机制,当接口调用失败时,会调用DeptClientServiceFallbackFactory中的方法进行回调
package com.atguigu.springcloud.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.atguigu.springcloud.entities.Dept;
import feign.hystrix.FallbackFactory;
@Component // 不要忘记添加,不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>
{
@Override
public DeptClientService create(Throwable throwable)
{
return new DeptClientService() {
@Override
public Dept get(long id)
{
return new Dept().setDeptno(id).setDname("该ID:" id "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
.setDb_source("no this database in MySQL");
}
@Override
public List<Dept> list()
{
return null;
}
@Override
public boolean add(Dept dept)
{
return false;
}
};
}
}
测试conrtoller层
package com.atguigu.springcloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.atguigu.springcloud.entities.Dept;
import com.atguigu.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@RestController
public class DeptController
{
@Autowired
private DeptService service = null;
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
//一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
//@HystrixCommand(fallbackMethod = "processHystrix_Get")
public Dept get(@PathVariable("id") Long id)
{
Dept dept = this.service.get(id);
if (null == dept) {
throw new RuntimeException("该ID:" id "没有没有对应的信息");
}
return dept;
}
}
总结
:
发现远程调用不成功,但是不会因为调用不成功导致服务异常,而是熔断了远程服务的连接并以友好的方式触发了我们的远程调用失败时指定的本地回调方法,输出了自定义信息。证明熔断成功。
服务监控
依赖
<!-- hystrix和 hystrix-dashboard相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
要想某个服务被监控,需要在需要监控的服务中添加依赖才能生效
<!-- actuator监控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
测试:
localhost:9001/hystrix
填写监控地址
详解:
可以监控某一时刻调用的峰值状况
来源:http://www./content-4-42851.html
|