Soul网关源码阅读17-解析rewrite插件

rewrite插件可以帮我们重置请求的URL,这样对外可以屏蔽实际的请求地址。我们来解析一下如何使用

一、环境搭建
  • soul-admin

开启 rewrite 插件:系统管理 --> 插件管理

  • soul-bootstrap

soul-bootstrap/pom.xml
网关中 rewrite 依赖默认是没有的需要手动添加

<dependency>
    <groupId>org.dromara</groupId>
    <artifactId>soul-spring-boot-starter-plugin-rewrite</artifactId>
    <version>${project.version}</version>
</dependency>
  • 开启服务

soul-admin
soul-bootstrap
soul-examples-http

二、配置选择器和选择器规则
  • devide 插件

我这里通过devide插件代理http请求,所以开启的devide插件,并且soul-examples-http服务开启后,数据会自动同步
无需手动添加,如果需要自定义可以自由修改

在这里插入图片描述

  • rewrite 插件

选择器和选择器规则需要手动配置

在这里插入图片描述

rewriteURL 配置的是接口需要转发的实际地址
在这里插入图片描述

三、测试

查看网关测的日志打印,请求已经被rewrite插件成功转发

http://127.0.0.1:9195/http/test/order/findById?id=5 ----> http://10.7.254.31:8188/order/findById?id=5

➜  ~ curl -X GET \
  'http://127.0.0.1:9195/http/test/order/findById?id=5' \
  -H 'cache-control: no-cache' \
  -H 'postman-token: 3877184f-0398-180a-12f9-8930ecfa24bf' \
  -H 'test: test'
{"id":"5","name":"hello world findById"}%                                                                                                       ➜  ~ 
2021-02-03 18:18:54.315  INFO 39475 --- [-work-threads-1] o.d.soul.plugin.base.AbstractSoulPlugin  : rewrite selector success match , selector name :rewrite-test
2021-02-03 18:18:54.316  INFO 39475 --- [-work-threads-1] o.d.soul.plugin.base.AbstractSoulPlugin  : rewrite rule success match , rule name :rewrite-rule
2021-02-03 18:18:54.318  INFO 39475 --- [-work-threads-1] o.d.soul.plugin.base.AbstractSoulPlugin  : divide selector success match , selector name :/http
2021-02-03 18:18:54.318  INFO 39475 --- [-work-threads-1] o.d.soul.plugin.base.AbstractSoulPlugin  : divide rule success match , rule name :/http/test/**
2021-02-03 18:18:54.327  INFO 39475 --- [-work-threads-1] o.d.s.plugin.httpclient.WebClientPlugin  : The request urlPath is http://10.7.254.31:8188/order/findById?id=5, retryTimes is 0
2021-02-03 18:18:54.498  WARN 39475 --- [-work-threads-1] io.netty.bootstrap.Bootstrap             : Unknown channel option 'SO_TIMEOUT' for channel '[id: 0x704e5387]'
四、解析rewrite源码

1、soul-bootstrap 加入了依赖 soul-spring-boot-starter-plugin-rewrite

org.dromara.soul.springboot.starter.plugin.rewrite.RewritePluginConfiguration
soul-bootstrap 启动后自动加载 RewritePluginConfiguration 配置类
向容器中注入RewritePlugin

@Configuration
public class RewritePluginConfiguration {
    /**
     * Rewrite plugin.
     * @return the soul plugin
     */
    @Bean
    public SoulPlugin rewritePlugin() {
        return new RewritePlugin();
    }
}

2、RewritePlugin

模块:soul-plugin-rewrite
org.dromara.soul.plugin.rewrite.RewritePlugin

RewritePlugin —> doExecute 方法会设置 ServerWebExchange 属性 exchange.getAttributes().put(Constants.REWRITE_URI, rewriteHandle.getRewriteURI());
这就是admin后台设置的rewriteURL
这里只看到了设置rewriteURL,并没有做转发地址的替换

@Slf4j
public class RewritePlugin extends AbstractSoulPlugin {
    @Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
        String handle = rule.getHandle();
        final RewriteHandle rewriteHandle = GsonUtils.getInstance().fromJson(handle, RewriteHandle.class);
        if (Objects.isNull(rewriteHandle) || StringUtils.isBlank(rewriteHandle.getRewriteURI())) {
            log.error("uri rewrite rule can not configuration:{}", handle);
            return chain.execute(exchange);
        }
        exchange.getAttributes().put(Constants.REWRITE_URI, rewriteHandle.getRewriteURI());
        return chain.execute(exchange);
    }
	......
}

3、DividePlugin

模块:soul-plugin-divide
org.dromara.soul.plugin.divide.DividePlugin
请求来到了devide插件
DividePlugin—> doExecute—>buildRealURL 方法,做了rewriteURI地址的拼接
到此就看到了rewrite插件的处理过程

@Slf4j
public class DividePlugin extends AbstractSoulPlugin {
    @Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        assert soulContext != null;
        final DivideRuleHandle ruleHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), DivideRuleHandle.class);
        final List<DivideUpstream> upstreamList = UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(selector.getId());
        ......
        String realURL = buildRealURL(domain, soulContext, exchange);
        exchange.getAttributes().put(Constants.HTTP_URL, realURL);
        // set the http timeout
        exchange.getAttributes().put(Constants.HTTP_TIME_OUT, ruleHandle.getTimeout());
        exchange.getAttributes().put(Constants.HTTP_RETRY, ruleHandle.getRetry());
        return chain.execute(exchange);
    }
    ......
    private String buildRealURL(final String domain, final SoulContext soulContext, final ServerWebExchange exchange) {
        String path = domain;
        final String rewriteURI = (String) exchange.getAttributes().get(Constants.REWRITE_URI);
        if (StringUtils.isNoneBlank(rewriteURI)) {
            path = path + rewriteURI;
        } else {
            final String realUrl = soulContext.getRealUrl();
            if (StringUtils.isNoneBlank(realUrl)) {
                path = path + realUrl;
            }
        }
        String query = exchange.getRequest().getURI().getQuery();
        if (StringUtils.isNoneBlank(query)) {
            return path + "?" + query;
        }
        return path;
    }
}

4、debug过程
在这里插入图片描述
在这里插入图片描述

五、总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值