Edge Service是ServiceComb提供的JAVA網關服務。Edge Service做爲整個微服務系統對外的接口,向最終用戶提供服務,接入RESTful請求,轉發給內部微服務。Edge Service以開發框架的形式提供,開發者能夠很是簡單的搭建一個Edge Service服務,經過簡單的配置就能夠定義路由轉發規則。同時Edge Service支持強大的擴展能力,服務映射、請求解析、加密解密、鑑權等邏輯均可以經過擴展實現。前端
Edge Service自己也是一個微服務,需遵照全部微服務開發的規則。其自己能夠部署爲多實例,前端使用負載均衡裝置進行負載分發;也能夠部署爲主備,直接接入用戶請求。開發者能夠根據Edge Service承載的邏輯和業務訪問量、組網狀況來規劃。java
開發微服務網關react
搭建框架git
使用ServiceComb的內置Edge Service邊緣服務github
3步完成搭建微服務網關web
↓↓↓正則表達式
•配置依賴關係spring
在項目中加入edge-core的依賴,就能夠啓動Edge Service的功能。Edge Service在請求轉發的時候,會通過處理鏈,所以還能夠加入相關的處理鏈的模塊的依賴,下面的實例增長的負載均衡的處理鏈,這個是必須的。數據庫
•定義啓動類apache
和開發普通微服務同樣,能夠經過加載Spring的方式將服務拉起來。
•增長配置文件microservie.yaml
Edge Service自己也是一個微服務,遵循微服務查找的規則,本身也會進行註冊。注意APPLICAIONT_ID與須要轉發的微服務相同。在下面的配置中,指定了Edge Service監聽的地址,處理鏈等信息。其中auth處理鏈是DEMO項目中自定義的處理鏈,用於實現認證。同時auth服務自己,不通過這個處理鏈,至關於不鑑權。
定製路由規則
使用Edge Service的核心工做是配置路由規則。場景不一樣,規則也不一樣。 路由規則由一系列AbstractEdgeDispatcher組成。Edge Service提供了幾個常見的Dispatcher,經過配置便可啓用,若是這些Dispatcher不知足業務場景須要,還能夠自定義。
•使用DefaultEdgeDispatcher
DefaultEdgeDispatcher是一個很是簡單、容易管理的Dispatcher,使用這個Dispatcher,用戶不用動態管理轉發規則,應用於實際的業務場景很是方便,這個也是推薦的一種管理機制。它包含以下幾個配置項:
常見的這些配置項的示例及含義以下:
•[prefix=rest;withVersion=true;prefixSegmentCount=1]微服務xService提供的URL爲: /xService/v1/abc,經過Edge訪問的地址爲/rest/xService/v1/abc,請求只轉發到[1.0.0-2.0.0)版本的微服務實例。
•[prefix=rest;withVersion=true;prefixSegmentCount=2]微服務xService提供的URL爲: /v1/abc,經過Edge訪問的地址爲/rest/xService/v1/abc,請求只轉發到[1.0.0-2.0.0)版本的微服務實例。
•[prefix=rest;withVersion=true;prefixSegmentCount=3]微服務xService提供的URL爲: /abc,經過Edge訪問的地址爲/rest/xService/v1/abc,請求只轉發到[1.0.0-2.0.0)版本的微服務實例。
•[prefix=rest;withVersion=false;prefixSegmentCount=1]微服務xService提供的URL爲: /xService/v1/abc,經過Edge訪問的地址爲/rest/xService/v1/abc,請求可能轉發到任意微服務實例。•[prefix=rest;withVersion=false;prefixSegmentCount=2]微服務xService提供的URL爲: /v1/abc,經過Edge訪問的地址爲/rest/xService/v1/abc,,請求可能轉發到任意微服務實例。
•[prefix=rest;withVersion=false;prefixSegmentCount=2]微服務xService提供的URL爲: /abc,經過Edge訪問的地址爲/rest/xService/abc,,請求可能轉發到任意微服務實例。
withVersion配置項提供了客戶端灰度規則,可讓客戶端指定訪問的服務端版本。Edge Service還包含根據接口兼容性自動路由的功能,請求會轉發到包含了該接口的實例。假設某微服務,兼容規劃爲全部高版本必須兼容低版本,部署瞭如下版本實例:
1.0.0,提供了operation1
1.1.0,提供了operation一、operation2
Edge Service在轉發operation1時,會自動使用1.0.0+的規則來過濾實例
Edge Service在轉發operation2時,會自動使用1.1.0+的規則來過濾實例
以上過程用戶沒必要作任何干預,全自動完成,以免將新版本的operation轉發到舊版本的實例中去。
•使用URLMappedEdgeDispatcher
URLMappedEdgeDispatcher容許用戶配置URL和微服務的映射關係。使用它能夠很是靈活的定義哪些URL轉發到哪些微服務。它包含以下幾個配置項:
businessV1配置項表示的含義是將請求路徑爲/usr/business/v1/.的請求,轉發到business這個微服務,而且只轉發到版本號爲1.0.0-2.0.0的實例(不含2.0.0)。轉發的時候URL爲/business/v1/.。path使用的是JDK的正則表達式,能夠查看Pattern類的說明。prefixSegmentCount表示前綴的URL Segment數量,前綴不包含在轉發的URL路徑中。
有三種形式的versionRule能夠指定。2.0.0-3.0.0表示版本範圍,含2.0.0,但不含3.0.0;2.0.0+表示大於2.0.0的版本,含2.0.0;2.0.0表示只轉發到2.0.0版本。2,2.0等價於2.0.0。從上面的配置能夠看出,URLMappedEdgeDispatcher也支持客戶端灰度。固然配置項會比DefaultEdgeDispatcher多。URLMappedEdgeDispatcher支持經過配置中心動態的修改配置,調整路由規則。
•自定義Dispatcher
自定義Dispatcher包含兩個步驟:
1.實現AbstractEdgeDispatcher
2.經過SPI發佈:增長文件META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher,並寫入實現類
詳細的代碼細節能夠參考下面的章節"DEMO功能說明"。開發者也能夠參考DefaultEdgeDispatcher等代碼來定義本身的Dispatcher。
•進行認證鑑權和其餘業務處理
經過Edge Servie工做流程能夠看出,能夠經過多種方式來擴展Edge Service的功能,包括Dispatcher、HttpServerFilter、Handler、HttpClientFilter等。比較經常使用和簡單的是經過Handler來擴展。DEMO裏面展現瞭如何經過Handler擴展來實現鑑權。詳細的代碼細節能夠參考下面的章節"DEMO功能說明"。
工做原理
工做流程
Edge Service的工做流程以下
藍色背景部分在Eventloop線程中執行,黃色背景部分:
•若是工做於reactive模式,則直接在Eventloop線程執行
•若是工做於線程池模式,則在線程池的線程中執行
工做模式
reactive (默認)
Edge Service默認工做於高性能的reactive模式,此模式要求工做於Edge Service轉發流程中的業務代碼不能有任何的阻塞操做,包括不限於:
•遠程同步調用,好比同步查詢數據庫、同步調用微服務,或是同步查詢遠程緩存等等
•任何的sleep調用
•任何的wait調用
•超大的循環
Edge Service的底層是基於netty的vertx,以上約束便是netty的reactive模式約束。
線程池
若是業務模型沒法知足reactive要求,則須要使用線程池模式。
此時須要在Edge Service的microservice.yaml中配置:
這裏的servicecomb.executor.groupThreadPool是ServiceComb內置的默認線程池對應的spring bean的beanId;業務能夠定製本身的線程池,並聲明爲一個bean,其beanId也能夠配置到這裏。
DEMO功能說明
請參考github上的edge service demo:
https://github.com/ServiceComb/ServiceComb-Java-Chassis/tree/master/demo/demo-edge
該demo包含如下工程:
authentication:微服務:鑑權服務器
edge-service
hiboard-business-1.0.0微服務:business,1.0.0版本,operation add
hiboard-business-1.1.0微服務:business,1.1.0版本,operation add/dec
hiboard-business-2.0.0微服務:business,2.0.0版本,operation add/dec
hiboard-consumer做爲一個普通的httpclient,而不是servicecomb consumer
hiboard-model非微服務,僅僅是一些公共的model
經過edge-service訪問微服務business的不一樣版本,並確認是由正確的實例處理的。
1.註冊Dispatcher
實現接口org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher,或從org.apache.servicecomb.edge.core.AbstractEdgeDispatcher繼承,實現本身的dispatcher功能。
實現類經過java標準的SPI機制註冊到系統中去。
Dispatcher須要實現2個方法:
•getOrder
Dispatcher須要向vertx注入路由規則,路由規則之間是有優先級順序關係的。
系統中全部的Dispatcher按照getOrder的返回值按從小到大的方式排序,按順序初始化。
若是2個Dispatcher的getOrder返回值相同,則2者的順序不可預知。
•init
init方法入參爲vertx框架中的io.vertx.ext.web.Router,須要經過該對象實現路由規則的定製。
能夠指定知足要求的url,是否須要處理cookie、是否須要處理body、使用哪一個自定義方法處理收到的請求等等
更多路由規則細節請參考vertx官方文檔:vertx路由機制https://vertx.io/docs/vertx-web/java/#_routing_by_exact_path
提示:
多個Dispatcher能夠設置路由規則,覆蓋到相同的url。
假設Dispatcher A和B均可以處理同一個url,而且A優先級更高,則:
•若是A處理完,既沒應答,也沒有調用RoutingContext.next(),則屬於bug,本次請求掛死了
•若是A處理完,而後調用了RoutingContext.next(),則會將請求轉移給B處理
2.轉發請求
註冊路由時,指定了使用哪一個方法來處理請求(下面使用onRequest來指代該方法),在onRequest中實現轉發邏輯。
方法原型爲:
系統封裝了org.apache.servicecomb.edge.core.EdgeInvocation來實現轉發功能,至少須要準備如下參數:
•microserviceName,業務自行制定規則,能夠在url傳入,或是根據url查找等等
•context,即onRequest的入參
•path,轉發目標的url
•httpServerFilters,Dispatcher父類已經初始化好的成員變量
edgeInvoke調用內部,會做爲ServiceComb標準consumer去轉發調用。
做爲標準consumer,意味着ServiceComb全部標準的治理能力在這裏都是生效的。
3.設置兼容規則
不一樣的業務可能有不一樣的兼容規劃,servicecomb默認的兼容規則,要求全部新版本兼容舊版本。若是知足這個要求,則沒必要作任何特殊的設置。
還有一種典型的規劃:
1.0.0-2.0.0內部兼容,url爲/microserviceName/v1/….的形式
2.0.0-3.0.0內部兼容,url爲/microserviceName/v2/….的形式
……
各大版本之間不兼容
此時,開發人員須要針對EdgeInvocation設置兼容規則:
versionMapper的做用是將v1或是v2這樣的串,轉爲1.0.0-2.0.0或2.0.0-3.0.0這樣的兼容規則。
注意:
接口不兼容會致使很是多的問題。java chassis要求高版本服務兼容低版本服務,只容許增長接口不容許刪除接口。在增長接口後,必須增長微服務的版本號。在開發階段,接口變動頻繁,開發者每每忘記這個規則。當這個約束被打破的時候,須要清理服務中心微服務的信息,並重啓微服務和Edge Service(以及依賴於該微服務的其餘服務)。不然可能出現請求轉發失敗等狀況。
4.鑑權
Edge Service是系統的邊界,對於不少請求須要執行鑑權邏輯。
基於標準的ServiceComb機制,能夠經過handler來實現這個功能。
最簡單的示意代碼以下:
Auth表示是鑑權微服務提供的接口,Invoker.createProxy("auth", "auth", Auth.class)是透明RPC開發模式中consumer的底層api,與@ReferenceRpc是等效,只不過不須要依賴spring bean機制。
Auth接口徹底由業務定義,這裏只是一個示例。
Handler開發完成後,配置到edge service的microservice.yaml中:
這個例子,表示轉發請求給全部的微服務都必須通過鑑權,可是調用鑑權微服務時不須要鑑權。
文末小結
本文向社區讀者從使用角度闡述了使用Edge Service作邊緣服務。
咱們也很是歡迎愛好者們向社區提問和貢獻代碼。
下章咱們將介紹ServiceComb+Zipkin使用篇。
若是在閱讀代碼時有任何疑問想交流,歡迎掃碼加入進微信羣。
期待志同道合的朋友們加入
ServiceComb的大門爲大家敞開~
用心作開源,不忘初衷
前期閱讀: