diff --git a/doc/docs/files/10112_使用eureka.md b/doc/docs/files/10112_使用eureka.md new file mode 100644 index 00000000..cd06ae54 --- /dev/null +++ b/doc/docs/files/10112_使用eureka.md @@ -0,0 +1,47 @@ +# 使用eureka + +## 修改网关 + +- 打开`/sop-gateway/pom.xml` + +添加依赖: + +```xml + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + +``` + +- 打开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 +``` + diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java index f4160a25..3ea9be79 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java @@ -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 listServiceInfo(ServiceSearchParam param) { - List 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 listServiceInfo(ServiceSearchParam param) { + List 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("该功能已下线"); } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java index 15f6492f..2284a716 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java @@ -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() { } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigServiceRouteMapper.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigServiceRouteMapper.java index 1365c93f..028b921a 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigServiceRouteMapper.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigServiceRouteMapper.java @@ -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 { + + @Select("SELECT distinct service_id FROM config_service_route") + List listAllServiceId(); + } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplication.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplication.java new file mode 100644 index 00000000..ec241147 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplication.java @@ -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 instance; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplications.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplications.java new file mode 100644 index 00000000..fd24e8ce --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApplications.java @@ -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 application; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApps.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApps.java new file mode 100644 index 00000000..7576212b --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaApps.java @@ -0,0 +1,11 @@ +package com.gitee.sop.adminserver.service.impl; + +import lombok.Data; + +/** + * @author tanghc + */ +@Data +public class EurekaApps { + private EurekaApplications applications; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaInstance.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaInstance.java new file mode 100644 index 00000000..61fefe20 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaInstance.java @@ -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 port; + + private String status; + private String statusPageUrl; + private String healthCheckUrl; + private String lastUpdatedTimestamp; + + private Map metadata; + + public String fetchPort() { + if (CollectionUtils.isEmpty(port)) { + return ""; + } + return String.valueOf(port.getOrDefault("$", "")); + } + +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaUri.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaUri.java new file mode 100644 index 00000000..a3a20805 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/EurekaUri.java @@ -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); + } +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/RegistryServiceEurekaImpl.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/RegistryServiceEurekaImpl.java new file mode 100644 index 00000000..34a5b7f1 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/RegistryServiceEurekaImpl.java @@ -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 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 serviceInfoList = new ArrayList<>(); + List applicationList = eurekaApps.getApplications().getApplication(); + for (EurekaApplication eurekaApplication : applicationList) { + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.setServiceId(eurekaApplication.getName()); + List 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("操作失败"); + } + } + +} diff --git a/sop-admin/sop-admin-server/src/main/resources/application-dev.properties b/sop-admin/sop-admin-server/src/main/resources/application-dev.properties index 8158468f..e33fd59c 100644 --- a/sop-admin/sop-admin-server/src/main/resources/application-dev.properties +++ b/sop-admin/sop-admin-server/src/main/resources/application-dev.properties @@ -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:淘宝开放平台签名方式 diff --git a/sop-admin/sop-admin-vue/src/views/service/limit.vue b/sop-admin/sop-admin-vue/src/views/service/limit.vue index 7a67559c..de459fe5 100644 --- a/sop-admin/sop-admin-vue/src/views/service/limit.vue +++ b/sop-admin/sop-admin-vue/src/views/service/limit.vue @@ -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) diff --git a/sop-admin/sop-admin-vue/src/views/service/route.vue b/sop-admin/sop-admin-vue/src/views/service/route.vue index 123338e3..5686365e 100644 --- a/sop-admin/sop-admin-vue/src/views/service/route.vue +++ b/sop-admin/sop-admin-vue/src/views/service/route.vue @@ -52,7 +52,8 @@ size="mini" icon="el-icon-delete" title="删除服务" - @click.stop="() => onDelService(data)"/> + @click.stop="() => onDelService(data)" + /> @@ -60,7 +61,10 @@ - + + + + 授权接口 查询 @@ -76,9 +80,9 @@ 新建路由 + @@ -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() } } } diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index 58acee0a..68bb982b 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -77,6 +77,12 @@ 2.1.0.RELEASE true + + com.netflix.ribbon + ribbon-eureka + 2.3.0 + true + diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BeanInitializer.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BeanInitializer.java index cbb0f71a..9710578d 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BeanInitializer.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BeanInitializer.java @@ -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 { /** * 执行加载操作 */ diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/InstanceDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/InstanceDefinition.java new file mode 100644 index 00000000..16f01a39 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/InstanceDefinition.java @@ -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 metadata; +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EnvironmentServerChooser.java similarity index 88% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EnvironmentServerChooser.java index 20cbe305..a3e7ddea 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/EnvironmentServerChooser.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EnvironmentServerChooser.java @@ -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 metadata = ((NacosServer) server).getMetadata(); + Map metadata = getMetada(server); return metadata.get(MEDATA_KEY_ENV); } + protected Map getMetada(Server server) { + return ((NacosServer) server).getMetadata(); + } + /** * 通过判断hostname来确定是否是预发布请求,可修改此方法实现自己想要的 diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EurekaEnvironmentServerChooser.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EurekaEnvironmentServerChooser.java new file mode 100644 index 00000000..f67ba85b --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/EurekaEnvironmentServerChooser.java @@ -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 getMetada(Server server) { + return ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata(); + } +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/SopPropertiesFactory.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/SopPropertiesFactory.java similarity index 90% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/SopPropertiesFactory.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/SopPropertiesFactory.java index 9d236943..605d3c65 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/loadbalancer/SopPropertiesFactory.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/loadbalancer/SopPropertiesFactory.java @@ -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 { * 可在配置文件中设置zuul.custom-rule-classname=com.xx.ClassName指定负载均衡规则类 * 默认使用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(); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java index c10a694f..e80ee1c2 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/AbstractConfiguration.java @@ -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() { diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ChannelMsgProcessor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ChannelMsgProcessor.java similarity index 54% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ChannelMsgProcessor.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ChannelMsgProcessor.java index 1747c03b..43bdf849 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/ChannelMsgProcessor.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ChannelMsgProcessor.java @@ -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) { + } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/NacosEventProcessor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/NacosEventProcessor.java new file mode 100644 index 00000000..e8e392a1 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/NacosEventProcessor.java @@ -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); + } + }); + } + +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRoutesListener.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRoutesListener.java index a7a23418..88809254 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRoutesListener.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRoutesListener.java @@ -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 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 registeredApplications = applications.getRegisteredApplications(); + List serviceList = registeredApplications + .stream() + .map(Application::getName) + .collect(Collectors.toList()); + + Set 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 registeredApplications, Set newServices) { + registeredApplications + .stream() + .filter(application -> !appName.equalsIgnoreCase(application.getName()) + && newServices.contains(application.getName())) + .forEach(application -> { + List 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 deletedServices) { + deletedServices.forEach(this::removeRoutes); + } + } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/NacosRoutesListener.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/NacosRoutesListener.java index 58475ff6..e7abd8e0 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/NacosRoutesListener.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/NacosRoutesListener.java @@ -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 subscribes = null; try { @@ -72,9 +72,4 @@ public class NacosRoutesListener extends BaseRoutesListener { } } - @Override - public void onDeregister(ApplicationEvent applicationEvent) { - - } - } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/RegistryListener.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/RegistryListener.java index 13df0741..1bd8ef80 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/RegistryListener.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/RegistryListener.java @@ -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); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/support/EurekaListenerConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/support/EurekaListenerConfiguration.java deleted file mode 100644 index fad894d3..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/support/EurekaListenerConfiguration.java +++ /dev/null @@ -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(); - } - -} diff --git a/sop-example/sop-book/sop-book-web/pom.xml b/sop-example/sop-book/sop-book-web/pom.xml index 4a79e027..367daa30 100644 --- a/sop-example/sop-book/sop-book-web/pom.xml +++ b/sop-example/sop-book/sop-book-web/pom.xml @@ -45,7 +45,7 @@ + org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery @@ -56,8 +56,13 @@ nacos-client ${nacos-client.version} + --> + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + org.springframework.cloud diff --git a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties b/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties index 05644cb7..4217726b 100644 --- a/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties +++ b/sop-example/sop-book/sop-book-web/src/main/resources/application-dev.properties @@ -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 diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml index 8e489cb5..976ef3bc 100644 --- a/sop-example/sop-story/sop-story-web/pom.xml +++ b/sop-example/sop-story/sop-story-web/pom.xml @@ -39,7 +39,7 @@ + org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery @@ -50,8 +50,14 @@ nacos-client ${nacos-client.version} + --> + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + org.springframework.cloud spring-cloud-starter-openfeign diff --git a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties b/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties index f0150321..ff51c42c 100644 --- a/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties +++ b/sop-example/sop-story/sop-story-web/src/main/resources/application-dev.properties @@ -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 diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index 7eefb128..84443c06 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -54,10 +54,20 @@ runtime + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery @@ -68,17 +78,19 @@ nacos-client ${nacos-client.version} + --> + com.alibaba.boot nacos-config-spring-boot-starter ${nacos-spring-boot-starter.version} + --> diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java index e416891f..4f0863a1 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java @@ -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(); - } - } /** diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java index 3b2f2b90..b6a96478 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java @@ -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; diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java index 03d41dec..c44c5ec5 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbEnvGrayManager.java @@ -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); - } - }); - } } diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java index b60aaf53..0eaf7b75 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIPBlacklistManager.java @@ -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 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 { diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java index c5d0ec71..250d3fbb 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvManager.java @@ -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 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); - } - }); - } - } diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java index 42f53528..c0bf32f9 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbIsvRoutePermissionManager.java @@ -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 { diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java index 7aa0a4bb..3cb71232 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbLimitConfigManager.java @@ -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); - } - }); - } } diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java index e826c252..de798b1f 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRouteConfigManager.java @@ -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); - } - }); - } } diff --git a/sop-gateway/src/main/resources/application-dev.properties b/sop-gateway/src/main/resources/application-dev.properties index f0a73399..9b84c486 100644 --- a/sop-gateway/src/main/resources/application-dev.properties +++ b/sop-gateway/src/main/resources/application-dev.properties @@ -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