soul 入门 第十四章 插件springcloud原理
springcloud微服务需要用到注册中心,这里我们用eureka,服务所在的ip端口都会注册到eureka上,那网关也需要从eureka获取服务的信息,然后构建真实的url请求springcloud服务,这一部分很像divide插件 。具体怎么跑通,这里不深入了,之前在第五章已有讲解。下面具体分析下springcloud插件的关键代码。
SpringCloudPlugin 类的核心方法,去掉部分不重要的代码
// 负载均衡器,初始化时注入
private final LoadBalancerClient loadBalancer;
public SpringCloudPlugin(final LoadBalancerClient loadBalancer) {
this.loadBalancer = loadBalancer;
}
@Override
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
// 获得请求的路径等信息
final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
final SpringCloudRuleHandle ruleHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), SpringCloudRuleHandle.class);
final SpringCloudSelectorHandle selectorHandle = GsonUtils.getInstance().fromJson(selector.getHandle(), SpringCloudSelectorHandle.class);
// 以上代码最终目的为了获得服务id
//loadBalancer 通过服务id选择一个服务实例。一个服务实例(主要包含id 端口)
final ServiceInstance serviceInstance = loadBalancer.choose(selectorHandle.getServiceId());
// 构造uri
final URI uri = loadBalancer.reconstructURI(serviceInstance, URI.create(soulContext.getRealUrl()));
// 生成真实url
String realURL = buildRealURL(uri.toASCIIString(), soulContext.getHttpMethod(), exchange.getRequest().getURI().getQuery());
// exchange 携带 真实url,供后面请求目标服务,divide插件也这样,他们都是走http协议,请求的逻辑封装到其他地方?供重复使用?
exchange.getAttributes().put(Constants.HTTP_URL, realURL);
//set time out.
exchange.getAttributes().put(Constants.HTTP_TIME_OUT, ruleHandle.getTimeout());
return chain.execute(exchange);
}
loadBalancer 是怎么同步注册到eureka上的服务实例到?真实请求真实服务的代码块在哪里,是如何走到那里的?这两个问题后面继续深入了解。