云原生应用需要处理 云中很容易出现瞬时故障。原因在以下文档 暂时性故障处理[1] 中有具体说明。

任何环境、任何平台或操作系统以及任何类型的应用程序都会发生暂时性故障。 在本地基础结构上运行的解决方案中,应用程序及其组件的性能与可用性通常是通过昂贵但通常很少使用的硬件冗余来维持的,并且组件与资源的位置互相靠近。 尽管此方法可以大大减少故障,但可能仍会导致暂时性故障,甚至是不可预见的事件(例如外部电源或网络问题或其他灾难性的状况)造成的中断。

云托管(包括私有云系统)可以通过跨许多商品计算节点使用共享资源、冗余、自动故障转移和动态资源分配,提供更高的整体可用性。 但是,这些环境的性质意味着更可能发生暂时性故障。 原因包括:

  • 云环境中的许多资源是共享的,为了保护这些资源,会限制对这些资源的访问。 某些服务在负载上升到特定级别时,或到达吞吐量比率的上限时,会拒绝连接以便处理现有的请求,并为所有用户维持服务性能。 限制有助于为共享资源的邻居与其他租户维持服务质量。

  • 云环境是使用大量商用硬件单元构建而成的。 云环境将负载动态分散到多个计算单元和基础结构组件上以提供性能,并通过自动回收或更换故障单元来提供可靠性。 这种动态性意味着可能偶尔会发生暂时性故障和暂时连接失败。

  • 在应用程序与资源及其使用的服务之间,通常有多个硬件组件,包括网络基础结构,例如路由器和负载均衡器。 这个附加的基础结构偶尔会导致额外的连接延迟与暂时性连接故障。

  • 客户端与服务器之间的网络状况会不时改变,尤其是通过 Internet 通信时。 即使在本地位置,高流量负载也可能减慢通信速度,并会导致间歇性的连接故障。

在许多情况下,恢复和切换是在云内部完成的。如果调用者等待一段时间,然后重试,那么它很有可能会成功。因此,建议[2]在应用程序中加入重试等提高弹性的机制。

Dapr 的诞生是为了减轻开发人员开发云原生应用程序的负担。应用程序开发人员很自然地会想,“我想知道 Dapr 是否会处理与弹性相关的问题。”

即将发布的Dapr 1.7 版本 有一个组织良好的 [提案] 跨所有构建块的弹性策略[3],这篇文章目的是总结 前面介绍介绍的问题,以及为做Dapr 技术选型的同仁提供参考,此外,我在写作的另一个目的也是希望这将是你对 Dapr 的弹性产生兴趣的机会。

Dapr 当前版本是1.6,Dapr 运行时在边车(sidecar)调用端的实现是是上面这个提案要清理的主题,调用者的可恢复性需要利用Kubernetes的各种恢复功能等基础设施来保证。

调用模式分为服务到服务调用和组件调用。

如果服务调用失败,每次调用重试[4]的回退间隔是 1 秒,最多重试三次。 通过 gRPC 连接目标 sidecar 的超时时间为5秒。

组件调用取决于每个实现

至此,大家看到了问题吧,上面这个提案就是要解决下面这几个问题。

  • 服务和组件之间的规范和实现不一致
  • 有些项目在规范中没有规定,需要确认执行。
  • 无法指定某些参数,例如重试次数和间隔。
  • 实现了许多重试,但我还想要其他模式,例如断路器。

上述提案[3]讨论了解决问题的方向以及如何进行。

虽然提高弹性的机制是非常好的,但它也包括风险,比如通过重试重复写入是典型的,假如你的接口不是幂等的。提案里面考虑到两个阶段来实施,或许第一阶段在1.7版本发布后会有很多反馈。预计到这一点,阶段 1 将重点放在基本功能上。

  • 阶段 1:可分配给每个构建块或组件的通用弹性策略
    • 将弹性策略定义为 Kubernetes 自定义资源
    • 来自有关超时、重试和断路器的策略
  • 阶段 2:允许覆盖的特定于 API 的策略

阶段1

在第 1 阶段,建议使用以下自定义资源:请参阅 https://github.com/dapr/dapr/issues/3586

apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: daprResiliency
# Like in the Subscriptions CRD, scopes lists the Dapr App IDs that this
# configuration applies to.
scopes:
- app1
- app2
spec: #------------------------------------------------------------------------------
# PHASE 1: Basic policy definition and applying policies to building blocks
#------------------------------------------------------------------------------ policies:
# Timeouts are simple named durations.
timeouts:
general: 5s
important: 60s
largeResponse: 10s # Retries are named templates for and are instantiated for life of the operation.
retries:
general: {} # Sane defaults pubsubRetry:
policy: constant
duration: 5s
maxRetries: 10 retryForever:
policy: exponential
maxInterval: 15s
maxRetries: 0 # Retry indefinitely important:
policy: constant
duration: 5s
maxRetries: 30 someOperation:
policy: exponential
maxInterval: 15s largeResponse:
policy: constant
duration: 5s
maxRetries: 3 # Circuit breakers are automatically instantiated per component, service endpoint, and application route.
# using these settings as a template. See logic below under `buildingBlocks`.
# Circuit breakers maintain counters that can live as long as the Dapr sidecar.
circuitBreakers:
general: {} # Sane defaults pubsubCB:
maxRequests: 1
interval: 8s
timeout: 45s
trip: consecutiveFailures > 8 # This section specifies default policies for:
# * service invocation
# * requests to components
# * events sent to routes
buildingBlocks:
services:
appB:
timeout: general
retry: general
# Circuit breakers for services are scoped per endpoint (e.g. hostname + port).
# When a breaker is tripped, that route is removed from load balancing for the configured `timeout` duration.
circuitBreaker: general actors:
myActorType:
timeout: general
retry: general
# Circuit breakers for actors are scoped by type, id, or both.
# When a breaker is tripped, that type or id is removed from the placement table for the configured `timeout` duration.
circuitBreaker: general
circuitBreakerScope: both
circuitBreakerCacheSize: 5000 components:
# For state stores, policies apply to saving and retrieving state.
# Watching, which is not implemented yet, is out of scope.
statestore1:
timeout: general
retry: general
# Circuit breakers for components are scoped per component configuration/instance (e.g. redis1).
# When this breaker is tripped, all interaction to that component is prevented for the configured `timeout` duration.
circuitBreaker: general # For Pub/Sub, policies apply only to publishing.
# Subscribing/consuming is handled by routes.
pubsub1:
retry: pubsubRetry
circuitBreaker: pubsubCB pubsub2:
retry: pubsubRetry
circuitBreaker: pubsubCB # Routes represent the application's URI/paths that receive incoming events from both
# PubSub and Input binding components. The route values correspond to the value configured
# in the Subscription configuration or programmatic call. For input bindings, this is
# configured in the component metadata via #3566.
routes:
'dsstatus.v3':
timeout: general
retry: general
circuitBreaker: general #------------------------------------------------------------------------------
# PHASE 2: Overriding policies for specific Dapr API operations
#------------------------------------------------------------------------------ apis:
invoke:
- match: appId == "appB"
# Nested rules: Prevent duplicative checks in rules.
# Its likely that controler-gen does not support this
# but apiextensionsv1.JSON can be used as workaround.
rules:
- match:
request.method == "GET" &&
request.metadata.count > 1000
timeout: largeResponse
retry: largeResponse
- match:
request.path == "/someOperation"
retry: someOperation publish:
- match: |
event.type == "important.event.v1"
timeout: important
retry: important # subscribe is when Dapr attempts to deliver a pubsub event to an application route.
subscribe:
- match: |
event.type == "important.event.v1"
timeout: important
retry: retryForever

Default resiliency.yml that could be installed by dapr init. Might include commented out examples for Redis.

apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: daprResiliency
scopes:
spec:
policies:
# Timeouts are simple named durations.
timeouts:
general: 5s
important: 60s
largeResponse: 10s # Retries are named templates for and are instantiated for life of the operation.
retries:
general: {} # Sane defaults # Circuit breakers are automatically instantiated per component, service endpoint, and application route.
# using these settings as a template. See logic below under `buildingBlocks`.
# Circuit breakers maintain counters that can live as long as the Dapr sidecar.
circuitBreakers:
general: {} # Sane defaults # This section specifies default policies for:
# * service invocation
# * requests to components
# * events sent to routes
buildingBlocks:
services: actors: components: # Routes represent the application's URI/paths that receive incoming events from both
# PubSub and Input binding components. The route values correspond to the value configured
# in the Subscription declarative or programmatic configurations.
routes: apis:
invoke:
publish:
subscribe:

定义超时、重试和断路器策略,并将它们分配给构成构建块的服务和组件。您可以根据您的目的创建策略,例如确定超时之前的时间以及固定/成倍增加的重试间隔。

目前,阶段 1 的目标是在计划于2022/3发布的 Dapr v1.7 中发布。当然,您必须支持每个组件包才能使用此自定义资源,但这是重要的第一步。第二阶段根据第 1 阶段的反馈,此时计划使用特定于 API 的策略定义的覆盖。

基于此,如果你现在使用 Dapr,我认为你应该注意以下几点。

  • 在选择时检查每个组件包具有什么样的弹性改进功能。
  • 考虑调用服务和应用程序中要实现的功能

从Dapr 1.0 发布以来的每个版本都在不断改进Dapr 的各项功能,Dapr 大约每两个月进行一次次要版本升级,这个月将发布1.7 版本,具体参见 https://github.com/dapr/dapr/issues/4170

[1]暂时性故障处理: https://docs.microsoft.com/zh-cn/azure/architecture/best-practices/transient-faults#why-do-transient-faults-occur-in-the-cloud

[2]可靠性模式: https://docs.microsoft.com/zh-cn/azure/architecture/framework/resiliency/reliability-patterns

[3][提案] 跨所有构建块的弹性策略: https://github.com/dapr/docs/issues/2059

[4] 服务调用重试: https://docs.dapr.io/developing-applications/building-blocks/service-invocation/service-invocation-overview/#retries

Dapr 弹性的策略的更多相关文章

  1. 分布式应用运行时 Dapr 1.7 发布

    Dapr 是一个开源.可移植的.事件驱动的运行时,可以帮助开发人员构建在云和边缘上运行的弹性的.微服务的.无状态和有状态应用程序,并且关注于业务逻辑而不用考虑分布式相关的问题. 分布式相关的问题交给D ...

  2. NET Core微服务之路:弹性和瞬态故障处理库Polly的介绍

    前言 上一节中我们介绍了Ocelot的常见使用配置,通过json配置文件,实现API网关的请求处理.和一个使用DownStream扩展下游中间件,来实现Http转RPC的简单实现,功能不算强大,但可以 ...

  3. 精准容量、秒级弹性,压测工具 + SAE 方案如何完美突破传统大促难关?

    作者 | 代序 阿里云云原生技术团队 本文整理自<Serverless 技术公开课>,"Serverless"公众号后台回复"入门",即可获取系列文 ...

  4. Effective HPA:预测未来的弹性伸缩产品

    作者 胡启明,腾讯云专家工程师,专注 Kubernetes.降本增效等云原生领域,Crane 核心开发工程师,现负责成本优化开源项目 Crane 开源治理和弹性能力落地工作. 余宇飞,腾讯云专家工程师 ...

  5. SmartIDE v0.1.19 - 码云(Gitee)最有价值开源项目奖项、工作区策略、类虚拟机镜像VMLC、Server安装手册

    SmartIDE v0.1.19 (CLI Build 3909, Server Build 3890) 已经发布,本次Sprint主要完成2个重要特性,工作区策略和类虚拟机容器(VM Like Co ...

  6. Android的Adapter用法

    1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的View(ListView,GridView)等地方都需要用到Adapter.如下图直 ...

  7. 百度云曲显平:AIOps时代下如何用运维数据系统性地解决运维问题?

    百度云智能运维负责人 曲显平 本文是根据百度云智能运维负责人曲显平10月20日在msup携手魅族.Flyme.百度云主办的第十三期魅族技术开放日<百度云智能运维实践>演讲中的分享内容整理而 ...

  8. 微服务监控之一:Metrics让微服务运行更透明

    摘要 让微服务运行状态清晰可见. 嘉宾演讲视频回顾及PPT:http://t.cn/R8b6i85 Metrics是什么 直译是“度量”,不同的领域定义有所区别,在微服务领域中的定义: “对微服务的某 ...

  9. 深度剖析:最新云端开发工具如何实现敏捷+DevOps开发落地

    相信很多软件开发人员们对今年国内新兴的云端开发工具——华为软件开发云都有耳闻,有些人可能还免费体验过,由于它5人以下的团队是免费使用的,很庆幸本人的这个项目正好5个人,就注册使用了.下面就自己的使用心 ...

随机推荐

  1. linux 批量替换文件内容及查找某目录下所有包含某字符串的文件

    转载请注明来源:https://www.cnblogs.com/hookjc/ 1. sed C代码   grep -rl matchstring somedir/ | xargs sed -i 's ...

  2. 前端常见原生方法的实现(bind,promise,new,extends,深拷贝,函数防抖,函数节流)

    前端原生方法的实现,这里写一下常见的一些实现: 1.bind Function.prototype.bind2 = function (context) { var self = this; retu ...

  3. Java微信公众号服务器配置-验证Token

    一.填写服务器配置 首先我们需要在微信公众平台上填写服务器配置 重点内容    服务器地址URL(一定要外网能访问的到)        在我们提交配置的时候,微信会发送GET请求到URL上,      ...

  4. NS前缀

    NS来自于NeXTStep的一个软件 NeXT Software OC中不支持命名空间(namespace) NS是为了避免命名冲突而给的前缀 看到NS前缀就知道是Cocoa中的系统类的名称

  5. Vue3.X安装

    1.查看node.js和npm版本 $ node -v //建议v10以上版本 $ npm -v 2.若已安装了2.x的旧版本,需要先卸载 npm uninstall vue-cli -g 3.安装淘 ...

  6. Python接口自动化测试_悠悠

    https://yuedu.baidu.com/ebook/585ab168302b3169a45177232f60ddccda38e695###  

  7. 手把手教你实现pynq-z2条形码识别

    我是 雪天鱼,一名FPGA爱好者,研究方向是FPGA架构探索和SOC设计. 关注公众号,拉你进"IC设计交流群". 1.前言 单单实现一个二维码识别就花了将近一个星期,这篇文章我就 ...

  8. 《PHP程序员面试笔试宝典》——什么是职场暗语?

    本文摘自<PHP程序员面试笔试宝典> 文末有该书电子版下载. 随着求职大势的变迁发展,以往常规的面试套路因为过于单调.简明,已经被众多"面试达人"们挖掘出了各种&quo ...

  9. Solution -「Code+#4」「洛谷 P4370」组合数问题 2

    \(\mathcal{Description}\)   Link.   给定 \(n,k\),求 \(0\le b\le a\le n\) 的 \(\binom{a}{b}\) 的前 \(k\) 大. ...

  10. Solution -「USACO 2020.12 P」Spaceship

    \(\mathcal{Description}\)   Link.   Bessie 在一张含 \(n\) 个结点的有向图上遍历,站在某个结点上时,她必须按下自己手中 \(m\) 个按钮中处于激活状态 ...