简介
基于spring boot 和 sentinel注解实现
maven依赖
<properties>
<sentinel.version>1.6.0</sentinel.version>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<artifactId>sentinel-extension</artifactId>
<groupId>com.alibaba.csp</groupId>
<version>${sentinel.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
</dependency>
注解支持
package com.zm.demo.sentinel.client.controller.config;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SentinelAspectConfiguration {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
规则初始化
package com.zm.demo.sentinel.client.controller.config;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.datasource.FileWritableDataSource;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.WritableDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
@Component
public class FileDataSourceInit implements InitFunc {
@PostConstruct
@Override
public void init() throws Exception {
String degradeRulePath = "E:\\git\\sentinelconfig.txt";
ReadableDataSource<String, List<DegradeRule>> ds = new FileRefreshableDataSource<>(
degradeRulePath, source -> JSON.parseObject(source, new TypeReference<List<DegradeRule>>() {})
);
// 将可读数据源注册至 DegradeRuleManager.
DegradeRuleManager.register2Property(ds.getProperty());
WritableDataSource<List<DegradeRule>> wds = new FileWritableDataSource<>(degradeRulePath, this::encodeJson);
// 将可写数据源注册至 transport 模块的 WritableDataSourceRegistry 中.
// 这样收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中.
WritableDataSourceRegistry.registerDegradeDataSource(wds);
}
private <T> String encodeJson(T t) {
return JSON.toJSONString(t);
}
}
资源及fallback
package com.zm.demo.sentinel.client.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zoum
* @create 2019/5/7 11:24
*/
@RestController
public class UserController {
@SentinelResource(value = "getUserInfo", fallback="getUserInfoFallback", fallbackClass = {UserControllerFallback.class})
@RequestMapping
public JSONObject getUserInfo(Integer id) throws InterruptedException{
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", id);
jsonObject.put("name", "zm");
jsonObject.put("age", "20");
Thread.sleep(1001L);
return jsonObject;
}
}
package com.zm.demo.sentinel.client.controller;
import com.alibaba.fastjson.JSONObject;
/**
* @author zoum
* @create 2019/5/7 11:29
*/
public class UserControllerFallback {
public static JSONObject getUserInfoFallback(Integer id) throws InterruptedException{
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", id);
jsonObject.put("name", "zmmm");
jsonObject.put("age", "188");
return jsonObject;
}
}
启动类
package com.zm.demo.sentinel.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动时增加启动参数:
* -Dcsp.sentinel.dashboard.server=localhost:8080 控制台ip及端口
* -Dproject.name=sentinel-client 客户端名称
* @author zoum
* @create 2019/5/7 11:23
*/
@SpringBootApplication
public class App {
public static void main(String[] args){
SpringApplication.run(App.class, args);
}
}
配置
application.yml
server:
port: 8081
验证
请求:http://localhost:8081/?id=1
熔断降级
描述:满足一次熔断条件,之后连续4次,一共五次都满足条件,则进行熔断降级。
熔断降级配置
[{"count":10.0,"grade":0,"limitApp":"default","passCount":0,"resource":"getUserInfo","timeWindow":20}]
count: 响应时间(ms)
limitApp:限制APP
passCount:通过量
resource: 资源名称
timeWindow:窗口时间,即当次熔断降级多久之后不再熔断
循环50次结果:
可以看出有45次请求被降级拒绝掉,返回fallback结果。
第6次开始熔断,如下:
移除测试代码:Thread.sleep(1001L);
循环请求请求50次:
image.png
可以看出,50次全部正常通过。
流控
控制台配置流控规则,qps限制为10
循环请求10次,不会触发控制规则,如下图:
image.png
并发请求20次,触发流控规则,如下图:
网友评论