做者:little-cuijava
ServiceComb提供了一套包含代碼框架生成,服務註冊發現,負載均衡,服務可靠性(容錯熔斷,限流降級,調用鏈追蹤)等功能的微服務框架。
git
他包含如下三個組件github
1. 註冊中心ServiceCenter: 負責服務註冊發現 https://github.com/apache/incubator-servicecomb-service-centerapache
2. java chassis:java語言編程框架 https://github.com/apache/incubator-servicecomb-java-chassis編程
3. saga: 分佈式事務 https://github.com/apache/servicecomb-sagabootstrap
Service center使用ETCD做爲存儲,上層封裝以微服務管理爲核心的API後端
可是隨着容器,容器平臺等技術的興起,ServiceCenter須要進行架構演進以支持更加複雜的場景,讓我看下如下場景bash
假設你開發了一套SaaS系統,你有些機器是裸金屬跑在本身的機房,有些機器跑在雲上的kubernetes容器平臺。網絡
ConsumerB 由go chassis開發,他們會擁有元數據,好比infra,size等。有些微服務跑在容器裏,有些跑在裸金屬中架構
請求經過API gateway(若是由go chassis開發gw,則ConsumerB能夠省略) 進入到惟一的入口ConsumerB, ConsumerB根據請求的特徵,也就是header來決定該路由到哪一個微服務中
對於付費用戶的請求,能夠轉給性能較高的裸金屬中運行的微服務。而對於一些試用用戶,則轉向k8s環境中,只消耗1核的容器中。
以上場景Service Center是沒法支持的,由於微服務數據都在kubernetes etcd當中,service center只能收到裸金屬中運行的微服務的註冊信息。
爲了可以支持異構的基礎設施,而且使開發者更容易開發出異地多活的分佈式系統進行了一次技術演進
如今使用ServiceComb開發的微服務已經支持多數據中心服務發現,這個特性主要是依賴於服務管理中心ServiceCenter的多註冊中心Adaptor架構設計。
從圖中能夠知,ServiceCenter實現了多種註冊中心的Adaptor,如基於客戶端註冊的etcd和基於平臺註冊的kubernetes;其中也包括ServiceCenter自身。ServiceCenter會將配置中聲明的Adaptor類型(聲明方式下面會詳述)找到對應的實現類,並註冊到Aggregator中,Aggregator按期(默認30秒)經過這些類的實例的discovery接口拉取已註冊的微服務實例信息。這樣設計的好處是方便擴展各種註冊中心的Adaptor,方式就是實現discovery接口便可。另外一個好處就是Adaptor能夠按配置屢次被實例化,也就是支持同時接入不一樣的註冊中心,ServiceCenter支持多數據中心服務發現的特性也正是依賴這一點實現的。
每一個數據中心會部署一套ServiceCenter集羣,且集羣的每一個實例配置中會聲明該集羣的別名和各個數據中心ServiceCenter集羣完整的地址列表,下面是一個例子:
Cluster | Datacenter | Address |
---|---|---|
sc-1-1 | dc-1 | 10.12.0.1 |
sc-1-2 | dc-1 | 10.12.0.2 |
sc-2-1 | dc-2 | 10.12.1.1 |
sc-2-2 | dc-2 | 10.12.1.2 |
sc-3-1 | dc-3 | 10.12.2.1 |
sc-3-2 | dc-3 | 10.12.2.2 |
咱們假設在三個數據中心dc-1/2/3中分別部署一套ServiceCenter集羣(高可靠)sc-1/2/3,並使得註冊到本數據中心的ServiceCenter的微服務能夠發現並調用其它數據中心的微服務,固然,前提是數據中心之間的網絡是互通的。
以配置一個數據中心的ServiceCenter爲例,打開編輯ServiceCenter程序目錄下conf/app.conf
# 服務監聽地址
httpaddr = 10.12.0.1
# 配置服務發現的插件類型
discovery_plugin = aggregate
# 註冊etcd和ServiceCenter兩種服務發現機制
aggregate_mode = "etcd,servicecenter"
# 配置服務註冊的插件類型
registry_plugin = etcd
# 當前集羣名稱後端註冊中心的訪問地址
manager_name = "sc-1"
manager_addr = "${ETCD_CLIENT_URLS}"
manager_cluster = "sc-1=http://10.12.0.1:30100,http://10.12.0.1:30100,sc-2=http://10.12.1.1:30100,http://10.12.1.1:30100,sc-3=http://10.12.2.1:30100,http://10.12.2.1:30100"
# 自動拉取實例週期
auto_sync_interval = 30s複製代碼
這裏解釋一下上述配置,aggregate_mode
會讓Aggregator建立etcd adaptor和servicecenter adaptor實例,etcd adaptor主要是讓ServiceCenter支持本數據中心的微服務使用客戶端註冊方式接入,而servicecenter adaptor主要是拉取其它數據中心的ServiceCenter集羣的微服務實例信息;manager_addr
指明etcd的訪問地址;manager_cluster
指明各個數據中心ServiceCenter集羣的完整地址列表。
httpaddr
,manager_name
,manager_addr
配置便可。scctl --addr http://10.12.0.1:30100 get cluster
# CLUSTER | ENDPOINTS
# +---------+-------------------------+
# sc-1 | http://10.12.0.1:30100
# | http://10.12.0.2:30100
# sc-2 | http://10.12.1.1:30100
# ...複製代碼
這裏演示了一個很簡單的例子,例子引用的微服務均爲微服務開發框架go-chassis
中的example
。
Microservice | Datacenter | Address |
---|---|---|
Client | dc-1 | 10.12.0.3 |
Server | dc-2 | 10.12.1.3 |
咱們假設微服務Client部署到數據中心dc-1,Server部署到數據中心dc-2中。
打開編輯配置文件
vi examples/discovery/server/conf/chassis.yaml複製代碼
修改以下
cse:
service:
registry:
type: servicecenter
address: http://10.12.1.1:30100 # the address of SC in dc-2複製代碼
運行
go run examples/discovery/server/main.go複製代碼
打開編輯配置文件
vi examples/discovery/client/conf/chassis.yaml複製代碼
修改以下
cse:
service:
registry:
type: servicecenter
address: http://10.12.0.1:30100 # the address of SC in dc-1複製代碼
運行
go run examples/discovery/client/main.go複製代碼
因爲Client微服務沒有暴露外部訪問接口,因此這裏咱們只須要檢查它的調用日誌便可。
2018-09-29 10:30:25.556 +08:00 INFO registry/bootstrap.go:69 Register [Client] success
...
2018-09-29 10:30:25.566 +08:00 WARN servicecenter/servicecenter.go:324 55c783c5c38e11e8951f0a58ac00011d Get instances from remote, key: default Server
2018-09-29 10:30:25.566 +08:00 INFO client/client_manager.go:86 Create client for highway:Server:127.0.0.1:8082
...
2018/09/29 10:30:25 AddEmploy ------------------------------ employList:<name:"One" phone:"15989351111" > 複製代碼
觀察日誌咱們能夠知道,部署在不一樣的數據中心的微服務相互發現和相互調用。
更多高級特性,可參考文檔