parent
be0adc0a8e
commit
35253be77d
@ -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 |
||||||
|
``` |
||||||
|
|
@ -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("操作失败"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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,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(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue