【Azure 應用服務】App Service 執行狀況健康檢查功能簡介 (Health check)

路邊兩盞燈發表於2021-08-04

通過Azure App Service門戶,啟用Health Check來監視應用服務的例項,當發現其中一個例項處於不健康(unhealthy)狀態時,通過重新路由(即把有問題的例項從負載均衡器中移除, Load Balancer)的方式把請求傳送到健康的例項上。並且如果不健康的例項一直存在問題,系統則會啟動一個新例項來替換不健康的這個例項。

This article uses Health check in the Azure portal to monitor App Service instances. Health check increases your application's availability by re-routing requests away from unhealthy instances, and replacing instances if they remain unhealthy.

應用服務計劃應該擴充套件到兩個或者更多的例項,以充分利用Health Check功能。並且應該是對應用的關鍵元件進行監控檢查。

Your App Service plan should be scaled to two or more instances to fully utilize Health check. The Health check path should check critical components of your application.

 

例如:如果應用依賴於資料庫和一個Message系統,那麼Health Check應該設定在需要與資料庫連線,Message系統連線的功能點。當應用關鍵元件出現異常時,通過返回500的狀態碼告訴Health Check表示當前例項的執行狀態為不健康(unhealthy)。

For example, if your application depends on a database and a messaging system, the Health check endpoint should connect to those components. If the application cannot connect to a critical component, then the path should return a 500-level response code to indicate the app is unhealthy.

【Azure 應用服務】App Service 執行狀況健康檢查功能簡介 (Health check)

 

 

Health Check 會做些什麼呢?

1)通過啟用Health Check功能時配置的請求URL,應用服務的所有例項將會每間隔1分鐘對該URL請求一次。

2)如果某一個例項在連續兩次或多次無法處理URL請求(響應狀態不在200 ~ 299 間),或者根本就無法響應URL的請求,則系統將判定這一個例項為不健康狀態並將其從請求路由表中刪除以便於不處理真正的業務請求。

3)當從路由表中移除後,Health check將繼續對這一個不健康的例項傳送請求,如果這個例項一直沒有成功響應,App Service將會重啟底層的VM,努力嘗試修復它並讓它正常工作。

4)如果這一個例項在一個小時內,一直都是unhealthy狀態,它將會被新的例項所取代。

5)此外,在向外擴充套件例項(新增新例項),App Service也會使用Health check中所配置的請求URL,確保當前例項已做好充分準備,正式接受真正業務請求。

注意:Health check不支援 302 重定向。 每小時最多更換一個例項,每個應用服務計劃每天最多更換三個例項。

 

啟用 Health Check

 【Azure 應用服務】App Service 執行狀況健康檢查功能簡介 (Health check)

  •  為了啟用Health Check,進入App Service的Azure 門戶頁面,然後選擇Health Check目錄
  •  選擇” 啟用 “按鈕,並輸入一個有效的URL,可以對應用的健康狀態起健康檢測的相對路徑,例如:/health  or /api/health
  •  點選” 儲存 “按鈕

 注意:Health Check啟用或更改會重啟當前應用程式。為了儘量減少對生產應用程式的影響,建議配置在Staging slots後,通過交換部署槽的方式釋出到生產。

 

Health Check的配置選項

為了修改預設的Health Check配置選項,可以在應用程式的設定(Application Setting)修改引數: WEBSITE_HEALTHCHECK_MAXPINGFAILURESWEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT

 

  • WEBSITE_HEALTHCHECK_MAXPINGFAILURES : 允許值為 2 ~10 。將例項視為unhealthy並將從負載均衡器中移除所需要滿足的失敗請求次數。例如,當設定為2時,例項將在2次ping失敗後被刪除(預設值為10)

 

  • WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT : 允許值為 0 ~ 100。預設情況下,一次將不超過一般的例項數從負載均衡器中移除,以避免壓倒剩餘的健康例項。例如,如果應用服務計劃擴充套件到四個例項並且三個不正常,則兩個將被排除。 另外兩個例項(一個健康和一個不健康)將繼續接收請求。 在所有例項都不健康的最壞情況下,不會排除任何例項。 將值修改為 0 到 100 之間,更高的值意味著將刪除更多不健康的例項(預設值為 50)。

 

Health Check的身份認證和安全

Health Check與應用服務的身份驗證和授權功能整合。 如果啟用了這些安全功能,則不需要其他設定。

如果使用的是自定義的身份驗證系統,則健康檢查路徑(Health Check Path)必須允許匿名訪問。

要保護 Health Check Endpoint,應該首先使用 IP 限制、客戶端證照或虛擬網路等功能來限制應用程式訪問。 可以通過要求傳入請求的 User-Agent 匹配 HealthCheck/1.0 來保護Health Check Endpoint。 User-Agent 不能被欺騙,因為請求已經被先前的安全功能保護了。

 

Health Check Metrics指標

啟用 App Service 的Health Check後,可以使用 Azure Monitor 監視站點的執行狀況。操作步驟如下:

【Azure 應用服務】App Service 執行狀況健康檢查功能簡介 (Health check)

 

常見問題

1: 如果應用程式在單個例項上執行會發生什麼?

如果應用程式僅擴充套件到一個例項並且變得不健康,它不會從負載均衡器中刪除,因為這會導致您的應用程式完全停機。 將兩個或更多例項擴充套件到兩個或更多例項,以獲得Health Check的重新路由優勢。 如果應用程式在單個例項上執行,仍然可以使用 Health check 的監控功能來跟蹤應用程式的健康狀況。

 

2: 為什麼健康檢查請求沒有顯示在前端日誌中?

Health Check請求在內部傳送到站點,因此該請求不會顯示在前端日誌中。這也意味著請求的來源為 127.0.0.1,因為它是在內部傳送的請求。可以在Health Check Path頁面的程式碼中新增日誌語句,以保留Health Check URL何時被 ping 的日誌。

 

3: Health Check請求是通過 HTTP 還是 HTTPS 傳送的?

當站點上啟用 HTTPS Only 時,Health Check請求將通過 HTTPS 傳送。否則,它們將通過 HTTP 傳送。

 

4: 如果在同一個應用服務計劃中有多個應用怎麼辦?

無論應用服務計劃中的其他應用如何(最多達到 WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT 中指定的百分比),執行狀況不佳的例項將始終從負載均衡器輪換中刪除。

當例項上的應用程式保持不健康狀態超過一小時時,僅當所有其他啟用Health Check的應用程式也處於不健康狀態時,才會更換該例項。未啟用Health Check的應用程式將不會被考慮在內。

例如:

假設您有兩個應用程式啟用了Health Check,稱為App A 和App B。它們在同一個應用服務計劃中,並且該計劃擴充套件到 4 個例項。

  • 如果 App A 在兩個例項上變得不健康,負載均衡器將停止向這兩個例項上的 App A 傳送請求。 假設 App B 是正常的(Healthy),請求仍會在這些例項上路由到 App B。
  • 如果 App A 在這兩個例項上保持不健康狀態超過一個小時,則只有當 App B 在這些例項上也不健康時,才會替換這些例項。 如果 App B 健康,則不會替換例項。

【Azure 應用服務】App Service 執行狀況健康檢查功能簡介 (Health check)

 注意:如果在同一個應用服務計劃下還有另外一個App Serice,它沒有啟用Health Check,則該例項將永遠不會因為Health Check功能而被替換。所以建議對重要的應用程式單獨部署在一個應用服務計劃中,並開啟Health Check。


5: 如果所有例項都不健康怎麼辦?

在應用程式的例項不正常的情況下,應用服務將從負載均衡器中刪除例項,最多可達 WEBSITE_HEALTHCHECK_MAXUNHEALTHYWORKERPERCENT 中指定的百分比。

在所有例項都不健康的最壞情況下,不會排除任何例項。

 

6: 測試Health Check的.Net程式碼 (設定Health Check Path為 /fail

建立一個預設的.NET Core API專案,在 Program.cs 檔案中替換預設的Host Builder方法。

  • 通過傳送一個/fail的請求,人為的設定請求返回為500。使得Health Check功能認為當前例項為不健康(unhealthy)
  • 在Host啟動的時候會自動生產一個GUID,用於標記當前例項。以便於在後續的驗證中跟蹤例項處理請求的行為或重啟動作
  • 啟用Health Check功能後,所以例項都會收到並處理 /fail 請求,返回500.  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace hellodotnetcore
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }


        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            //初始化當前Host例項時候隨機生成一個GUID,用於在此後的請求中判斷當前時候是否被標記為健康,非健康,回收。
            var instance = Guid.NewGuid();
            //firstFailure來記錄第一個失敗請求所進入當前例項的時間,firstFailure儲存在記憶體中
            DateTime? firstFailure = null;

            return Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                webBuilder.Configure(configureApp =>
                configureApp.Run(async context =>
                {
                    //當請求URL為fail時候,認為設定返回狀態為500,告訴App Service的Health Check功能,當前例項出現故障。
                    if (firstFailure == null && context.Request.Path.Value.ToLower().Contains("fail"))
                    {
                        firstFailure = DateTime.UtcNow;
                    }

                    if (firstFailure != null)
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "text/html; charset=utf-8";
                        await context.Response.WriteAsync(
                           $"當前例項的GUID為 {instance}.\n" +
                            $"這個例項最早出現錯誤的時間是 {firstFailure.Value}.\n\n" +
                            $"根據文件的描述 https://docs.microsoft.com/en-us/azure/app-service/monitor-instances-health-check, 如果一個例項在一直保持unhealthy狀態一小時,它將會被一個新例項所取代\n\n" +
                            $"According to https://docs.microsoft.com/en-us/azure/app-service/monitor-instances-health-check, \"If an instance remains unhealthy for one hour, it will be replaced with new instance.\".");
                    }
                    else
                    {
                        context.Response.StatusCode = 200;
                        context.Response.ContentType = "text/html; charset=utf-8";
                        await context.Response.WriteAsync($"當前例項的GUID為 {instance}.\n" +
                            $"此例項報告顯示一切工作正常.");
                    }
                })));



            //public static IHostBuilder CreateHostBuilder(string[] args) =>
            //    Host.CreateDefaultBuilder(args)
            //        .ConfigureWebHostDefaults(webBuilder =>
            //        {
            //            webBuilder.UseStartup<Startup>();
            //        });
        }
    }
}

在本地測試以上程式碼效果如下:

【Azure 應用服務】App Service 執行狀況健康檢查功能簡介 (Health check)

 

 

參考資料

Monitor App Service instances using Health check:https://docs.azure.cn/zh-cn/app-service/monitor-instances-health-check

相關文章