ServiceComb ServiceCenter 新的版本即將發佈,在此次發版中將帶來異構、多服務中心同步工具 Syncer,在這裏將從咱們的已有的實踐經驗出發,帶來對Syncer的介紹。
項目地址:https://github.com/apache/servicecomb-service-center/tree/master/syncerhtml
從傳統架構到微服務,爲了解決微服務之間動態變動帶來的問題,各微服務框架百花齊放,從而衍生出Service-center、eureka、consul等一系列服務中心;在雲環境大行其道的今天,公/私有云並存、混合雲部署在企業實踐中彷佛已成爲趨勢。在這過程當中不得不面臨一些問題:java
在最初的項目中,咱們應用了ServiceCenter的中心化解決方案 ServiceCenter Aggregate,詳細介紹請參考:https://github.com/apache/servicecomb-service-center/blob/master/docs/multidcs.md。在使用這樣的中心化解決方案後,異構服務中心的實例被同步到 Aggregate 中,服務只需指定服務發現地址到 Aggregate,便可實現對異構、跨區域實例的發現,同時也支持了微服務架構之間的平滑遷移。
通過一段時間的使用,集中式、中心化方案的不足逐漸顯現,因而便有了以下的思考:linux
針對以上的問題與思考,咱們帶來了無中心化的解決方案 Apche ServiceComb Syncer。Syncer是一個多服務中心的同步工具,專爲大型微服務架構設計,用於在網絡互通的狀況下,不一樣技術棧服務中心、跨區域的實例同步,將來將對跨網絡、跨雲等場景提供支持。git
Syncer以服務中心的伴生系統的形式而存在,主要負責從當前服務中心發現實例,並向網絡其餘成員進行廣播;接收其餘成員的廣播,並拉取實例信息向當前服務中心進行註冊。Syncer 有以下特色:github
下面咱們經過具體的業務流程來進一步瞭解 Syncer。golang
上圖左側綠色 SyncerN 是一個待加入網絡的成員。web
Syncer的同步流程同步流程並不複雜,下圖具體描述了兩個Syncer將不一樣服務中心的實例進行同步的過程。
適用場景spring
上圖左,兩套服務中心(ServiceCenter 和 Eureka)各自爲政,各自轄區的服務沒法跨越架構邊界,沒法發現對方服務實例,從而沒法進行通信。上圖右,兩套服務中心的實例將經過 Syncer 同步,在兩個服務中內心,最後都將呈現出全部的實例,服務之間無障礙發現,從而實現實例的共享通信。apache
syncer統一了同步數據結構 SyncData,並以插件的形式提供對各服務中心的支持,各服務中心只需實現實例數據與 SyncData 的轉換,便可完成異構服務中心數據的轉換。從而在架構遷移的過程當中,可使用 syncer 實現系統的逐步遷移,平穩過渡。json
在企業的發展道路中,常常會出現因爲某個核心服務使用了某個技術棧,致使與其對接的服務只能遷就,從而放棄更適合的選型。Syncer 支持異構同步的特性,能夠有效衝破這個限制,使業務選型聽從業務自己訴求。
下面咱們將經過一個異構服務中心同步的示例,從實踐出發進一步瞭解 Syncer。
示例代碼:https://github.com/apache/servicecomb-service-center/blob/master/syncer/samples/multi-servicecenters
本案例模擬了異構服務中心之間的通信場景,包括如下四個部分:
機器: 10.0.0.10
# 記錄當前目錄
$ project_dir=`pwd`
# 下載源碼
$ git clone https://github.com/apache/servicecomb-service-center.git
# 編譯 Syncer
$ cd servicecomb-service-center/syncer $ GO111MODULE=on go build
# 編譯 EurekaServer 和 AccountServer
$ cd samples/multi-servicecenters/eureka $ mvn clean install
文件位置:${project_dir}/servicecomb-service-center/syncer/samples/multi-servicecenters/eureka/eureka-server/src/main/resources/application.yaml
spring: application: name: eureka-server server: port : 8761 # servlet: # context-path: /eureka eureka: instance: hostname : 10.0.0.10 client: registerWithEureka : false fetchRegistry : false serviceUrl: defaultZone : http://${eureka.instance.hostname}:${server.port}/eureka/ management: endpoints: web: exposure: include: "*"
# 啓動 EurekaServer
$ cd ${project_dir}/servicecomb-service-center/syncer/samples/multi-servicecenters/eureka/eureka-server/ $ nohup mvn spring-boot:run & >> eureka-server.log 2>&1 &
瀏覽器打開http://10.0.0.10:8761,若出現以下頁面,則啓動成功
文件位置:${project_dir}/servicecomb-service-center/syncer/samples/multi-servicecenters/eureka/account-server/src/main/resources/application.yaml
spring: application: name: account-server server: port: 8090 eureka: instance: hostname: 10.0.0.10 client: service-url: defaultZone: http://${eureka.instance.hostname}:8761/eureka/ management: endpoints: web: exposure: include: "*"
#啓動 AccountServer
$ cd ${project_dir}/servicecomb-service-center/syncer/samples/multi-servicecenters/eureka/account-server $ mvn spring-boot:run#啓動 AccountServer $ cd ${project_dir}/servicecomb-service-center/syncer/samples/multi-servicecenters/eureka/account-server $ mvn spring-boot:run
# 出現以下字樣則爲成功
2019-09-19 17:20:35.534 INFO 20890 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path '' 2019-09-19 17:20:35.548 INFO 20890 --- [ main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8090 2019-09-19 17:20:35.551 INFO 20890 --- [ main] o.a.s.s.account.AccountApplication : Started AccountApplication in 3.92 seconds (JVM running for 6.754) 2019-09-19 17:20:35.617 INFO 20890 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_ACCOUNT-SERVER/10.0.0.10:account-server:8090 - registration status: 2042019-09-19 17:20:35.534 INFO 20890 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path '' 2019-09-19 17:20:35.548 INFO 20890 --- [ main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8090 2019-09-19 17:20:35.551 INFO 20890 --- [ main] o.a.s.s.account.AccountApplication : Started AccountApplication in 3.92 seconds (JVM running for 6.754) 2019-09-19 17:20:35.617 INFO 20890 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_ACCOUNT-SERVER/10.0.0.10:account-server:8090 - registration status: 204
此時打開http://10.0.0.10:8761,能夠看到AccountServer已經註冊成功
$ cd ${project_dir}/servicecomb-service-center/syncer $ ./syncer daemon --sc-addr http://10.0.0.10:8761/eureka --bind-addr 10.0.0.10:30190 --rpc-addr 10.0.0.10:30191 --sc-plugin=eureka
# 出現以下字樣則爲成功
2019-09-19T17:28:28.809+0800 INFO etcd/agent.go:55 start etcd success 2019-09-19T17:28:28.809+0800 INFO grpc/server.go:94 start grpc success 2019-09-19T17:28:28.809+0800 DEBUG server/handler.go:39 is leader: true 2019-09-19T17:28:28.809+0800 DEBUG server/handler.go:43 Handle Tick
機器: 10.0.0.11
# 記錄當前目錄
$ project_dir=`pwd`
# 下載源碼
$ git clone https://github.com/apache/servicecomb-service-center.git
# 編譯 Syncer
$ cd servicecomb-service-center/syncer $ GO111MODULE=on go build
# 編譯 HelloServer
$ cd samples/multi-servicecenters/servicecenter/hello-server/ $ GO111MODULE=on go build
$ cd ${project_dir}
# 下載 ServiceCenter 1.2.0版本包
$ curl -O https://mirrors.tuna.tsinghua.edu.cn/apache/servicecomb/servicecomb-service-center/1.2.0/apache-servicecomb-service-center-1.2.0-linux-amd64.tar.gz $ tar -zxvf apache-servicecomb-service-center-1.2.0-linux-amd64.tar.gz
文件位置:${project_dir}/apache-servicecomb-service-center-1.2.0-linux-amd64/conf/app.conf
frontend_host_ip = 10.0.0.11 frontend_host_port = 30103 ################################################################### # sever options ################################################################### # if you want to listen at ipv6 address, then set the httpaddr value like: # httpaddr = 2400:A480:AAAA:200::159 (global scope) # httpaddr = fe80::f816:3eff:fe17:c38b%eth0 (link-local scope) httpaddr = 10.0.0.11 httpport = 30100 # ...如下省略...
瀏覽器打開http://10.0.0.11:30103,若出現以下頁面,則啓動成功
文件位置:${project_dir}/servicecomb-service-center/syncer/samples/multi-servicecenters/servicecenter/hello-server/conf/microservice.yaml
service: # 微服務配置 appId: eureka # eureka 中同步的實例appID均爲:eureka name: hello-server version: 0.0.1 instance: # 實例信息 protocol: rest listenAddress: 10.0.0.11:8091 #實例監聽地址 provider: # 服務端信息 appId: eureka name: account-server version: 0.0.1 registry: address: http://10.0.0.11:30100
$ cd ${project_dir}/servicecomb-service-center/syncer/samples/multi-servicecenters/servicecenter/hello-server $ ./hello-server 2019-09-19T18:37:50.645+0800 DEBUG servicecenter/servicecenter.go:163 send heartbeat success 2019-09-19T18:37:50.645+0800 WARN servicecenter/servicecenter.go:85 discovery provider failed, appID = eureka, name = account-server, version = 0.0.1 2019-09-19T18:37:50.645+0800 INFO servicecenter/servicecenter.go:87 waiting for retry
此時打開http://10.0.0.11:30103,能夠看到HelloServer已經註冊成功
但因爲沒法發現屬於Eureka服務中心的AccountServer實例,HelloServer處於重試狀態
(注:重試次數爲3次,每次間隔30秒,因此咱們須要在90秒內完成後面的操做)
$ cd ${project_dir}/servicecomb-service-center/syncer $ ./syncer daemon --sc-addr http://10.0.0.11:30100 --bind-addr 10.0.0.11:30190 --rpc-addr 10.0.0.11:30191 --sc-plugin=servicecenter --join-addr 10.0.0.10:30190
# 出現如下內容則爲Syncer成功啓動,並同步了對方的實例
2019-09-19T18:44:35.536+0800 DEBUG server/handler.go:62 is leader: true 2019-09-19T18:44:35.536+0800 DEBUG server/handler.go:79 Receive serf user event 2019-09-19T18:44:35.536+0800 DEBUG serf/agent.go:130 member = xxxxxa, groupName = 0204d59328090c2f4449a088d4e0f1d8 2019-09-19T18:44:35.536+0800 DEBUG serf/agent.go:130 member = xxxxxb, groupName = 34f53a9520a11c01f02f58f733e856b3 2019-09-19T18:44:35.536+0800 DEBUG server/handler.go:97 Going to pull data from xxxxxb 10.0.0.10:30191 2019-09-19T18:44:35.536+0800 INFO grpc/client.go:76 Create new grpc connection to 10.0.0.10:30191 2019-09-19T18:44:35.538+0800 DEBUG servicecenter/servicecenter.go:87 create service success orgServiceID= account-server, curServiceID = 80784229255ec96d90353e3c041bdf3586fdbbae 2019-09-19T18:44:35.538+0800 DEBUG servicecenter/servicecenter.go:90 trying to do registration of instance, instanceID = 10.0.0.10:account-server:8090 2019-09-19T18:44:35.540+0800 DEBUG servicecenter/sync.go:63 Registered instance successful, instanceID = 78bca3e2daca11e99638fa163eca30e0
1.此時的HelloServer獲取實例成功,並調用了AccountServer的CheckHealth接口
2.分別打開Euraka和ServiceCenter的網頁,兩個服務中內心均包含了全部的實例信息
$ curl -X POST \ http://192.168.88.75:8091/login \ -H 'Content-Type: application/json' \ -d '{ "user":"Jack", "password":"123456" }' welcome Jack
HelloServer與AccountServer分別會打印以下的信息
AccountServer :
HelloServer:
ServiceComb Syncer在異構層面,目前已支持ServiceCenter、Eureka兩個服務中心,在後面的工做中將對接更多的生態,將增長對跨網絡的場景的支持。
以上就是今天對Syncer的介紹,後面會持續對Syncer的新特性進行分享,同時也歡迎感興趣的小夥伴加入咱們,一塊兒作些有意思的事情。