LocalPreferenceLoadBalancer extends RandomLoadBalancer { @Override public ProviderInfo doSelect(SofaRequest invocation, List<ProviderInfo> providerInfos) { String localhost = SystemInfo.getLocalHost(); if (StringUtils.isEmpty(localhost)) { return super.doSelect(invocation, providerInfos); } List<ProviderInfo> localProviderInfo = new ArrayList<ProviderInfo>(); for (ProviderInfo providerInfo : providerInfos) { if (localhost.equals(providerInfo.getHost())) { localProviderInfo.add(providerInfo); } } if (CommonUtils.isNotEmpty(localProviderInfo)) { return super.doSelect(invocation, localProviderInfo); } else { return super.doSelect(invocation, providerInfos); } } LocalPreferenceLoadBalancer(ConsumerBootstrap consumerBootstrap); @Override ProviderInfo doSelect(SofaRequest invocation, List<ProviderInfo> providerInfos);  }
@Test public void doSelect() throws Exception { LocalPreferenceLoadBalancer loadBalancer = new LocalPreferenceLoadBalancer(null); Map<Integer, Integer> cnt = new HashMap<Integer, Integer>(); int size = 20; int total = 100000; SofaRequest request = new SofaRequest(); { for (int i = 0; i < size; i++) { cnt.put(9000 + i, 0); } List<ProviderInfo> providers = buildSameWeightProviderList(size); int localps = 5; for (int i = 0; i < localps; i++) { ProviderInfo localProvider = new ProviderInfo(); localProvider.setHost(SystemInfo.getLocalHost()); localProvider.setPort(22000 + i); providers.add(localProvider); cnt.put(22000 + i, 0); } long start = System.currentTimeMillis(); for (int i = 0; i < total; i++) { ProviderInfo provider = loadBalancer.doSelect(request, providers); int port = provider.getPort(); cnt.put(port, cnt.get(port) + 1); } long end = System.currentTimeMillis(); LOGGER.info("elapsed" + (end - start) + "ms"); LOGGER.info("avg " + (end - start) * 1000 * 1000 / total + "ns"); for (int i = 0; i < size; i++) { Assert.assertTrue(cnt.get(9000 + i) == 0); } int avg = total / localps; for (int i = 0; i < localps; i++) { Assert.assertTrue(avg * 0.9 < cnt.get(22000 + i) && avg * 1.1 > cnt.get(22000 + i)); } } { for (int i = 0; i < size; i++) { cnt.put(9000 + i, 0); } List<ProviderInfo> providers = buildDiffWeightProviderList(size); int localps = 5; for (int i = 0; i < localps; i++) { ProviderInfo localProvider = new ProviderInfo(); localProvider.setHost(SystemInfo.getLocalHost()); localProvider.setPort(22000 + i); localProvider.setWeight(i * 100); providers.add(localProvider); cnt.put(22000 + i, 0); } long start = System.currentTimeMillis(); for (int i = 0; i < total; i++) { ProviderInfo provider = loadBalancer.doSelect(request, providers); int port = provider.getPort(); cnt.put(port, cnt.get(port) + 1); } long end = System.currentTimeMillis(); LOGGER.info("elapsed" + (end - start) + "ms"); LOGGER.info("avg " + (end - start) * 1000 * 1000 / total + "ns"); for (int i = 0; i < size; i++) { Assert.assertTrue(cnt.get(9000 + i) == 0); } int count = 0; for (int i = 0; i < localps; i++) { count += i; } int per = total / count; Assert.assertTrue(cnt.get(22000) == 0); for (int i = 1; i < localps; i++) { Assert.assertTrue(per * i * 0.9 < cnt.get(22000 + i) && per * i * 1.1 > cnt.get(22000 + i)); } } }