@Override
    public ProviderInfo doSelect(SofaRequest invocation, List<ProviderInfo> providerInfos) {
        ProviderInfo providerInfo = null;
        int size = providerInfos.size(); // 总个数
        int totalWeight = 0; // 总权重
        boolean isWeightSame = true; // 权重是否都一样
        for (int i = 0; i < size; i++) {
            int weight = getWeight(providerInfos.get(i));
            totalWeight += weight; // 累计总权重
            if (isWeightSame && i > 0 && weight != getWeight(providerInfos.get(i - 1))) {
                isWeightSame = false; // 计算所有权重是否一样
            }
        }
        if (totalWeight > 0 && !isWeightSame) {
            // 如果权重不相同且权重大于0则按总权重数随机
            int offset = random.nextInt(totalWeight);
            // 并确定随机值落在哪个片断上
            for (int i = 0; i < size; i++) {
                offset -= getWeight(providerInfos.get(i));
                if (offset < 0) {
                    providerInfo = providerInfos.get(i);
                    break;
                }
            }
        } else {
            // 如果权重相同或权重为0则均等随机
            providerInfo = providerInfos.get(random.nextInt(size));
        }
        return providerInfo;
    }
@Test
    public void doSelect() throws Exception {

        RandomLoadBalancer loadBalancer = new RandomLoadBalancer(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);
            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");

            int avg = total / size;
            for (int i = 0; i < size; i++) {
                Assert.assertTrue(avg * 0.9 < cnt.get(9000 + i)
                    && avg * 1.1 > cnt.get(9000 + i)); // 随机偏差不会太大，应该不超过10%
            }
        }

        {
            for (int i = 0; i < size; i++) {
                cnt.put(9000 + i, 0);
            }
            List<ProviderInfo> providers = buildDiffWeightProviderList(size);
            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");

            Assert.assertTrue(cnt.get(9000) == 0);

            int count = 0;
            for (int i = 0; i < size; i++) {
                count += i;
            }
            int per = total / count;
            for (int i = 1; i < size; i++) {
                Assert.assertTrue(per * i * 0.85 < cnt.get(9000 + i)
                    && per * i * 1.15 > cnt.get(9000 + i)); // 随机偏差不会太大，应该不超过15%
            }
        }
    }