|
|
@@ -1,64 +1,63 @@
|
|
|
package com.mrxu.framework.boot.irule;
|
|
|
|
|
|
-import com.google.common.base.Optional;
|
|
|
-import com.mrxu.framework.boot.util.ComputerInfo;
|
|
|
-import com.mrxu.framework.boot.util.SpringApplicationContextUtil;
|
|
|
+import cn.hutool.core.net.NetUtil;
|
|
|
+import com.mrxu.framework.boot.config.MetaFilterAutoConfiguration;
|
|
|
+import com.mrxu.framework.common.MrxuConst;
|
|
|
import com.netflix.loadbalancer.ILoadBalancer;
|
|
|
import com.netflix.loadbalancer.Server;
|
|
|
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
|
|
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
|
|
-import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
* 功能概要:[原信息过滤器,根据原信息过滤合法的服务,可用于开发调试和版本过滤] <br>
|
|
|
- *
|
|
|
- * @author zzt
|
|
|
- * @date 2020/10/15
|
|
|
+ * 只有 spring.application.open-dev配置存在且为true 这个类才会被加载(MetaFilterAutoConfiguration中加载的)
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
public class MetadataAwareRule extends ZoneAvoidanceRule {
|
|
|
|
|
|
@Override
|
|
|
public Server choose(Object key) {
|
|
|
+ log.debug("开启微服务本地调试");
|
|
|
ILoadBalancer lb = getLoadBalancer();
|
|
|
- //是注册中心中的服务时,判断过滤逻辑
|
|
|
- EurekaInstanceConfigBean eurekaInstanceConfigBean = SpringApplicationContextUtil.getBean(EurekaInstanceConfigBean.class);
|
|
|
- if(eurekaInstanceConfigBean != null){
|
|
|
- String isOpenDevStr = eurekaInstanceConfigBean.getEnvironment().getProperty("spring.application.open-dev","false");
|
|
|
- if("true".equalsIgnoreCase(isOpenDevStr)){
|
|
|
- //本地开启调试模式,转发本机机器码的服务
|
|
|
- String localMac = ComputerInfo.getMacAddress();
|
|
|
- List<Server> upList = lb.getReachableServers();
|
|
|
- for(Server upServer : upList){
|
|
|
- DiscoveryEnabledServer server = (DiscoveryEnabledServer) upServer;
|
|
|
- Map<String, String> metadata = server.getInstanceInfo().getMetadata();
|
|
|
- if(metadata!=null&&metadata.size()>0&&metadata.keySet().contains("mac-addr")){
|
|
|
- String remoteMac = metadata.get("mac-addr");
|
|
|
- if(localMac.equalsIgnoreCase(remoteMac)){
|
|
|
- return upServer;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //没有找到合适的服务,但是需要访问公网ip
|
|
|
- for(Server upServer : upList){
|
|
|
- String ip = upServer.getHost();
|
|
|
- if(ip.startsWith("192.")||ip.startsWith("127.")||ip.startsWith("172.")||ip.startsWith("10.")){
|
|
|
- continue;
|
|
|
- }
|
|
|
- return upServer;
|
|
|
- }
|
|
|
-
|
|
|
+ String localMac = NetUtil.getLocalMacAddress();
|
|
|
+ List<Server> upList = lb.getReachableServers();
|
|
|
+ // 优先查找本机可用服务
|
|
|
+ for(Server upServer : upList) {
|
|
|
+ DiscoveryEnabledServer server = (DiscoveryEnabledServer) upServer;
|
|
|
+ Map<String,String> metadata = server.getInstanceInfo().getMetadata();
|
|
|
+ if(metadata != null && localMac.equals(metadata.get(MetaFilterAutoConfiguration.MAC_KEY))) {
|
|
|
+ log.debug("本机有服务可用");
|
|
|
+ return upServer;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //没有找到合适的服务
|
|
|
- Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key);
|
|
|
- if (server.isPresent()) {
|
|
|
- return server.get();
|
|
|
- } else {
|
|
|
- return null;
|
|
|
+ String host = NetUtil.getLocalhost().getHostAddress();
|
|
|
+ Server innerServer = null;// 匹配同网段服务
|
|
|
+ // 没有找到本机的服务,则寻找公网ip的服务
|
|
|
+ for(Server upServer : upList) {
|
|
|
+ String ip = upServer.getHost();
|
|
|
+ // 如果有外网服务 则直接使用
|
|
|
+ if(!(ip.startsWith("192.") || ip.startsWith("127.")
|
|
|
+ || ip.startsWith("172.") || ip.startsWith("10."))) {
|
|
|
+ log.debug("外网IP:{},对外提供服务可用",ip);
|
|
|
+ return upServer;
|
|
|
+ }
|
|
|
+ if(ip.startsWith(host.substring(MrxuConst.zero,host.indexOf(".")+1))) {
|
|
|
+ log.debug("同网段IP:{},对外提供服务可用",ip);
|
|
|
+ innerServer = upServer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 程序运行到这里说明没有外网服务可以对外提供,则看同网段内网服务存在吧
|
|
|
+ if(innerServer != null) {
|
|
|
+ log.debug("使用同网段IP:{},提供的服务",innerServer.getHost());
|
|
|
+ return innerServer;
|
|
|
}
|
|
|
+ log.warn("根据规则未找到可用服务");
|
|
|
+ //没有找到合适的服务使用默认规则
|
|
|
+ return super.choose(key);
|
|
|
}
|
|
|
}
|