フッターコンテンツにスキップ
.NETヘルプ

.NET Core Polly (開発者向けの仕組み)

Pollyは、開発者がリトライポリシー、サーキットブレーカ、タイムアウト、バルクヘッド分離ポリシー、フォールバックなどのレジリエンスポリシーを表現できる.NETのレジリエンス戦略と一時的なフォルトハンドリングライブラリです。 PollyはASP.NET Coreを対象としており、.NET Coreのレジリエンスに不可欠なツールです。 Pollyはスレッドセーフで、複数の同時要求を成功した応答で処理することをサポートしています。

このチュートリアルでは、一時的なフォルトハンドリングの.NETライブラリであるPollyについて、ASP.NET CoreアプリケーションでIronPDFと共に使用する方法について詳しく説明します。 Pollyの各側面を詳しく調べ、サーキットブレーカパターンの仕組みを説明し、バルクヘッド分離とタイムアウトを議論し、特定の例外や失敗するサービスを、制御されたスレッドセーフな方法で失敗応答と共に処理する方法を示します。

Pollyのポリシー

一時的なフォルトは、アプリケーションがHTTPリクエスト、データベース、またはその他の外部リソースを通じてWebサービスに接続しようとする際に頻繁に発生します。 これらのフォルトは、ネットワーク障害、ネットワーク接続の一時的な問題、またはタイムアウトなど、短時間で自然治癒することが一般的です。

Pollyは、リトライポリシー、高度なサーキットブレーカポリシー、タイムアウトポリシー、フォールバックポリシー、およびバルクヘッド分離ポリシーなどの異なる戦略を適用して、これらの一時的なフォルトを管理します。

リトライポリシー

リトライポリシーは、リトライロジックを使って失敗した同時要求を自動的に再試行します。 無限に再試行するように設定したり、一定回数の自動再試行を行ったり、リトライ間に一定のインターバルを待つか、指数関数的バックオフを利用することができます。

サーキットブレーカ

サーキットブレーカポリシーは、設定された失敗要求の閾値を超えた後に特定のサービスを試みるためのキャンセルトークンをサポートします。 サーキットブレーカ戦略は、カオスエンジニアリングや船が損傷を局所化するために防水扉を閉めることに類似しており、1つのフォルトでは船全体を沈めません。

タイムアウトポリシー

タイムアウトポリシーは、.NETレジリエンスコードの特定の部分が実行できる最大時間を強制します。 楽観的タイムアウトと悲観的タイムアウトという2つの方法があります。

フォールバックポリシー

フォールバックポリシーは、障害が発生した場合に代用の値または動作を提供するために使用されます。 このポリシーは、障害が発生したサービスがプロセス全体を停止させるべきではない場合に有用です。

バルクヘッド分離

バルクヘッド分離は特定の操作に対して同時に実行できる要求の数を制限し、ソケット枯渇の可能性を制限し、制御された数の実行スロットを維持します。

キャッシュポリシー

キャッシュポリシーは、同じ実行が再び呼び出された場合に分散キャッシュ値を返すことができるように、実行の成功応答をキャッシュします。

ポリシーラップ

複数のポリシーを1つのユニットとして機能させるためにそれらをまとめてラップすることができます。

ポリシーの作成と設定

リトライポリシー

リトライポリシーは簡単です。特定の例外またはフォルトが発生すると、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

サーキットブレーカ Policy

サーキットブレーカポリシーは、指定された期間内に設定された閾値を超えると、サーキットを"開く"状態にし、その時間中は更なる要求をブロックします。これを"オープン"状態と呼びます。 この時間の後、サーキットは "ハーフオープン" 状態になり、特定のサービスの健康状態を確認するために一部のトラフィックを許可します。これらの要求が成功し、フォルトが発生しない場合、サーキットは閉じます; それ以外の場合、再度開きます。

// 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は2種類のタイムアウトを提供します: 楽観的と悲観的。 楽観的タイムアウトは、別のスレッドで動作し、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 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

開始方法

PollyをIronPDFと一緒に使用するには、Visual Studioをインストールし、.NET Coreの新しいコンソールアプリケーションプロジェクトを作成してください。 Visual StudioでNuGetパッケージマネージャーコンソールを開き、PollyIronPDFパッケージをインストールしてください:

Install-Package Polly
Install-Package IronPdf

Pollyを使ってIronPDFでURLをPDFに変換する

IronPDFの目立つ機能はそのHTML to PDF機能で、レイアウトとスタイルを維持します。 この機能はWebコンテンツを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に変換する例を見てみましょう。 一時的なフォルトにより時折失敗するWebサービスがあり、それらの失敗を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 は、指数関数的バックオフ戦略を使用して、失敗したリクエストを最大3回まで再試行し、リトライ間に2秒、4秒、8秒待機します。 circuitBreakerPolicy は、30秒間隔内で2回連続して失敗するとサーキットを開きます。

次に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

この例のコードでは、retryPolicycircuitBreakerPolicyWrapAsync メソッドを使用して包んでいます。 これにより、新しいリクエストに複数のポリシーを順次適用することができます。 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}");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$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アプリケーション向けです。再試行、サーキットブレーカー、タイムアウト、バルクヘッドアイソレーション、フォールバックなどの戦略を提供し、堅牢で障害耐性のあるシステムを保証します。

Pollyを使って.NET Coreでリトライポリシーを実装するにはどうすればよいですか?

.NET Coreでは、Pollyを使ってリトライポリシーを実装し、失敗したリクエストを自動的に再試行するように設定できます。再試行の回数と試行間の時間間隔を設定することで、一時的な障害の効果的な管理が可能になります。

.NETアプリケーションでサーキットブレーカーポリシーはどのようにして連鎖する障害を防ぐのか?

Pollyのサーキットブレーカーポリシーは、障害を監視し、障害の閾値に達したときにサーキットを開いてリクエストをブロックすることで、連鎖する障害を防ぎます。サーキットがリセットされるまでさらなるリクエストを停止し、システムが新しいリクエストを受け入れる前に回復できるようにします。

バルクヘッドアイソレーションはリソースの枯渇を管理する上でどのような役割を果たすのか?

Pollyのバルクヘッドアイソレーションは、サービスへの同時リクエストの数を制限し、実行スロットを管理することでリソースの枯渇を防ぎます。このポリシーは、障害を封じ込め、.NET Coreアプリケーション内で効率的なリソース管理を保証します。

Pollyのタイムアウトポリシーは、アプリケーションの応答性をどのように向上させるのか?

Pollyのタイムアウトポリシーは、操作に最大実行時間を設定し、サービスがすぐに応答しないシナリオを管理します。楽観的または悲観的なタイムアウトを設定することで、開発者はアプリケーションの応答性を確保できます。

Pollyを使用してURLからPDFへの変換の信頼性を向上させることができますか?

はい、PollyはPDF生成ツールとその再試行およびサーキットブレーカーポリシーを統合することで、URLからPDFへの変換の信頼性を向上させることができます。これにより、変換プロセスが一時的な障害に対して堅牢であることを保証し、信頼性を維持します。

Pollyのフォールバックポリシーはどのようにサービスの優雅な劣化を保証するのか?

Pollyのフォールバックポリシーは、サービスが失敗した場合に代替の応答や動作を提供します。これにより、失敗がアプリケーション全体を停止させることを防ぎ、優雅な劣化と継続的な操作を可能にします。

.NETアプリケーションで複数のPollyポリシーをどのように組み合わせますか?

.NETアプリケーションでは、Policy Wrapを使って複数のPollyポリシーを組み合わせることができます。これにより、異なるレジリエンス戦略を一緒に実行でき、より包括的で柔軟な障害処理アプローチが可能になります。

PollyとIronPDFの統合はどのようにPDF生成の一時的な障害を処理するのか?

PollyとIronPDFを統合することで、開発者はPDF生成中の一時的な障害を再試行やサーキットブレーカーポリシーなどによって処理できます。この統合により、時折のサービス中断にもかかわらず安定した信頼性のあるPDF生成が保証されます。

Pollyを.NET Coreで使用する際の一般的なトラブルシューティング戦略は何ですか?

一般的なトラブルシューティング戦略には、ポリシー設定の確認(再試行間隔やサーキットブレーカーの閾値など)、および異なるシナリオでポリシーをテストし、障害の適切な処理とシステムレジリエンスを保証することが含まれます。

Curtis Chau
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。