目标

  • 运行 examples下面的 apache-dubbo 服务
  • 学习文档,结合 dubbo 插件,发起 http 请求 soul 网关,体验 dubbo 代理

soul 网关接入 Dubbo 应用

  • 参考官方文档:https://dromara.org/zh-cn/doc...

    • 引入相关依赖(官方示例默认开启的alibaba-dubbo,具体参考:soul-examples-dubbo

      soul-bootstrap新增如下依赖:

            <!--soul  apache dubbo plugin start-->
               <dependency>
                  <groupId>org.dromara</groupId>
                  <artifactId>soul-spring-boot-starter-plugin-apache-dubbo</artifactId>
                  <version>${project.version}</version>
              </dependency>
              <dependency>
                  <groupId>org.apache.dubbo</groupId>
                  <artifactId>dubbo</artifactId>
                  <version>2.7.5</version>
              </dependency>
              
              <!-- Dubbo zookeeper registry dependency start -->
            <dependency>
                  <groupId>org.apache.curator</groupId>
                  <artifactId>curator-client</artifactId>
                  <version>4.0.1</version>
              </dependency>
              <dependency>
                  <groupId>org.apache.curator</groupId>
                  <artifactId>curator-framework</artifactId>
                  <version>4.0.1</version>
              </dependency>
              <dependency>
                  <groupId>org.apache.curator</groupId>
                  <artifactId>curator-recipes</artifactId>
                  <version>4.0.1</version>
              </dependency>
               <!-- Dubbo zookeeper registry dependency end -->

      soul-examples-apache-dubbo-service新增如下依赖:

      
                 <!--soul apache dubbo plugin start-->
                 <dependency>
                     <groupId>org.dromara</groupId>
                     <artifactId>soul-spring-boot-starter-plugin-apache-dubbo</artifactId>
                     <version>2.2.1</version>
                 </dependency>
                 <!--soul apache dubbo plugin end-->
                 
                 <!-- Dubbo dependency -->
                 <dependency>
                     <groupId>org.apache.dubbo</groupId>
                     <artifactId>dubbo</artifactId>
                     <version>2.7.5</version>
                 </dependency>
                 
                <!-- Dubbo zookeeper registry dependency start-->
                 <dependency>
                  <groupId>org.apache.zookeeper</groupId>
                  <artifactId>zookeeper</artifactId>
                  <version>3.5.6</version>
                  <exclusions>
                      <exclusion>
                          <groupId>org.slf4j</groupId>
                          <artifactId>slf4j-log4j12</artifactId>
                      </exclusion>
                      <exclusion>
                          <groupId>log4j</groupId>
                          <artifactId>log4j</artifactId>
                      </exclusion>
                  </exclusions>
              </dependency>
             <!-- Dubbo zookeeper registry dependency end -->
    • application.yml添加相关配置

        soul:
           dubbo:
             adminUrl: http://localhost:9095
             contextPath: /dubbo
             appName: dubbo
            # adminUrl: 为你启动的soul-admin 项目的ip + 端口,注意要加 http://
            # contextPath: 为你的这个项目在soul网关的路由前缀,比如/order ,/product 等等,网关会根据你的这个前 缀来进行路由.
            # appName:你的应用名称,不配置的话,会默认取 dubbo配置中application 中的名称
  • dubbo 插件设置

    soul-admin 插件管理中,dubbo 插件设置为开启
    image-20210116223835118

    dubbo 插件中配置你的注册地址
    image-20210116201405

  • 接口注册到网关

    • dubbo 服务实现类的方法上加上 @SoulDubboClient 注解,表示该接口方法注册到网关
  • 先启动zk,然后再启动TestApacheDubboApplication,输出日志 dubbo client register success,表示dubbo接口已经发布到 soul 网关

    image-20210116201725

@SoulDubboClient 注解解析

服务在启动时会将类方法上的 @SoulDubboClient 注解注册到网关,接下来分析一下@SoulDubboClient 注册逻辑。

soul-examples-apache-dubbo-service添加了soul-spring-boot-starter-plugin-apache-dubbo依赖,注册逻辑应该就在这个自定义的spring-boot-starter中。

首先注释掉DubboTestServicel类中findById方法上的@SoulDubboClient注解

    @Override
    //@SoulDubboClient(path = "/findById", desc = "Query by Id")
    public DubboTest findById(final String id) {
        DubboTest dubboTest = new DubboTest();
        dubboTest.setId(id);
        dubboTest.setName("hello world Soul Apache, findById");
        return dubboTest;
    }

soul-spring-boot-starter-client-apache-dubbo 自定义spring-boot-starter通过 spring.factories 加载了SoulApacheDubboClientConfiguration类:

@Configuration
public class SoulApacheDubboClientConfiguration {
    
    /**
     * Apache dubbo service bean post processor alibaba dubbo service bean post processor.
     *
     * @param dubboConfig the dubbo config
     * @return the alibaba dubbo service bean post processor
     */
    @Bean
    public ApacheDubboServiceBeanPostProcessor apacheDubboServiceBeanPostProcessor(final DubboConfig dubboConfig) {
        return new ApacheDubboServiceBeanPostProcessor(dubboConfig);
    }
    
    /**
     * Dubbo config dubbo config.
     *
     * @return the dubbo config
     */
    @Bean
    @ConfigurationProperties(prefix = "soul.dubbo")
    public DubboConfig dubboConfig() {
        return new DubboConfig();
    }
}

SoulApacheDubboClientConfiguration加载了ApacheDubboServiceBeanPostProcessor实例,该实例实现了ApplicationListener<ContextRefreshedEvent> 接口,该类中的主要方法:

    public ApacheDubboServiceBeanPostProcessor(final DubboConfig dubboConfig) {
        //获取 application.yml 文件中的配置信息
        String contextPath = dubboConfig.getContextPath();
        String adminUrl = dubboConfig.getAdminUrl();
        if (StringUtils.isEmpty(contextPath)
                || StringUtils.isEmpty(adminUrl)) {
            throw new RuntimeException("apache dubbo client must config the contextPath, adminUrl");
        }
        this.dubboConfig = dubboConfig;
        url = dubboConfig.getAdminUrl() + "/soul-client/dubbo-register";
        executorService = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
    }
    @Override
    public void onApplicationEvent(final ContextRefreshedEvent contextRefreshedEvent) {
        if (Objects.nonNull(contextRefreshedEvent.getApplicationContext().getParent())) {
            return;
        }
        // Fix bug(https://github.com/dromara/soul/issues/415), upload dubbo metadata on ContextRefreshedEvent
        
        //根据 beanType 获取所有的 bean,这里获取的是 spring-dubbo.xml 中 <dubbo:service/>中的DubboTestService和               //DubboMultiParamService         
        //ServiceBean.class:org.apache.dubbo.config.spring.ServiceBean.class
        Map<String, ServiceBean> serviceBean = contextRefreshedEvent.getApplicationContext().getBeansOfType(ServiceBean.class);
        for (Map.Entry<String, ServiceBean> entry : serviceBean.entrySet()) {
            executorService.execute(() -> handler(entry.getValue()));
        }
    }

处理类中的每个方法

private void handler(final ServiceBean serviceBean) {
        Class<?> clazz = serviceBean.getRef().getClass();
        if (ClassUtils.isCglibProxyClass(clazz)) {
            String superClassName = clazz.getGenericSuperclass().getTypeName();
            try {
                clazz = Class.forName(superClassName);
            } catch (ClassNotFoundException e) {
                log.error(String.format("class not found: %s", superClassName));
                return;
            }
        }
       // 获取类中每个方法
        final Method[] methods = ReflectionUtils.getUniqueDeclaredMethods(clazz);
        for (Method method : methods) {
            //获取类上的 @SoulDubboClient 注解
            SoulDubboClient soulDubboClient = method.getAnnotation(SoulDubboClient.class);
            if (Objects.nonNull(soulDubboClient)) {
                //远程调用,注册方法信息到 soul-admin
                RegisterUtils.doRegister(buildJsonParams(serviceBean, soulDubboClient, method), url, RpcTypeEnum.DUBBO);
            }
        }
    }

当获取到DubboTestServicel类中findById的方法时,由于我们上面注释了 @SoulDubboClient注解,所有以这里获取 SoulDubboClient 的值为 null。

img

至此,@SoulDubboClient注解分析完毕

问题

先记录一个问题,明天再看:soul 的数据同步是将数据库中的信息同步到本地缓存中,如果是已经通过 @SoulDubboClient注解注册到soul-admin的方法被删除了,数据库中的信息什么时候删除?例如上面findById方法已经注释掉了 @SoulDubboClient注解,服务重启时输出的注册信息已经没有了findById方法,但是soul-admin中dubbo 插件列表和元数据列表中依然存在findById方法信息。

image-20210116223835118

image-20210116224221733


zhurd
4 声望1 粉丝

引用和评论

0 条评论