Apache ShenYu 网关 springCloud 插件底层原理解析

说明

  • 本文将探讨 Apache ShenYu 网关的 springCloud插件的底层原理
  • 本文不再讨论 springCloud 项目如何接入 shenyu 网关,shenyu-bootstrap 关于springCloud 插件的引入,shenyu-admin 开启插件等;详情可参考 Apache ShenYu 官方examples体验系列文章

springCloud插件底层原理分析

插件说明

springCloud插件提供了http访问springCloud微服务的功能。

源码解析

在 shenyu-spring-boot-starter-plugin-springcloud pom文件得知,该插件引入了 spring-cloud-commons以及spring-cloud-starter-netflix-ribbon组件,它会默认注入负载均衡等核心bean。

接下来我们分析SpringCloudPlugin插件的核心代码,它的核心逻辑是,进入该插件后获取选择器和规则信息,然后做相关判断。条件满足后,根据选择器的关联信息去得到上游服务注册到 eureka注册中心的 serviceId,用LoadBalancerClient.choose(serviceId) 负载均衡获取可用服务,并取出可用服务的uri,最后用spring-web 通过该 uri 去访问目标服务。核心代码如下:

public class SpringCloudPlugin extends AbstractShenyuPlugin {
    ……
    @Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
        ……
        //根据serviceId从springCloud负载均衡器里获取上游服务s
        final ServiceInstance serviceInstance = loadBalancer.choose(selectorHandle.getServiceId());
        if (Objects.isNull(serviceInstance)) {
            Object error = ShenyuResultWrap.error(ShenyuResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getCode(), ShenyuResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getMsg(), null);
            return WebFluxResultUtils.result(exchange, error);
        }
        //从上游服务中获取上游服务的 uri
        final URI uri = loadBalancer.reconstructURI(serviceInstance, URI.create(shenyuContext.getRealUrl()));
        //构造上游服务的完整url
        String realURL = buildRealURL(uri.toASCIIString(), shenyuContext.getHttpMethod(), exchange.getRequest().getURI().getQuery());

        exchange.getAttributes().put(Constants.HTTP_URL, realURL);
        //设置超时时间
        exchange.getAttributes().put(Constants.HTTP_TIME_OUT, ruleHandle.getTimeout());
        //用 spring-web 去请求上游服务
        return chain.execute(exchange);
    }
}

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注