美文网首页
Soul源码阅读 SpringCloud集成原理2【第十五天】

Soul源码阅读 SpringCloud集成原理2【第十五天】

作者: cutieagain | 来源:发表于2021-01-31 00:25 被阅读0次

    springcloud是如何进行调用的

    SpringCloudPlugin中进行调用,核心代码如下

    @Override
        // 执行代理调用
        protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
            // 如果没有规则,直接返回空
            if (Objects.isNull(rule)) {
                return Mono.empty();
            }
            // 获取soul全局context
            final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
            assert soulContext != null;
            // springcloud规则
            final SpringCloudRuleHandle ruleHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), SpringCloudRuleHandle.class);
            // 选择器
            final SpringCloudSelectorHandle selectorHandle = GsonUtils.getInstance().fromJson(selector.getHandle(), SpringCloudSelectorHandle.class);
            // 选择器和规则都不存在
            if (StringUtils.isBlank(selectorHandle.getServiceId()) || StringUtils.isBlank(ruleHandle.getPath())) {
                // 返回错误信息
                Object error = SoulResultWrap.error(SoulResultEnum.CANNOT_CONFIG_SPRINGCLOUD_SERVICEID.getCode(), SoulResultEnum.CANNOT_CONFIG_SPRINGCLOUD_SERVICEID.getMsg(), null);
                return WebFluxResultUtils.result(exchange, error);
            }
            // 负载均衡选择一个实例
            final ServiceInstance serviceInstance = loadBalancer.choose(selectorHandle.getServiceId());
            // 如果负载均衡选择的实例是空
            if (Objects.isNull(serviceInstance)) {
                // 返回错误信息
                Object error = SoulResultWrap.error(SoulResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getCode(), SoulResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getMsg(), null);
                return WebFluxResultUtils.result(exchange, error);
            }
            // 获取uri
            final URI uri = loadBalancer.reconstructURI(serviceInstance, URI.create(soulContext.getRealUrl()));
            //获取真实的url地址
            String realURL = buildRealURL(uri.toASCIIString(), soulContext.getHttpMethod(), exchange.getRequest().getURI().getQuery());
            // 存储需要执行调用的信息到exchange
            exchange.getAttributes().put(Constants.HTTP_URL, realURL);
            //set time out.
            exchange.getAttributes().put(Constants.HTTP_TIME_OUT, ruleHandle.getTimeout());
            return chain.execute(exchange);
        }
    

    WebClientPlugin执行请求

     @Override
        public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
            // 获取soulcontext
            final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
            assert soulContext != null;
            // 获取请求的url
            String urlPath = exchange.getAttribute(Constants.HTTP_URL);
            if (StringUtils.isEmpty(urlPath)) {
                // 如果是空,返回错误信息
                Object error = SoulResultWrap.error(SoulResultEnum.CANNOT_FIND_URL.getCode(), SoulResultEnum.CANNOT_FIND_URL.getMsg(), null);
                return WebFluxResultUtils.result(exchange, error);
            }
            // 超时时间
            long timeout = (long) Optional.ofNullable(exchange.getAttribute(Constants.HTTP_TIME_OUT)).orElse(3000L);
            // 重试册数
            int retryTimes = (int) Optional.ofNullable(exchange.getAttribute(Constants.HTTP_RETRY)).orElse(0);
            log.info("The request urlPath is {}, retryTimes is {}", urlPath, retryTimes);
            // 方法
            HttpMethod method = HttpMethod.valueOf(exchange.getRequest().getMethodValue());
            // 执行方法
            WebClient.RequestBodySpec requestBodySpec = webClient.method(method).uri(urlPath);
            return handleRequestBody(requestBodySpec, exchange, timeout, retryTimes, chain);
        }
    

    WebClientResponsePlugin返回请求结果

    @Override
        public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
            return chain.execute(exchange).then(Mono.defer(() -> {
                // 请求返回结果
                ServerHttpResponse response = exchange.getResponse();
                // 客户端返回
                ClientResponse clientResponse = exchange.getAttribute(Constants.CLIENT_RESPONSE_ATTR);
                // 如果返回结果为空,状态为失败,返回错误信息
                if (Objects.isNull(clientResponse)
                        || response.getStatusCode() == HttpStatus.BAD_GATEWAY
                        || response.getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR) {
                    Object error = SoulResultWrap.error(SoulResultEnum.SERVICE_RESULT_ERROR.getCode(), SoulResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
                    return WebFluxResultUtils.result(exchange, error);
                }
                // 超时,返回超时错误
                if (response.getStatusCode() == HttpStatus.GATEWAY_TIMEOUT) {
                    Object error = SoulResultWrap.error(SoulResultEnum.SERVICE_TIMEOUT.getCode(), SoulResultEnum.SERVICE_TIMEOUT.getMsg(), null);
                    return WebFluxResultUtils.result(exchange, error);
                }
                response.setStatusCode(clientResponse.statusCode());
                response.getCookies().putAll(clientResponse.cookies());
                response.getHeaders().putAll(clientResponse.headers().asHttpHeaders());
                // 返回结果
                return response.writeWith(clientResponse.body(BodyExtractors.toDataBuffers()));
            }));
        }
    

    相关文章

      网友评论

          本文标题:Soul源码阅读 SpringCloud集成原理2【第十五天】

          本文链接:https://www.haomeiwen.com/subject/evahtltx.html