Dubbo常用配置解析


一、多版本的支持

如何發布服務,需要將需要暴露的服務接口發布出去供客戶端調用,需要在java同級目錄新建一個resources目錄,然后將resoureces目錄標記成Test Resoureces Root,然后在esources目錄下新建MATE-INF.spring目錄,在該目錄下添加配置文件dubbo-server.xml文件
  dubbo的服務端配置文件如下
<?xml version="1.0" encoding="UTF-8"?>
<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--提供方信息,用於計算依賴關系-->
<dubbo:application name="dubbo-server" owner="mic"/>

<!--注冊中心 暴露服務地址-->
<dubbo:registry address="zookeeper://192.168.126.129:2181"/>

<!--用dubbo協議在20880 端口暴露服務-->
<dubbo:protocol port="20880" name="dubbo"/>

<!--聲明需要暴露的服務接口,指定協議為dubbo,設置版本號1.1.1-->
<dubbo:service interface="com.gupaoedu.dubbo.IGpHello"  ref="gpHelloService" protocol="dubbo" version="1.1.1"/>
<!--聲明需要暴露的服務接口,指定協議為dubbo,設置版本號1.1.2-->
<dubbo:service interface="com.gupaoedu.dubbo.IDemoService"    ref="demoService" protocol="dubbo" version="1.1.2"/>

<!--和本地服務一樣實現服務-->
<bean id="gpHelloService" class="com.gupaoedu.dubbo.GpHelloImpl"/>

<bean id="demoService" class="com.gupaoedu.dubbo.DemoService"/>
</beans>

服務端的接口以及實現類

public interface IGpHello {String sayHello(String msg);}
public interface IDemoService {String protocolDemo(String msg);}
public class GpHelloImpl implements IGpHello{
@Override
public String sayHello(String msg) {return "Hello:"+msg;}
}
public class GpHelloImpl2 implements IGpHello{
@Override
public String sayHello(String msg) {return "Hello,i'm server 2:"+msg;}
}

編寫Main方法,用spring容器來啟動服務

public class Main {
public static void main(String[] args) throws IOException {
//默認情況下會使用spring容器來啟動服務
com.alibaba.dubbo.container.Main.main(new String[]{"spring","log4j"});}
}
服務啟動過程會進行服務注冊,啟動監聽端口,啟動服務之后
在客戶端通過遠程調用訪問服務端發布的服務,相應的客戶端配置文件 dubbo-client.xml 如下
<?xml version="1.0" encoding="UTF-8"?>
<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--提供方信息-->
<dubbo:application name="dubbo-client" owner="mic"/>

<!--注冊中心-->
<dubbo:registry id="zokeeper" address="zookeeper://192.168.126.129:2181?register=false" file="d:/dubbo-server"/>

<!--聲明需要暴露的服務接口,指定版本號-->
<dubbo:reference id="gpHelloService" interface="com.gupaoedu.dubbo.IGpHello" registry="zookeeper" version="1.1.1"/>
</beans>

其實我們可以在zookeeper的客戶端可以發現,事實上已經發布了服務方已經發布了兩個不同版本的服務,具體如下

1 dubbo%3A%2F%2F192.168.126.1%3A20880%2Fcom.gupaoedu.dubbo.IDemoService%3Fanyhost%3Dtrue%26application%3Ddubbo-server%26dubbo%3D2.5.3%26interface%3Dcom.gupaoedu.dubbo.IDemoService%26methods%3DprotocolDemo%26owner%3Dmic%26pid%3D22548%26revision%3D1.1.2%26side%3Dprovider%26timestamp%3D1530450331827%26version%3D1.1.2
2 dubbo%3A%2F%2F192.168.126.1%3A20880%2Fcom.gupaoedu.dubbo.IGpHello%3Fanyhost%3Dtrue%26application%3Ddubbo-server%26dubbo%3D2.5.3%26interface%3Dcom.gupaoedu.dubbo.IGpHello%26methods%3DsayHello%26owner%3Dmic%26pid%3D22548%26revision%3D1.1.1%26side%3Dprovider%26timestamp%3D1530450325703%26version%3D1.1.1

我們知道,這兩個版本正是我們在服務發布方設置的不同版本號,同樣的,在消費端,我們可以通過設置指定的版本號獲取相應的版本服務,消費的代碼如下

public class App{
         public static void main( String[] args ) throws IOException, InterruptedException {
                   ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("dubbo-client.xml");
                    context.start();
                   IGpHello demoService = (IGpHello)context.getBean("gpHelloService");//獲取遠程服務代理
                  String hello = demoService.sayHello("world");//執行遠程調用方法
                  System.out.println(hello);//顯示調用結果
         }
}

在控制台,我們可以看到同樣的服務發布地址url。

二、主機綁定

  什么叫主機綁定呢?主機綁定的流程是什么?
在發布一個dubbo服務的時候,會生成一個dubbo://ip:port的協議地址。這就是主機綁定過程,那么這個IP是如何生成的呢?大家可以通過ServiceConfig.java 中的 doExportUrlForlProtocol 方法中找到如下代碼塊。大致的邏輯是,首先從配置文件中獲取,如果失敗再嘗試從本地網卡中獲取host,如果這個也失敗,會繼續執行,直到找到合適的IP地址。
String name = protocolConfig.getName();
if (name == null || name.length() == 0) {
    name = "dubbo";
}

String host = protocolConfig.getHost();//從配置文件中獲取host
if (provider != null && (host == null || host.length() == 0)) {
    host = provider.getHost();
}
boolean anyhost = false;
if (NetUtils.isInvalidLocalHost(host)) {
    anyhost = true;
    try {
        host = InetAddress.getLocalHost().getHostAddress();//獲取本機的host地址
    } catch (UnknownHostException e) {
        logger.warn(e.getMessage(), e);
    }
    if (NetUtils.isInvalidLocalHost(host)) {
        if (registryURLs != null && registryURLs.size() > 0) {//如果還是沒有獲取到host地址
            for (URL registryURL : registryURLs) {
                try {
                    Socket socket = new Socket();
                    try {
                        SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
                        socket.connect(addr, 1000);
                        host = socket.getLocalAddress().getHostAddress();//3、
                        break;
                    } finally {
                        try {
                            socket.close();
                        } catch (Throwable e) {}
                    }
                } catch (Exception e) {
                    logger.warn(e.getMessage(), e);
                }
            }
        }
        if (NetUtils.isInvalidLocalHost(host)) {//4、
            host = NetUtils.getLocalHost();
        }
    }
}

三、集群容錯

在分析dubbo的集群容錯前,先了解什么是容錯機制?容錯機制指的是某種系統控制在一 定范圍內的一種允許或包容犯錯情況的發生,舉個簡單例 子,我們在電腦上運行一個程序,有時候會出現無響應的情況,然后系統會彈出一個提示框讓我們選擇,是立即結 束還是繼續等待,然后根據我們的選擇執行對應的操作, 這就是“容錯”。
       在分布式架構下,網絡、硬件、應用都可能發生故障,由 於各個服務之間可能存在依賴關系,如果一條鏈路中的其 中一個節點出現故障,將會導致雪崩效應。為了減少某一 個節點故障的影響范圍,所以我們才需要去構建容錯服務(這里要說明一點,容錯機制僅僅是處理節點故障的一種機制), 來優雅的處理這種中斷的響應結果 。
Dubbo提供了6種容錯機制,分別如下 
1. failsafe 失敗安全,可以認為是把錯誤吞掉(記錄日 志) 
2. failover(默認)   重試其他服務器; retries(2) ,缺省的重試次數,不包含第一次
3. failfast 快速失敗, 失敗以后立馬報錯 
4. failback  失敗后自動恢復。 
5. forking  forks. 設置並行數 
6. broadcast  廣播,任意一台報錯,則執行的方法報錯 
配置方式如下,通過cluster方式,配置指定的容錯方案
<!--聲明需要暴露的服務接口,指定版本號-->
<dubbo:reference id="gpHelloService" interface="com.gupaoedu.dubbo.IGpHello"
registry="zookeeper" version="1.1.1"
cluster="failover"/>
配置的優先級別
客戶端會優於服務端,這里還可以細化,可以細化到方法級別
1. 方法級優先,接口級次之,全局配置再次之。 
2. 如果級別一樣,則消費方優先,提供方次之
其中,服務提供方配置,通過URL經由注冊中心傳遞給消 費方
什么應該配置在客戶端,什么應該配置在服務端,retires、loadBlance、cluster(客戶端)、timeout(服務端)
以 timeout 為例,建議由服務提供方設置超時,因為一個方法需要執行多長 時間,服務提供方更清楚,如果一個消費方同時引用多個 服務,就不需要關心每個服務的超時設置。

四、服務降級

降級的目的是為了保證核心服務可用。 
降級可以有幾個層面的分類: 自動降級和人工降級; 按 照功能可以分為:讀服務降級和寫服務降級; 
1. 對一些非核心服務進行人工降級,在大促之前通過降級 開關關閉哪些推薦內容、評價等對主流程沒有影響的功 能 
2. 故障降級,比如調用的遠程服務掛了,網絡故障、或者 RPC服務返回異常。 那么可以直接降級,降級的方案比 如設置默認值、采用兜底數據(系統推薦的行為廣告掛 了,可以提前准備靜態頁面做返回)等等 
3. 限流降級,在秒殺這種流量比較集中並且流量特別大的 情況下,因為突發訪問量特別大可能會導致系統支撐不 了。這個時候可以采用限流來限制訪問量。當達到閥值 時,后續的請求被降級,比如進入排隊頁面,比如跳轉 到錯誤頁(活動太火爆,稍后重試等) 
dubbo的降級方式: Mock 機制
實現步驟
1. 在client端創建一個TestMock類,實現對應IGpHello 的接口(需要對哪個接口進行 mock,就實現哪個), 名稱必須以Mock結尾 
2. 在client端的xml配置文件中,添加如下配置,增加一 個mock屬性指向創建的TestMock 
3. 模擬錯誤(設置 timeout),模擬超時異常,運行測試代碼即可訪問到TestMock這個類。當服務端故障解除 以后,調用過程將恢復正常 
服務端的類及實現類,以及配置文件,參考第一點的類及實現類以及配置文件,然后再客戶端的配置文件的加上mock,具體見如下截圖。
<!--聲明需要暴露的服務接口,指定版本號-->
<dubbo:reference id="gpHelloService" interface="com.gupaoedu.dubbo.IGpHello"
registry="zookeeper" version="1.1.1" timeout="1" cluster="failover"
mock="com.gupaoedu.dubbo.TestMock"/>
根據Mock機制實現步驟
首先我們再客戶端添加一個TestMock類,實現IGpHello接口,配置文件我已經添加好了,可以看到我這里的配置相對第一點客戶端的配置添加了幾個參數 timeout、failover、mock。這里主要是看mock和timeout配置,因為我們是要去驗證mock機制,而failover是集群容錯的配置,之所以我這里沒有將這個參數去掉,是因為確定這里他們不會有配置沖突,配置好之后,先發布服務端的服務,然后運氣客戶端的App.java.在控制台我們可以看到打印結果,系統繁忙,這個結果說明,我們設置1秒超時,客戶端遠程調用服務超時,報錯了,然后就走到了Mock里。

然后我們再驗證,將超時間加大,設置為100,再運行,此時就不會報錯,就會正常輸出Hello world,輸出結果如下

<!--聲明需要暴露的服務接口,指定版本號-->
<dubbo:reference id="gpHelloService" interface="com.gupaoedu.dubbo.IGpHello"
registry="zookeeper" version="1.1.1" timeout="100" cluster="failover"
mock="com.gupaoedu.dubbo.TestMock"/>

五、總結

好了,總結一下,整理了兩個晚上,沒有整理出我預想的效果,這篇文章主要是以一種開發文檔的形式簡單介紹了dubbo的多版本機制實現、主機綁定、集群容錯處理機制、以及服務降級處理。后續會介紹dubbo的SPI機制,他是dubbo一種核心機制,我也是剛學習dubbo源碼不久,到時候有問題忘大家指正。該篇文章也存在許多不足的地方,比如結構可能不是非常清晰,描述也可能不是非常通俗易懂,后續我會努力矯正,今天就到這了,太困了現在,不寫了睡覺。

 

歡迎掃碼關注我的微信公眾號,我會不定期的更新一些個人技術文章

  

  

  

  

  

  


免責聲明!

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



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