服务端tokenServer实现
1.项目结构:
2.加入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
</dependency>
3.tokenserver实现
/**
* 集群流控运行类
*
*/
@Component
public class SentinelServerRunning implements CommandLineRunner {
//端口使用当前服务的端口
@Value("${server.port}")
private int port;
//zookeeper的ip+端口/也可以是nacos的ip+端口
private static final String REMOTE_ADDRESS = "";
//自定义分组
private static final String GROUP_ID = "SENTINEL_GROUP";
//跟appname拼接成dataId
public static final String FLOW_POSTFIX = "-flow-rules";
@Override
public void run(String... args) throws Exception {
ClusterServerConfigManager.loadGlobalTransportConfig(new ServerTransportConfig()
.setIdleSeconds(600)
.setPort(port));
SentinelDefaultTokenServer tokenServer = new SentinelDefaultTokenServer();
tokenServer.start();
//设置为服务端
ClusterStateManager.applyState(ClusterStateManager.CLUSTER_SERVER);
//加载流控规则
ClusterFlowRuleManager.setPropertySupplier(namespace -> {
ReadableDataSource<String, List<FlowRule>> ds = new ZookeeperDataSource<>(REMOTE_ADDRESS, GROUP_ID,
//下面命名空间加载后会在这里回调拿到namespace
namespace + FLOW_POSTFIX,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
return ds.getProperty();
});
//配置命名空间数据源--必须放在最后!!!这里会加载命名空间,默认加载出来的是appname
String namespaceSetDataId = "cluster-server-namespace-set";
ReadableDataSource<String, Set<String>> namespaceDs = new ZookeeperDataSource<>(REMOTE_ADDRESS, GROUP_ID,
namespaceSetDataId, source -> JSON.parseObject(source, new TypeReference<Set<String>>() {
}));
ClusterServerConfigManager.registerNamespaceSetProperty(namespaceDs.getProperty());
}
}
4.启动项目
@SpringBootApplication
public class SentinelServerApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelServerApplication.class, args);
}
}
流控客户端实现
1.项目结构:
2.实现流控客户端:
/**
* sentinel集群流控客户端配置类
*/
@Slf4j
@Component
public class SentinelClientConfig implements CommandLineRunner {
private static final String REMOTE_ADDRESS = "";
private static final String GROUP_ID = "SENTINEL_GROUP";
public static final String FLOW_POSTFIX = "-flow-rules";
@Value("${spring.application.name}")
private String appName;
/**
* Callback used to run the bean.z
*
* @param args incoming main method arguments
*/
@Override
public void run(String... args) {
//设置为客户端
ClusterStateManager.applyState(ClusterStateManager.CLUSTER_CLIENT);
log.info("[sentinel loader] 从zookeeper上读取的集群流控服务端地址。。。");
//配置服务端地址
ReadableDataSource<String, ClusterClientAssignConfig> clusterClientAssignConfigds = new ZookeeperDataSource<>(
REMOTE_ADDRESS,
GROUP_ID,
"cluster-flow-server",
source -> JSON.parseObject(source, new TypeReference<ClusterClientAssignConfig>() {
}));
ClusterClientConfigManager.registerServerAssignProperty(clusterClientAssignConfigds.getProperty());
//配置客户端
ReadableDataSource<String, ClusterClientConfig> clientConfigDs = new ZookeeperDataSource<>(
REMOTE_ADDRESS,
GROUP_ID,
"cluster-flow-server",
source -> JSON.parseObject(source, new TypeReference<ClusterClientConfig>() {
}));
ClusterClientConfigManager.registerClientConfigProperty(clientConfigDs.getProperty());
//加载流控规则
ZookeeperDataSource<List<FlowRule>> zkDs = new ZookeeperDataSource<>(
REMOTE_ADDRESS,
GROUP_ID,
appName + FLOW_POSTFIX,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(zkDs.getProperty());
}
}
3.客户端流控异常类
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) {
if (e instanceof FlowException) {
throw new CommonException(-1, "Flow limit");
} else if (e instanceof DegradeException) {
throw new CommonException(-2, "服务降级了");
} else if (e instanceof ParamFlowException) {
throw new CommonException(-3, "参数限流了");
} else if (e instanceof AuthorityException) {
throw new CommonException(-4, "Access denied");
} else if (e instanceof SystemBlockException) {
throw new CommonException(-5, "System protection");
}
}
}
4.配置sentinel控制台
spring:
cloud:
sentinel:
transport:
port: 9719
dashboard: localhost:9999
application:
name: appname
在zookeeper中添加流控规则
1.
2.配置tokenserver的地址,本地就是127.0.0.1
3.配置命名空间,其实就是你的appname,要流控几个加几个
4.添加流控规则,这里flowId必须唯一,注意json格式不要弄错,我在这里粗心json格式弄错了,导致流控规则一至加载不出来
5.启动你的微服务