文章出處

隨著大數據時代的到來,分布式是解決大數據問題的一個主要手段,隨著越來越多的分布式的服務,如何在分布式的系統中對這些服務做協調變成了一個很棘手的問題。今天我們就來看看如何使用C# ,利用開源對分布式服務做協調。

在對分布式的應用做協調的時候,主要會碰到以下的應用場景:

  • 業務發現(service discovery)

找到分布式系統中存在那些可用的服務和節點

  • 名字服務 (name service)

通過給定的名字知道到對應的資源

  • 配置管理 (configuration management)

如何在分布式的節點中共享配置文件,保證一致性。

  • 故障發現和故障轉移 (failure detection and failover)

當某一個節點出故障的時候,如何檢測到并通知其它節點, 或者把想用的服務轉移到其它的可用節點

  • 領導選舉(leader election)

如何在眾多的節點中選舉一個領導者,來協調所有的節點

  • 分布式的鎖 (distributed exclusive lock)

如何通過鎖在分布式的服務中進行同步

  • 消息和通知服務 (message queue and notification)

如何在分布式的服務中傳遞消息,以通知的形式對事件作出主動的響應

Consul

Consul是用Go開發的分布式服務協調管理的工具,它提供了服務發現,健康檢查,Key/Value存儲等功能,并且支持跨數據中心的功能。consul提供的一些關鍵特性:

  • service discovery:consul通過DNS或者HTTP接口使服務注冊和服務發現變的很容易,一些外部服務,例如saas提供的也可以一樣注冊。
  • health checking:健康檢測使consul可以快速的告警在集群中的操作。和服務發現的集成,可以防止服務轉發到故障的服務上面。
  • key/value storage:一個用來存儲動態配置的系統。提供簡單的HTTP接口,可以在任何地方操作。
  • multi-datacenter:無需復雜的配置,即可支持任意數量的區域。

Consul基于HTTP的API可以方便的和各種語言進行綁定,C# 語言綁定https://github.com/PlayFab/consuldotnet

Consul在Cluster上的每一個節點都運行一個Agent,這個Agent可以使用Server或者Client模式。Client負責到Server的高效通信,相對為無狀態的。 Server負責包括選舉領導節點,維護cluster的狀態,對所有的查詢做出響應,跨數據中心的通信等等。

consul官網已經有編譯好的二進制包,支持各種平臺:win、linux等等,下載符合你平臺的軟件包:在這里,下載包:0.5.2_windows_386.zip。解壓完畢后只有一個consul文件。

D:\GitHub\consuldotnet\Consul.Test>consul

usage: consul [--version] [--help] <command> [<args>]

Available commands are:

agent Runs a Consul agent

configtest Validate config file

event Fire a new event

exec Executes a command on Consul nodes

force-leave Forces a member of the cluster to enter the "left" state

info Provides debugging information for operators

join Tell Consul agent to join cluster

keygen Generates a new encryption key

keyring Manages gossip layer encryption keys

leave Gracefully leaves the Consul cluster and shuts down

lock Execute a command holding a lock

maint Controls node or service maintenance mode

members Lists the members of a Consul cluster

monitor Stream logs from a Consul agent

reload Triggers the agent to reload configuration files

version Prints the Consul version

watch Watch for changes in Consul

consul安裝完畢后,agent就可以啟動了,agent可以運行在server或者client模式,每個數據中心至少有一個agent運行在server模式,一般建議是3或者5個server。部署單個server是非常不好的,因為在失敗場景中出現數據丟失是不可避免的。本文涵蓋的是創建一個新的數據中心,所有其他的agents都運行在client模式,這是一個非常輕量級的服務注冊進程,它會運行健康監測,并將查詢結果轉發到服務。agent必須運行在集群中的每一個節點上。

consul.exe agent -config-file test_config.json

我們先運行一個agent在server模式:

D:\GitHub\consuldotnet\Consul.Test> consul.exe agent -config-file test_config.json

==> WARNING: Bootstrap mode enabled! Do not enable unless necessary

==> WARNING: Windows is not recommended as a Consul server. Do not use in production.

==> WARNING: It is highly recommended to set GOMAXPROCS higher than 1

==> Starting Consul agent...

==> Starting Consul agent RPC...

==> Consul agent running!

Node name: 'GEFFZHANG-NB'

Datacenter: 'dc1'

Server: true (bootstrap: true)

Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)

Cluster Addr: 192.168.1.4 (LAN: 8301, WAN: 8302)

Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false

Atlas: <disabled>

 

==> Log data will now stream in as it occurs:

 

2015/08/09 09:14:48 [INFO] serf: EventMemberJoin: GEFFZHANG-NB 192.168.1.4

2015/08/09 09:14:48 [INFO] serf: EventMemberJoin: GEFFZHANG-NB.dc1 192.168.1.4

2015/08/09 09:14:48 [INFO] raft: Node at 192.168.1.4:8300 [Follower] entering Follower state

2015/08/09 09:14:48 [INFO] consul: adding server GEFFZHANG-NB (Addr: 192.168.1.4:8300) (DC: dc1)

2015/08/09 09:14:48 [INFO] consul: adding server GEFFZHANG-NB.dc1 (Addr: 192.168.1.4:8300) (DC: dc1)

2015/08/09 09:14:48 [ERR] agent: failed to sync remote state: No cluster leader

2015/08/09 09:14:50 [WARN] raft: Heartbeat timeout reached, starting election

2015/08/09 09:14:50 [INFO] raft: Node at 192.168.1.4:8300 [Candidate] entering Candidate state

2015/08/09 09:14:50 [DEBUG] raft: Votes needed: 1

2015/08/09 09:14:50 [DEBUG] raft: Vote granted. Tally: 1

2015/08/09 09:14:50 [INFO] raft: Election won. Tally: 1

2015/08/09 09:14:50 [INFO] raft: Node at 192.168.1.4:8300 [Leader] entering Leader state

2015/08/09 09:14:50 [INFO] consul: cluster leadership acquired

2015/08/09 09:14:50 [INFO] consul: New leader elected: GEFFZHANG-NB

2015/08/09 09:14:50 [INFO] raft: Disabling EnableSingleNode (bootstrap)

2015/08/09 09:14:50 [DEBUG] raft: Node 192.168.1.4:8300 updated peer set (2): [192.168.1.4:8300]

2015/08/09 09:14:50 [DEBUG] consul: reset tombstone GC to index 2

2015/08/09 09:14:50 [INFO] consul: member 'GEFFZHANG-NB' joined, marking health alive

2015/08/09 09:14:51 [INFO] agent: Synced service 'consul'

2015/08/09 09:16:03 [DEBUG] agent: Service 'consul' in sync

2015/08/09 09:17:30 [DEBUG] agent: Service 'consul' in sync

2015/08/09 09:18:38 [DEBUG] agent: Service 'consul' in sync

2015/08/09 09:19:47 [DEBUG] http: Request /v1/status/peers (0)

2015/08/09 09:19:52 [DEBUG] agent: Service 'consul' in sync

正如你看到的一樣,consul agent已經啟動了,并且打印了一些日志到終端上,從日志中可以看到我們的agent已經運行在server模式了,并且已經是整個集群的領導節點。而且,本地成員已經被標記為集群中的健康成員了。這時候你在另一個終端中運行consul members就可以看到整個集群中的成員了。這時候你只能看到你自己,因為我們的集群中還沒加入其他成員。

輸出已經顯示了你自己的節點信息,有地址信息、健康狀況、在集群中的角色、以及一些版本信息,如果要查看一些metadata,則可以加入-detailed標記

consul members命令輸出的信息是基于gossip協議產生的,并且最終一致的。

 

KV基本操作

Consul提供了一個簡單的K/V存儲系統,這可以用來動態獲取配置、進行服務協調、主節點選舉,其他開發人員能想到的build過程等等。

var client = new Client();

var kv = client.KV;

var key = GenerateTestKeyName();

var value = Encoding.UTF8.GetBytes("test");

var getRequest = kv.Get(key);

Assert.IsNull(getRequest.Response);

var pair = new KVPair(key)

{

Flags = 42,

Value = value

};

var putRequest = kv.Put(pair);

Assert.IsTrue(putRequest.Response);

getRequest = kv.Get(key);

var res = getRequest.Response;

Assert.IsNotNull(res);

Assert.IsTrue(StructuralComparisons.StructuralEqualityComparer.Equals(value, res.Value));

Assert.AreEqual(pair.Flags, res.Flags);

Assert.IsTrue(getRequest.LastIndex > 0);

var del = kv.Delete(key);

Assert.IsTrue(del.Response);

getRequest = kv.Get(key);

Assert.IsNull(getRequest.Response);

服務發現(Service Discovery)和健康檢查(Health Check)

Consul的另一個主要的功能是用于對分布式的服務做管理,用戶可以注冊一個服務,同時還提供對服務做健康檢測的功能。

服務定義:一個服務可以通過提供服務定義配置文件或者通過調用HTTP API來動態的增加、刪除、修改服務。

服務查詢:一旦agent啟動后,并且服務已經同步,我們就可以使用DNS或者HTTP API來進行查詢了。

服務升級:服務定義的升級可以通過先修改服務定義配置文件,然后給agent發送一個SIGHUP信號即可,這樣允許你在升級服務時,而不會產生agent宕機時間或者服務不可達。或者通過HTTP API接口來動態的增加、刪除、修改服務。

Consul支持三種Check的模式:

  • 調用一個外部腳本(Script),在該模式下,consul定時會調用一個外部腳本,通過腳本的返回內容獲得對應服務的健康狀態。
  • 調用HTTP,在該模式下,consul定時會調用一個HTTP請求,返回2XX,則為健康;429 (Too many request)是警告。其它均為不健康
  • 主動上報,在該模式下,服務需要主動調用一個consul提供的HTTP PUT請求,上報健康狀態。

C# API提供對應的接口

  • Client.Agent.Service
  • Client.Agent.Check

Consul的Health Check,通過調用腳本,HTTP或者主動上報的方式檢查服務的狀態,更為靈活,可以獲得等多的信息,但是也需要做更多的工作。

故障檢測(Failure Detection)

Consul提供Session的概念,利用Session可以檢查服務是否存活。對每一個服務我們都可以創建一個session對象,注意這里我們設置了ttl,consul會以ttl的數值為間隔時間,持續的對session的存活做檢查。對應的在服務中,我們需要持續的renew session,保證session是合法的。

var client = new Client();

var sessionRequest = client.Session.Create(new SessionEntry() { TTL = TimeSpan.FromSeconds(10) });

var id = sessionRequest.Response;

Assert.IsTrue(sessionRequest.RequestTime.TotalMilliseconds > 0);

Assert.IsFalse(string.IsNullOrEmpty(sessionRequest.Response));

var tokenSource = new CancellationTokenSource();

var ct = tokenSource.Token;

client.Session.RenewPeriodic(TimeSpan.FromSeconds(1), id, WriteOptions.Empty, ct);

tokenSource.CancelAfter(3000);

Task.Delay(3000, ct).Wait(ct);

var infoRequest = client.Session.Info(id);

Assert.IsTrue(infoRequest.LastIndex > 0);

Assert.IsNotNull(infoRequest.KnownLeader);

Assert.AreEqual(id, infoRequest.Response.ID);

Assert.IsTrue(client.Session.Destroy(id).Response);

這里注意,因為是基于ttl(最小10秒)的檢測,從業務中斷到被檢測到,至少有10秒的時延,對應需要實時響應的情景,并不適用。

領導選舉和分布式的鎖

這篇文檔介紹了如何利用Consul的KV存儲來實現Leader Election,利用Consul的KV功能,可以很方便的實現領導選舉和鎖的功能。

WEB UI

consul同樣也支持web界面,這個UI可以用來查看所有的服務和節點,所有的健康檢測和它們當前的狀態,讀取設置K/V系統的值。UI默認自動支持多datacenter。這些UI是靜態html你不需要單獨運行一個web服務器,consul agent本身可以配置一個web服務。

下載UI組件:WEB UI

        下載完成后是一個0.5.2_web_ui.zip壓縮文件,解壓后是一個dist目錄。然后添加-ui-dir參數和-client參數重新啟動agent。

D:\GitHub\consuldotnet\Consul.Test> consul.exe agent -config-file test_config.json -ui-dir=D:\GitHub\consuldotnet\Consul.Test\0.5.2_web_ui\dist

在瀏覽器中輸入http://127.0.0.1:8500,即可訪問UI了

有services、nodes、K/V、acl、datacenter的管理,很完善的一個系統了。

總結

Consul作為使用Go語言開發的分布式協調,對業務發現的管理提供很好的支持,他的HTTP API也能很好的和不同的語言綁定,并支持跨數據中心的應用。缺點是相對較新,適合喜歡嘗試新事物的用戶。

https://github.com/anurse/Consulate

https://github.com/geffzhang/Consul-IO-WindowsDemo

https://github.com/catwithboots/Hortlak

https://github.com/catwithboots/Orek

https://github.com/geffzhang/Pk.OrleansUtils

http://blog.csdn.net/u010246789/article/category/6286612 

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()