
.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
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)斷路器政策
斷路器策略允許 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
Dim circuitBreakerPolicy = Policy.Handle(Of HttpRequestException)().CircuitBreakerAsync(5, TimeSpan.FromMinutes(1))超時政策
超時政策處理服務在合理時間範圍內未響應的場景。 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
Dim timeoutPolicy = Policy.TimeoutAsync(30) ' 30 secondsBulkhead 隔離
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
Dim bulkheadIsolationPolicy = Policy.BulkheadAsync(10, 20) ' 10 concurrent actions, 20 queue slots回退政策
當所有其他方法均失敗時,回退政策可用於提供預設行為或替代值。
// 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)策略包裝
可以使用 PolicyWrap 靈活地結合多個政策:
// 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)入門
要開始使用 IronPDF 的 Polly,確保您已安裝 Visual Studio 並在 .NET Core 中建立一個新的控制台應用專案。 在 Visual Studio 中打開 NuGet 包管理器控制台並安裝 Polly 和 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");
}
}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讓我們通過一個實例展示如何使用 Polly 與 IronPDF 將 URL 轉換為 PDF。 假設我們有一個網路服務,由於瞬態故障時常失敗,我們希望使用 Polly 優雅地處理這些失敗。
首先,讓我們在 Program.cs 文件中導入必需的命名空間:
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接下來,我們將定義我們的政策。 在這個例子中,我們將使用重試和斷路器策略的組合來處理失敗:
// 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))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");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")在上述範例程式碼中,我們使用 WrapAsync 方法包裝我們的 retryPolicy 和 circuitBreakerPolicy。 這使我們可以按順序將多個政策應用於新請求。 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}");
}
}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在上述程式碼中,我們遍歷了一組測試 URL,並嘗試將每一個轉換為 PDF。 如果請求失敗,異常將被捕捉,並在控制台顯示適當的訊息。

結論
Polly 是實現 .NET Core 應用中的彈性和瞬態錯誤處理的強大而靈活的程式庫。 通過結合重試和斷路器等政策,開發者可以構建穩健且容錯的系統,以優雅地處理失敗。
在本教程中,我們探討了如何使用 Polly 與 IronPDF 將 URL 轉換為 PDF。 我們學習了如何定義和應用 Polly 策略,包括重試和斷路器。 我們還使用不同的 URL 測試了我們的策略。 我們也可以用 將 HTML 轉換為 PDF 的方法來實現。
IronPDF 提供 免費試用,授權以具競爭力的價格起售,讓您可以在專案中發揮其功能。

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


