微服務路由

服務路由的應用場景

  • 分組調用。通常來說,爲了保證服務的高可用性,實現異地多活的需求,一個服務每每不止部署在一個數據中心,並且出於節省成本等考慮,有些業務可能不只在私有機房部署,還會採用公有云部署,甚至採用多家公有云部署。服務節點也會按照不一樣的數據中心分紅不一樣的分組,這時對於服務消費者來講,選擇哪個分組調用,就必須有相應的路由規則。java

  • 灰度發佈。在服務上線發佈的過程當中,通常須要先在一小部分規模的服務節點上先發布服務,而後驗證功能是否正常。若是正常的話就繼續擴大發布範圍;若是不正常的話,就須要排查問題,解決問題後繼續發佈。這個過程就叫做灰度發佈,也叫金絲雀部署。框架

  • 流量切換。在業務線上運行過程當中,常常會遇到一些不可抗力因素致使業務故障,好比某個機房的光纜被挖斷,或者發生着火等事故致使整個機房的服務都不可用。這個時候就須要按照某個指令,可以把原來調用這個機房服務的流量切換到其餘正常的機房。性能

  • 讀寫分離。對於大多數互聯網業務來講都是讀多寫少,因此在進行服務部署的時候,能夠把讀寫分開部署,全部寫接口能夠部署在一塊兒,而讀接口部署在另外的節點上。code

服務路由的規則

根據個人實踐經驗,服務路由主要有兩種規則:一種是條件路由,一種是腳本路由。router

1. 條件路由接口

條件路由是基於條件表達式的路由規則,如下面的條件路由爲例,我來給你詳細講解下它的用法。ip

condition://0.0.0.0/dubbo.test.interfaces.TestService?category=routers&dynamic=true&priority=2&enabled=true&rule=" + URL.encode(" host = 10.20.153.10=> host = 10.20.153.11")

這裏面「condition://」表明了這是一段用條件表達式編寫的路由規則,具體的規則是路由

host = 10.20.153.10 => host = 10.20.153.11

分隔符「=>」前面是服務消費者的匹配條件,後面是服務提供者的過濾條件。當服務消費者節點知足匹配條件時,就對該服務消費者執行後面的過濾規則。那麼上面這段表達式表達的意義就是IP爲「10.20.153.10」的服務消費者都調用IP爲「10.20.153.11」的服務提供者節點。部署

若是服務消費者的匹配條件爲空,就表示對全部的服務消費者應用,就像下面的表達式同樣。get

=> host != 10.20.153.11

若是服務提供者的過濾條件爲空,就表示禁止服務消費者訪問,就像下面的表達式同樣。

host = 10.20.153.10=>

下面我舉一些Dubbo框架中的條件路由,來給你講解下條件路由的具體應用場景。

  • 排除某個服務節點
=> host != 172.22.3.91

一旦這條路由規則被應用到線上,全部的服務消費者都不會訪問IP爲172.22.3.91的服務節點,這種路由規則通常應用在線上流量排除預發佈機以及摘除某個故障節點的場景。

  • 白名單和黑名單功能
host != 10.20.153.10,10.20.153.11 =>

這條路由規則意思是除了IP爲10.20.153.10和10.20.153.11的服務消費者能夠發起服務調用之外,其餘服務消費者都不能夠,主要用於白名單訪問邏輯,好比某個後臺服務只容許特定的幾臺機器才能夠訪問,這樣的話能夠機器控制訪問權限。

host = 10.20.153.10,10.20.153.11 =>

同理,這條路由規則意思是除了IP爲10.20.153.10和10.20.153.11的服務消費者不能發起服務調用之外,其餘服務消費者均可以,也就是實現了黑名單功能,好比線上常常會遇到某些調用方不論是出於有意仍是無心的不合理調用,影響了服務的穩定性,這時候能夠經過黑名單功能暫時予以封殺。

  • 機房隔離
host = 172.22.3.* => host = 172.22.3.*

這條路由規則意思是IP網段爲172.22.3.*的服務消費者,才能夠訪問同網段的服務節點,這種規則通常應用於服務部署在多個IDC,理論上同一個IDC內的調用性能要比跨IDC調用性能要好,應用這個規則是爲了實現同IDC就近訪問。

  • 讀寫分離
method = find*,list*,get*,is* => host =172.22.3.94,172.22.3.95
method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98

這條路由規則意思是find*、get*、is*等讀方法調用IP爲172.22.3.94和172.22.3.95的節點,除此之外的寫方法調用IP爲172.22.3.97和172.22.3.98的節點。對於大部分互聯網業務來講,每每讀請求要遠遠大於寫請求,而寫請求的重要性每每要遠遠高於讀請求,因此須要把讀寫請求進行分離,以免讀請求異常影響到寫請求,這時候就能夠應用這種規則。

2. 腳本路由

腳本路由是基於腳本語言的路由規則,經常使用的腳本語言好比JavaScript、Groovy、JRuby等。如下面的腳本路由規則爲例,我來給你詳細講解它的用法。

"script://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule=" + URL.encode("(function route(invokers) { ... } (invokers))")

這裏面「script://」就表明了這是一段腳本語言編寫的路由規則,具體規則定義在腳本語言的route方法實現裏,好比下面這段用JavaScript編寫的route()方法表達的意思是,只有IP爲10.20.153.10的服務消費者能夠發起服務調用。

function route(invokers){
  var result = new java.util.ArrayList(invokers.size());
  for(i =0; i < invokers.size(); i ++){
    if("10.20.153.10".equals(invokers.get(i).getUrl().getHost())){ 
       result.add(invokers.get(i));
    } 
  }
  return result; 
 } (invokers));

既然服務路由是經過路由規則來實現的,那麼服務消費者該如何獲取路由規則呢?

服務路由的獲取方式

根據個人實踐經驗,服務路由的獲取方式主要有三種:

  • 本地配置

顧名思義就是路由規則存儲在服務消費者本地上。服務消費者發起調用時,從本地固定位置讀取路由規則,而後按照路由規則選取一個服務節點發起調用。

  • 配置中心管理

這種方式下,全部的服務消費者都從配置中心獲取路由規則,由配置中心來統一管理。

  • 動態下發

經過服務治理平臺修改路由規則,服務治理平臺調用配置中心接口,把修改後的路由規則持久化到配置中心。由於服務消費者訂閱了路由規則的變動,因而就會從配置中心獲取最新的路由規則,按照最新的路由規則來執行。

通常來說,服務路由最好是存儲在配置中心中,由配置中心來統一管理。這樣的話,全部的服務消費者就不須要在本地管理服務路由,由於大部分的服務消費者並不關心服務路由的問題,或者說也不須要去了解其中的細節。經過配置中心,統一給各個服務消費者下發統一的服務路由,節省了溝通和管理成本。

但也不排除某些服務消費者有特定的需求,須要定製本身的路由規則,這個時候就適合經過本地配置來定製。

而動態下發能夠理解爲一種高級功能,它可以動態地修改路由規則,在某些業務場景下十分有用。好比某個數據中心存在問題,須要把調用這個數據中心的服務消費者都切換到其餘數據中心,這時就能夠經過動態下發的方式,向配置中心下發一條路由規則,將全部調用這個數據中心的請求都遷移到別的地方。

固然,這三種方式也能夠一塊兒使用,這個時候服務消費者的判斷優先級是本地配置>動態下發>配置中心管理。

相關文章
相關標籤/搜索