Spring cloud boot节点中的项目往往都比较小,适合本地启动调试(本地断点调试很方便),但在实行本地调试的时候遇到了如下问题:
1.非boot节点本地环境启动时往往配置不好就注册到了dev环境,由于appName,serviceId(vipAdress)相同,导致dev环境形成集群,该节点参与dev环境运作,影响dev环境稳定性(本地服务频繁启动且由于节点不能被及时剔除导致dev环境经常出现500,以及触发开启了保护模式的eureka server)
2.如若纯本地跑,本地环境需要一套eureka server与zuul等配置,环境配置复杂,涉及服务间调用的话还需要启动多个服务导致本机卡顿,环境稳定性不可靠。
如何既能访问dev环境一整套完整的服务,又不影响dev环境的稳定性?
1.spring boot节点
boot节点配置可以从配置中心拉取local配置,只需要在local配置中改成和dev环境不一样的appName就可以避免集群了,这样自己本地能够访问dev环境,而dev环境却因为没有指向local的appName的服务而不会访问本地。
2.非boot节点
之前因为迫于本地服务总注册到dev环境的压力,于是弄了一套“假的”eureka server 让本地服务去注册,这样虽然避免了本地服务注册到eureka上,但除非本地再将另一个服务注册上去,否则是无法访问的。
基于boot节点的隔离处理原理,同样的非boot节点也可以修改appName:
package com.kowalski.demo.eureka;
import com.netflix.appinfo.MyDataCenterInstanceConfig;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.Query;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Set;
/**
* Created by kowalski 2017/5/25
*/
public class MyInstanceConfig extends MyDataCenterInstanceConfig {
/**
* 优先使用ip 替换 hostname
* @param refresh
* @return
*/
@Override
public String getHostName(boolean refresh) {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
return super.getHostName(refresh);
}
}
/***
*获取本机启动中tomcat端口号
* @return
*/
@Override
public int getNonSecurePort(){
int tomcatPort;
try {
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"),
Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
tomcatPort = Integer.valueOf(objectNames.iterator().next().getKeyProperty("port"));
}catch (Exception e){
return super.getNonSecurePort();
}
return tomcatPort;
}
/**
* 区分服务器环境与本地环境
* @return
*/
@Override
public String getAppname(){
try {
String ipAddr = InetAddress.getLocalHost().getHostAddress();
if (ipAddr.startsWith("10.")) {
return super.getAppname();
} else {
return "local-" + super.getAppname();
}
} catch (UnknownHostException e) {
e.printStackTrace();
return "localAppnameErr";
}
}
}
由于是非boot节点,本地启动tomcat端口号取决于本地配置,所以这里采用了动态获取本机tomcat端口号的方法,再由于我们dev环境采用的是腾讯云服务器,所以暂时是通过ip来做区分(也可以采取别的方式),ip如果不是以10.开头就会被认为是本地服务(可以搞一个ip列表区分),appName会被加上local字样用以区分,这样就实现了本地与dev的隔离