API网关Ocelot 使用Polly 处理部分失败问题

在实现API Gateway过程中,另外一个需要考虑的问题就是部分失败。这个问题发生在分布式系统中当一个服务调用另外一个服务超时或者不可用的情况。API Gateway不应该被阻断并处于无限期等待下游服务的状态。但是,如何处理这种失败依赖于特定的场景和具体服务。如果是产品信息服务无响应,那么API Gateway就应该给客户端返回一个错误,这里使用的就是云计算设计模式(二)——断路器模式

Ocelot 是一个使用.NET Core平台上的一个API Gateway,最近我在参与这个项目的开发,开发完成第一个被项目作者认同功能就是使用Polly 处理部分失败问题。各位同学可能对Polly这个项目不熟悉,先简单介绍下,Polly是.NET基金会下的一个开源项目,Polly记录那些超过预设定的极限值的调用。它实现了 circuit break模 式,使得可以将客户端从无响应服务的无尽等待中停止。如果一个服务的错误率超过预设值,Polly 将中断服务,并且在一段时间内所有请求立刻失效,Polly 可以为请求失败定义一个fallback操作,例如读取缓存或者返回默认值,有时候我们需要调用其他API的时候出现暂时连接不通超时的情况,那这时候也可以通过Polly进行Retry,具体信息参考 http://www.thepollyproject.org/2016/10/25/polly-5-0-a-wider-resilience-framework/ 。

Ocelot从实现上来说就是一系列的中间件组合,在HTTP请求到达Ocelot,经过一系列的中间件的处理转发到下游的服务,其中负责调用下游服务的中间件是HttpRequestBuilderMiddleware,通过调用HttpClient请求下游的HTTP服务,我们这里就是要给HttpClient 的调用加上熔断器功能,代码参看https://github.com/TomPallister/Ocelot/pull/27/files ,主要的一段代码如下:

using Ocelot.Logging;
using Polly;
using Polly.CircuitBreaker;
using Polly.Timeout;
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;namespace Ocelot.Requester
{public class CircuitBreakingDelegatingHandler : DelegatingHandler{private readonly IOcelotLogger _logger;private readonly int _exceptionsAllowedBeforeBreaking;private readonly TimeSpan _durationOfBreak;private readonly Policy _circuitBreakerPolicy;private readonly TimeoutPolicy _timeoutPolicy;public CircuitBreakingDelegatingHandler(int exceptionsAllowedBeforeBreaking,
TimeSpan durationOfBreak,TimeSpan timeoutValue,TimeoutStrategy timeoutStrategy,
IOcelotLogger logger, HttpMessageHandler innerHandler): base(innerHandler){this._exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;this._durationOfBreak = durationOfBreak;_circuitBreakerPolicy = Policy.Handle<HttpRequestException>().Or<TimeoutRejectedException>().Or<TimeoutException>().CircuitBreakerAsync(exceptionsAllowedBeforeBreaking: exceptionsAllowedBeforeBreaking,durationOfBreak: durationOfBreak,onBreak: (ex, breakDelay) =>{_logger.LogError(".Breaker logging: Breaking the
circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);},onReset: () => _logger.LogDebug(".Breaker logging: Call ok!
Closed the circuit again."),onHalfOpen: () => _logger.LogDebug(".Breaker logging:
Half-open; next call is a trial."));_timeoutPolicy = Policy.TimeoutAsync(timeoutValue, timeoutStrategy);_logger = logger;}protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken){Task<HttpResponseMessage> responseTask = null;try{responseTask = Policy.WrapAsync(_circuitBreakerPolicy, _timeoutPolicy)
.ExecuteAsync<HttpResponseMessage>(() =>{return base.SendAsync(request,cancellationToken);});return responseTask;}catch (BrokenCircuitException ex){_logger.LogError($"Reached to allowed number of exceptions.
Circuit is open. AllowedExceptionCount:
{_exceptionsAllowedBeforeBreaking},
DurationOfBreak: {_durationOfBreak}",ex);throw;}catch (HttpRequestException){return responseTask;}}private static bool IsTransientFailure(HttpResponseMessage result){return result.StatusCode >= HttpStatusCode.InternalServerError;}} }

上面代码我们使用Policy.WrapAsync组合了熔断器和重试的两个策略来解决部分失败问题,思路很简单,定义需要处理的异常有哪些,比如 Policy.Handle<HttpRequestException>() .Or<TimeoutRejectedException>() .Or<TimeoutException>(),当异常发生时候需要如何处理,使用熔断器还是重试,上面这个代码当然也是适合调用第三方服务用了。


欢迎大家加入建设.NET Core的微服务开发框架。

相关文章: 

  • 云计算设计模式(一)缓存预留模式

  • 使用熔断器设计模式保护软件

  • 云计算设计模式(二)——断路器模式

原文地址:http://www.cnblogs.com/shanyou/p/6366360.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326995.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组模拟环形队列

思路分析 代码实现 package com.atguigu.queue;import java.util.Calendar; import java.util.Scanner;/*** 创建人 wdl* 创建时间 2021/3/17* 描述*/ public class CircleArrayQueueDemo {public static void main(String[] args) {//测试一把System.out.println("测试数…

Error:(1, 10) java: 需要class, interface或enum

https://blog.csdn.net/zf18234031156/article/details/103047649 反复做这一步&#xff0c;30多个文件一个一个弄&#xff0c;有乱码用txt打开&#xff0c;黏贴覆盖&#xff0c; 目录 1.前言 2.原因(UTF-8BOM造成) 3.如何解决 3.11使用Notepad&#xff0c;选择“格式--以…

彻底理解ThreadLocal

转载自 彻底理解ThreadLocal 先总述&#xff0c;后分析 深挖过threadLocal之后&#xff0c;一句话概括&#xff1a;Synchronized用于线程间的数据共享&#xff0c;而ThreadLocal则用于线程间的数据隔离。所以ThreadLocal的应用场合&#xff0c;最适合的是按线程多实例&#xff…

mybatis简单案例源码详细【注释全面】——实体层(Role.java)

package org.entity;import java.util.Date; /*** * * 项目名称&#xff1a;ssm_chop2 * 类名称&#xff1a;Role * 类描述&#xff1a; 角色表的实体类 * 创建人&#xff1a;Mu Xiongxiong * 创建时间&#xff1a;2017-10-7 上午10:01:31 * 修改人&#xff…

IDEA导入Eclipse项目

https://blog.csdn.net/zeal9s/article/details/90690524 背景&#xff1a;用习惯了idea再去用eclipse实在用的不习惯&#xff0c;于是将老的eclipse项目导入到eclipse&#xff0c;网上有很多教程&#xff0c;看了很多博客都不行&#xff0c;一直报错&#xff0c;各种报错&…

云计算设计模式(四)——消费者的竞争模式

允许多个并发用户处理在同一个通讯通道接收的消息。这种模式使系统能够同时处理多个邮件&#xff0c;以优化吞吐量&#xff0c;提高可扩展性和可用性&#xff0c;以及平衡工作负载。 背景和问题 在云中运行的应用程序&#xff0c;可以预计&#xff0c;以处理大量的请求。而不是…

带头单链表有序版

package com.atguigu.linkedlist;/*** 创建人 wdl* 创建时间 2021/3/17* 描述*/ public class SingleLinkedListDemo {public static void main(String[] args) {//进行测试//先创建节点HeroNode hearo1 new HeroNode(1, "宋江", "及时雨");HeroNode hear…

mybatis简单案例源码详细【注释全面】——Dao层接口(UserMapper.java)

/** * Title: IUserDao.java * Package org.dao * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-10-5 下午8:59:34 * version V1.0 */ package org.dao;import java.util.Date; import java.util.List; import java.u…

java笔记--关于线程同步(7种同步方式)

转载自 java笔记--关于线程同步&#xff08;7种同步方式&#xff09; 为何要使用同步&#xff1f; java允许多线程并发控制&#xff0c;当多个线程同时操作一个可共享的资源变量时&#xff08;如数据的增删改查&#xff09;&#xff0c; 将会导致数据不准确&#xf…

前后端分离趋势谈

最近已经不止一个人和我提起过vue了&#xff0c;在我的前端印象中&#xff0c;我还停留在smarty渲染模版&#xff0c;jquery做js处理。学了一晚上&#xff0c;对现在这种工程化webpack打包生成html&#xff0c;js&#xff0c;css的生产方式越来越有兴趣了。工作年限摆在这里的好…

mybatis简单案例源码详细【注释全面】——Dao层映射文件(UserMapper.xml)【重要】

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace"org.dao.UserMapper"><…

from + size must be less than or equal to: [10000] but was [10550]

from size must be less than or equal to: [10000] but was [10550]_绅士jiejie的博客-CSDN博客 以上错误是ElasticSearch分页搜索时出现的&#xff0c;这是因为ES默认支持的最大条数就是10000条&#xff0c;深度分页导致总条数超过10000&#xff0c;就会报这个错。 解决方…

java并发编程之4——Java锁分解锁分段技术

转载自 java并发编程之4——Java锁分解锁分段技术 并发编程的所有问题&#xff0c;最后都转换成了&#xff0c;“有状态bean”的状态的同步与互斥修改问题。而最后提出的解决“有状态bean”的同步与互斥修改问题的方案是为所有修改这个状态的方法都加上锁&#xff0c;这样也就可…

云计算设计模式(五)——计算资源整合模式

合并多个任务或操作成一个单一的计算单元。这种模式可以提高计算资源的利用率&#xff0c;并降低与云托管的应用程序进行计算处理相关的成本和管理开销。 背景和问题 云应用程序频繁执行各种操作。在某些解决方案也可能是有意义的最初遵循的关注点分离的设计原则&#xff0c;并…

stream获取filter

Java集合Stream类filter的使用_黄嘉成的博客-CSDN博客 Java集合Stream类filter的使用 黄嘉成 2018-05-11 11:49:42 242767 收藏 116 分类专栏&#xff1a; Java高级编程 文章标签&#xff1a; java 集合 Stream filter 过滤 版权 Java高级编程 专栏收录该内容 4 篇文章0 订…

MySQL数据库开发的 36 条军规

转载自 MySQL数据库开发的 36 条军规 核心军规 尽量不在数据库做运算 控制单表数据量 纯INT不超过10M条&#xff0c;含Char不超过5M条 保持表身段苗条 平衡范式和冗余 拒绝大SQL&#xff0c;复杂事务&#xff0c;大批量任务 字段类军规 用好数值字段&#xff0c;尽量简化…

mybatis简单案例源码详细【注释全面】——测试层(UserMapperTest.java)

/** * Title: UserMapperTest.java * Package org.test * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-10-5 下午7:51:50 * version V1.0 */ package org.test;import java.io.IOException; import java.io.InputStr…

Visual Studio 2017 RC3支持.NET Core,延迟对Python的支持

Visual Studio 2017第三个候选版本上周发布&#xff0c;解决了之前发现的安装程序的小问题。由于这些问题得到了解决&#xff0c;现在值得关注的就是这次版本中更新了什么内容。&#xff08;版本是发布于1月27日的build 26127.00&#xff09; RC3版本中最值得关注的部分就是对N…

双向链表的(CRUD)

代码实现(CRUD) package com.atguigu.linkedlist;/*** 创建人 wdl* 创建时间 2021/3/19* 描述*/ public class DoubleLinkedListDemo {public static void main(String[] args) {//测试System.out.println("双向链表的测试");HeroNode2 hearo1 new HeroNode2(1, &q…