适配eureka

pull/1/head
tanghc 5 years ago
parent be0adc0a8e
commit 35253be77d
  1. 47
      doc/docs/files/10112_使用eureka.md
  2. 41
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java
  3. 14
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java
  4. 7
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigServiceRouteMapper.java
  5. 14
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplication.java
  6. 13
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplications.java
  7. 11
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApps.java
  8. 70
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaInstance.java
  9. 84
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaUri.java
  10. 94
      sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/RegistryServiceEurekaImpl.java
  11. 8
      sop-admin/sop-admin-server/src/main/resources/application-dev.properties
  12. 7
      sop-admin/sop-admin-vue/src/views/service/limit.vue
  13. 86
      sop-admin/sop-admin-vue/src/views/service/route.vue
  14. 6
      sop-common/sop-gateway-common/pom.xml
  15. 4
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BeanInitializer.java
  16. 17
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/InstanceDefinition.java
  17. 8
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EnvironmentServerChooser.java
  18. 16
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EurekaEnvironmentServerChooser.java
  19. 4
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/SopPropertiesFactory.java
  20. 31
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java
  21. 5
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ChannelMsgProcessor.java
  22. 115
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/NacosEventProcessor.java
  23. 87
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRoutesListener.java
  24. 7
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/NacosRoutesListener.java
  25. 14
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/RegistryListener.java
  26. 43
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/support/EurekaListenerConfiguration.java
  27. 7
      sop-example/sop-book/sop-book-web/pom.xml
  28. 5
      sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties
  29. 8
      sop-example/sop-story/sop-story-web/pom.xml
  30. 5
      sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties
  31. 16
      sop-gateway/pom.xml
  32. 8
      sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java
  33. 2
      sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java
  34. 21
      sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java
  35. 21
      sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java
  36. 28
      sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java
  37. 20
      sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java
  38. 22
      sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java
  39. 21
      sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java
  40. 8
      sop-gateway/src/main/resources/application-dev.properties

@ -0,0 +1,47 @@
# 使用eureka
## 修改网关
- 打开`/sop-gateway/pom.xml`
添加依赖:
```xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
```
- 打开sop-gateway下`application-dev.properties`
注释nacos配置
```properties
# nacos cloud配置
#spring.cloud.nacos.discovery.server-addr=${nacos.url}
#nacos.config.server-addr=${nacos.url}
```
添加eureka配置
```properties
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
```
## 微服务端修改
步骤同上
## admin修改
打开`application-dev.properties`,新增配置
```properties
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# 如果使用eureka,填eureka,使用nacos,填eureka
registry.name=eureka
```

@ -1,7 +1,5 @@
package com.gitee.sop.adminserver.api.service;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.naming.NamingService;
import com.gitee.easyopen.annotation.Api;
import com.gitee.easyopen.annotation.ApiService;
import com.gitee.easyopen.doc.annotation.ApiDoc;
@ -27,6 +25,7 @@ import com.gitee.sop.adminserver.entity.ConfigGray;
import com.gitee.sop.adminserver.entity.ConfigGrayInstance;
import com.gitee.sop.adminserver.mapper.ConfigGrayInstanceMapper;
import com.gitee.sop.adminserver.mapper.ConfigGrayMapper;
import com.gitee.sop.adminserver.mapper.ConfigServiceRouteMapper;
import com.gitee.sop.adminserver.service.ConfigPushService;
import com.gitee.sop.adminserver.service.RegistryService;
import lombok.extern.slf4j.Slf4j;
@ -61,58 +60,36 @@ public class ServiceApi {
private ConfigGrayInstanceMapper configGrayInstanceMapper;
@Autowired
private ConfigPushService configPushService;
private ConfigServiceRouteMapper configServiceRouteMapper;
@NacosInjected
private NamingService namingService;
@Autowired
private ConfigPushService configPushService;
@Api(name = "registry.service.list")
@ApiDocMethod(description = "注册中心的服务列表", elementClass = RouteServiceInfo.class)
List<RouteServiceInfo> listServiceInfo(ServiceSearchParam param) {
List<ServiceInfo> servicesOfServer = null;
try {
servicesOfServer = registryService.listAllService(1, Integer.MAX_VALUE);
} catch (Exception e) {
log.error("获取服务列表失败", e);
throw new BizException("获取服务列表失败");
}
return servicesOfServer
@ApiDocMethod(description = "路由配置中的服务列表", elementClass = String.class)
List<String> listServiceInfo(ServiceSearchParam param) {
List<String> allServiceId = configServiceRouteMapper.listAllServiceId();
return allServiceId
.stream()
.filter(serviceInfo -> {
String serviceId = serviceInfo.getServiceId();
if ("api-gateway".equalsIgnoreCase(serviceId)) {
return false;
}
// 隐藏空服务
if (CollectionUtils.isEmpty(serviceInfo.getInstances())) {
return false;
}
.filter(serviceId -> {
if (StringUtils.isBlank(param.getServiceId())) {
return true;
} else {
return serviceId.contains(param.getServiceId());
}
})
.map(serviceInfo -> {
RouteServiceInfo routeServiceInfo = new RouteServiceInfo();
routeServiceInfo.setServiceId(serviceInfo.getServiceId());
return routeServiceInfo;
})
.collect(Collectors.toList());
}
@Api(name = "service.custom.add")
@ApiDocMethod(description = "添加服务")
void addService(ServiceAddParam param) {
// TODO: 添加服务
throw new BizException("该功能已下线");
}
@Api(name = "service.custom.del")
@ApiDocMethod(description = "删除自定义服务")
void delService(ServiceSearchParam param) {
// TODO: 删除自定义服务
throw new BizException("该功能已下线");
}

@ -10,11 +10,13 @@ import com.gitee.easyopen.interceptor.ApiInterceptor;
import com.gitee.easyopen.session.ApiSessionManager;
import com.gitee.sop.adminserver.interceptor.LoginInterceptor;
import com.gitee.sop.adminserver.service.RegistryService;
import com.gitee.sop.adminserver.service.impl.RegistryServiceEurekaImpl;
import com.gitee.sop.adminserver.service.impl.RegistryServiceNacosImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@ -75,10 +77,22 @@ public class WebConfig {
* @return
*/
@Bean
@ConditionalOnProperty(value = "registry.name", havingValue = "nacos", matchIfMissing = true)
RegistryService registryServiceNacos() {
return new RegistryServiceNacosImpl();
}
/**
* 当配置了registry.name=eureka生效
*
* @return
*/
@Bean
@ConditionalOnProperty(value = "registry.name", havingValue = "eureka")
RegistryService registryServiceEureka() {
return new RegistryServiceEurekaImpl();
}
@PostConstruct
public void after() {
}

@ -2,10 +2,17 @@ package com.gitee.sop.adminserver.mapper;
import com.gitee.fastmybatis.core.mapper.CrudMapper;
import com.gitee.sop.adminserver.entity.ConfigServiceRoute;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author tanghc
*/
public interface ConfigServiceRouteMapper extends CrudMapper<ConfigServiceRoute, Long> {
@Select("SELECT distinct service_id FROM config_service_route")
List<String> listAllServiceId();
}

@ -0,0 +1,14 @@
package com.gitee.sop.adminserver.service.impl;
import lombok.Data;
import java.util.List;
/**
* @author tanghc
*/
@Data
public class EurekaApplication {
private String name;
private List<EurekaInstance> instance;
}

@ -0,0 +1,13 @@
package com.gitee.sop.adminserver.service.impl;
import lombok.Data;
import java.util.List;
/**
* @author tanghc
*/
@Data
public class EurekaApplications {
private List<EurekaApplication> application;
}

@ -0,0 +1,11 @@
package com.gitee.sop.adminserver.service.impl;
import lombok.Data;
/**
* @author tanghc
*/
@Data
public class EurekaApps {
private EurekaApplications applications;
}

@ -0,0 +1,70 @@
package com.gitee.sop.adminserver.service.impl;
import lombok.Data;
import org.springframework.util.CollectionUtils;
import java.util.Map;
/**
* {
* "instance": {
* "instanceId": "demo-order2:11101",
* "app": "demo-order2",
* "appGroutName": null,
* "ipAddr": "127.0.0.1",
* "sid": "na",
* "homePageUrl": null,
* "statusPageUrl": null,
* "healthCheckUrl": null,
* "secureHealthCheckUrl": null,
* "vipAddress": "demo-order2",
* "secureVipAddress": "demo-order2",
* "countryId": 1,
* "dataCenterInfo": {
* "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
* "name": "MyOwn"
* },
* "hostName": "127.0.0.1",
* "status": "UP",
* "leaseInfo": null,
* "isCoordinatingDiscoveryServer": false,
* "lastUpdatedTimestamp": 1529391461000,
* "lastDirtyTimestamp": 1529391461000,
* "actionType": null,
* "asgName": null,
* "overridden_status": "UNKNOWN",
* "port": {
* "$": 11102,
* "@enabled": "false"
* },
* "securePort": {
* "$": 7002,
* "@enabled": "false"
* },
* "metadata": {
* "@class": "java.util.Collections$EmptyMap"
* }* }
* }
* @author tanghc
*/
@Data
public class EurekaInstance {
private String instanceId;
private String ipAddr;
private Map<String, Object> port;
private String status;
private String statusPageUrl;
private String healthCheckUrl;
private String lastUpdatedTimestamp;
private Map<String, String> metadata;
public String fetchPort() {
if (CollectionUtils.isEmpty(port)) {
return "";
}
return String.valueOf(port.getOrDefault("$", ""));
}
}

@ -0,0 +1,84 @@
package com.gitee.sop.adminserver.service.impl;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.internal.http.HttpMethod;
/**
* https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
*
* @author tanghc
*/
public enum EurekaUri {
/**
* 查询所有实例 Query for all instances
*/
QUERY_APPS("GET", "/apps"),
/**
* 查询一个实例
*/
QUERY_INSTANCES("GET", "/instances/%s"),
/**
* 下线 Take instance out of service
*/
OFFLINE_SERVICE("PUT", "/apps/%s/%s/status?value=OUT_OF_SERVICE"),
/**
* 上线 Move instance back into service (remove override)
*/
ONLINE_SERVICE("DELETE", "/apps/%s/%s/status?value=UP"),
/**
* 设置metadata信息
*
* /apps/{appID}/{instanceID}/metadata?key=value
*/
SET_METADATA("PUT", "/apps/%s/%s/metadata?%s=%s")
;
public static final String URL_PREFIX = "/";
String uri;
String requestMethod;
EurekaUri(String httpMethod, String uri) {
if (!uri.startsWith(URL_PREFIX)) {
uri = "/" + uri;
}
this.uri = uri;
this.requestMethod = httpMethod;
}
public String getUri(String... args) {
if (args == null || args.length == 0) {
return uri;
}
Object[] param = new Object[args.length];
for (int i = 0; i < args.length; i++) {
param[i] = args[i];
}
return String.format(uri, param);
}
public Request getRequest(String url, String... args) {
if (url.endsWith("/")) {
url = url.substring(0, url.length() - 1);
}
String requestUrl = url + getUri(args);
Request request = this.getBuilder()
.url(requestUrl)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.build();
return request;
}
public Request.Builder getBuilder() {
String method = requestMethod;
RequestBody requestBody = null;
if (HttpMethod.requiresRequestBody(method)) {
MediaType contentType = MediaType.parse("application/json");
requestBody = RequestBody.create(contentType, "{}");
}
return new Request.Builder().method(requestMethod, requestBody);
}
}

@ -0,0 +1,94 @@
package com.gitee.sop.adminserver.service.impl;
import com.alibaba.fastjson.JSON;
import com.gitee.sop.adminserver.bean.ServiceInfo;
import com.gitee.sop.adminserver.bean.ServiceInstance;
import com.gitee.sop.adminserver.service.RegistryService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
* eureka接口实现
* @author tanghc
*/
@Slf4j
public class RegistryServiceEurekaImpl implements RegistryService {
private OkHttpClient client = new OkHttpClient();
@Value("${eureka.client.serviceUrl.defaultZone:}")
private String eurekaUrl;
@Override
public List<ServiceInfo> listAllService(int pageNo, int pageSize) throws Exception {
if (StringUtils.isBlank(eurekaUrl)) {
throw new IllegalArgumentException("未指定eureka.client.serviceUrl.defaultZone参数");
}
String json = this.requestEurekaServer(EurekaUri.QUERY_APPS);
EurekaApps eurekaApps = JSON.parseObject(json, EurekaApps.class);
List<ServiceInfo> serviceInfoList = new ArrayList<>();
List<EurekaApplication> applicationList = eurekaApps.getApplications().getApplication();
for (EurekaApplication eurekaApplication : applicationList) {
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.setServiceId(eurekaApplication.getName());
List<EurekaInstance> instanceList = eurekaApplication.getInstance();
if (!CollectionUtils.isEmpty(instanceList)) {
serviceInfo.setInstances(new ArrayList<>(instanceList.size()));
for (EurekaInstance eurekaInstance : instanceList) {
ServiceInstance serviceInstance = new ServiceInstance();
serviceInstance.setInstanceId(eurekaInstance.getInstanceId());
serviceInstance.setServiceId(serviceInfo.getServiceId());
serviceInstance.setIp(eurekaInstance.getIpAddr());
serviceInstance.setPort(Integer.valueOf(eurekaInstance.fetchPort()));
serviceInstance.setStatus(eurekaInstance.getStatus());
Date updateTime = new Date(Long.valueOf(eurekaInstance.getLastUpdatedTimestamp()));
serviceInstance.setUpdateTime(DateFormatUtils.format(updateTime, TIMESTAMP_PATTERN));
serviceInstance.setMetadata(eurekaInstance.getMetadata());
serviceInfo.getInstances().add(serviceInstance);
}
}
serviceInfoList.add(serviceInfo);
}
return serviceInfoList;
}
@Override
public void onlineInstance(ServiceInstance serviceInstance) throws Exception {
this.requestEurekaServer(EurekaUri.ONLINE_SERVICE, serviceInstance.getServiceId(), serviceInstance.getInstanceId());
}
@Override
public void offlineInstance(ServiceInstance serviceInstance) throws Exception {
this.requestEurekaServer(EurekaUri.OFFLINE_SERVICE, serviceInstance.getServiceId(), serviceInstance.getInstanceId());
}
@Override
public void setMetadata(ServiceInstance serviceInstance, String key, String value) throws Exception {
this.requestEurekaServer(EurekaUri.SET_METADATA, serviceInstance.getServiceId(), serviceInstance.getInstanceId(), key, value);
}
private String requestEurekaServer(EurekaUri eurekaUri, String... args) throws IOException {
Request request = eurekaUri.getRequest(this.eurekaUrl, args);
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
log.error("操作失败,url:{}, msg:{}, code:{}", eurekaUri.getUri(args), response.message(), response.code());
throw new RuntimeException("操作失败");
}
}
}

@ -11,10 +11,16 @@ mysql.password=root
nacos.url=127.0.0.1:8848
# 网关地址,多个用逗号隔开
# 此配置仅在使用eureka时有用,不用的话注释掉
# 在不使用nacos时有用,使用nacos时注释掉
gateway.host=127.0.0.1:8081
# ------- 需要改的配置end -------
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# 如果使用eureka,填eureka,使用nacos,填eureka
registry.name=eureka
# token过期时间,分钟
admin.access-token.timeout-minutes=30
# 签名方式,rsa:支付宝开放平台签名方式,md5:淘宝开放平台签名方式

@ -382,14 +382,13 @@ export default {
convertToTreeData(data, pid) {
const result = []
const root = {
label: '服务列表',
label: data.length === 0 ? '无服务' : '服务列表',
parentId: pid
}
const children = []
for (let i = 0; i < data.length; i++) {
data[i].parentId = 1
data[i].label = data[i].serviceId
children.push(data[i])
const child = { parentId: 1, label: data[i] }
children.push(child)
}
root.children = children
result.push(root)

@ -52,7 +52,8 @@
size="mini"
icon="el-icon-delete"
title="删除服务"
@click.stop="() => onDelService(data)"/>
@click.stop="() => onDelService(data)"
/>
</span>
</span>
</el-tree>
@ -60,7 +61,10 @@
<el-main style="padding-top:0">
<el-form :inline="true" :model="searchFormData" class="demo-form-inline" size="mini">
<el-form-item label="路由名称">
<el-input v-model="searchFormData.id" placeholder="输入接口名或版本号" />
<el-input v-model="searchFormData.id" :clearable="true" placeholder="输入接口名或版本号" />
</el-form-item>
<el-form-item>
<el-checkbox v-model="searchFormData.permission">授权接口</el-checkbox>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onSearchTable">查询</el-button>
@ -76,9 +80,9 @@
新建路由
</el-button>
<el-table
:data="tableData"
:data="pageInfo.rows"
border
max-height="500"
highlight-current-row
style="margin-top: 10px;"
>
<el-table-column
@ -141,6 +145,17 @@
</template>
</el-table-column>
</el-table>
<el-pagination
background
style="margin-top: 5px"
:current-page="searchFormData.pageIndex"
:page-size="searchFormData.pageSize"
:page-sizes="[10, 20, 40]"
:total="pageInfo.total"
layout="total, sizes, prev, pager, next"
@size-change="onSizeChange"
@current-change="onPageIndexChange"
/>
</el-main>
</el-container>
<!-- route dialog -->
@ -252,7 +267,14 @@ export default {
isCustomService: false,
searchFormData: {
id: '',
serviceId: ''
serviceId: '',
permission: 0,
pageIndex: 1,
pageSize: 10
},
pageInfo: {
rows: [],
total: 0
},
defaultProps: {
children: 'children',
@ -347,37 +369,36 @@ export default {
/**
* 数组转成树状结构
* @param data 数据结构 [{
"_parentId": 14,
"gmtCreate": "2019-01-15 09:44:38",
"gmtUpdate": "2019-01-15 09:44:38",
"id": 15,
"isShow": 1,
"name": "用户注册",
"orderIndex": 10000,
"parentId": 14
},...]
"_parentId": 14,
"gmtCreate": "2019-01-15 09:44:38",
"gmtUpdate": "2019-01-15 09:44:38",
"id": 15,
"isShow": 1,
"name": "用户注册",
"orderIndex": 10000,
"parentId": 14
},...]
* @param pid 初始父节点id一般是0
* @return 返回结果 [{
label: '一级 1',
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
label: '三级 1-1-1'
}]
}
}]
}
*/
convertToTreeData(data, pid) {
const result = []
const root = {
label: '服务列表',
label: data.length === 0 ? '无服务' : '服务列表',
parentId: pid
}
const children = []
for (let i = 0; i < data.length; i++) {
data[i].parentId = 1
data[i].label = data[i].serviceId
children.push(data[i])
const child = { parentId: 1, label: data[i] }
children.push(child)
}
root.children = children
result.push(root)
@ -385,12 +406,17 @@ export default {
},
// table
loadTable: function(param) {
if (!this.searchFormData.serviceId) {
this.tip('请选择一个服务', 'error')
return
}
const postData = param || this.searchFormData
this.post('route.list', postData, function(resp) {
this.tableData = resp.data
this.post('route.page', postData, function(resp) {
this.pageInfo = resp.data
})
},
onSearchTable: function() {
this.searchFormData.pageIndex = 1
this.loadTable()
},
onTableUpdate: function(row) {
@ -509,6 +535,14 @@ export default {
this.loadTree()
})
})
},
onSizeChange: function(size) {
this.searchFormData.pageSize = size
this.loadTable()
},
onPageIndexChange: function(pageIndex) {
this.searchFormData.pageIndex = pageIndex
this.loadTable()
}
}
}

@ -77,6 +77,12 @@
<version>2.1.0.RELEASE</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
<version>2.3.0</version>
<optional>true</optional>
</dependency>
</dependencies>

@ -1,9 +1,11 @@
package com.gitee.sop.gatewaycommon.bean;
import com.gitee.sop.gatewaycommon.manager.ChannelMsgProcessor;
/**
* @author tanghc
*/
public interface BeanInitializer {
public interface BeanInitializer extends ChannelMsgProcessor {
/**
* 执行加载操作
*/

@ -0,0 +1,17 @@
package com.gitee.sop.gatewaycommon.bean;
import lombok.Data;
import java.util.Map;
/**
* @author tanghc
*/
@Data
public class InstanceDefinition {
private String instanceId;
private String serviceId;
private String ip;
private int port;
private Map<String, String> metadata;
}

@ -1,4 +1,4 @@
package com.gitee.sop.gateway.loadbalancer;
package com.gitee.sop.gatewaycommon.loadbalancer;
import com.gitee.sop.gatewaycommon.bean.SpringContext;
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.BaseServerChooser;
@ -39,10 +39,14 @@ public class EnvironmentServerChooser extends BaseServerChooser {
private String getEnvValue(Server server) {
// eureka存储的metadata
Map<String, String> metadata = ((NacosServer) server).getMetadata();
Map<String, String> metadata = getMetada(server);
return metadata.get(MEDATA_KEY_ENV);
}
protected Map<String, String> getMetada(Server server) {
return ((NacosServer) server).getMetadata();
}
/**
* 通过判断hostname来确定是否是预发布请求可修改此方法实现自己想要的

@ -0,0 +1,16 @@
package com.gitee.sop.gatewaycommon.loadbalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
import java.util.Map;
/**
* @author tanghc
*/
public class EurekaEnvironmentServerChooser extends EnvironmentServerChooser {
@Override
protected Map<String, String> getMetada(Server server) {
return ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata();
}
}

@ -1,4 +1,4 @@
package com.gitee.sop.gateway.loadbalancer;
package com.gitee.sop.gatewaycommon.loadbalancer;
import com.netflix.loadbalancer.IRule;
import org.springframework.beans.factory.annotation.Autowired;
@ -15,7 +15,7 @@ public class SopPropertiesFactory extends PropertiesFactory {
* 可在配置文件中设置<code>zuul.custom-rule-classname=com.xx.ClassName</code>指定负载均衡规则类
* 默认使用com.gitee.sop.gateway.loadbalancer.PreEnvironmentServerChooser
*/
private static final String PROPERTIES_KEY = "zuul.custom-rule-classname";
public static final String PROPERTIES_KEY = "zuul.custom-rule-classname";
private static final String CUSTOM_RULE_CLASSNAME = EnvironmentServerChooser.class.getName();

@ -5,8 +5,10 @@ import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.bean.BeanInitializer;
import com.gitee.sop.gatewaycommon.bean.SpringContext;
import com.gitee.sop.gatewaycommon.limit.LimitManager;
import com.gitee.sop.gatewaycommon.loadbalancer.SopPropertiesFactory;
import com.gitee.sop.gatewaycommon.message.ErrorFactory;
import com.gitee.sop.gatewaycommon.param.ParameterFormatter;
import com.gitee.sop.gatewaycommon.route.EurekaRoutesListener;
import com.gitee.sop.gatewaycommon.route.NacosRoutesListener;
import com.gitee.sop.gatewaycommon.route.RegistryListener;
import com.gitee.sop.gatewaycommon.secret.IsvManager;
@ -14,8 +16,11 @@ import com.gitee.sop.gatewaycommon.session.SessionManager;
import com.gitee.sop.gatewaycommon.validate.Validator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.netflix.ribbon.PropertiesFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
@ -53,21 +58,35 @@ public class AbstractConfiguration implements ApplicationContextAware {
*/
@EventListener(classes = HeartbeatEvent.class)
public void listenNacosEvent(ApplicationEvent heartbeatEvent) {
Object source = heartbeatEvent.getSource();
if (source != null && source.getClass().getName().contains("NacosWatch")) {
registryListener.onRegister(heartbeatEvent);
}
registryListener.onEvent(heartbeatEvent);
}
@Bean
PropertiesFactory propertiesFactory() {
return new SopPropertiesFactory();
}
@Bean
@ConditionalOnClass(name = "com.alibaba.nacos.api.config.ConfigService")
public NacosEventProcessor nacosEventProcessor() {
return new NacosEventProcessor();
}
/**
* 微服务路由加载
*/
@Bean
@ConditionalOnMissingBean
RegistryListener registryListener() {
@ConditionalOnProperty("spring.cloud.nacos.discovery.server-addr")
RegistryListener registryListenerNacos() {
return new NacosRoutesListener();
}
@Bean
@ConditionalOnProperty("eureka.client.serviceUrl.defaultZone")
RegistryListener registryListenerEureka() {
return new EurekaRoutesListener();
}
@Bean
@ConditionalOnMissingBean
Validator validator() {

@ -1,4 +1,4 @@
package com.gitee.sop.gateway.manager;
package com.gitee.sop.gatewaycommon.manager;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
@ -6,5 +6,6 @@ import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
* @author tanghc
*/
public interface ChannelMsgProcessor {
void process(ChannelMsg channelMsg);
default void process(ChannelMsg channelMsg) {
}
}

@ -0,0 +1,115 @@
package com.gitee.sop.gatewaycommon.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.exception.NacosException;
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.secret.IsvManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
/**
* @author tanghc
*/
@Slf4j
public class NacosEventProcessor {
@NacosInjected
private ConfigService configService;
@Autowired
private EnvGrayManager envGrayManager;
@Autowired
private IPBlacklistManager ipBlacklistManager;
@Autowired
private IsvManager isvManager;
@Autowired
private IsvRoutePermissionManager isvRoutePermissionManager;
@Autowired
private LimitConfigManager limitConfigManager;
@Autowired
private RouteConfigManager routeConfigManager;
@PostConstruct
public void after() throws NacosException {
log.debug("初始化nacos事件监听");
initEnvGray();
initIPBlack();
initIsv();
initIsvRoutePermission();
initLimitConfig();
initRouteConfig();
}
private void initEnvGray() throws NacosException {
configService.addListener(NacosConfigs.DATA_ID_GRAY, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
envGrayManager.process(channelMsg);
}
});
}
private void initIPBlack() throws NacosException {
configService.addListener(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
ipBlacklistManager.process(channelMsg);
}
});
}
private void initIsv() throws NacosException {
configService.addListener(NacosConfigs.DATA_ID_ISV, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
isvManager.process(channelMsg);
}
});
}
private void initIsvRoutePermission() throws NacosException {
configService.addListener(NacosConfigs.DATA_ID_ROUTE_PERMISSION, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
isvRoutePermissionManager.process(channelMsg);
}
});
}
private void initLimitConfig() throws NacosException {
configService.addListener(NacosConfigs.DATA_ID_LIMIT_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
limitConfigManager.process(channelMsg);
}
});
}
private void initRouteConfig() throws NacosException {
configService.addListener(NacosConfigs.DATA_ID_ROUTE_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
routeConfigManager.process(channelMsg);
}
});
}
}

@ -1,11 +1,22 @@
package com.gitee.sop.gatewaycommon.route;
import com.gitee.sop.gatewaycommon.bean.InstanceDefinition;
import com.gitee.sop.gatewaycommon.loadbalancer.EurekaEnvironmentServerChooser;
import com.gitee.sop.gatewaycommon.loadbalancer.SopPropertiesFactory;
import com.netflix.appinfo.InstanceInfo;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.context.ApplicationEvent;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 加载服务路由eureka实现
*
@ -13,22 +24,66 @@ import org.springframework.context.ApplicationEvent;
*/
public class EurekaRoutesListener extends BaseRoutesListener {
@Override
public void onRegister(ApplicationEvent applicationEvent) {
EurekaInstanceRegisteredEvent event = (EurekaInstanceRegisteredEvent)applicationEvent;
InstanceInfo instanceInfo = event.getInstanceInfo();
InstanceDefinition instanceDefinition = new InstanceDefinition();
instanceDefinition.setInstanceId(instanceInfo.getInstanceId());
instanceDefinition.setServiceId(instanceInfo.getAppName());
instanceDefinition.setIp(instanceInfo.getIPAddr());
instanceDefinition.setPort(instanceInfo.getPort());
instanceDefinition.setMetadata(instanceInfo.getMetadata());
pullRoutes(instanceDefinition);
static {
System.setProperty(SopPropertiesFactory.PROPERTIES_KEY, EurekaEnvironmentServerChooser.class.getName());
}
private Set<String> cacheServices = new HashSet<>();
@Value("${spring.application.name:api-gateway}")
private String appName;
@Override
public void onDeregister(ApplicationEvent applicationEvent) {
EurekaInstanceCanceledEvent event = (EurekaInstanceCanceledEvent)applicationEvent;
removeRoutes(event.getServerId());
public void onEvent(ApplicationEvent applicationEvent) {
Object source = applicationEvent.getSource();
CloudEurekaClient cloudEurekaClient = (CloudEurekaClient) source;
Applications applications = cloudEurekaClient.getApplications();
List<Application> registeredApplications = applications.getRegisteredApplications();
List<String> serviceList = registeredApplications
.stream()
.map(Application::getName)
.collect(Collectors.toList());
Set<String> currentServices = new HashSet<>(serviceList);
currentServices.removeAll(cacheServices);
// 如果有新的服务注册进来
if (currentServices.size() > 0) {
this.doRegister(registeredApplications, currentServices);
}
currentServices = new HashSet<>(serviceList);
cacheServices.removeAll(currentServices);
// 如果有服务删除
if (cacheServices.size() > 0) {
this.doRemove(cacheServices);
}
cacheServices = new HashSet<>(serviceList);
}
private void doRegister(List<Application> registeredApplications, Set<String> newServices) {
registeredApplications
.stream()
.filter(application -> !appName.equalsIgnoreCase(application.getName())
&& newServices.contains(application.getName()))
.forEach(application -> {
List<InstanceInfo> instances = application.getInstances();
if (CollectionUtils.isNotEmpty(instances)) {
instances.sort(Comparator.comparing(InstanceInfo::getLastUpdatedTimestamp).reversed());
InstanceInfo instanceInfo = instances.get(0);
InstanceDefinition instanceDefinition = new InstanceDefinition();
instanceDefinition.setInstanceId(instanceInfo.getInstanceId());
instanceDefinition.setServiceId(instanceInfo.getAppName());
instanceDefinition.setIp(instanceInfo.getIPAddr());
instanceDefinition.setPort(instanceInfo.getPort());
instanceDefinition.setMetadata(instanceInfo.getMetadata());
pullRoutes(instanceDefinition);
}
});
}
private void doRemove(Set<String> deletedServices) {
deletedServices.forEach(this::removeRoutes);
}
}

@ -31,7 +31,7 @@ public class NacosRoutesListener extends BaseRoutesListener {
private ConfigService configService;
@Override
public void onRegister(ApplicationEvent applicationEvent) {
public void onEvent(ApplicationEvent applicationEvent) {
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
List<ServiceInfo> subscribes = null;
try {
@ -72,9 +72,4 @@ public class NacosRoutesListener extends BaseRoutesListener {
}
}
@Override
public void onDeregister(ApplicationEvent applicationEvent) {
}
}

@ -9,18 +9,6 @@ import org.springframework.context.ApplicationEvent;
*/
public interface RegistryListener {
/**
* 触发新服务注册
*
* @param applicationEvent 事件可能是nacos事件也可能是eureka事件
*/
void onRegister(ApplicationEvent applicationEvent);
/**
* 注销服务
*
* @param applicationEvent
*/
void onDeregister(ApplicationEvent applicationEvent);
void onEvent(ApplicationEvent applicationEvent);
}

@ -1,43 +0,0 @@
package com.gitee.sop.gatewaycommon.support;
import com.gitee.sop.gatewaycommon.route.EurekaRoutesListener;
import com.gitee.sop.gatewaycommon.route.RegistryListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
/**
* eureka注册中心事件监听
* @author tanghc
*/
public class EurekaListenerConfiguration {
@Autowired
private RegistryListener registryListener;
/**
* 客户端注册触发
* @param event
*/
@EventListener
public void onEurekaInstanceRegisteredEvent(EurekaInstanceRegisteredEvent event) {
registryListener.onRegister(event);
}
/**
* 客户端下线触发
* @param event
*/
@EventListener
public void onEurekaInstanceCanceledEvent(EurekaInstanceCanceledEvent event) {
registryListener.onDeregister(event);
}
@Bean
RegistryListener registryListener() {
return new EurekaRoutesListener();
}
}

@ -45,7 +45,7 @@
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
@ -56,8 +56,13 @@
<artifactId>nacos-client</artifactId>
<version>${nacos-client.version}</version>
</dependency>
-->
<!-- 注册中心end -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>

@ -1,8 +1,11 @@
server.port=3333
spring.application.name=book-service
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# nacos注册中心
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# consumer不需要检查provider是否启动
dubbo.consumer.check=false

@ -39,7 +39,7 @@
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
@ -50,8 +50,14 @@
<artifactId>nacos-client</artifactId>
<version>${nacos-client.version}</version>
</dependency>
-->
<!-- 注册中心end -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>

@ -1,8 +1,11 @@
server.port=2222
spring.application.name=story-service
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# nacos注册中心
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# dubbo配置
dubbo.protocol.name=dubbo

@ -54,10 +54,20 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
@ -68,17 +78,19 @@
<artifactId>nacos-client</artifactId>
<version>${nacos-client.version}</version>
</dependency>
-->
<!-- 注册中心end -->
<!--
这里依赖springboot版本,非cloud版本。
如果依赖了spring-cloud-starter-alibaba-nacos-config,需要额外配置一个bootstrap.properties
-->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${nacos-spring-boot-starter.version}</version>
</dependency>
-->
<!-- test -->
<dependency>

@ -6,10 +6,7 @@ package com.gitee.sop.gateway.config;
* 注意下面两个只能使用一个
*/
import com.gitee.sop.gateway.loadbalancer.SopPropertiesFactory;
import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration;
import org.springframework.cloud.netflix.ribbon.PropertiesFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
@ -19,11 +16,6 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class ZuulConfig extends AlipayZuulConfiguration {
@Bean
PropertiesFactory propertiesFactory() {
return new SopPropertiesFactory();
}
}
/**

@ -1,7 +1,6 @@
package com.gitee.sop.gateway.controller;
import com.alibaba.fastjson.JSON;
import com.gitee.sop.gateway.manager.ChannelMsgProcessor;
import com.gitee.sop.gateway.manager.DbEnvGrayManager;
import com.gitee.sop.gateway.manager.DbIPBlacklistManager;
import com.gitee.sop.gateway.manager.DbIsvManager;
@ -11,6 +10,7 @@ import com.gitee.sop.gateway.manager.DbRouteConfigManager;
import com.gitee.sop.gatewaycommon.bean.GatewayPushDTO;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.bean.SpringContext;
import com.gitee.sop.gatewaycommon.manager.ChannelMsgProcessor;
import com.gitee.sop.gatewaycommon.util.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

@ -1,16 +1,11 @@
package com.gitee.sop.gateway.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.sop.gateway.entity.ConfigGray;
import com.gitee.sop.gateway.entity.ConfigGrayInstance;
import com.gitee.sop.gateway.mapper.ConfigGrayInstanceMapper;
import com.gitee.sop.gateway.mapper.ConfigGrayMapper;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.bean.ServiceGrayDefinition;
import com.gitee.sop.gatewaycommon.manager.DefaultEnvGrayManager;
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig;
@ -20,7 +15,6 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -36,7 +30,7 @@ import java.util.stream.Stream;
*/
@Slf4j
@Service
public class DbEnvGrayManager extends DefaultEnvGrayManager implements ChannelMsgProcessor {
public class DbEnvGrayManager extends DefaultEnvGrayManager {
private static final int STATUS_ENABLE = 1;
@ -49,9 +43,6 @@ public class DbEnvGrayManager extends DefaultEnvGrayManager implements ChannelMs
@Autowired
private ConfigGrayInstanceMapper configGrayInstanceMapper;
@NacosInjected
private ConfigService configService;
@Override
public void load() {
@ -116,15 +107,5 @@ public class DbEnvGrayManager extends DefaultEnvGrayManager implements ChannelMs
}
}
@PostConstruct
protected void after() throws Exception {
configService.addListener(NacosConfigs.DATA_ID_GRAY, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
process(channelMsg);
}
});
}
}

@ -1,19 +1,13 @@
package com.gitee.sop.gateway.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.gitee.sop.gateway.mapper.IPBlacklistMapper;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.manager.DefaultIPBlacklistManager;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;
/**
@ -23,14 +17,11 @@ import java.util.List;
*/
@Slf4j
@Service
public class DbIPBlacklistManager extends DefaultIPBlacklistManager implements ChannelMsgProcessor {
public class DbIPBlacklistManager extends DefaultIPBlacklistManager {
@Autowired
private IPBlacklistMapper ipBlacklistMapper;
@NacosInjected
private ConfigService configService;
@Override
public void load() {
List<String> ipList = ipBlacklistMapper.listAllIP();
@ -56,16 +47,6 @@ public class DbIPBlacklistManager extends DefaultIPBlacklistManager implements C
}
}
@PostConstruct
protected void after() throws Exception {
configService.addListener(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
process(channelMsg);
}
});
}
@Data
private static class IPDto {

@ -1,22 +1,16 @@
package com.gitee.sop.gateway.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.gitee.sop.gateway.entity.IsvDetailDTO;
import com.gitee.sop.gateway.mapper.IsvInfoMapper;
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
import com.gitee.sop.gatewaycommon.bean.IsvDefinition;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.secret.CacheIsvManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;
/**
@ -24,14 +18,15 @@ import java.util.List;
*/
@Slf4j
@Service
public class DbIsvManager extends CacheIsvManager implements ChannelMsgProcessor{
public class DbIsvManager extends CacheIsvManager {
public DbIsvManager() {
ApiConfig.getInstance().setIsvManager(this);
}
@Autowired
private IsvInfoMapper isvInfoMapper;
@NacosInjected
private ConfigService configService;
@Override
public void load() {
List<IsvDetailDTO> isvInfoList = isvInfoMapper.listIsvDetail();
@ -60,17 +55,4 @@ public class DbIsvManager extends CacheIsvManager implements ChannelMsgProcessor
}
}
@PostConstruct
protected void after() throws Exception {
ApiConfig.getInstance().setIsvManager(this);
configService.addListener(NacosConfigs.DATA_ID_ISV, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
process(channelMsg);
}
});
}
}

@ -1,9 +1,6 @@
package com.gitee.sop.gateway.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.sop.gateway.entity.IsvInfo;
import com.gitee.sop.gateway.entity.PermIsvRole;
@ -13,7 +10,6 @@ import com.gitee.sop.gateway.mapper.PermIsvRoleMapper;
import com.gitee.sop.gateway.mapper.PermRolePermissionMapper;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
import com.gitee.sop.gatewaycommon.bean.IsvRoutePermission;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.manager.DefaultIsvRoutePermissionManager;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@ -23,7 +19,6 @@ import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -40,7 +35,7 @@ import static java.util.stream.Collectors.toList;
*/
@Slf4j
@Service
public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManager implements ChannelMsgProcessor {
public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManager {
@Autowired
Environment environment;
@ -54,8 +49,6 @@ public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManage
@Autowired
IsvInfoMapper isvInfoMapper;
@NacosInjected
private ConfigService configService;
@Override
public void load() {
@ -147,17 +140,6 @@ public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManage
}
}
@PostConstruct
protected void after() throws Exception {
configService.addListener(NacosConfigs.DATA_ID_ROUTE_PERMISSION, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
process(channelMsg);
}
});
}
@Data
static class IsvRole {

@ -1,14 +1,9 @@
package com.gitee.sop.gateway.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.sop.gateway.mapper.ConfigLimitMapper;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
import com.gitee.sop.gatewaycommon.bean.ConfigLimitDto;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.manager.DefaultLimitConfigManager;
import com.gitee.sop.gatewaycommon.util.MyBeanUtil;
import lombok.extern.slf4j.Slf4j;
@ -16,15 +11,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
/**
* 限流配置管理
* @author tanghc
*/
@Slf4j
@Service
public class DbLimitConfigManager extends DefaultLimitConfigManager implements ChannelMsgProcessor {
public class DbLimitConfigManager extends DefaultLimitConfigManager {
@Autowired
ConfigLimitMapper configLimitMapper;
@ -32,9 +25,6 @@ public class DbLimitConfigManager extends DefaultLimitConfigManager implements C
@Autowired
Environment environment;
@NacosInjected
private ConfigService configService;
@Override
public void load() {
Query query = new Query();
@ -65,15 +55,5 @@ public class DbLimitConfigManager extends DefaultLimitConfigManager implements C
}
}
@PostConstruct
protected void after() throws Exception {
configService.addListener(NacosConfigs.DATA_ID_LIMIT_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
process(channelMsg);
}
});
}
}

@ -1,14 +1,9 @@
package com.gitee.sop.gateway.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.sop.gateway.mapper.ConfigRouteBaseMapper;
import com.gitee.sop.gateway.mapper.ConfigRouteLimitMapper;
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
import com.gitee.sop.gatewaycommon.bean.NacosConfigs;
import com.gitee.sop.gatewaycommon.bean.RouteConfig;
import com.gitee.sop.gatewaycommon.bean.RouteDefinition;
import com.gitee.sop.gatewaycommon.bean.TargetRoute;
@ -19,7 +14,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Collection;
/**
@ -27,7 +21,7 @@ import java.util.Collection;
*/
@Slf4j
@Service
public class DbRouteConfigManager extends DefaultRouteConfigManager implements ChannelMsgProcessor {
public class DbRouteConfigManager extends DefaultRouteConfigManager {
@Autowired
ConfigRouteBaseMapper configRouteBaseMapper;
@ -38,9 +32,6 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager implements C
@Autowired
Environment environment;
@NacosInjected
private ConfigService configService;
@Override
public void load() {
loadAllRoute();
@ -88,14 +79,4 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager implements C
}
}
@PostConstruct
protected void after() throws Exception {
configService.addListener(NacosConfigs.DATA_ID_ROUTE_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
ChannelMsg channelMsg = JSON.parseObject(configInfo, ChannelMsg.class);
process(channelMsg);
}
});
}
}

@ -1,4 +1,5 @@
server.port=8081
# 固定不变
spring.application.name=api-gateway
# ------- 需要改的配置 -------
@ -17,6 +18,9 @@ zipkin.url=http://127.0.0.1:9411/
pre.domain=localhost
# ------- 需要改的配置end -------
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# 入口地址,不用改,默认是/zuul
zuul.servlet-path=/api
# 禁用默认的过滤器,不能删,不用改
@ -36,8 +40,8 @@ ribbon.ReadTimeout=2000
ribbon.OkToRetryOnAllOperations=false
# nacos cloud配置
spring.cloud.nacos.discovery.server-addr=${nacos.url}
nacos.config.server-addr=${nacos.url}
#spring.cloud.nacos.discovery.server-addr=${nacos.url}
#nacos.config.server-addr=${nacos.url}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://${mysql.host}/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai

Loading…
Cancel
Save