寫(xiě)在前面

          我們的系統(tǒng)可能因?yàn)檎诓渴?、服?wù)異常終止或者其他問(wèn)題導(dǎo)致系統(tǒng)處于非健康狀態(tài),這個(gè)時(shí)候我們需要知道系統(tǒng)的健康狀況,而
          健康檢查可以幫助我們快速確定系統(tǒng)是否處于正常狀態(tài)。一般情況下,我們會(huì)提供公開(kāi)的HTTP接口,用于專門(mén)化健康檢查。

          NET
          Core提供的健康檢查庫(kù)包括Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions和Microsoft.Extensions.Diagnostics.HealthChecks。這兩個(gè)庫(kù)共同為我們提供了最基礎(chǔ)的健康檢查的解決方案,后面擴(kuò)展的組件主要有下面幾個(gè),本文不作其他說(shuō)明。

          AspNetCore.HealthChecks.System
          AspNetCore.HealthChecks.Network
          AspNetCore.HealthChecks.SqlServer
          AspNetCore.HealthChecks.MongoDb
          AspNetCore.HealthChecks.Npgsql
          AspNetCore.HealthChecks.Redis
          AspNetCore.HealthChecks.AzureStorage
          AspNetCore.HealthChecks.AzureServiceBus
          AspNetCore.HealthChecks.MySql
          AspNetCore.HealthChecks.DocumentDb
          AspNetCore.HealthChecks.SqLite
          AspNetCore.HealthChecks.Kafka
          AspNetCore.HealthChecks.RabbitMQ
          AspNetCore.HealthChecks.IdSvr
          AspNetCore.HealthChecks.DynamoDB
          AspNetCore.HealthChecks.Oracle
          AspNetCore.HealthChecks.Uris

          源碼探究

          Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions是.NET
          Core健康檢查的抽象基礎(chǔ),從中我們可以看出這個(gè)庫(kù)的設(shè)計(jì)意圖。它提供了一個(gè)統(tǒng)一的接口IHealthCheck,用于檢查應(yīng)用程序中各個(gè)被監(jiān)控組件的狀態(tài),包括后臺(tái)服務(wù)、數(shù)據(jù)庫(kù)等。這個(gè)接口只有一個(gè)方法CheckHealthAsync,


          該方法有一個(gè)參數(shù)是HealthCheckContext,它表示當(dāng)前健康檢查執(zhí)行時(shí)所關(guān)聯(lián)的上下文對(duì)象,它的返回值HealthCheckResult表示當(dāng)前健康檢查結(jié)束后所產(chǎn)生的被監(jiān)控組件的運(yùn)行狀態(tài)。

          源碼如下所示:
          1: public interface IHealthCheck 2: { 3: Task<HealthCheckResult>
          CheckHealthAsync(HealthCheckContext context, CancellationToken
          cancellationToken =default); 4: }
          HealthCheckRegistration

          HealthCheckContext里面只有一個(gè)成員就是HealthCheckRegistration實(shí)例。

          而HealthCheckRegistration是一個(gè)相當(dāng)重要的對(duì)象,它體現(xiàn)了健康檢查需要關(guān)注和注意的地方,其內(nèi)部涉及到五個(gè)屬性,分別用于:

          * 標(biāo)識(shí)健康檢查名稱
          * 創(chuàng)建IHealthCheck實(shí)例
          * 健康檢查的超時(shí)時(shí)間(防止我們因?yàn)榻】禉z查而過(guò)多占用資源)
          * 失敗狀態(tài)標(biāo)識(shí)
          * 一個(gè)標(biāo)簽集合(可用于健康檢查過(guò)濾)

          這五個(gè)屬性的相關(guān)源碼如下:
          1: public Func<IServiceProvider, IHealthCheck> Factory 2: { 3: get =>
          _factory; 4: set 5: { 6: if (value == null) 7: { 8: throw new
          ArgumentNullException(nameof(value)); 9: } 10: 11: _factory = value; 12:
          } 13: } 14: 15: public HealthStatus FailureStatus { get; set; } 16: 17:
          public TimeSpan Timeout 18: { 19: get => _timeout; 20: set 21: { 22: if
          (value <= TimeSpan.Zero && value != System.Threading.Timeout.InfiniteTimeSpan)
          23: { 24: throw new ArgumentOutOfRangeException(nameof(value)); 25: } 26:
          27: _timeout = value; 28: } 29: } 30: 31: public string Name 32: { 33:
          get => _name; 34: set 35: { 36: if (value == null) 37: { 38: throw new
          ArgumentNullException(nameof(value)); 39: } 40: 41: _name = value; 42: }
          43:} 44: 45: public ISet<string> Tags { get; }
          ?

          HealthCheckResult

          HealthCheckResult是一個(gè)結(jié)構(gòu)體,可以看出這里更多的是基于承擔(dān)數(shù)據(jù)存儲(chǔ)和性能問(wèn)題的考量。

          HealthCheckResult用于表示健康檢查的相關(guān)結(jié)果信息,同樣的,通過(guò)該類,我們知道了健康檢查需要關(guān)注的幾個(gè)點(diǎn):

          * 組件的當(dāng)前狀態(tài)
          * 異常信息
          * 友好的描述信息(不管是異常還是正常)
          * 額外可描述當(dāng)前組件的鍵值對(duì),這是一個(gè)開(kāi)放式的屬性,方面我們記錄更多信息
          該類含有四個(gè)公共屬性,和三個(gè)方法,相關(guān)源碼如下:
          1: public struct HealthCheckResult 2: { 3: private static readonly
          IReadOnlyDictionary<string, object> _emptyReadOnlyDictionary = new Dictionary<
          string, object>(); 4: ? 5: public HealthCheckResult(HealthStatus status,
          string description = null, Exception exception = null, IReadOnlyDictionary<
          string, object> data = null) 6: { 7: Status = status; 8: Description =
          description; 9: Exception = exception; 10: Data = data ??
          _emptyReadOnlyDictionary; 11: } 12: ? 13: public IReadOnlyDictionary<string,
          object> Data { get; } 14: ? 15: public string Description { get; } 16: ? 17:
          public Exception Exception { get; } 18: ? 19: public HealthStatus Status {
          get; } 20: ? 21: public static HealthCheckResult Healthy(string description =
          null, IReadOnlyDictionary<string, object> data = null) 22: { 23: return new
          HealthCheckResult(status: HealthStatus.Healthy, description, exception:null,
          data); 24: } 25: ? 26: public static HealthCheckResult Degraded(string
          description =null, Exception exception = null, IReadOnlyDictionary<string,
          object> data = null) 27: { 28: return new HealthCheckResult(status:
          HealthStatus.Degraded, description, exception: exception, data); 29: } 30:
          31: public static HealthCheckResult Unhealthy(string description = null,
          Exception exception =null, IReadOnlyDictionary<string, object> data = null) 32:
          { 33: return new HealthCheckResult(status: HealthStatus.Unhealthy,
          description, exception, data); 34: } 35: }

          可以看出這個(gè)三個(gè)方法都是基于HealthStatus這個(gè)枚舉而創(chuàng)建不同狀態(tài)的HealthCheckResult實(shí)例,這個(gè)枚舉表達(dá)了健康檢查需要關(guān)注的幾種狀態(tài),健康、異常以及降級(jí)。

          HealthStatus的源碼如下:
          1: public enum HealthStatus 2: { 3: Unhealthy = 0, 4: ? 5: Degraded = 1,
          6:? 7: Healthy = 2, 8: }
          IHealthCheckPublisher

          健康檢查功能本質(zhì)上是一種輪詢功能,需要定期執(zhí)行,.NET Core
          抽象定期執(zhí)行的接口,即IHealthCheckPublisher,我們可以通過(guò)實(shí)現(xiàn)這個(gè)接口,并與我們自定義的定時(shí)功能相結(jié)合。

          同時(shí),作為一次健康檢查,我們還需要關(guān)注相關(guān)的健康檢查報(bào)告,那么我們需要關(guān)注那些點(diǎn)呢?

          * 額外可描述當(dāng)前組件的鍵值對(duì),這是一個(gè)開(kāi)放式的屬性,方面我們記錄更多信息
          * 友好的描述信息(不管是異常還是正常)
          * 組件的當(dāng)前狀態(tài)
          * 異常信息
          * 當(dāng)前這次檢查所耗費(fèi)的時(shí)間
          * 相關(guān)的標(biāo)簽信息
          HealthReportEntry表示單個(gè)健康檢查報(bào)告,HealthReport表示一組健康檢查報(bào)告。HealthReport內(nèi)部維護(hù)了一個(gè)
          HealthReportEntry的字典數(shù)據(jù),HealthReport源碼如下所示:
          1: public sealed class HealthReport 2: { 3: public
          HealthReport(IReadOnlyDictionary<string, HealthReportEntry> entries, TimeSpan
          totalDuration) 4: { 5: Entries = entries; 6: Status =
          CalculateAggregateStatus(entries.Values); 7: TotalDuration = totalDuration;
          8: } 9: ? 10: public IReadOnlyDictionary<string, HealthReportEntry> Entries {
          get; } 11: ? 12: public HealthStatus Status { get; } 13: ? 14: public
          TimeSpan TotalDuration { get; } 15: ? 16: private HealthStatus
          CalculateAggregateStatus(IEnumerable<HealthReportEntry> entries) 17: { 18:
          var currentValue = HealthStatus.Healthy; 19: foreach (var entry in entries)
          20: { 21: if (currentValue > entry.Status) 22: { 23: currentValue =
          entry.Status; 24: } 25: ? 26: if (currentValue == HealthStatus.Unhealthy)
          27: { 28: // Game over, man! Game over! 29: // (We hit the worst possible
          status, so there's no need to keep iterating) 30: return currentValue; 31: }
          32: } 33: ? 34: return currentValue; 35: } 36: }
          總結(jié)


          通過(guò)以上內(nèi)容,我們知道了,一個(gè)完整的健康檢查需要關(guān)注健康檢查上下文、健康狀態(tài)的維護(hù)、健康檢查結(jié)果、健康檢查報(bào)告,同時(shí),為了更好的維護(hù)健康檢查,我們可以將健康檢查發(fā)布抽象出來(lái),并與外部的定時(shí)器相結(jié)合,共同守護(hù)健康檢查程序。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點(diǎn)信息
          問(wèn)題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                欧美黄片在线免费看 | 日日躁夜夜躁天天躁av | 两个男的操一个女的 | 啊我cao死你个荡货 | 公交车后挺进老师 |