程序栈 wavedorm centos8 performance tkinter matrix ajax的get请求 datetimepicker赋值 mysql删除一列 matlab中axis mysql修改字段值 pip环境变量 centos查看python版本 反函数的二阶导数 mysql插入 python的random函数 python平台 python正则匹配数字 java类 java编程实例 java字符串替换 垃圾邮件数据集 vs2010sp1 脚本下载 小米5c拆机 苹果滚动截屏 图片放大软件 php抓取网页数据 流水账软件 电脑书籍下载 directx卸载 vs2008中文版下载 grep正则表达式 lol无限视野 影音先锋下载速度慢 linux解压 exe文件反编译 iosps腹肌 id页码怎么设置 ps镂空字体怎么做
当前位置: 首页 > 学习教程  > 编程语言

soul网关源码学习13-springcloud插件解析

2021/1/28 23:41:33 文章标签:

soul网关源码学习13-springcloud插件解析 目标 跑通springcloud插件理解springcloud插件底层原理与divide插件进行对比 一、运行项目 引入依赖 springcloud插件支持eureka或者nacos作为注册中心&#xff0c;这里我们使用eureka&#xff0c;引入eureka依赖。 <dependenc…

soul网关源码学习13-springcloud插件解析

目标

  • 跑通springcloud插件
  • 理解springcloud插件底层原理
  • 与divide插件进行对比

一、运行项目

引入依赖

  • springcloud插件支持eureka或者nacos作为注册中心,这里我们使用eureka,引入eureka依赖。
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
  • 想要让soul支持springcloud插件,还需要引入springcloud相关引入。
        <!--soul springCloud plugin start-->
       <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>soul-spring-boot-starter-plugin-springcloud</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <!--soul springCloud plugin start end-->

启动项目

  • 启动eureka
  • 启动soul-admin
  • 启动soul-bootstrap
  • 启动springcloud-example
    在这里插入图片描述

开启插件

  • 打开系统http://localhost:9095,admin/admin
  • 在插件管理中开启springcloud插件。

在这里插入图片描述

测试接口

  • 打开postman工具,测试接口:http://localhost:9195/springcloud/order/findById?id=1
    在这里插入图片描述

二、源码解析

插件链调用

  • 项目启动加载插件,同步数据的步骤前面都已经讲过,这里打上断点直接进入调用插件链。
    在这里插入图片描述
  • 这里有18个插件,按之前divide插件的分析,有些是公共的插件,有些是没有启动的插件,这里最重要的是看springcloud这个插件。
  • 以下是SpringCloudPlugin插件的执行过程。
        if (Objects.isNull(rule)) {
            return Mono.empty();
        }
        // 通过插件链调用,把前面GlobalPlugin插件放进去的接口上下文在这里拿出来用
        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);
        }
  • 根据前面配置的负载均衡策略去注册中心获取服务实例,这里跟divide插件不同的地方是,divide这里的负载均衡策略是去拿到所有的upstream,也就是不用的ip,然后自己实现了负载均衡策略,这里是用了springcloud原生的负载均衡。
        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);
        }
  • 构造出真实调用的url,放到exchange中,供后面的插件使用。
        final URI uri = loadBalancer.reconstructURI(serviceInstance, URI.create(soulContext.getRealUrl()));

        String realURL = buildRealURL(uri.toASCIIString(), soulContext.getHttpMethod(), exchange.getRequest().getURI().getQuery());

        exchange.getAttributes().put(Constants.HTTP_URL, realURL);
        //set time out.
        exchange.getAttributes().put(Constants.HTTP_TIME_OUT, ruleHandle.getTimeout());
  • 可以看一下这里的realURL,这里有点疑问,为什么地址是主机名呢?
    在这里插入图片描述
  • 查了一下,是在eureka配置的,可以通过修改配置修改主机名。
eureka:
  instance:
    hostname: ${hostname:localhost}
  • 接着就是跟divide插件一样通过WebClientPlugin去调真实的接口,然后返回信息。

三、总结

  • 两个插件调用的流程基本一致,除了拿真实url那里有点区别。
  • springcloud插件是需要第三方注册中心的,而divide插件不需要。
  • springcloud插件用了springcloud原生的负载均衡策略,而divide插件是自己实现的。

本文链接: http://www.dtmao.cc/news_show_650282.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?