简介
在分布式系统开发时,会面临一序列问题,比如雪崩效应。特别是高并发没法处理请求或者接口异常情况下,我们需要降级请求,防止出现雪崩效应。此外,在一些并发系统的情况下,个别接口需要进行限流,防止大量并发占用别的接口服务资源,基于此个人便捷记录熔断和限流笔记!
技术栈
- hystrix
- java
- hystrix-dashboard
- maven
- idea pc
- sentinel
熔断
目前居于原有项目的user-center模块开发,分支为feat/hystrix
导入maven
目前使用hystrix和dashboard,因此此时需要导入actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
yml配置
需要配置暴露地址和hystrix熔断时间以及代理允许监控的上报服务器ip
hystrix:
dashboard:
proxy-stream-allow-list: localhost
metrics:
enabled: true
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
management:
endpoints:
web:
base-path: /actuator
exposure:
include: '*'
配置启动相关数据
需要@EnableHystrixDashboard启动仪表,@EnableCircuitBreaker启动熔断,此外,由于仪表需要页面,目前新版本没有启动。
@SpringBootApplication
@MapperScan("com.lgh.mapper")
@EnableSwagger2
@EnableFeignClients
@EnableEurekaClient
@EnableHystrixDashboard
@EnableCircuitBreaker
public class RunApplication {
public static void main(String[] args) {
SpringApplication.run(RunApplication.class, args);
}
}
新版本@EnableHystrixDashboard在启动类配置外,还需要配置web页面
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/hystrix/**")
.addResourceLocations("classpath:/static/hystrix/");
}
代码演示
目前注解@HystrixCommand启动熔断,使用fallbackMethod友好降级。
@Service
public class HystrixDemoImpl implements IHystrixDemo {
@HystrixCommand(fallbackMethod = "fallbackMethod")
@Override
public String test(String inputStr) {
try {
System.out.println("test Hystrix");
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "SUCCESS";
}
public String fallbackMethod(String inputStr) {
System.out.println("fallbackMethod");
return "Time out" + inputStr;
}
}
@Api(tags = "熔断限流测试")
@RestController
@RequestMapping("/hystrixtest")
public class HystrixController {
@Autowired
private IHystrixDemo iHystrixDemo;
@GetMapping("/test")
public String test(String inputStr) {
return iHystrixDemo.test(inputStr);
}
}
验证正确性
查看hystrix-dashboard是否生效http://localhost:8088/hystrix,接着输入监控地址:http://localhost:8088/actuator/hystrix.stream,点击Monitor Stream即可,若没数据,则需要请求才有数据,如下图
接下来使用jmeter并发请求,具体下载地址:jmeter配置完直接执行
查看控制台日志或者打断点看熔断情况:
限流
限流比较简单使用,具体可以参考alibaba官网。sentinel
下载监控
直接官网下载sentinel-dashboard,具体操作官网有详解。打包完jar包后,启动命令:
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar target/sentinel-dashboard.jar
浏览监控http://localhost:8080/
添加配置
主要pom导入和限流aop配置,具体如下(更多版本参考https://mvnrepository.com/)
pom:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
SentinelResourceAspect配置
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SentinelConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
上报sentinel-dashboard的配置,sentinel-dashboard上可动态配置规则
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
enabled: true
代码演示
这里主要处理限流异常处理类和实现注解@SentinelResource
阻塞异常处理:
package com.lgh.exception;
import com.alibaba.csp.sentinel.slots.block.BlockException;
public class ExceptionUtil {
public static String handleException(String inputStr, BlockException ex) {
System.out.println("Oops: " + ex.getClass().getCanonicalName());
return "Fail";
}
}
异常实现类HystrixDemoImpl
package com.lgh.service.impl;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.lgh.exception.ExceptionUtil;
import com.lgh.service.IHystrixDemo;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
@Service
public class HystrixDemoImpl implements IHystrixDemo {
@SentinelResource(value = "testSentinel",
blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
@Override
public String testSentinel(String inputStr) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "SUCCESS";
}
}
controller请求处理HystrixController
package com.lgh.controller;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.lgh.service.IHystrixDemo;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "熔断限流测试")
@RestController
@RequestMapping("/hystrixtest")
public class HystrixController {
@Autowired
private IHystrixDemo iHystrixDemo;
@GetMapping("/testSentinel")
public String testSentinel(String inputStr) {
return iHystrixDemo.testSentinel(inputStr);
}
}
验证代码
启动user-center工程,去sentinel dashboard查看是否已经上报监控,具有user-center说明已经上报,启动工程前需要启动注册中心哦eureka-server
配置降级规则(没有降级规则,是不生效的哦)
启动jemter请求验证
源码
https://github.com/soft1302/project-study/tree/feat/hystrix
参考文献
【1】sentinel
【2】howtodoinjava
【3】简述