带着问题读源码-soul(2021-01-16)

### 带着问题读源码系列之Dubbo插件

像往常一样启动 【soul-admin】 和 【soul-bootstrap】 。

因为dubbo需要依赖zookeeper, 需要需要启动一个监听在 localhost:2181 的zookeeper组件。

然后使用 【soul-examples-apache-dubbo-service】中的 org.dromara.soul.examples.apache.dubbo.service.TestApacheDubboApplication 来注册服务。

这是就可以打开 管理界面 查看dubbo插件的信息。发现已经注册完毕了。

然后使用soul提供的http请求访问

curl http://localhost:9195/dubbo/findAll

{"code":-107,"message":"Can not find selector, please check your configuration!","data":null}%

这里报得是找不到选择器,再查看日志:

java.lang.IllegalStateException: No such application config! Please add <dubbo:application name="..." /> to your spring config.

at com.alibaba.dubbo.config.AbstractInterfaceConfig.checkApplication(AbstractInterfaceConfig.java:145) ~[dubbo-2.6.5.jar:2.6.5]

at com.alibaba.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:278) ~[dubbo-2.6.5.jar:2.6.5]

at com.alibaba.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:163) ~[dubbo-2.6.5.jar:2.6.5]

at org.dromara.soul.plugin.alibaba.dubbo.cache.ApplicationConfigCache.build(ApplicationConfigCache.java:166) ~[classes/:na]

at org.dromara.soul.plugin.alibaba.dubbo.cache.ApplicationConfigCache.initRef(ApplicationConfigCache.java:130) ~[classes/:na]

at org.dromara.soul.plugin.alibaba.dubbo.subscriber.AlibabaDubboMetaDataSubscriber.onSubscribe(AlibabaDubboMetaDataSubscriber.java:43) ~[classes/:na]

at org.dromara.soul.plugin.sync.data.weboscket.handler.MetaDataHandler.lambda$null$0(MetaDataHandler.java:42) ~[classes/:na]

at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_201]

at org.dromara.soul.plugin.sync.data.weboscket.handler.MetaDataHandler.lambda$doRefresh$1(MetaDataHandler.java:42) ~[classes/:na]

at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_201]

at org.dromara.soul.plugin.sync.data.weboscket.handler.MetaDataHandler.doRefresh(MetaDataHandler.java:42) ~[classes/:na]

at org.dromara.soul.plugin.sync.data.weboscket.handler.AbstractDataHandler.handle(AbstractDataHandler.java:68) ~[classes/:na]

at org.dromara.soul.plugin.sync.data.weboscket.handler.WebsocketDataHandler.executor(WebsocketDataHandler.java:61) ~[classes/:na]

at org.dromara.soul.plugin.sync.data.weboscket.client.SoulWebsocketClient.handleResult(SoulWebsocketClient.java:87) ~[classes/:na]

at org.dromara.soul.plugin.sync.data.weboscket.client.SoulWebsocketClient.onMessage(SoulWebsocketClient.java:68) ~[classes/:na]

at org.java_websocket.client.WebSocketClient.onWebsocketMessage(WebSocketClient.java:591) [Java-WebSocket-1.5.0.jar:na]

at org.java_websocket.drafts.Draft_6455.processFrameText(Draft_6455.java:885) [Java-WebSocket-1.5.0.jar:na]

at org.java_websocket.drafts.Draft_6455.processFrame(Draft_6455.java:819) [Java-WebSocket-1.5.0.jar:na]

at org.java_websocket.WebSocketImpl.decodeFrames(WebSocketImpl.java:379) [Java-WebSocket-1.5.0.jar:na]

at org.java_websocket.WebSocketImpl.decode(WebSocketImpl.java:216) [Java-WebSocket-1.5.0.jar:na]

at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:508) [Java-WebSocket-1.5.0.jar:na]

at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]

> 2021-01-16 08:30:17.149 INFO 6397 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 9195

> 2021-01-16 08:30:17.152 INFO 6397 --- [ main] o.d.s.b.SoulBootstrapApplication : Started SoulBootstrapApplication in 3.704 seconds (JVM running for 4.3)

> 2021-01-16 08:30:26.271 INFO 6397 --- [ocket-connect-1] o.d.s.p.s.d.w.WebsocketSyncDataService : websocket reconnect is successful.....

> 2021-01-16 08:30:26.612 ERROR 6397 --- [-work-threads-1] o.d.soul.plugin.base.utils.CheckUtils : can not match selector data: divide

这里日志现实dubbo服务就没有注册上来,说明dubbo插件没有启动成功,通过查看插件管理,发现dubbo插件没有开启,手动开启后。然后调用:

curl http://127.0.0.1:9195/dubbo/findAll

{"code":200,"message":"Access to success!","data":{"name":"hello world Soul Apache, findAll","id":"-721302769"}}%

如此调用成功。

通过example的列子,可以将soul网关dubbo插件的使用分为如下过程:

1. 在提供者处添加依赖

<dependencies>

        <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>soul-spring-boot-starter-client-apache-dubbo</artifactId>
            <version>${soul.version}</version>
        </dependency>

        <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>soul-examples-dubbo-api</artifactId>
        </dependency>

        <!--spring boot的核心启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--aop支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--自动配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

        <!-- Dubbo dependency -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>${apache.dubbo.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-registry-nacos -->
        <!-- Dubbo Nacos registry dependency -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-nacos</artifactId>
            <version>${apache.dubbo.version}</version>
        </dependency>

        <!-- Keep latest Nacos client version -->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>${nacos-client.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-client</artifactId>
            <version>${curator.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${curator.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>${curator.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>${zookeeper.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
</dependencies>

2. 添加dubbo配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <dubbo:application name="test-dubbo-service"/>

    <dubbo:registry address="zookeeper://localhost:2181"/>

    <dubbo:protocol name="dubbo" port="20888"/>

    <dubbo:service timeout="10000" interface="org.dromara.soul.examples.dubbo.api.service.DubboTestService" ref="dubboTestService"/>
    <dubbo:service timeout="10000" interface="org.dromara.soul.examples.dubbo.api.service.DubboMultiParamService" ref="dubboMultiParamService"/>
</beans>

3. 在application.yml添加配置

soul:

    dubbo:

        # soul-admin地址
    
        adminUrl: http://localhost:9095

        # 匹配的url前缀

        contextPath: /dubbo

        appName: dubbo    

下面阅读Soul的 DubboPlugin 的代码

public class ApacheDubboPlugin extends AbstractSoulPlugin {

    private final ApacheDubboProxyService dubboProxyService;

    /**
     * Instantiates a new Dubbo plugin.
     *
     * @param dubboProxyService the dubbo proxy service
     */
    public ApacheDubboPlugin(final ApacheDubboProxyService dubboProxyService) {
        this.dubboProxyService = dubboProxyService;
    }

    @Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
        String body = exchange.getAttribute(Constants.DUBBO_PARAMS); // 获取dubbo的请求
        SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT); // 获取soul上下文
        assert soulContext != null;
        MetaData metaData = exchange.getAttribute(Constants.META_DATA); // 获取元数据

        if (!checkMetaData(metaData)) {

            assert metaData != null;

            log.error(" path is :{}, meta data have error.... {}", soulContext.getPath(), metaData.toString());

            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);

            Object error = SoulResultWrap.error(SoulResultEnum.META_DATA_ERROR.getCode(), SoulResultEnum.META_DATA_ERROR.getMsg(), null);

            return WebFluxResultUtils.result(exchange, error);

        }

        if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && StringUtils.isBlank(body)) { // 判断请求合法性
            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            Object error = SoulResultWrap.error(SoulResultEnum.DUBBO_HAVE_BODY_PARAM.getCode(), SoulResultEnum.DUBBO_HAVE_BODY_PARAM.getMsg(), null);
            return WebFluxResultUtils.result(exchange, error);
        }
        final Mono<Object> result = dubboProxyService.genericInvoker(body, metaData, exchange);
        return result.then(chain.execute(exchange));
    }

    /**
     * acquire plugin name.
     *
     * @return plugin name.
     */
    @Override
    public String named() {
        return PluginEnum.DUBBO.getName();
    }

    /**
     * plugin is execute.
     *
     * @param exchange the current server exchange
     * @return default false.
     */
    @Override
    public Boolean skip(final ServerWebExchange exchange) {
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        assert soulContext != null;
        return !Objects.equals(soulContext.getRpcType(), RpcTypeEnum.DUBBO.getName());
    }

    @Override
    public int getOrder() {
        return PluginEnum.DUBBO.getCode();
    }

    private boolean checkMetaData(final MetaData metaData) {
        return null != metaData && !StringUtils.isBlank(metaData.getMethodName()) && !StringUtils.isBlank(metaData.getServiceName());
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值