本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly)

什么是Polly?

Polly是一款基于.NET的弹性及瞬间错误处理库, 它允许开发人员以顺畅及线程安全的方式执行重试(Retry),断路器(Circuit),超时(Timeout),隔板隔离(Bulkhead Isolation)及后背策略(Fallback)。

Polly适用于.NET 4.0, .NET 4.5及.NET Standard 1.1(覆盖.NET Core, Mono, Xamarin.IOS, Xamarin.Android, UWP, WP 8.1+)。

安装Polly

.NET 4.0版本

Install-Package Polly.Net40Async

.NET 4.5及以上版本, .Net Standard 1.1

Install-Package Polly

弹性策略

Polly提供多种弹性策略。

重试策略

前提

程序会产生许多瞬时故障,但是在一定时间延迟之后,程序会自动纠正故障。

实现效果

允许配置自动重试。

断路器策略

前提

当系统发生严重故障时,快速响应请求失败比让用户等待要好。

避免故障系统过载有助于恢复系统。

实现效果

当系统错误超过预配置的数量,系统将断路一段时间。

超时策略

前提

超出一定时间的等待,想要得到正确的结果是不太可能的。

实现效果

保证调用者不需要等待超时。

隔板隔离

前提

当进程出现故障,多个失败的请求很容易占满服务器资源(线程/CPU)。

一个处于故障状态的下游系统,也会导致其上游系统故障。

实现效果

将严格管控故障进程,使其使用固定大小的资源池,隔离他们对其他进程的潜在影响

缓存策略

前提

一定比例的请求可能是相似的。

实现效果

从缓存中提供已知的响应。

当第一次读取的时候,将响应自动缓存起来。

后备策略

前提

当故障依然存在的时候,你打算做什么。

实现效果

当程序依然发生故障时,执行指定操作。

包装策略

前提

不同的故障需要不同的策略。包装策略即组合策略。

实现效果

允许灵活的将以上任意几种策略组合在一起。

如何使用Polly进行故障/异常处理?

Polly处理故障/异常有以下几个步骤。

  1. 指定处理的异常/故障类型
  2. [可选] 指定处理的异常返回值
  3. 指定处理策略
  4. 执行策略

指定处理异常/故障的类型

Polly使用Policy类的泛型方法Handle指定Polly需要处理异常/故障的类型。

指定单个异常类型

  1. Policy.Handle<DivideByZeroException>()

指定带条件的异常类型

  1. Policy.Handle<SqlException>(ex => ex.Number == 1205)

Polly也支持指定多种异常/故障类型, 这里需要使用Or方法

  1. Policy.Handle<DivideByZeroException>().Or<ArgumentException>()

指定多个带条件的异常类型

  1. Policy
  2. .Handle<SqlException>(ex =ex.Number == 1205)
  3. .Or<ArgumentException>(ex =ex.ParamName == "example")

Polly也支持指定内部异常

  1. Policy
  2. .HandleInner<HttpResponseException>()
  3. .OrInner<OperationCanceledException>(ex => ex.CancellationToken == myToken)

指定处理的异常返回值

Polly除了支持处理异常/故障类型,还支持处理异常返回值。所谓的处理异常结果,就是当Polly监控的方法,返回某些特定结果时, Polly会触发异常/故障处理策略。

Polly使用Policy类的泛型方法HandleResult制定Polly需要处理的异常结果.

指定触发异常/故障处理策略的返回值

例如:当某个方法的返回值类型是HttpResposneMessage, 并且返回值的StatusCode是NotFound时,触发异常/故障处理策略。

  1. Policy
  2. .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound)

指定多个返回值

  1. Policy
  2. .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
  3. .OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.BadGateway)

同时指定异常类型和返回值

  1. HttpStatusCode[] httpStatusCodesWorthRetrying = {
  2. HttpStatusCode.RequestTimeout, // 408
  3. HttpStatusCode.InternalServerError, // 500
  4. HttpStatusCode.BadGateway, // 502
  5. HttpStatusCode.ServiceUnavailable, // 503
  6. HttpStatusCode.GatewayTimeout // 504
  7. };
  8. HttpResponseMessage result = Policy
  9. .Handle<HttpResponseException>()
  10. .OrResult<HttpResponseMessage>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))

指定异常处理策略

重试策略

重试一次

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .Retry()

重试多次

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .Retry(3)

重试多次,每次重试触发一个行为

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .Retry(3, (exception, retryCount) =>
  4. {
  5. // do something
  6. });

永久重试(直到成功)

永久重试

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .RetryForever()

永久重试,每次重试触发一个行为

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .RetryForever(exception =>
  4. {
  5. // do something
  6. });

等待并重试

指定每个重试的间隔时间

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .WaitAndRetry(new[]
  4. {
  5. TimeSpan.FromSeconds(1),
  6. TimeSpan.FromSeconds(2),
  7. TimeSpan.FromSeconds(3)
  8. });

在这个例子如果第一次出现异常,会在1秒后重试,如果依然出现异常,会在再次出现异常后2秒继续重试,以此类推,下次异常后3秒继续重试

每次重试,触发一个行为

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .WaitAndRetry(new[]
  4. {
  5. TimeSpan.FromSeconds(1),
  6. TimeSpan.FromSeconds(2),
  7. TimeSpan.FromSeconds(3)
  8. }, (exception, timeSpan) => {
  9. // do something
  10. });

断路器策略

在发生指定次数的异常/故障之后,断开回路

  1. Policy
  2. .Handle<DivideByZeroException>()
  3. .CircuitBreaker(2, TimeSpan.FromMinutes(1));

发生2次异常之后,断开回路1分钟

  1. Action<Exception, TimeSpan> onBreak = (exception, timespan) => { ... };
  2. Action onReset = () => { ... };
  3. CircuitBreakerPolicy breaker = Policy
  4. .Handle<DivideByZeroException>()
  5. .CircuitBreaker(2, TimeSpan.FromMinutes(1), onBreak, onReset);

发生2次异常之后,断开回路1分钟, 在触发断路时触发onBreak方法,当重置断路器时,触发onReset方法

后备策略

  1. Policy
  2. .Handle<Whatever>()
  3. .Fallback<UserAvatar>(UserAvatar.Blank)

当程序触发异常/故障后,返回一个备用值

  1. Policy
  2. .Handle<Whatever>()
  3. .Fallback<UserAvatar>(() => UserAvatar.GetRandomAvatar())

当程序触发异常/故障后,使用一个方法返回一个备用值

  1. Policy
  2. .Handle<Whatever>()
  3. .Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) =>
  4. {
  5. // do something
  6. });

当程序触发异常/故障后,返回一个备用值,并触发一个方法

  1. Policy
  2. .Handle<Whatever>()
  3. .Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) =>
  4. {
  5. // do something
  6. });

执行策略

Polly将监控DoSomething方法,如果发生DivideByZeroException异常,就使用重试策略

  1. var policy = Policy
  2. .Handle<DivideByZeroException>()
  3. .Retry();
  4. policy.Execute(() => DoSomething());

向Polly上下文中传递任意值

  1. var policy = Policy
  2. .Handle<DivideByZeroException>()
  3. .Retry(3, (exception, retryCount, context) =>
  4. {
  5. var methodThatRaisedException = context["methodName"];
  6. Log(exception, methodThatRaisedException);
  7. });
  8. policy.Execute(
  9. () => DoSomething(),
  10. new Dictionary<string, object>() {{ "methodName", "some method" }}
  11. );

基于.NET的弹性及瞬间错误处理库Polly的更多相关文章

  1. .NET的弹性及瞬间错误处理库Polly

    原文:.NET的弹性及瞬间错误处理库Polly 本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET ...

  2. 基于Raft构建弹性伸缩的存储系统的一些实践

    基于Raft构建弹性伸缩的存储系统的一些实践 原创 2016-07-18 黄东旭 聊聊架构 最近几年来,越来越多的文章介绍了 Raft 或者 Paxos 这样的分布式一致性算法,但主要集中在算法细节和 ...

  3. Hive数据分析——Spark是一种基于rdd(弹性数据集)的内存分布式并行处理框架,比于Hadoop将大量的中间结果写入HDFS,Spark避免了中间结果的持久化

    转自:http://blog.csdn.net/wh_springer/article/details/51842496 近十年来,随着Hadoop生态系统的不断完善,Hadoop早已成为大数据事实上 ...

  4. SQL Server 检测到基于一致性的逻辑 I/O 错误 pageid 不正确

    最近在查询SQL时遇到SQL文件错误,可能是文件数据已损坏.解决过程分享给大家. 问题描述 消息 824,级别 24,状态 2,第 1 行SQL Server 检测到基于一致性的逻辑 I/O 错误 p ...

  5. 解决方法:SQL Server 检测到基于一致性的逻辑 I/O 错误 校验和不正(转载)

    引用:http://luowei1371984.blog.163.com/blog/static/44041589201491844323885/ SQL2008运行select count(*) f ...

  6. SQL Server 检测到基于一致性的逻辑 I/O 错误 pageid 不正确(应为 1:1772,但实际为 0:0)。在文件 'D:\Program Files\Microsoft SQL Ser

    SQL Server 检测到基于一致性的逻辑 I/O 错误 pageid 不正确(应为 1:1772,但实际为 0:0).在文件 'D:\Program Files\Microsoft SQL Ser ...

  7. SQL Server 检测到基于一致性的逻辑 I/O 错误

    背景:新建DB_GZN 恢复数据库备份文件 执行:          select * from VI_MPS_PAPLT 错误提示: 消息 824,级别 24,状态 2,第 2 行 SQL Serv ...

  8. sql-server 2005数据库文件恢复(检測到基于一致性的逻辑 I/O 错误)

    今天sql-server数据库突然报错: SQL Server 检測到基于一致性的逻辑 I/O 错误 校验和不对(应为: 0x7c781313,但实际为: 0x67a313c9). 在文件 'C:\P ...

  9. 云原生的弹性 AI 训练系列之一:基于 AllReduce 的弹性分布式训练实践

    引言 随着模型规模和数据量的不断增大,分布式训练已经成为了工业界主流的 AI 模型训练方式.基于 Kubernetes 的 Kubeflow 项目,能够很好地承载分布式训练的工作负载,业已成为了云原生 ...

随机推荐

  1. 使用XML设计某大学主页站点地图--ASP.NET

    一.使用XML设计某大学主页站点地图步骤如下 1.创建一个空网站,在项目文件上右击,然后[添加新项],选择[站点地图],新建一个可默认为Web.sitemap的文件. 2.在Web.sitemap里修 ...

  2. Python mysqldb模块

    #!/usr/bin/env python2.7 #-*- coding:utf8 -*- import os import sys import logging import MySQLdb fro ...

  3. configure配置脚本的使用

    Linux下软件的安装一般由3个步骤组成: ./configure --host=arm-linux ... //配置 make //编译 make install //安装 若取消编译: make ...

  4. 线程&进程&协程

    线程 线程是应用程序中工作的最小单元,它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.Threading用 ...

  5. JavaScript学习笔记(十二)——箭头函数(Arrow Function)

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  6. 4. 跟踪标记 (Trace Flag) 610 对索引组织表(IOT)最小化日志

    跟踪标记:610 功能: 用批量导入操作(Bulk Import Operations)加载数据时,对于索引组织表(即有聚集索引的表) 最小化日志: 上图为simple/bulk-logged恢复模式 ...

  7. 使用sklearn进行数据挖掘-房价预测(3)—绘制数据的分布

    使用sklearn进行数据挖掘系列文章: 1.使用sklearn进行数据挖掘-房价预测(1) 2.使用sklearn进行数据挖掘-房价预测(2)-划分测试集 3.使用sklearn进行数据挖掘-房价预 ...

  8. python中的“.T”操作

    其实就是对一个矩阵的转置 看代码: a array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) a.T array([[1, 4, 7], [2, 5, 8], [3, 6, ...

  9. eclipse 常用插件 整理

    开发过程中的常用Eclipse插件,按字母排序: (1)    AmaterasUML        介绍:Eclipse的UML插件,支持UML活动图,class图,sequence图,usecas ...

  10. 在没有DOM操作的日子里,我是怎么熬过来的(终结篇)

    前言 在我写终结篇的日子里,Vue版本稳定在2.9.1.当我摸清Vue的脉络之后,以一个爬坑无数的亲历者的身份,谈谈我在MVVM时代里遇到的那些事儿. 接下来,正文从这开始~ 好多童鞋学习Vue都有灯 ...