任务

研究 divide 底层原理,负载均衡,ip端口探活

divide 插件底层原理

核心工程

聚焦于两个工程 soul-spring-boot-starter-plugin-divide 和 soul-spring-boot-starter-plugin-httpclient。

首先,看下 soul-spring-boot-starter-plugin-divide 的 maven 模块依赖。

  • soul-plugin-divide:divide 插件的实现
  • soul-plugin-base:插件的基础实现类(抽象)
  • soul-plugin-api:插件的接口
  • soul-spi
  • soul-sync-data-api:数据同步接口
  • soul-common:公共模块

image.png

基础实现原理

然后,再看 soul-plugin-divide 的核心类 DividePlugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
...
//从 UpstreamCacheManager 缓存管理中,根据选择器的 ID 获取 divide 插件的 upstream 列表,upstream 的实体其实就是 host、protocol、url 那些
final List<DivideUpstream> upstreamList = UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(selector.getId());
...
//校验 IP
final String ip = Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
//负载均衡工具类选择实际访问的服务
DivideUpstream divideUpstream = LoadBalanceUtils.selector(upstreamList, ruleHandle.getLoadBalance(), ip);
...
// set the http url
//构建域
String domain = buildDomain(divideUpstream);
//构建实际 url
String realURL = buildRealURL(domain, soulContext, exchange);
...
//将 httpUrl、httpTimeout、httpRetry 传递出去
return chain.execute(exchange);
}

负载均衡 balance

上面的实现原理提到了负载均衡工具类选择实际访问的服务,接下来可以看 LoadBalanceUtils 究竟做了些什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class LoadBalanceUtils {
//三个参数:
//upstream 的流,就是 divide 插件的基本信息;
//algorithm,算术逻辑,就是 hash、random、roundRobin
//ip,地址
public static DivideUpstream selector(final List<DivideUpstream> upstreamList, final String algorithm, final String ip) {
//选择合适的负载策略
LoadBalance loadBalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getJoin(algorithm);
//选择合适的服务
return loadBalance.select(upstreamList, ip);
}

}

具体的负载策略实现类:

  • HashLoadBalance
  • RandomBalance
  • RoundRobinBalance

涉及到的主要是算法,明天举个栗子好好研究下。

后续安排

  • HashLoadBalance
  • http 探活逻辑

Link