Java接口方法内调用不同方法实现负载均衡方式

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。Java接口方法内调用不同方法实现负载均衡方式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

业务场景:现有个接口,非方法级负载均衡,而是在接口内部实在,实现方法均摊。具体代码如下。

这里使用平均数来生成判断走那个逻辑,可能会出现均衡度不一样情况,比如高并发调用一千次,可能第一个走600,第二第三各走200。这样就无法实现比较均衡的平均分配。 

Java接口方法内调用不同方法实现负载均衡方式

100线程循环1000次,想当于调用10w次 

Java接口方法内调用不同方法实现负载均衡方式

具体代码:

/**
     * @program: 工具箱
     * @description
     * 使用同步锁和洗牌算法 展示了如何在处理四个数字(a、b、c、d)的情况下实现均衡的累加。
     * <p>
     * 在 `saveOne()` 方法中,通过循环执行 `numRequests` 次请求。在每次循环中,我们首先使用 `getRandomIndex()` 方法获取一个随机索引,该方法会对索引进行随机打乱以实现均衡分布。
     * <p>
     * 然后,使用 `switch` 语句根据随机索引对 `a`、`b`、`c` 和 `d` 进行累加操作。
     * <p>
     * 接下来,我们输出当前的执行次数 `total`,以及每个数字的计数值 `a`、`b`、`c` 和 `d`。
     * <p>
     * 在 `getRandomIndex()` 方法中,我们将索引数组 `{0, 1, 2, 3}` 传递给 `shuffleArray()` 方法进行随机打乱,并返回打乱后的数组中的第一个索引。
     * <p>
     * `shuffleArray()` 方法使用 Fisher-Yates 洗牌算法来打乱数组元素的顺序,确保每个索引以均衡的方式出现。
     * <p>
     * 在 `main()` 方法中,我们创建 `TestController` 实例,并启动 30 个线程,每个线程执行 `saveOne(100)` 方法来模拟并发执行。
     * <p>
     * 通过以上代码,您可以观察到每个数字(a、b、c、d)的计数值在不同线程间进行均衡的累加,并输出执行次数和各数字的计数情况。这样可以实现较为均衡的处理。请注意,由于线程调度和竞争条件的存在,无法保证每个数字的计数完全相等,但整体上可以达到较好的均衡效果。
     */
    private int total = 0;
    private int a = 0;
    private int b = 0;
    private int c = 0;
    private int d = 0;

    public void saveOne(int numRequests) {
        for (int i = 0; i < numRequests; i++) {
            int randomIndex = getRandomIndex();
            switch (randomIndex) {
                case 0:
                    a++;
                    break;
                case 1:
                    b++;
                    break;
                case 2:
                    c++;
                    break;
                case 3:
                    d++;
                    break;
            }
            total++;
            System.out.println("执行了第->" + total);
            System.out.println("a: " + a);
            System.out.println("b: " + b);
            System.out.println("c: " + c);
            System.out.println("d: " + d);
        }
    }

    /**
     * Fisher–Yates shuffle 洗牌算法
     * 这里的{0, 1, 2, 3}和上面case 0 1 2 4 一一对应.
     */
    private int getRandomIndex() {
        int[] indices = {0, 1, 2, 3};
        shuffleArray(indices);
        return indices[0];
    }

    /**
     * Fisher–Yates shuffle 洗牌算法
     * @param array
     */
    private void shuffleArray(int[] array) {
        Random random = new Random();
        for (int i = array.length - 1; i > 0; i--) {
            int index = random.nextInt(i + 1);
            int temp = array[index];
            array[index] = array[i];
            array[i] = temp;
        }
    }

    public static void main(String[] args) {
        TestController example = new TestController();
        for (int i = 0; i < 30; i++) {
            Thread thread = new Thread(() -> example.saveOne(100));
            thread.start();
        }
    }

    private final Object lock = new Object(); // 添加同步锁

    @ApiOperation(value = "负载均衡测试", notes = "负载均衡测试")
    @GetMapping("/oneMQ1")
    public void oneMQ1() {
        int randomIndex = getRandomIndex();
        synchronized (lock) {
            total++;
            switch (randomIndex) {
                case 0:
                    a++;
                    break;
                case 1:
                    b++;
                    break;
                case 2:
                    c++;
                    break;
                case 3:
                    d++;
                    break;
            }
        }
        System.out.println("执行了第->" + total);
        System.out.println("a: " + a);
        System.out.println("b: " + b);
        System.out.println("c: " + c);
        System.out.println("d: " + d);
    }

使用压测工具调用执行结果:

执行了第->100000
a: 25234
b: 25276
c: 24769
d: 24721 

可以看出非常均匀的进行部分运算了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192735.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!