1. spring cloud集成hystrix

定义

1 服务降级









2 服务熔断









3 hystrix dashboard 仪表盘


a) hystrix dashboard 端
第一步 pom.xml
<!--hystrix 仪表盘的依赖包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
==========================================================
第二步 启动类
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixdashboardOrder9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixdashboardOrder9001.class,args);
}
}
==========================================================
b) 被检测的服务端
第一步 pom.xml引入相关的依赖
<!--actuator信息完善 后,方可以被hystrix dashboard监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
==========================================================
第二步 启动类(加注解 + 额外添加一个新的方法)
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient //表明是eureka客户端
@EnableCircuitBreaker //开启hystrix功能
public class HystrixPaymentApplication8001 {
public static void main(String[] args) {
SpringApplication.run(HystrixPaymentApplication8001.class,args);
}
/**
*配置 hystris dashbaord 须添加的额外方法
*/
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
==========================================================
4. Spring boot 整合hystrix 实现服务降级 服务熔断 代码
服务提供者
pom.xml
<dependencies>
<!--actuator信息完善 后,方可以被hystrix dashboard监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--添加common 通用包-->
<dependency>
<artifactId>springcloud-api-common</artifactId>
<groupId>com.tina.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--添加swagger2依赖的jar包-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--添加热部署的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 引入eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
==========================================================
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient //表明是eureka客户端
@EnableCircuitBreaker //开启hystrix功能
public class HystrixPaymentApplication8001 {
public static void main(String[] args) {
SpringApplication.run(HystrixPaymentApplication8001.class,args);
}
/**
*配置 hystris dashbaord 须添加的额外方法
*/
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
==========================================================
配置文件
#设置端口号
server:
port: 8001
##设置name
spring:
#配置mysql数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://152.136.27.48:3306/d_xiaokai?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
#配置热部署
devtools:
restart:
enabled: true
application:
name: springcloud-payment-hystrix-service
#注册到eureka
eureka:
client:
register-with-eureka: true #是否将自己注册到注册中心,集群必须设置为true配合ribbon
fetch-registry: true #是否从服务端抓取已有的注册信息
service-url:
defaultZone: http://springcloud-eureka-server7001:7001/eureka,http://springcloud-eureka-server7002:7002/eureka
instance:
instance-id: springcloud-payment-hystrix-service
prefer-ip-address: true #访问路径可以显示IP地址
lease-renewal-interval-in-seconds: 1 #向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-expiration-duration-in-seconds: 2 #收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除
#开启eureka负载均衡策略
ribbon:
eureka:
enabled: true
==========================================================
service 层
/**
* @program: springcloud2020
* @description
* @author: tina.liu
* @create: 2020-03-10 10:56
**/
@Service
public class PaymentService {
/**
* 服务熔断
* commandKey = "findUserById", groupKey = "UserGroup", threadPoolKey = "findUserByIdThread"
*/
@HystrixCommand(fallbackMethod = "payment_circuit_breaker_fallback"//指定专属的回调函数
// commandProperties = {
// @HystrixProperty(name ="circuitBreaker.enable",value = "true"),//是否开启熔断器
// @HystrixProperty(name ="circuitBreaker.requestVolumeThreshold",value = "10"),//请求次数
// @HystrixProperty(name ="circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间窗口
// @HystrixProperty(name ="circuitBreaker.errorThresholdPercentage",value = "60")//失败率达到多少后跳闸
// }
)
public String paymentCircuitBreaker(@PathVariable(value = "id") Integer id){
if(id<0){
throw new RuntimeException("****id不能为负数***");
}else {
String serialNumber = IdUtil.simpleUUID();//利用糊涂工具生成一个随机的ID不含"-"
return Thread.currentThread().getName()+"调用成功的流水号为:"+serialNumber;
}
}
//专属的回调方法(不能带参数)
public String payment_circuit_breaker_fallback(){
return "id的值不能为负数,请稍后再重试";
}
//专属的回调方法(不能带参数)
public String payment_circuit_breaker_fallback(@PathVariable(value = "id") Integer id){
return "id的值不能为负数,请稍后再重试";
}
public String paymentInfo_ok(Integer id){
return "线程池"+Thread.currentThread().getName()+"方法 PaymentService ,id的值为"+id;
}
/**
* 服务降级
* @param id
* @return
*/
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})
public String paymentInfo_TimeOut(Integer id){
if(id<0){
throw new RuntimeException("****id不能为负数***");
}else {
String serialNumber = IdUtil.simpleUUID();//利用糊涂工具生成一个随机的ID不含"-"
return Thread.currentThread().getName()+"调用成功的流水号为:"+serialNumber;
}
// int timeNumber = 5 ;
//// try {
//// TimeUnit.SECONDS.sleep(timeNumber);
//// } catch (InterruptedException e) {
//// e.printStackTrace();
//// }
// int i =10/0 ;
// return "线程池"+Thread.currentThread().getName()+"方法 paymentInfo_TimeOut ,id的值为"+id;
}
public String paymentInfo_TimeOutHandler(Integer id){
return "线程池"+Thread.currentThread().getName()+"方法 paymentInfo_TimeOutHandler ,id的值为"+id+"服务降级";
}
}
==========================================================
controller
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String port ;
@Resource
private PaymentService paymentService ;
//服务熔断测试
@GetMapping(value = "/payment/circuit/{id}")
public String paymentCircuitBreaker(@PathVariable(value = "id") Integer id){
return paymentService.paymentCircuitBreaker(id);
}
@GetMapping(value = "/payment/paymentInfo_TimeOut/{id}")
public String paymentInfo_TimeOut(@PathVariable(value = "id") Integer id){
return paymentService.paymentInfo_TimeOut(id);
}
@GetMapping(value = "/payment/paymentInfo_ok/{id}")
public String paymentInfo_ok(@PathVariable(value = "id") Integer id){
return paymentService.paymentInfo_ok(id);
}
}
==========================================================
服务消费者
pom.xml
<dependencies>
<!--hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--添加common 通用包-->
<dependency>
<artifactId>springcloud-api-common</artifactId>
<groupId>com.tina.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--添加swagger2依赖的jar包-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<!--添加openFeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<!--eureka依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- boot web actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 一般通用配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
==========================================================
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient //表明是eureka的客户端
@EnableFeignClients //开启openFeign
@EnableCircuitBreaker //开启hystrix
public class HystrixOrderApplication8002 {
public static void main(String[] args) {
SpringApplication.run(HystrixOrderApplication8002.class,args);
}
}
==========================================================
配置文件
server:
port: 8002
eureka:
client:
register-with-eureka: true #是否将自己注册到注册中心
fetch-registry: true #是否从服务端抓取已有的注册信息
service-url:
defaultZone: http://springcloud-eureka-server7001:7001/eureka,http://springcloud-eureka-server7002:7002/eureka
instance:
instance-id: springcloud-consumer-feign-hystrix-order
prefer-ip-address: true #访问路径可以显示IP地址
spring:
application:
name: springcloud-consumer-feign-hystrix-order
# 配置feign的日志级别,以什么级别监视哪个接口
logging:
level:
com.tina.consumer.openfeign.service.PaymentFeignService: debug
#用户服务降级,设置为true,可以在注解@FeignClient中添加fallbackFactory
feign:
hystrix:
enabled: true
==========================================================
service
接口
@Component
@org.springframework.cloud.openfeign.FeignClient(value = "SPRINGCLOUD-PAYMENT-HYSTRIX-SERVICE",fallback = PaymentFeignClientFallBack.class )
public interface PaymentFeignClient {
@GetMapping(value = "/payment/paymentInfo_TimeOut/{id}")
public String paymentInfo_TimeOut(@PathVariable(value = "id") Integer id);
@GetMapping(value = "/payment/paymentInfo_ok/{id}")
public String paymentInfo_ok(@PathVariable(value = "id") Integer id);
}
==========================================================
回调函数
@Component
public class PaymentFeignClientFallBack implements PaymentFeignClient {
@Override
public String paymentInfo_TimeOut(Integer id) {
return "服务消费者8002,PaymentFeignClientFallBack类,paymentInfo_TimeOut方法的服务降级";
}
@Override
public String paymentInfo_ok(Integer id) {
return "服务消费者8002,PaymentFeignClientFallBack类,paymentInfo_ok方法的服务降级";
}
}
==========================================================
controller
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallBackMethod")
public class ConsumerController {
@Resource
private PaymentFeignClient paymentFeignClient ;
/**
* 服务降级
* @param id
* @return
*/
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000")
})//有指定的专属方法 就执行专属方法,没的话就是执行默认的方法
@GetMapping(value = "/consumer/payment/paymentInfo_TimeOut/{id}")
//@HystrixCommand
public String paymentInfo_TimeOut(@PathVariable(value = "id") Integer id){
int i = 10/0;
return paymentFeignClient.paymentInfo_TimeOut(id);
};
//定义一个全局的降级方法 ps 一定要写两个方法 (无参数方法和有参数方法)
public String payment_Global_FallBackMethod(@PathVariable(value = "id") Integer id){
return "Global服务消费者8001对方系统繁忙或者一次";
}
public String payment_Global_FallBackMethod(){
return "Global服务消费者8001对方系统繁忙或者一次";
}
//定义一个专属对象的回调方法
public String paymentInfo_TimeOutHandler(@PathVariable(value = "id") Integer id){
return "我是服务消费者8001,执行服务降级";
}
@GetMapping(value = "/consumer/payment/paymentInfo_ok/{id}")
public String paymentInfo_ok(@PathVariable(value = "id") Integer id){
return paymentFeignClient.paymentInfo_ok(id);
};
}
==========================================================
网友评论