1.SpringCloudGateWay整合sentinel
1.网关pom文件加入 sentinel 依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<--数据持久化-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2.bootstrap 文件添加配置
spring:
profiles:
active: ${DEPLOY_ENV:dev}
aop:
proxy-target-class: true
application:
name: oppc.gateway
cloud:
sentinel:
#心跳启动
eager: true
transport:
#sentinel控制台访问路径
dashboard: xxxxxx:8080
port: 8719
<--读取nacos流控配置-->
datasource:
gw-flow:
nacos:
server-addr: ${NACOS_ADDR:xxxxx:8848}
dataId: ${spring.application.name}-gateway-flow
namespace: ${NACOS_NAMESPACE:oppc}
groupId: SENTINEL_GROUP
# namespace: public
# 规则类型,取值见:
# org.springframework.cloud.alibaba.sentinel.datasource.RuleType
data-type: json
rule-type: gw-flow
gw-api-group:
nacos:
server-addr: ${NACOS_ADDR:xxxxx:8848}
dataId: ${spring.application.name}-gateway-api
groupId: SENTINEL_GROUP
data-type: json
rule-type: gw-api-group
3.添加网关配置类 设置限流与降级处理的回调函数
@Configuration
public class GatewayConfig {
@PostConstruct
public void doInit(){
//设置限流或降级的回调函数
GatewayCallbackManager.setBlockHandler((serverWebExchange, throwable) -> ServerResponse.status(500).syncBody("系统繁忙请稍后"));
}
}
4.特别注意的地方是 sentinel初始化加载的逻辑中有一个服务类型的参数appType默认为 0 ,0代表是普通的服务,只有设置为1 的时候才是针对网关的。后台页面会有不同,需要在网关服务中添加 参数设置
@SpringBootApplication
@RestController
@EnableDiscoveryClient
@EnableAsync(proxyTargetClass = true)
@EnableFeignClients
public class GatewayApplication {
public static void main(String[] args) {
//sentinel 接入网关 设置类型为 1 不设置的话 按普通服务
System.setProperty("csp.sentinel.app.type", "1");
SpringApplication.run(GatewayApplication.class, args);
}
}
2.应用服务整合sentinel
1.服务pom文件添加依赖
<!-- sentinel -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
<--数据持久化-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2.bootstrap文件在cloud节点下添加配置
spring:
application:
name: xxx.user
profiles:
active: ${DEPLOY_ENV:dev}
devtools:
restart:
enabled: true
main:
allow-bean-definition-overriding: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
servlet:
multipart:
maxFileSize: 5MB #单位必须大写MB或不写(即为B)
maxRequestSize: 10MB
cloud:
sentinel:
transport:
dashboard: xxxxxx:8080
eager: true
<--读取nacos流控配置-->
datasource:
flow:
nacos:
server-addr: ${NACOS_ADDR:xxxxx:8848}
dataId: ${spring.application.name}-flow-rules
namespace: ${NACOS_NAMESPACE:oppc}
groupId: SENTINEL_GROUP
# namespace: public
# 规则类型,取值见:
# org.springframework.cloud.alibaba.sentinel.datasource.RuleType
data-type: json
rule-type: flow
degrade:
nacos:
server-addr: ${NACOS_ADDR:xxxxx:8848}
dataId: ${spring.application.name}-degrade-rules
groupId: SENTINEL_GROUP
data-type: json
rule-type: degrade
system:
nacos:
server-addr: ${NACOS_ADDR:xxxxx:8848}
dataId: ${spring.application.name}-system-rules
groupId: SENTINEL_GROUP
data-type: json
rule-type: system
authority:
nacos:
server-addr: ${NACOS_ADDR:xxxxx:8848}
dataId: ${spring.application.name}-authority-rules
groupId: SENTINEL_GROUP
data-type: json
rule-type: authority
param-flow:
nacos:
server-addr: ${NACOS_ADDR:xxxxx:8848}
dataId: ${spring.application.name}-param-rules
groupId: SENTINEL_GROUP
data-type: json
rule-type: param-flow
3.添加流控异常处理类
@Service
public class BlockHandler implements UrlBlockHandler {
@Override
public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
httpServletResponse.setHeader("Content-Type","application/json;chartset=UTF-8");
httpServletResponse.setCharacterEncoding("utf-8");
httpServletResponse.getWriter().write(new Gson().toJson(R.error("当前访问人数过多,请稍后重试")));
}
}
3.sentinel 源码改造实现流控规则数据持久化
sentinel流控规则通过推送与拉取模式实现与nacos同步,在sentinel控制台和nacos控制台对规则的修改都可互相同步各微服务通过配置nacos数据源,监听nacos配置的变化,拉取nacos的配置并更新到应用的内存中,具体改造步骤如下:
1.去掉SENTINEL-DASHBOARD 工程的POM中TEST
<!-- 去掉test -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!-- <scope>test</scope>-->
</dependency>
2.找到 sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos目录,将整个目录拷贝到 sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos下,如下图所示:
3.修改流控规则Controller,到com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2类的源码中找到这一段:
@Autowired
@Qualifier("flowRuleDefaultProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleDefaultPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
修改@Qualifier注解的内容,将其修改为:
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
4.打开sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html文件,找到一段被注释的代码,如下:
<li ui-sref-active="active" ng-if="!entry.isGateway">
<a ui-sref="dashboard.flowV1({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i>流控规则</a>
</li>
把V1去掉,即改为:
<li ui-sref-active="active" ng-if="!entry.isGateway">
<a ui-sref="dashboard.flow({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i>流控规则</a>
</li>
源码中的添加接口回去调用V1接口,此接口是保存规则数据到内存中,我们要改造成调用源码中的V2接口,同步数据到nacos中
5.添加限流,降级等各个功能的拉取与推送类
代码示例:其余各功能类似
推送:
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author wanggeng
*/
@Component("degradeRuleNacosProvider")
public class DegradeRuleNacosProvider implements DynamicRuleProvider<List<DegradeRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<String, List<DegradeRuleEntity>> converter;
@Override
public List<DegradeRuleEntity> getRules(String appName) throws Exception {
String rules = configService.getConfig(appName + NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
拉取:
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author wanggeng
*/
@Component("degradeRuleNacosPublisher")
public class DegradeRuleNacosPublisher implements DynamicRulePublisher<List<DegradeRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<List<DegradeRuleEntity>, String> converter;
@Override
public void publish(String app, List<DegradeRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, converter.convert(rules));
}
}
- 修改nacos配置类:
package com.alibaba.csp.sentinel.dashboard.rule.nacos;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.*;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.Properties;
/**
* @author wanggeng
*/
@Configuration
public class NacosConfig {
@Value("${nacos.addr}")
private String nacosAddr;
@Value("${nacos.namespace}")
private String nacosNameSpace;
@Value("${nacos.username}")
private String nacosUsername;
@Value("${nacos.password}")
private String nacosPassword;
@Bean
public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
return s -> JSON.parseArray(s, FlowRuleEntity.class);
}
@Bean
public Converter<List<AuthorityRuleEntity>, String> authorityRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<AuthorityRuleEntity>> authorityRuleEntityDecoder() {
return s -> JSON.parseArray(s, AuthorityRuleEntity.class);
}
@Bean
public Converter<List<DegradeRuleEntity>, String> degradeRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<DegradeRuleEntity>> degradeRuleEntityDecoder() {
return s -> JSON.parseArray(s, DegradeRuleEntity.class);
}
@Bean
public Converter<List<ParamFlowRuleEntity>, String> paramFlowRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<ParamFlowRuleEntity>> paramFlowRuleEntityDecoder() {
return s -> JSON.parseArray(s, ParamFlowRuleEntity.class);
}
@Bean
public Converter<List<SystemRuleEntity>, String> systemRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<SystemRuleEntity>> systemRuleEntityDecoder() {
return s -> JSON.parseArray(s, SystemRuleEntity.class);
}
/**
* 网关flowRule
*
* @return
* @throws Exception
*/
@Bean
public Converter<List<GatewayFlowRuleEntity>, String> gatewayFlowRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<GatewayFlowRuleEntity>> gatewayFlowRuleEntityDecoder() {
return s -> JSON.parseArray(s, GatewayFlowRuleEntity.class);
}
/**
* 网关flowRule
*
* @return
* @throws Exception
*/
@Bean
public Converter<List<ApiDefinitionEntity>, String> gatewayApiRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<ApiDefinitionEntity>> gatewayApiRuleEntityDecoder() {
return s -> JSON.parseArray(s, ApiDefinitionEntity.class);
}
@Bean
public ConfigService nacosConfigService() throws Exception {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR,nacosAddr);
properties.put(PropertyKeyConst.NAMESPACE,nacosNameSpace);
properties.put(PropertyKeyConst.USERNAME,nacosUsername);
properties.put(PropertyKeyConst.PASSWORD,nacosPassword);
return ConfigFactory.createConfigService(properties);
}
}
7.修改nacos配置工具类NacosConfigUtil
package com.alibaba.csp.sentinel.dashboard.rule.nacos;
/**
* @author wanggeng
*/
public final class NacosConfigUtil {
public static final String GROUP_ID = "SENTINEL_GROUP";
public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
public static final String DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";
public static final String SYSTEM_DATA_ID_POSTFIX = "-system-rules";
public static final String DASHBOARD_POSTFIX = "-dashboard";
public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-flow-rules";
public static final String AUTHORITY_DATA_ID_POSTFIX = "-authority-rules";
public static final String GETWAY_API_DATA_ID_POSTFIX = "-getway-api";
public static final String GETWAY_FLOW_DATA_ID_POSTFIX = "-getway-flow";
// public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";
// /**
// * cc for `cluster-client`
// */
// public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";
// /**
// * cs for `cluster-server`
// */
// public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";
// public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";
// public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";
private NacosConfigUtil() {}
}
- 修改V2各个Controller中的代码:不再一一列举
例如:
各controller添加:
/**
* 推送 到 nacos
* @param app
* @throws Exception
*/
private void publishApis(String app) throws Exception {
List<ApiDefinitionEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app,rules);
}
具体代码如下:
package com.alibaba.csp.sentinel.dashboard.controller.gateway;
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService;
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiPredicateItemEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.AddApiReqVo;
import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.ApiPredicateItemVo;
import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.UpdateApiReqVo;
import com.alibaba.csp.sentinel.dashboard.repository.gateway.InMemApiDefinitionStore;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import static com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants.*;
/**
* @author wanggeng
*/
@RestController
@RequestMapping(value = "/gateway/api")
public class GatewayApiController {
private final Logger logger = LoggerFactory.getLogger(GatewayApiController.class);
@Autowired
private InMemApiDefinitionStore repository;
@Autowired
private SentinelApiClient sentinelApiClient;
@Autowired
@Qualifier("gateWayApiNacosProvider")
private DynamicRuleProvider<List<ApiDefinitionEntity>> ruleProvider;
@Autowired
@Qualifier("gateWayApiNacosPublisher")
private DynamicRulePublisher<List<ApiDefinitionEntity>> rulePublisher;
@GetMapping("/list.json")
@AuthAction(AuthService.PrivilegeType.READ_RULE)
public Result<List<ApiDefinitionEntity>> queryApis(String app, String ip, Integer port) {
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
if (StringUtil.isEmpty(ip)) {
return Result.ofFail(-1, "ip can't be null or empty");
}
if (port == null) {
return Result.ofFail(-1, "port can't be null");
}
try {
// List<ApiDefinitionEntity> apis = sentinelApiClient.fetchApis(app, ip, port).get();
List<ApiDefinitionEntity> apis = ruleProvider.getRules(app);
repository.saveAll(apis);
return Result.ofSuccess(apis);
} catch (Throwable throwable) {
logger.error("queryApis error:", throwable);
return Result.ofThrowable(-1, throwable);
}
}
@PostMapping("/new.json")
@AuthAction(AuthService.PrivilegeType.WRITE_RULE)
public Result<ApiDefinitionEntity> addApi(HttpServletRequest request, @RequestBody AddApiReqVo reqVo) {
String app = reqVo.getApp();
if (StringUtil.isBlank(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
ApiDefinitionEntity entity = new ApiDefinitionEntity();
entity.setApp(app.trim());
String ip = reqVo.getIp();
if (StringUtil.isBlank(ip)) {
return Result.ofFail(-1, "ip can't be null or empty");
}
entity.setIp(ip.trim());
Integer port = reqVo.getPort();
if (port == null) {
return Result.ofFail(-1, "port can't be null");
}
entity.setPort(port);
// API名称
String apiName = reqVo.getApiName();
if (StringUtil.isBlank(apiName)) {
return Result.ofFail(-1, "apiName can't be null or empty");
}
entity.setApiName(apiName.trim());
// 匹配规则列表
List<ApiPredicateItemVo> predicateItems = reqVo.getPredicateItems();
if (CollectionUtils.isEmpty(predicateItems)) {
return Result.ofFail(-1, "predicateItems can't empty");
}
List<ApiPredicateItemEntity> predicateItemEntities = new ArrayList<>();
for (ApiPredicateItemVo predicateItem : predicateItems) {
ApiPredicateItemEntity predicateItemEntity = new ApiPredicateItemEntity();
// 匹配模式
Integer matchStrategy = predicateItem.getMatchStrategy();
if (!Arrays.asList(URL_MATCH_STRATEGY_EXACT, URL_MATCH_STRATEGY_PREFIX, URL_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {
return Result.ofFail(-1, "invalid matchStrategy: " + matchStrategy);
}
predicateItemEntity.setMatchStrategy(matchStrategy);
// 匹配串
String pattern = predicateItem.getPattern();
if (StringUtil.isBlank(pattern)) {
return Result.ofFail(-1, "pattern can't be null or empty");
}
predicateItemEntity.setPattern(pattern);
predicateItemEntities.add(predicateItemEntity);
}
entity.setPredicateItems(new LinkedHashSet<>(predicateItemEntities));
// 检查API名称不能重复
List<ApiDefinitionEntity> allApis = repository.findAllByMachine(MachineInfo.of(app.trim(), ip.trim(), port));
if (allApis.stream().map(o -> o.getApiName()).anyMatch(o -> o.equals(apiName.trim()))) {
return Result.ofFail(-1, "apiName exists: " + apiName);
}
Date date = new Date();
entity.setGmtCreate(date);
entity.setGmtModified(date);
try {
entity = repository.save(entity);
} catch (Throwable throwable) {
logger.error("add gateway api error:", throwable);
return Result.ofThrowable(-1, throwable);
}
try{
// 修改 推送到nacos
publishApis(entity.getApp());
}catch (Exception e){
logger.warn("publish gateway flow rules fail after add");
}
//此处为推送到应用内存中
// if (!publishApis(app, ip, port)) {
// logger.warn("publish gateway apis fail after add");
// }
return Result.ofSuccess(entity);
}
@PostMapping("/save.json")
@AuthAction(AuthService.PrivilegeType.WRITE_RULE)
public Result<ApiDefinitionEntity> updateApi(@RequestBody UpdateApiReqVo reqVo) {
String app = reqVo.getApp();
if (StringUtil.isBlank(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
Long id = reqVo.getId();
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
ApiDefinitionEntity entity = repository.findById(id);
if (entity == null) {
return Result.ofFail(-1, "api does not exist, id=" + id);
}
// 匹配规则列表
List<ApiPredicateItemVo> predicateItems = reqVo.getPredicateItems();
if (CollectionUtils.isEmpty(predicateItems)) {
return Result.ofFail(-1, "predicateItems can't empty");
}
List<ApiPredicateItemEntity> predicateItemEntities = new ArrayList<>();
for (ApiPredicateItemVo predicateItem : predicateItems) {
ApiPredicateItemEntity predicateItemEntity = new ApiPredicateItemEntity();
// 匹配模式
int matchStrategy = predicateItem.getMatchStrategy();
if (!Arrays.asList(URL_MATCH_STRATEGY_EXACT, URL_MATCH_STRATEGY_PREFIX, URL_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {
return Result.ofFail(-1, "Invalid matchStrategy: " + matchStrategy);
}
predicateItemEntity.setMatchStrategy(matchStrategy);
// 匹配串
String pattern = predicateItem.getPattern();
if (StringUtil.isBlank(pattern)) {
return Result.ofFail(-1, "pattern can't be null or empty");
}
predicateItemEntity.setPattern(pattern);
predicateItemEntities.add(predicateItemEntity);
}
entity.setPredicateItems(new LinkedHashSet<>(predicateItemEntities));
Date date = new Date();
entity.setGmtModified(date);
try {
entity = repository.save(entity);
} catch (Throwable throwable) {
logger.error("update gateway api error:", throwable);
return Result.ofThrowable(-1, throwable);
}
try{
//修改 推送到nacos
publishApis(entity.getApp());
}catch (Exception e){
logger.warn("publish gateway flow rules fail after add");
}
// if (!publishApis(app, entity.getIp(), entity.getPort())) {
// logger.warn("publish gateway apis fail after update");
// }
return Result.ofSuccess(entity);
}
@PostMapping("/delete.json")
@AuthAction(AuthService.PrivilegeType.DELETE_RULE)
public Result<Long> deleteApi(Long id) {
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
ApiDefinitionEntity oldEntity = repository.findById(id);
if (oldEntity == null) {
return Result.ofSuccess(null);
}
try {
repository.delete(id);
} catch (Throwable throwable) {
logger.error("delete gateway api error:", throwable);
return Result.ofThrowable(-1, throwable);
}
try{
//推送到nacos
publishApis(oldEntity.getApp());
}catch (Exception e){
logger.warn("publish gateway flow rules fail after add");
}
// if (!publishApis(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {
// logger.warn("publish gateway apis fail after delete");
// }
return Result.ofSuccess(id);
}
/**
* api 推送 到 nacos
* @param app
* @throws Exception
*/
private void publishApis(String app) throws Exception {
List<ApiDefinitionEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app,rules);
}
// 此处为推送到内存中
// private boolean publishApis(String app, String ip, Integer port) {
// List<ApiDefinitionEntity> apis = repository.findAllByMachine(MachineInfo.of(app, ip, port));
// return sentinelApiClient.modifyApis(app, ip, port, apis);
// }
}
需要源码的可发邮件至314503256@qq.com
有不尽之处,欢迎大神指正,转发请标明出处,谢谢