簡單讀讀源碼 - dubbo多提供者(provider)配置方法,以及泛接口多實現類作為提供者上nacos的方案


  1. 消費者端dubbo的yml配置

    dubbo:
      consumer:
        timeout: 300000
      protocol:
        name: dubbo
        port: -1
      cloud:
        subscribed-services: order-server
    #    subscribed-services: hello-server,account-server,storage-server,order-server
    
  2. 按住ctrl + 鼠標左擊subscribed-services如下圖:

    按住鼠標左擊

  3. 這里是對應的setter方法,上面找到定義地方

    	/**
    	 * All services of Dubbo.
    	 */
    	public static final String ALL_DUBBO_SERVICES = "*";
    
    	/**
    	 * The subscribed services, the default value is "*". The multiple value will use
    	 * comma(",") as the separator.
    	 *
    	 * @see #ALL_DUBBO_SERVICES
    	 */
    	private String subscribedServices = ALL_DUBBO_SERVICES;
    

    讀一讀就知道答案了。默認為*,多個值時候用,隔開。


    接下來,走走最表面的流程,就是看看怎么處理我們輸入的數據的,至於是怎么找到提供者的,先不管。

  4. 光標點到類DubboCloudProperties上面,這里ctrl+單擊是點不進去的,但是你點一下有提醒

    No usages found in Project Files 
    Press Ctrl+Alt+F7 again to search in 'Project and Libraries
    
  5. 跟着提醒,Ctrl+Alt+F7,如果提醒關閉了,就雙擊F7,出來下圖。

    ctrl+alt+f7

  6. 直接回車,就是高亮的這一行。回去復制ubscribedServices,不要開頭的s,不管大寫還是小寫,Ctrl+F搜出來看看。

  7. 通過點擊向上向下的箭頭,或者F3(下一個)/Shift+F3(上一個)來讀一讀源碼。這里我們看到他在237行時候進行了初始化。

    初始化

  8. 老樣子,ctrl+單擊initSubscribedServices()方法。

    初始化方法

    讀一下,如果ALL_DUBBO_SERVICES等於我們輸入的提供者,就是輸出巴拉巴拉。

  9. 那么ALL_DUBBO_SERVICES是啥,ctrl點,發現又跳回第一個文件了:

    @ConfigurationProperties(prefix = CONFIG_PROPERTY_PREFIX)
    public class DubboCloudProperties {
    
    	/**
    	 * All services of Dubbo.
    	 */
    	public static final String ALL_DUBBO_SERVICES = "*";
        
        // 這里是默認為*,如果set方法沒有執行,那么get時候獲得的就是*
        private String subscribedServices = ALL_DUBBO_SERVICES;
        
        /* ... */
        
    }
    
#### **現在測試一下輸出那個東西,啟動一個提供者,然后消費者訂閱的提供者寫成`*`或者注釋掉。啟動消費者。**

查看日志:

```txt
2021-05-27 16:28:24.950  WARN 6564 --- [client.listener] a.c.d.m.r.DubboServiceMetadataRepository : Current application will subscribe all services(size:20) in registry, a lot of memory and CPU cycles may be used, thus it's strongly recommend you using the externalized property 'dubbo.cloud.subscribed-services' to specify the services
```

與步驟8中一致。
  1. 接着讀else,如果我們填入內容了,就subscribedServices()后加入到那個集合中

    newSubscribedServices.addAll(dubboCloudProperties.subscribedServices());
    

    ctrl點subscribedServices(),然后發現又轉到第一個文件了:

    轉回來了

    再繼續讀一下:使用commaDelimitedListToStringArray將我們輸入的東西轉化了字符串數組,處理返回。

  2. 我們來看看commaDelimitedListToStringArray怎么處理的,找到導入它的地方:

    import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;

    然后ctrl點:

    	/**
    	 * Convert a comma delimited list (e.g., a row from a CSV file) into an
    	 * array of strings.
    	 * @param str the input {@code String} (potentially {@code null} or empty)
    	 * @return an array of strings, or the empty array in case of empty input
    	 */
    	public static String[] commaDelimitedListToStringArray(@Nullable String str) {
    		return delimitedListToStringArray(str, ",");
    	}
    

    這里與標題3.中The multiple value will use comma(",") as the separator.對應。

  3. 結論:

    • 不寫或者*會訂閱所有的。
    • 寫多就使用,隔開。

泛型接口多種實現方法的提供者上nacos的解決方法。

參考:Dubbo配合SpringBoot,實現接口多個實現(group)

yml文件的dubbo部分與平時沒有兩樣

(這是提供者和消費者都是自己的情況,如果分開就是scanregistry加上面是提供者,cloud加上面的是消費者(不包括scan和registry))

dubbo:
  consumer:
    retries: 5
  protocol:
    port: -1
    name: dubbo
  scan: #將那個目錄下的文件上nacos作為提供者
    base-packages: com.example.service.impl
  registry: #注冊中心
    address: nacos://127.0.0.1:8848
  cloud: #訂閱提供者
    subscribed-services: my-application

只是在提供者的實現方法1的注解@Service后添加組,代碼如下:

package com.example.service.impl;

import com.alibaba.dubbo.config.annotation.Service;

@Service(group = "service1")
public class TestServiceOneImpl implements TestService {
    /* ... */
}

提供者的實現方法2的注解@Service后也添加組,代碼如下:

package com.example.service.impl;

import com.alibaba.dubbo.config.annotation.Service;

@Service(group = "service2")
public class TestServiceOneImpl implements TestService {
    /* ... */
}

在消費者端使用時候,同樣注解@Reference后面添加組,代碼如下:

package com.example.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @Reference(group = "service1")
    private TestService testServiceOne;
    
    @PostMapping("/test")
    public String testMethod() {
        testServiceOne...
            
        return null;
    }
    
}

至此就可以指定同接口提供的不同實現類接口了。

​ 若接口是泛型定義的,也即不確定參數或者返回類型,那么在定義接口時候使用TestService<T>,實現類可以指定實現類型方式 implements TestService<MyOwnClass>這個泛型接口是與分組不沖突的。


擴展:

關於DubboReference和DubboService這兩個注解。

參考:Dubbo整合Spring原理之@Reference和@DubboReference生效機制(3)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM