package com.shawn.rule; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; import java.util.Optional; import java.util.concurrent.ThreadLocalRandom; import org.apache.commons.lang.math.RandomUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.Server; import java.net.*; import java.util.*; import lombok.extern.slf4j.Slf4j; /** * * @ClassName: GameCenterBalanceRule * @Description: 根据node对服务进行负载均衡。 */ @Component @Scope("prototype") @Slf4j public class NodeBalanceRule extends RandomRule { @Override public Server choose(Object key) { if (key == null) { return super.choose(null); } List servers = getLoadBalancer().getReachableServers(); // log.info("server size is : {} , serverList is : {}" , servers.size() ,servers); Optional serverOpt = servers.stream().filter(server -> server.getId().contains(String.valueOf(key))).findFirst(); if(serverOpt.isPresent()) { log.info("choose rule..." + key); return serverOpt.get(); } // 根据本机ip,走本机的子服务 // 获取本机ip String localIp = getLocalIP(); // log.info("localIp:" + localIp); Optional opt_local = servers.stream().filter(server -> server.getId().contains(localIp)).findFirst(); if(opt_local.isPresent()) { // 优先走本机 // log.info("choose local server: {}" , opt_local.get()); return opt_local.get(); }else{ // 走同网段 String localIp2 = localIp.substring(0,localIp.lastIndexOf(".")); Optional opt_local2 = servers.stream().filter(server -> server.getId().contains(localIp2)).findFirst(); if(opt_local2.isPresent()){ // log.info("choose same segment: {}" , opt_local2.get()); return opt_local2.get(); } } // log.info("choose Random server"); return super.choose(null); } /** * 获取本机ip * @return */ public static String getLocalIP() { String localIP = "127.0.0.1"; try { OK: for (Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements(); ) { NetworkInterface networkInterface = interfaces.nextElement(); if (networkInterface.isLoopback() || networkInterface.isVirtual() || !networkInterface.isUp()) { continue; } Enumeration addresses = networkInterface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress address = addresses.nextElement(); if (address instanceof Inet4Address) { localIP = address.getHostAddress(); break OK; } } } } catch (SocketException e) { e.printStackTrace(); } return localIP; } }