前言
在上一篇文章中,主要完成了 《 Rest微服务加入Feign负载均衡客户端组件 》,并且完成了 《 Hystrix 基本理论概述 》的详细简介,本篇博客将带领读者完整在 Rest 微服务中集成 Hystrix 实现服务的熔断(服务端)与服务的降级(客户端),本篇博客主要主要涉及模块,包括:
Hystrix断路器,实现服务的熔断与降级
1、Hystrix 服务熔断
新增 hystrix 服务提供者模块,参考一号服务提供者模块服务器 “ microservice-provider-8001 ” 新建模块 “ microservice-hystrix-8001 ” 模块,创建完成后,如下图:
POM 内容修改,新增对 Hystrix 的支持,完整内容如下:
4.0.0
com.huazai.springcloud
microservice
${project.version}
microservice-hystrix-8001
服务提供者模块(包括Hystrix延迟和容错的开源库)-8001
com.huazai.springcloud
microservice-api
${project.version}
junit
junit
mysql
mysql-connector-java
com.alibaba
druid
ch.qos.logback
logback-core
org.mybatis.spring.boot
mybatis-spring-boot-starter
org.springframework.boot
spring-boot-starter-jetty
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-config
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-ribbon
org.springframework.cloud
spring-cloud-starter-hystrix
org.springframework
springloaded
org.springframework.boot
spring-boot-devtools
yml 内容修改,将服务的实例ID修改为 “ microservice-hystrix-8001 ”,主要目的为体现出当前项目支持 Hystrix 的服务提供者,当然还可根据需求修改为其它,完整内容如下:
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.huazai.springcloud.entity # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: microservice-provider # 该模块的服务提供者的应用名称必须一致
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://***.***.***.***:*****/microservice-01 # 数据库名称
username: *****
password: ***********
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://www.eureka7001.com:7001/eureka/,http://www.eureka7002.com:7002/eureka/,http://www.eureka7003.com:7003/eureka/
instance:
instance-id: microservice-hystrix-8001
prefer-ip-address: true
info:
app.name: learning-microservice-springcloud
company.name: huazai-studio
build.artifactId: $project.artifactId$
build.version: $project.version$
修改 Controller 类
新增注解 “ @HystrixCommand ” ,其目的为:在基于微服务架构风格的业务系统中,当服务消费者模块对服务提供者模块调用失败时,不会直接卡死或者直接抛出一大坨异常,而是自动调用使用 “ @HystrixCommand ” 注解标注的指定的目标方法,返回指定的什么内容,完整内容如下:
package com.huazai.springcloud.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.huazai.springcloud.entity.Department;
import com.huazai.springcloud.service.DepartmentService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@RestController
@RequestMapping(value = "/department")
@SuppressWarnings("unused")
public class DepartmentController
{
@Autowired
private DepartmentService departmentService;
@RequestMapping(value = "/add", method = RequestMethod.POST)
@HystrixCommand(fallbackMethod = "processHystrix_add")
public boolean add(@RequestBody Department department)
{
boolean result = departmentService.add(department);
if (!result)
{
throw new RuntimeException(department.toString() + "/n---添加异常");
}
return result;
}
private boolean processHystrix_add(@RequestBody Department department)
{
return false;
}
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
@HystrixCommand(fallbackMethod = "processHystrix_delete")
public void delete(@PathVariable Long id)
{
departmentService.delete(id);
}
private void processHystrix_delete(@PathVariable Long id)
{
System.out.println(id + "删除异常");
}
@RequestMapping(value = "/update", method = RequestMethod.PUT)
@HystrixCommand(fallbackMethod = "processHystrix_update")
public void update(@RequestBody Department department)
{
departmentService.update(department);
}
private void processHystrix_update(@RequestBody Department department)
{
System.out.println(department.toString());
}
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
@HystrixCommand(fallbackMethod = "processHystrix_get")
public Department get(@PathVariable Long id)
{
Department department = departmentService.get(id);
if (department == null)
{
throw new RuntimeException(id + "号的部门信息不存在");
}
return department;
}
private Department processHystrix_get(@PathVariable Long id)
{
// Department department = new Department(id, id + "号的部门信息不存在", "not this data in the MySQL");
Department department = new Department(id + "号的部门信息不存在");
return department;
}
@RequestMapping(value = "/list")
@HystrixCommand(fallbackMethod = "processHystrix_list")
public List list()
{
List departments = departmentService.list();
if (departments.size() == 0)
{
throw new RuntimeException("部门信息获取异常");
}
return departments;
}
private List processHystrix_list()
{
List departments = new ArrayList<>();
// Department department = new Department(id, id + "号的部门信息不存在", "not this data
// in the MySQL");
Department department = new Department("部门信息异常,无部门信息");
departments.add(department);
return departments;
}
}
修改启动类,新增注解 “ @EnableCircuitBreaker ” ,表示开启对hystrixR熔断机制的支持,完整内容如下:
package com.huazai.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
*
* @author HuaZai
* @contact [email protected]
*
* @description
* - Hystrix 熔断器
*
* @className MicroserviceHystrixApp_8001
* @package com.huazai.springcloud
* @createdTime 2018年05月06日 下午2:21:44
*
* @version V1.0.0
*/
@SpringBootApplication
@EnableEurekaClient // 本服务启动后会自动注册进eureka服务中
@EnableCircuitBreaker // 开启对hystrixR熔断机制的支持
public class MicroserviceHystrixApp_8001
{
public static void main(String[] args)
{
SpringApplication.run(MicroserviceHystrixApp_8001.class, args);
}
}
测试基于 Hystrix 的服务熔断机制
先启动 Eureka 集群,再启动基于 Hystrix 的服务提供者,并注册进 Eureka 注册中心,如下图:
启动消费在服务模块 “ microservice-consumer-80 ” ,并访问消费者服务器地址,当访问的数据存在时则正常显示,如下图:
当访问的数据不存在或者出现异常时,会立即返回自定义的信息,不会出现访问延迟的显现,页面访问异常的现象,如下图:
2、Hystrix 服务降级
服务降级处理是在客户端完成的,与服务端是不存在任何关系的,所以需要在公共子模块 “ microservice-api ” 中新增一个 Factory 类 “ DepartmentClientServiceFallbackFactory.java ” ,实现 “ FallbackFactory ” ,并重写 FallbackFactory 的 “ create ” 方法,当然里面的方法就需要根据实际的需求来自定义了,本次的完整类容如下:
package com.huazai.springcloud.factory;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
import com.huazai.springcloud.entity.Department;
import com.huazai.springcloud.service.DepartmentClientService;
import feign.hystrix.FallbackFactory;
/**
*
* @author HuaZai
* @contact [email protected]
*
* @description TODO
*
*
* @className DepartmentClientServiceFallbackFactory
* @package com.huazai.springcloud.factory
* @createdTime 2018年05月14日 下午7:48:16
*
* @version V1.0.0
*/
@Component
public class DepartmentClientServiceFallbackFactory implements FallbackFactory
{
@Override
public DepartmentClientService create(Throwable cause)
{
return new DepartmentClientService()
{
@Override
public void update(Department department)
{
// TODO Auto-generated method stub
}
@Override
public List list()
{
List departments = new ArrayList<>();
Department department = new Department("部门信息异常,无部门信息");
departments.add(department);
return departments;
}
@Override
public Department get(Long id)
{
Department department = new Department(id + "号的部门信息不存在");
return department;
}
@Override
public void delete(Long id)
{
// TODO Auto-generated method stub
}
@Override
public boolean add(Department department)
{
// TODO Auto-generated method stub
return false;
}
};
}
}
在接口类 “ DepartmentClientService ” 中的 “ @FeignClient ” 注解中新增 fallbackFactory 属性,并指向方才新增的 “ DepartmentClientServiceFallbackFactory ” 工厂类,完整内容如下:
package com.huazai.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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.huazai.springcloud.entity.Department;
import com.huazai.springcloud.factory.DepartmentClientServiceFallbackFactory;
/**
*
* @author HuaZai
* @contact [email protected]
*
* @description TODO
*
* @className DepartmentClientService
* @package com.huazai.springcloud.service
* @createdTime 2018年05月13日 下午8:21:01
*
* @version V1.0.0
*/
@FeignClient(value = "MICROSERVICE-PROVIDER/department", fallbackFactory = DepartmentClientServiceFallbackFactory.class) // 添加 Fallback,实现服务降级
public interface DepartmentClientService
{
@RequestMapping(value = "/add", method = RequestMethod.POST)
public boolean add(@RequestBody Department department);
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
public void delete(@PathVariable(value = "id") Long id);
@RequestMapping(value = "/update", method = RequestMethod.PUT)
public void update(@RequestBody Department department);
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
public Department get(@PathVariable(value = "id") Long id);
@RequestMapping(value = "/list")
public List list();
}
重新安装公共模块 “ microservice-api ” ,以供其它子模块引用,达到通用的目的,点击项目右键 -> Run As -> Maven clean/Maven install。
修改基于 Feign 的服务消费者模块 “ microservice-feign-80 ” ,修改 YML 配置文件,新增开启 Hystrix 支持的配置,完整内容如下:
server:
port: 80
feign:
hystrix:
enabled: true
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://www.eureka7001.com:7001/eureka/,http://www.eureka7002.com:7002/eureka/,http://www.eureka7003.com:7003/eureka/
测试基于 Hystrix 的服务降级机制
先启动 Eureka 集群,再一个服务提供者模块,查看 Eureka 集群服务注册列表内容,如下图:
最后启动基于 Feign 的消费者服务器,正常访问消费者服务器地址,如下图:
模拟服务提供者出项异常宕机的情况,手动关闭提供者服务器,再次消费者服务器地址,会得出另外一个结果,如下图:
关于 Hystrix 的服务降级:
在上面通过手动关闭提供者服务器的形式,模拟在实际环境中,服务器宕机的情况,使消费者请求不达的情况。因为在消费者服务器客户端使用了 Hystrix 的服务降级机制,所以,当遇到服务器宕机,请求不达的情况下,消费者客户端直接返回事先预定义的响应内容,期间会停止几毫秒,一般用户根本不会察觉,客户端会在这短短的时间里裁定服务器是否死亡,之后用户再次刷新访问时,客户端则会立即返回,不会再次访问并裁定是否死亡。
GitHub 源码地址:源码Clone地址
项目源码地址(zip格式的工程包):源码包下载地址
好了,关于 Spring Cloud 进阶--Rest微服务加入Hystrix断路器,实现服务的熔断与降级 就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。
歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。
作 者: | 华 仔 |
联系作者: | [email protected] |
来 源: | CSDN (Chinese Software Developer Network) |
原 文: | https://blog.csdn.net/Hello_World_QWP/article/details/88087407 |
版权声明: | 本文为博主原创文章,请在转载时务必注明博文出处! |