跳至頁尾內容
開發者更新

.NET Core Polly(開發者的工作原理)

Polly 是一個 .NET 的彈性策略和瞬態錯誤處理程式庫,允許開發者表達彈性策略,例如重試策略、斷路器、超時、舷隔隔離策略和回退。 Polly 專注於 ASP.NET Core,使其成為 .NET Core 彈性策略的關鍵工具。 Polly 是執行緒安全的,並支持處理多個同時請求以成功回應。

本教程將提供有關瞬態錯誤處理 .NET 程式庫 Polly 的更多細節,以及如何在 ASP.NET Core 應用中與 IronPDF 一起使用它。 我們將深入探討 Polly 的每個方面,解釋斷路器模式的機制,討論舷隔隔離和超時,並展示如何以受控且執行緒安全的方式處理特定異常或失效服務的失敗回應。

Polly 策略

瞬態錯誤通常在您的應用企圖通過 HTTP 請求、資料庫或其他外部資源與 Web 服務連接時發生。 這些錯誤,如網路故障、暫時的連接問題或超時,是短暫的,並且通常在短時間內自動糾正。

Polly 透過應用不同的策略來管理這些瞬態錯誤,表達重試政策、先進的斷路器政策、超時政策、回退政策和舷隔隔離政策等策略。

重試政策

重試政策會自動使用重新嘗試邏輯重新嘗試失敗的並發請求。 它可以被配置為永遠重試,或者自動重試一定次數,也可以在重試之間等待設置的時間間隔或使用指數回退。

斷路器

斷路器政策允許您的系統在達到預設的失敗請求閾值後,嘗試特定服務時支持取消令牌。 斷路器策略類似於混沌工程或船關閉防水門以局部化損壞:一個故障不會讓整個船沉沒。

超時政策

超時政策強制執行特定 .NET 彈性程式碼的執行最大時間。 它有兩種型別:樂觀超時和悲觀超時。

回退政策

回退政策用於在失敗時提供替代值或行為。 當一個失效的服務不應該中止整個過程時,這個政策可能會很有用。

Bulkhead 隔離

Bulkhead 隔離用於限制可對特定操作進行的並發請求數量,從而限制可能的插槽耗盡並保持一個受控的執行槽數量。

快取策略

快取策略會將成功執行的回應快取下來,以便如果再次調用同一執行,Polly 可以返回已分發的快取值。

Policy Wrap

允許我們將多個政策包裝在一起,以便它們能夠作為單個單元運作。

建立和配置政策

重試政策

重試政策很簡單:當發生特定的異常或錯誤時,Polly 將嘗試再次執行基礎委託。 您可以定義重試的次數、重試之間的時間間隔,或者使用指數回退策略,否則會永遠重試。 以下是一個範例:

// Retry policy for handling HttpRequestException with exponential back-off
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), 
    (exception, timeSpan, retryCount, context) =>
    {
        // This is the OnRetry delegate, where you can log or monitor failed requests
        Console.WriteLine($"Retry {retryCount} after {timeSpan}. Exception: {exception.Message}");
    });
// Retry policy for handling HttpRequestException with exponential back-off
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), 
    (exception, timeSpan, retryCount, context) =>
    {
        // This is the OnRetry delegate, where you can log or monitor failed requests
        Console.WriteLine($"Retry {retryCount} after {timeSpan}. Exception: {exception.Message}");
    });
' Retry policy for handling HttpRequestException with exponential back-off
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetryAsync(3, Function(retryAttempt) TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), Sub(exception, timeSpan, retryCount, context)
	Console.WriteLine($"Retry {retryCount} after {timeSpan}. Exception: {exception.Message}")
End Sub)
$vbLabelText   $csharpLabel

斷路器政策

斷路器策略允許 Polly 程式庫監控錯誤,如果在指定期間內錯誤次數超過配置的閾值,電路將 '中斷',進一步的請求將被阻止指定的時間。這稱為"開"狀態。 在這段時間之後,電路進入"半開放"狀態,在此期間允許某些流量以檢查特定服務的健康狀況。如果這些請求成功且沒有錯誤發生,則電路會關閉; 否則,它將再次開啟。

// Circuit breaker policy to handle failing requests with open and half-open states
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreakerAsync(5, TimeSpan.FromMinutes(1));
// Circuit breaker policy to handle failing requests with open and half-open states
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreakerAsync(5, TimeSpan.FromMinutes(1));
' Circuit breaker policy to handle failing requests with open and half-open states
Dim circuitBreakerPolicy = Policy.Handle(Of HttpRequestException)().CircuitBreakerAsync(5, TimeSpan.FromMinutes(1))
$vbLabelText   $csharpLabel

超時政策

超時政策處理服務在合理時間範圍內未響應的場景。 Polly 提供兩種型別的超時:樂觀和悲觀。 樂觀超時在一個單獨的執行緒上工作,並通過一個 CancellationToken 取消基礎操作。 悲觀超時會阻止父執行緒,直到操作完成或超時時間過去。

// Timeout policy with a 30-second optimistic timeout
var timeoutPolicy = Policy.TimeoutAsync(30); // 30 seconds
// Timeout policy with a 30-second optimistic timeout
var timeoutPolicy = Policy.TimeoutAsync(30); // 30 seconds
' Timeout policy with a 30-second optimistic timeout
Dim timeoutPolicy = Policy.TimeoutAsync(30) ' 30 seconds
$vbLabelText   $csharpLabel

Bulkhead 隔離

Bulkhead Isolation 用於限制針對特定服務的並發操作數。它提供了一種隔離錯誤並防止其級聯的方式。 它還限制了我們對依賴項施加的負載。

// Bulkhead isolation policy to limit concurrency and queue length
var bulkheadIsolationPolicy = Policy.BulkheadAsync(10, 20); // 10 concurrent actions, 20 queue slots
// Bulkhead isolation policy to limit concurrency and queue length
var bulkheadIsolationPolicy = Policy.BulkheadAsync(10, 20); // 10 concurrent actions, 20 queue slots
' Bulkhead isolation policy to limit concurrency and queue length
Dim bulkheadIsolationPolicy = Policy.BulkheadAsync(10, 20) ' 10 concurrent actions, 20 queue slots
$vbLabelText   $csharpLabel

回退政策

當所有其他方法均失敗時,回退政策可用於提供預設行為或替代值。

// Fallback policy to provide a default result on failure
var fallbackPolicy = Policy
    .Handle<Exception>()
    .FallbackAsync<FallbackResult>(
        FallbackResult.SomethingWentWrong, 
        (exception, context) => 
        {
            Console.WriteLine($"Fallback triggered due to: {exception.Message}");
            return Task.CompletedTask;
        });
// Fallback policy to provide a default result on failure
var fallbackPolicy = Policy
    .Handle<Exception>()
    .FallbackAsync<FallbackResult>(
        FallbackResult.SomethingWentWrong, 
        (exception, context) => 
        {
            Console.WriteLine($"Fallback triggered due to: {exception.Message}");
            return Task.CompletedTask;
        });
' Fallback policy to provide a default result on failure
Dim fallbackPolicy = Policy.Handle(Of Exception)().FallbackAsync(Of FallbackResult)(FallbackResult.SomethingWentWrong, Function(exception, context)
			Console.WriteLine($"Fallback triggered due to: {exception.Message}")
			Return Task.CompletedTask
End Function)
$vbLabelText   $csharpLabel

策略包裝

可以使用 PolicyWrap 靈活地結合多個政策:

// Combining multiple policies using PolicyWrap
var policyWrap = Policy.WrapAsync(fallbackPolicy, retryPolicy, circuitBreakerPolicy, timeoutPolicy, bulkheadIsolationPolicy);
// Combining multiple policies using PolicyWrap
var policyWrap = Policy.WrapAsync(fallbackPolicy, retryPolicy, circuitBreakerPolicy, timeoutPolicy, bulkheadIsolationPolicy);
' Combining multiple policies using PolicyWrap
Dim policyWrap = Policy.WrapAsync(fallbackPolicy, retryPolicy, circuitBreakerPolicy, timeoutPolicy, bulkheadIsolationPolicy)
$vbLabelText   $csharpLabel

入門

要開始使用 IronPDF 的 Polly,確保您已安裝 Visual Studio 並在 .NET Core 中建立一個新的控制台應用專案。 在 Visual Studio 中打開 NuGet 包管理器控制台並安裝 PollyIronPDF 包:

Install-Package Polly
Install-Package IronPdf

使用 Polly 與 IronPDF 將 URL 轉換為 PDF

IronPDF 的一個顯著特點是其 HTML 到 PDF 功能,可確保佈局和樣式完好無損。 此功能將網頁內容轉換為 PDF,非常適合報告、發票和文件。 它支持將 HTML 文件、URL 和 HTML 字串轉換為 PDF。

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

讓我們通過一個實例展示如何使用 Polly 與 IronPDF 將 URL 轉換為 PDF。 假設我們有一個網路服務,由於瞬態故障時常失敗,我們希望使用 Polly 優雅地處理這些失敗。

首先,讓我們在 Program.cs 文件中導入必需的命名空間:

using System;
using System.Threading.Tasks;
using Polly;
using Polly.Wrap;
using IronPdf;
using System;
using System.Threading.Tasks;
using Polly;
using Polly.Wrap;
using IronPdf;
Imports System
Imports System.Threading.Tasks
Imports Polly
Imports Polly.Wrap
Imports IronPdf
$vbLabelText   $csharpLabel

接下來,我們將定義我們的政策。 在這個例子中,我們將使用重試和斷路器策略的組合來處理失敗:

// Retry policy with exponential backoff
var retryPolicy = Policy
    .Handle<Exception>()
    .WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(2 * i));

// Circuit breaker policy to block requests after consecutive failures
var circuitBreakerPolicy = Policy
    .Handle<Exception>()
    .CircuitBreakerAsync(2, TimeSpan.FromSeconds(30));
// Retry policy with exponential backoff
var retryPolicy = Policy
    .Handle<Exception>()
    .WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(2 * i));

// Circuit breaker policy to block requests after consecutive failures
var circuitBreakerPolicy = Policy
    .Handle<Exception>()
    .CircuitBreakerAsync(2, TimeSpan.FromSeconds(30));
' Retry policy with exponential backoff
Dim retryPolicy = Policy.Handle(Of Exception)().WaitAndRetryAsync(3, Function(i) TimeSpan.FromSeconds(2 * i))

' Circuit breaker policy to block requests after consecutive failures
Dim circuitBreakerPolicy = Policy.Handle(Of Exception)().CircuitBreakerAsync(2, TimeSpan.FromSeconds(30))
$vbLabelText   $csharpLabel

retryPolicy 將以指數回退策略重試失敗的請求最多三次,重試間隔為2秒、4秒和8秒。 circuitBreakerPolicy 將在30秒時間間隔內發生兩次連續失敗時打開電路。

現在,讓我們定義將 URL 轉換為 PDF 的 IronPDF 程式碼:

var htmlToPdf = new ChromePdfRenderer();
var pdfBytes = await retryPolicy
    .WrapAsync(circuitBreakerPolicy)
    .ExecuteAsync(async () =>
    {
        Console.WriteLine("Attempting to convert URL to PDF...");
        var result = await htmlToPdf.RenderUrlAsPdfAsync("https://example.com");
        Console.WriteLine("Conversion successful!");
        return result;
    });

pdfBytes.SaveAs("output.pdf");
var htmlToPdf = new ChromePdfRenderer();
var pdfBytes = await retryPolicy
    .WrapAsync(circuitBreakerPolicy)
    .ExecuteAsync(async () =>
    {
        Console.WriteLine("Attempting to convert URL to PDF...");
        var result = await htmlToPdf.RenderUrlAsPdfAsync("https://example.com");
        Console.WriteLine("Conversion successful!");
        return result;
    });

pdfBytes.SaveAs("output.pdf");
Dim htmlToPdf = New ChromePdfRenderer()
Dim pdfBytes = Await retryPolicy.WrapAsync(circuitBreakerPolicy).ExecuteAsync(Async Function()
		Console.WriteLine("Attempting to convert URL to PDF...")
		Dim result = Await htmlToPdf.RenderUrlAsPdfAsync("https://example.com")
		Console.WriteLine("Conversion successful!")
		Return result
End Function)

pdfBytes.SaveAs("output.pdf")
$vbLabelText   $csharpLabel

在上述範例程式碼中,我們使用 WrapAsync 方法包裝我們的 retryPolicycircuitBreakerPolicy。 這使我們可以按順序將多個政策應用於新請求。 ExecuteAsync 方法執行提供的委託,在此程式碼中為 IronPDF 的 RenderUrlAsPdfAsync 方法。

通過應用 Polly 策略,我們確保我們的程式碼能夠適應瞬態錯誤。 如果一個請求失敗,Polly 會根據重試政策自動再次嘗試。 如果連續失敗的次數超過預設的閾值,斷路器策略將打開電路,阻止進一步的請求一段時間。

Polly 策略的測試案例

為了測試我們的 Polly 策略的有效性,讓我們模擬一些失敗的請求。 將 URL 修改為不存在的端點,並新增一些測試案例:

var testUrls = new[]
{
    "https://ironpdf.com",
    "https://notexistingdomain.com/",
    "http://httpbin.org/delay/120"
};

foreach (var url in testUrls)
{
    try
    {
        var pdfBytes = await retryPolicy
            .WrapAsync(circuitBreakerPolicy)
            .ExecuteAsync(() => htmlToPdf.RenderUrlAsPdfAsync(url));

        pdfBytes.SaveAs($"{Guid.NewGuid()}.pdf");
        Console.WriteLine($"Successfully converted {url} to PDF.");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Failed to convert {url} to PDF: {ex.Message}");
    }
}
var testUrls = new[]
{
    "https://ironpdf.com",
    "https://notexistingdomain.com/",
    "http://httpbin.org/delay/120"
};

foreach (var url in testUrls)
{
    try
    {
        var pdfBytes = await retryPolicy
            .WrapAsync(circuitBreakerPolicy)
            .ExecuteAsync(() => htmlToPdf.RenderUrlAsPdfAsync(url));

        pdfBytes.SaveAs($"{Guid.NewGuid()}.pdf");
        Console.WriteLine($"Successfully converted {url} to PDF.");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Failed to convert {url} to PDF: {ex.Message}");
    }
}
Imports System

Dim testUrls = {
    "https://ironpdf.com",
    "https://notexistingdomain.com/",
    "http://httpbin.org/delay/120"
}

For Each url In testUrls
    Try
        Dim pdfBytes = Await retryPolicy _
            .WrapAsync(circuitBreakerPolicy) _
            .ExecuteAsync(Function() htmlToPdf.RenderUrlAsPdfAsync(url))

        pdfBytes.SaveAs($"{Guid.NewGuid()}.pdf")
        Console.WriteLine($"Successfully converted {url} to PDF.")
    Catch ex As Exception
        Console.WriteLine($"Failed to convert {url} to PDF: {ex.Message}")
    End Try
Next
$vbLabelText   $csharpLabel

在上述程式碼中,我們遍歷了一組測試 URL,並嘗試將每一個轉換為 PDF。 如果請求失敗,異常將被捕捉,並在控制台顯示適當的訊息。

.NET Core Polly (它如何為開發者運作):圖 1 - URL 到 PDF 輸出

結論

Polly 是實現 .NET Core 應用中的彈性和瞬態錯誤處理的強大而靈活的程式庫。 通過結合重試和斷路器等政策,開發者可以構建穩健且容錯的系統,以優雅地處理失敗。

在本教程中,我們探討了如何使用 Polly 與 IronPDF 將 URL 轉換為 PDF。 我們學習了如何定義和應用 Polly 策略,包括重試和斷路器。 我們還使用不同的 URL 測試了我們的策略。 我們也可以用 將 HTML 轉換為 PDF 的方法來實現。

IronPDF 提供 免費試用,授權以具競爭力的價格起售,讓您可以在專案中發揮其功能。

常見問題

什麼是 Polly,以及它如何增強 .NET Core 的韌性?

Polly 是一個為韌性和短暫故障處理而設計的 .NET 程式庫,特別適用於 ASP.NET Core 應用程式。它通過提供重試、斷路器、超時、隔艙隔離和回退等策略來增強韌性,確保系統穩健和容錯能力強。

如何在 .NET Core 中使用 Polly 實現重試政策?

在 .NET Core 中,您可以使用 Polly 來實現重試政策,透過配置自動重試失敗的請求。這可以通過設置重試次數和嘗試之間的時間間隔來實現,從而有效管理短暫故障。

斷路器政策如何防止 .NET 應用程式中的級聯故障?

Polly 的斷路器政策通過監控故障並在達到故障閾值時打開電路以阻止請求來防止級聯故障。這會阻止進一步的請求,直到電路重置,允許系統在接受新請求之前恢復。

隔艙隔離在管理資源耗盡方面發揮了什麼作用?

Polly 中的隔艙隔離通過限制一個服務的並發請求數來防止資源耗盡。此政策有助於控制故障並確保 .NET Core 應用程式內的資源管理高效。

Polly 的超時政策如何提高我的應用程式的回應能力?

Polly 的超時政策為操作強制設置最大執行時間,這有助於管理服務未能及時回應的場景。通過設定樂觀或悲觀的超時,開發者可以確保其應用程式保持回應能力。

Polly 是否能增強 URL 到 PDF 轉換的可靠性?

是的,Polly 可以通過將其重試和斷路器政策與 PDF 生成工具整合來增強 URL 到 PDF 轉換的可靠性。這樣確保轉換過程對短暫故障具有彈性,保持可靠性。

Polly 的回退政策如何確保服務優雅降級?

Polly 中的回退政策在服務失敗時提供替代回應或行為。這有助於確保故障不會停止整個應用程式,從而實現優雅降級並繼續運行。

如何在一個 .NET 應用程式中結合多個 Polly 政策?

在一個 .NET 應用程式中,您可以使用政策包裝來結合多個 Polly 政策。這允許開發者一起運行不同的韌性策略,使得故障處理方法更加全面靈活。

將 Polly 與 IronPDF 整合後如何處理 PDF 生成中的短暫故障?

通過將 Polly 與 IronPDF 整合,開發者可以在 PDF 生成期間通過重試和斷路器等政策來處理短暫故障。這種整合確保了即使在偶爾的服務中斷下,PDF 生成依然穩定可靠。

using Polly 與 .NET Core 時的一些常見故障排除策略有哪些?

常見的故障排除策略包括驗證政策配置,如重試間隔和斷路器閾值,並使用不同的場景測試策略,以確保正確處理故障和系統韌性。

Jacob Mellor,首席技術官 @ Team Iron
首席技術官

Jacob Mellor是Iron Software的首席技術官,一位在C# PDF技術上開創先河的遠見工程師。作為Iron Software核心程式碼庫的原開發者,他從創立以來就一直在塑造公司的產品架構,與首席執行官Cameron Rimington一起將公司轉變為服務於NASA、特斯拉和全球政府公司的50多名人員的公司。

Jacob擁有曼徹斯特大學的土木工程一等榮譽學士學位(BEng),於1998-2001年之間獲得。在1999年於倫敦創辦他的第一家軟體公司並於2005年建立了他的第一批.NET元組件後,他專注於解決Microsoft生態系統中的複雜問題。

他的旗艦IronPDF和Iron Suite .NET程式庫在全球獲得了超過3000萬次NuGet安裝依據,他的基礎程式碼基繼續支援著世界各地開發者使用的工具。擁有25年的商業經驗和41年的程式設計專業知識,他仍專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話