Tip: 此篇已加入.NET Core微服務基礎系列文章索引html
上一篇發佈以後,不少人點贊和評論,不勝惶恐,這一篇把上一篇沒有弄到的東西補一下,也算是給各位前來詢問的朋友的一些回覆吧。node
1、Consul服務註冊之配置文件方式
1.1 重溫Consul實驗集羣
這裏咱們有三個Consul Server節點,一個Consul Client節點,在Client節點上跑了兩個ClientService實例,分別佔用8810和8820端口。至於基於Ocelot的API網關服務,尚未實現,留到之後跟各位分享。這裏假設咱們已經啓動了這幾個節點,而且可以成功訪問這兩個ClientService實例(事先把實例啓動起來,能夠經過IIS,也能夠經過命令行啓動Kerstel服務器運行)。web
實例1:192.168.80.71:8810json
實例2:192.168.80.71:8820api
1.2 準備好json配置文件
這裏我準備了一個以下所示的JSON配置文件(eg.取名爲services_config.json),配置了兩個服務在裏邊:服務器
{ "services":[ { "id": "EDC_DNC_MSAD_CLIENT_SERVICE_01", "name" : "CAS Client Service", "tags": [ "urlprefix-/ClientService01" ], "address": "192.168.80.71", "port": 8810, "checks": [ { "name": "clientservice_check", "http": "http://192.168.80.71:8810/api/health", "interval": "10s", "timeout": "5s" } ] }, { "id": "EDC_DNC_MSAD_CLIENT_SERVICE_02", "name" : "CAS Client Service", "tags": [ "urlprefix-/ClientService02" ], "address": "192.168.80.71", "port": 8820, "checks": [ { "name": "clientservice_check", "http": "http://192.168.80.71:8820/api/health", "interval": "10s", "timeout": "5s" } ] } ] }
至於配置文件的含義,這裏再也不贅述,和上一篇在代碼中進行註冊的items一致。負載均衡
編輯完成後,咱們在Consul Client節點中新建一個文件夾,放入json配置文件,而後啓動/重啓Consul Client服務:curl
192.168.80.71>consul agent -bind 0.0.0.0 -client 192.168.80.71 -config-dir=C:\Server\Consul\config -data-dir=C:\Server\Consul\tempdata -node EDC.DEV.WebServer -join 192.168.80.100 分佈式
啓動以後,能夠看到Consul已經經過掃描配置文件,去註冊了這兩個ClientService的實例。微服務
1.3 經過WebUI查看服務情況
能夠看到,兩個ClientService實例已經成功註冊。
1.4 經過API進行服務發現
URL>192.168.80.100:8500/v1/catalog/service/CAS Client Service
能夠看到返回了兩個服務實例的信息,固然,這裏建議服務名仍是不要有空格爲好。此外,在服務發現的過程當中,會加以必定的負載均衡策略,從這兩個服務實例中選擇一個返回給服務消費端,好比:隨機、輪詢、加權輪詢、基於性能的最小鏈接數等等。關於這一塊,會在後面的API網關實踐中跟你們分享。
2、Consul集羣之Key/Value存儲
Consul除了能夠實現服務註冊和服務發現以外,還提供了強大的KV(Key/Value)存儲。咱們可使用Consul的分層KV存儲幹任何事情,好比:動態配置,特徵標記,協調,leader選舉等。KV存儲的API是基於http的。
2.1 查看全部KV
咱們能夠經過命令行在consul節點中進行查詢:
192.168.80.100>curl -v http://192.168.80.100:8500/v1/kv/?recurse
能夠看到,返回的是404 Not Found,可見如今木有一個Key/Value存儲項。
*.關於?recurse參數=>用來指定查看多個KV
固然咱們也能夠經過WebUI來查看和管理KV,以下圖所示,後續咱們都以Shell命令行來調用API,不會進行WebUI界面的調用。
2.2 新增KV
這裏假設咱們要配置一個視頻直播平臺的帳號:
192.168.80.100>curl -X PUT -d 'edisonchou' http://192.168.80.100:8500/v1/kv/web/vhallaccount
key:vhallaccount, value:edisonchou
添加後能夠經過以下命令調用接口查看這個Key的Value
192.168.80.100>curl http://192.168.80.100:8500/v1/kv/web/vhallaccount
*.因爲Consul的Value是通過Base64編碼的(主要是爲了容許非UTF-8的字符),因此這裏看到的是編碼後的結果。咱們能夠經過解碼獲得最終的Value值。
2.3 驗證KV是否同步
因爲咱們調用的是Leader節點進行的KV存儲,咱們想要驗證一下是否在另外兩個節點進行了同步,不然KV只存在一個節點達不到同步的效果。
192.168.80.101 節點:
192.168.80.102 節點:
能夠看到該key值已經在集羣中三個節點進行了同步。
2.4 編輯KV和刪除KV
編輯KV其實和添加KV徹底一致,以下所示:
192.168.80.100>curl -X PUT -d 'andyai' http://192.168.80.100:8500/v1/kv/web/vhallaccount
刪除KV主要用到HTTP DELETE
192.168.80.100>curl -X DELETE http://192.168.80.100:8500/v1/kv/web/vhallaccount
這裏再也不演示結果。
3、Consul服務告警之Watch機制
熔斷保護在Consul和Ocelot中都有實現,意思就是當一個服務不正常時(好比咱們的一個服務實例掛了,Consul的健康檢查機制檢測到了),應該給系統維護人員給以告警。在Consul中,服務告警也是經過配置文件來實現的。
3.1 添加watch.json配置文件
{ "watches": [ { "type": "checks", "handler_type": "http", "state": "critical", "http_handler_config": { "path": "http://192.168.80.71:9000/notice", "method": "POST", "timeout": "10s", "header": { "Authorization": [ "token" ] } } } ] }
*.有關watch的細節,請參考:https://www.consul.io/docs/agent/watches.html
這裏編輯完成以後,就能夠放到config目錄下了,後面重啓Consul Client Agent服務時會加載新的watches_config.json配置文件。
3.2 添加NoticeService服務
新寫一個ASP.NET Core WebAPI程序,其主要功能就是接受Consul POST過來的參數並調用方法發送電子郵件。
(1)Controller編寫
[Route("api/[controller]")] public class HomeController : Controller { public IConfiguration Configuration { get; } public HomeController(IConfiguration configuration) { Configuration = configuration; } [HttpPost("/notice")] public IActionResult Notice() { var bytes = new byte[10240]; var i = Request.Body.ReadAsync(bytes, 0, bytes.Length); var content = System.Text.Encoding.UTF8.GetString(bytes).Trim('\0'); EmailSettings settings = new EmailSettings() { SmtpServer = Configuration["Email:SmtpServer"], SmtpPort = Convert.ToInt32(Configuration["Email:SmtpPort"]), AuthAccount = Configuration["Email:AuthAccount"], AuthPassword = Configuration["Email:AuthPassword"], ToWho = Configuration["Email:ToWho"], ToAccount = Configuration["Email:ToAccount"], FromWho = Configuration["Email:FromWho"], FromAccount = Configuration["Email:FromAccount"], Subject = Configuration["Email:Subject"] }; EmailHelper.SendHealthEmail(settings, content); return Ok(); } }
再也不解釋這段代碼。
(2)SendHealthEmail方法編寫
public class EmailHelper { public static void SendHealthEmail(EmailSettings settings, string content) { try { dynamic list = JsonConvert.DeserializeObject(content); if (list != null && list.Count > 0) { var emailBody = new StringBuilder("健康檢查故障:\r\n"); foreach (var noticy in list) { emailBody.AppendLine($"--------------------------------------"); emailBody.AppendLine($"Node:{noticy.Node}"); emailBody.AppendLine($"Service ID:{noticy.ServiceID}"); emailBody.AppendLine($"Service Name:{noticy.ServiceName}"); emailBody.AppendLine($"Check ID:{noticy.CheckID}"); emailBody.AppendLine($"Check Name:{noticy.Name}"); emailBody.AppendLine($"Check Status:{noticy.Status}"); emailBody.AppendLine($"Check Output:{noticy.Output}"); emailBody.AppendLine($"--------------------------------------"); } var message = new MimeMessage(); message.From.Add(new MailboxAddress(settings.FromWho, settings.FromAccount)); message.To.Add(new MailboxAddress(settings.ToWho, settings.ToAccount)); message.Subject = settings.Subject; message.Body = new TextPart("plain") { Text = emailBody.ToString() }; using (var client = new SmtpClient()) { client.ServerCertificateValidationCallback = (s, c, h, e) => true; client.Connect(settings.SmtpServer, settings.SmtpPort, false); client.AuthenticationMechanisms.Remove("XOAUTH2"); client.Authenticate(settings.AuthAccount, settings.AuthPassword); client.Send(message); client.Disconnect(true); } } } catch(Exception ex) { Console.WriteLine(ex.Message); } }
這裏使用的是MailKit庫(支持.net core),能夠經過NuGet搜索並安裝,此外爲什麼接受的參數屬性是這些,你們能夠看看Consul官方文檔中watches頁中的checks類型,見下圖所示:
(3)發佈NoticeService到192.168.80.71服務器中,一樣也能夠加入Consul配置文件中:
發佈完成以後,重啓Consul Client節點(192.168.80.71)的Consul服務,能夠看到NoticeService也註冊成功:
3.3 測試服務告警
(1)手動在IIS中關閉一個ClientService服務,例如:這裏我關閉了ClientService.01
(2)查看自動發送的Email內容:從Email中咱們能夠知道哪一個Server節點的哪一個Service出了問題,而且能夠大概瞭解緣由(Check Output),這時咱們的系統維護人員就該起牀加班了。
*.須要注意的是確保你的虛擬機能夠訪問外網,否則是發佈出來Email的。
4.小結
本篇將上篇中遺留的內容進行了彌補,下篇將開始基於Ocelot+Polly的API網關服務實踐,敬請期待,我要睡了。
此外,今天是高考次日,也預祝各位高三學子高考成功,加油最後兩科!
參考資料
桂素偉,《Ocelot+Consul實踐》
卓一抗,《學習Consul》
陳沖,《Consul分佈式集羣搭建&簡單功能測試&故障恢復》