Dubbo 一些你不一定知道但是很好用的功能

2019-04-02 10:51 更新

dubbo功能非常完善,很多時候我們不需要重復造輪子,下面列舉一些不一定知道,但是很好用的功能;

直連Provider

在開發(fā)及測試環(huán)境下,可能需要繞過注冊中心,只測試指定服務提供者,這時候可能需要點對點直連,點對點直連模式,將以服務接口為單位,忽略注冊中心的提供者列表,A 接口配置點對點,不影響 B 接口從注冊中心獲取列表(說明:官方只建議開發(fā)&測試環(huán)境使用該功能),用法如下,url指定的地址就是直連地址:

<dubbo:reference id="demoService" 
interface="com.alibaba.dubbo.demo.DemoService" version="1.0.0" 
url="dubbo://172.18.1.205:20888/" />

多版本

當一個接口實現(xiàn),出現(xiàn)不兼容升級時,可以用版本號過渡,版本號不同的服務相互間不引用,用法如下:

<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" 
ref="demoService" version="1.0.0" />

利用dubbo該特性,我們能夠實現(xiàn)一些功能的灰度發(fā)布,實現(xiàn)步驟如下:

1、接口舊的實現(xiàn)定義version="1.0.0",接口新的實現(xiàn)version="2.0.0"

2、Consumer端定義version=""

這樣定義Provider和Consumer后,新舊接口實現(xiàn)各承擔50%的流量;

利用dubbo該特性,還能完成不兼容版本遷移:

1、在低壓力時間段,先升級一半Provider為新版本;

2、再將所有消費者升級為新版本;

3、然后將剩下的一半提供者升級為新版本。

回聲測試

回聲測試用于檢測服務是否可用,回聲測試按照正常請求流程執(zhí)行,能夠測試整個調用是否通暢,可用于監(jiān)控。

所有服務自動實現(xiàn)EchoService接口,只需將任意服務引用強制轉型為EchoService 即可使用,使用方式(demoService是spring管理的bean)

EchoService echoService = (EchoService) demoService;
System.out.println(echoService.$echo("hello"));

隱式參數(shù)

可以通過 RpcContext 的 setAttachment() 和 getAttachment() 在Consumer和Provider之間進行參數(shù)的隱式傳遞,例如Controller層攔截登錄token,把根據(jù)token得到的memberId傳給dubbo服務就能使用隱式參數(shù)傳遞的方式,setAttachment()設置的 KV 對,在完成一次遠程調用會被清空,即多次遠程調用要多次設置。使用方式:

服務端set:

RpcContext.getContext().setAttachment("CRT_MEMBER_ID", "13828886888");

客戶端get:

RpcContext.getContext().getAttachment("CRT_MEMBER_ID")

上下文

上下文中存放的是當前調用過程中所需的環(huán)境信息。所有配置信息都將轉換為 URL 的參數(shù)

RpcContext 是一個 ThreadLocal 的臨時狀態(tài)記錄器,當接收到 RPC 請求,或發(fā)起 RPC 請求時,RpcContext 的狀態(tài)

都會變化。例如:A 調 B,B 再調 C,則 B 機器上,在 B 調 C 之前,RpcContext 記錄的是 A 調 B 的信息,在 B 調 C

之后,RpcContext 記錄的是 B 調 C 的信息。使用方式:

boolean isConsumerSide = RpcContext.getContext().isConsumerSide();

本地偽裝

本地偽裝通常用于服務降級,例如某驗權服務,當服務提供方全部掛掉后,客戶端不拋出異常,而是通過 Mock 數(shù)據(jù)

返回授權失敗。使用方式如下,mock指定的實現(xiàn)類在Provider拋出RpcException異常時執(zhí)行(一定要拋出RpcException異常才執(zhí)行),取代遠程返回結果:

<dubbo:reference id="demoService" 
interface="com.alibaba.dubbo.demo.DemoService" version="1.0.0" 
mock="com.alibaba.dubbo.demo.consumer.mock.DemoServiceMock"/>

DemoServiceMock實現(xiàn)源碼:

public class DemoServiceMock implements DemoService {
    public String sayHello(String name) {
        return "mock-value";
    }
}

泛化調用

泛化接口調用方式主要用于客戶端沒有 API 接口及模型類元的情況,參數(shù)及返回值中的所有 POJO 均用Map表示,通常用于框架集成,例如:實現(xiàn)一個通用的服務測試框架,可通過GenericService調用所有服務實現(xiàn)。使用方式:

<dubbo:reference id="demoService" 
interface="com.alibaba.dubbo.demo.DemoService" generic="true"/>

調用源碼:

/*
  @author afei
  @version 1.0.0
  @since 2017年11月22日
 */
public class Main {

    public static void main(String[] args) {
        // 引?遠程服務, 該實例??封裝了所有與注冊中?及服務提供?連接,請緩存
        ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
        // 弱類型接?名
        reference.setInterface("com.alibaba.dubbo.demo.DemoService");
        reference.setVersion("1.0.0");
        // 聲明為泛化接?
        reference.setGeneric(true);
        // ?com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用?
        GenericService genericService = reference.get();
        // 基本類型以及Date,List,Map等不需要轉換,直接調?
        Object result = genericService.$invoke("sayYes", new String[] {"java.lang.String"}, new Object[] {"afei"});
        System.out.println("result --> "+result);

        // ?Map表示POJO參數(shù),如果返回值為POJO也將自動轉成Map
        Map<String, Object> teacher = new HashMap<String, Object>();
        teacher.put("id", "1");
        teacher.put("name", "admin");
        teacher.put("age", "18");
        teacher.put("level", "3");
        teacher.put("remark", "測試");
        // 如果返回POJO將自動轉成Map
        result = genericService.$invoke("justTest", new String[]
                {"com.alibaba.dubbo.demo.bean.HighTeacher"}, new Object[]{teacher});
        System.out.println("result --> "+result);
    }
}

訪問日志

如果想記錄每次請求信息,可開啟訪問日志,類似于Ngnix的訪問日志。注意:此日志量比較大,請注意磁盤容量。使用方式(如果配置局部,全局訪問日志就會失效):
配置全局:

<dubbo:provider accesslog="/app/dubbo-demo.log"/>
配置局部:
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" 
ref="demoService" accesslog="/app/demo.log"/>

 <dubbo:service interface="com.alibaba.dubbo.demo.TestService" 
ref="testService" accesslog="/app/test.log"/>
日志格式樣式:
[2017-11-22 10:23:20] 172.18.1.205:56144 -> 172.18.1.205:20886 - 
com.alibaba.dubbo.demo.DemoService:1.0.0 sayHello(java.lang.String) ["afei"]

延遲暴露

如果服務需要預熱時間,比如初始化本地緩存,等待相關資源就位等,可以使用delay進行延遲暴露。使Dubbo在Spring容器初始化完后延遲多少毫秒再暴露服務。使用方式:

<dubbo:provider delay="5000"/>
或者:

<dubbo:service delay="5000" interface="com.alibaba.dubbo.demo.DemoService" 
ref="demoService" version="1.0.0"/>


文章來源:https://blog.csdn.net/madongyu1259892936/article/details/85789154

推薦閱讀:https://www.roncoo.com/search/dubbo



以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號