【Apache ShenYu源码】如何实现负载均衡模块设计

ShenYu是一个异步的,高性能的,跨语言的,响应式的 API 网关。有关ShenYu的介绍可以戳这。

一、前瞻

今天我们尝试不同的代码阅读方式,按模块 来去阅读源码,看看效果如何。

本次阅读锁定在shenyu-loadbalancer ,根据模块名可以了解这个模块主要作用就是负载均衡。

我们可以根据这个模块的组织机构,来思考本次的阅读线索:

  1. 整个模块为ShenYu提供了什么功能
  2. 我们很好奇,负载均衡的cache缓存有什么作用
  3. spi的作用是什么

二、探索

那开始我们今天的模块阅读。

看起来factory就是这个模块的核心了,作为工厂来生产核心对象,我们就从这个工厂开始阅读。

java 复制代码
public final class LoadBalancerFactory {

    private LoadBalancerFactory() {
    }

    /**
     * Selector upstream.
     *
     * @param upstreamList the upstream list
     * @param algorithm    the loadBalance algorithm
     * @param ip           the ip
     * @return the upstream
     */
    public static Upstream selector(final List<Upstream> upstreamList, final String algorithm, final String ip) {
        LoadBalancer loadBalance = ExtensionLoader.getExtensionLoader(LoadBalancer.class).getJoin(algorithm);
        return loadBalance.select(upstreamList, ip);
    }
}

很明显LoadBalancerFactory是作为外部的调用中心,那LoadBalancerFactory又是调用了内部的什么模块去返回?我们接着往下看。

java 复制代码
@SPI
public interface LoadBalancer {

    /**
     * this is select one for upstream list.
     *
     * @param upstreamList upstream list
     * @param ip ip
     * @return upstream
     */
    Upstream select(List<Upstream> upstreamList, String ip);
}

可以看到通过select方法进行调用内部方法。

我们可以看下这个接口类的类图,看下调用的最终实现者是什么对象。

类图很清晰地告诉我们,最终实现者共有6个子类对象,也就是说每个子类对象都是不同的负载均衡算法实现。

大家有没看到类图最上面的底层接口SPI,和模块里的spi文件夹是相对应的 ,spi的作用就是存储各种负载均衡算法的实现。那我们就解决了我们的阅读线索3。

spi的作用是什么

我们继续探索,看看阅读线索2的答案:

负载均衡的cache缓存有什么作用

查询代码发现缓存对象是UPSTREAM_MAP,但很奇怪这个核心的缓存对象只有删除、设置的引用,却没有使用的逻辑。

通过Git的历史查询,发现这个缓存对象被废弃了,最新版本的核心缓存对象应该是下面这两个

java 复制代码
    private final Map<String, List<Upstream>> healthyUpstream = Maps.newConcurrentMap();

    private final Map<String, List<Upstream>> unhealthyUpstream = Maps.newConcurrentMap();

找到了核心缓存对象,我们就来看看这个cache对象的作用究竟是什么。

我们看看调用缓存的对应方法。

Upstream流从shenyu-loadbalancer 取出,需要负载均衡时把该缓存传入。也就是说这个模块的cache充当了存储所有Upstream流的作用。

到这我们就解决了阅读线索2的问题了。

三、总结

而阅读线索3也显而易见:整个模块为ShenYu提供了什么功能。我们可以看下上文我们提到的工厂对象。

java 复制代码
public final class LoadBalancerFactory {

    private LoadBalancerFactory() {
    }

    /**
     * Selector upstream.
     *
     * @param upstreamList the upstream list
     * @param algorithm    the loadBalance algorithm
     * @param ip           the ip
     * @return the upstream
     */
    public static Upstream selector(final List<Upstream> upstreamList, final String algorithm, final String ip) {
        LoadBalancer loadBalance = ExtensionLoader.getExtensionLoader(LoadBalancer.class).getJoin(algorithm);
        return loadBalance.select(upstreamList, ip);
    }
}

核心方法很清晰,我们传入Upsteam列表,通过这个模块的负载均衡算法,负载均衡地返回其中一个对象。

这也就是这个模块提供的功能。

未完待续。。。

好了,今天的分享就到这🤔。大家能否感受到通过按模块这种方式来阅读源码的乐趣呢 !

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

相关推荐
深蓝AI6 小时前
Python 3.13 的 Queue.shutdown:异步消费者终于能正常收工了
后端
武子康6 小时前
MultiNet6 空闲崩溃:`EXCVADDR=0x8` 后又出现 `CORRUPT HEAP`
人工智能·后端·agent
武子康7 小时前
MultiNet7 每轮都 clean,ESP32-P4 内存为什么还在掉?
人工智能·后端·agent
超级架构师8 小时前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
陈随易8 小时前
AI 运维服务器,安全又可靠的方法
前端·后端·程序员
IT_陈寒10 小时前
JavaScript的this坑人实录,这次我真的记下来了
前端·人工智能·后端
starzy199011 小时前
Scala类和对象:从构造器到样例类的完整指南
开发语言·后端·scala
梦影_11 小时前
MySQL进阶教程(五)—— SQL调优(下)
android·大数据·数据库·后端·sql·mysql·database
考虑考虑11 小时前
mariadb数据库
数据库·后端·mariadb
明月_清风11 小时前
用自然语言操控真机:Google Artemis 移动端 AI Agent 上手与实践
人工智能·后端