Dapr 弹性的策略
云原生应用需要处理 云中很容易出现瞬时故障。原因在以下文档 暂时性故障处理[1] 中有具体说明。
任何环境、任何平台或操作系统以及任何类型的应用程序都会发生暂时性故障。 在本地基础结构上运行的解决方案中,应用程序及其组件的性能与可用性通常是通过昂贵但通常很少使用的硬件冗余来维持的,并且组件与资源的位置互相靠近。 尽管此方法可以大大减少故障,但可能仍会导致暂时性故障,甚至是不可预见的事件(例如外部电源或网络问题或其他灾难性的状况)造成的中断。
云托管(包括私有云系统)可以通过跨许多商品计算节点使用共享资源、冗余、自动故障转移和动态资源分配,提供更高的整体可用性。 但是,这些环境的性质意味着更可能发生暂时性故障。 原因包括:
云环境中的许多资源是共享的,为了保护这些资源,会限制对这些资源的访问。 某些服务在负载上升到特定级别时,或到达吞吐量比率的上限时,会拒绝连接以便处理现有的请求,并为所有用户维持服务性能。 限制有助于为共享资源的邻居与其他租户维持服务质量。
云环境是使用大量商用硬件单元构建而成的。 云环境将负载动态分散到多个计算单元和基础结构组件上以提供性能,并通过自动回收或更换故障单元来提供可靠性。 这种动态性意味着可能偶尔会发生暂时性故障和暂时连接失败。
在应用程序与资源及其使用的服务之间,通常有多个硬件组件,包括网络基础结构,例如路由器和负载均衡器。 这个附加的基础结构偶尔会导致额外的连接延迟与暂时性连接故障。
客户端与服务器之间的网络状况会不时改变,尤其是通过 Internet 通信时。 即使在本地位置,高流量负载也可能减慢通信速度,并会导致间歇性的连接故障。
在许多情况下,恢复和切换是在云内部完成的。如果调用者等待一段时间,然后重试,那么它很有可能会成功。因此,建议[2]在应用程序中加入重试等提高弹性的机制。
Dapr 的诞生是为了减轻开发人员开发云原生应用程序的负担。应用程序开发人员很自然地会想,“我想知道 Dapr 是否会处理与弹性相关的问题。”
即将发布的Dapr 1.7 版本 有一个组织良好的 [提案] 跨所有构建块的弹性策略[3],这篇文章目的是总结 前面介绍介绍的问题,以及为做Dapr 技术选型的同仁提供参考,此外,我在写作的另一个目的也是希望这将是你对 Dapr 的弹性产生兴趣的机会。
Dapr 当前版本是1.6,Dapr 运行时在边车(sidecar)调用端的实现是是上面这个提案要清理的主题,调用者的可恢复性需要利用Kubernetes的各种恢复功能等基础设施来保证。
调用模式分为服务到服务调用和组件调用。
如果服务调用失败,每次调用重试[4]的回退间隔是 1 秒,最多重试三次。 通过 gRPC 连接目标 sidecar 的超时时间为5秒。
- 实现invokeWithRetry :https://github.com/dapr/dapr/blob/release-1.6/pkg/messaging/direct_messaging.go#L136
- 定义是一个常数: https://github.com/dapr/dapr/blob/release-1.6/pkg/retry/retry.go#L20
组件调用取决于每个实现
- 每个组件的规格(按构建块): https://v1-6.docs.dapr.io/reference/components-reference/
- 有些可以指定重试的参数
- 按构建块(components-contrib)为每个组件提供包的源代码:https://github.com/dapr/components-contrib
- 在每个构建块目录下,每个组件都有一个 Go 包
- 许多组件的包都单独实现了重试功能。
- dapr/kit 中有一个 retry 包,但是使用是可选的:https://github.com/dapr/kit/blob/main/retry/retry.go
至此,大家看到了问题吧,上面这个提案就是要解决下面这几个问题。
- 服务和组件之间的规范和实现不一致
- 有些项目在规范中没有规定,需要确认执行。
- 无法指定某些参数,例如重试次数和间隔。
- 实现了许多重试,但我还想要其他模式,例如断路器。
上述提案[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,我认为你应该注意以下几点。
- 在选择时检查每个组件包具有什么样的弹性改进功能。
- 考虑调用服务和应用程序中要实现的功能
- 即使我们期待未来的扩展,也需要最少的错误处理
- 参考 SDK 以及如何使用 它
- 最好从 SDK 的角度检查已知的问题、问题和情况。
- 示例:从状态 apis --Go SDK 中删除重试选项
从Dapr 1.0 发布以来的每个版本都在不断改进Dapr 的各项功能,Dapr 大约每两个月进行一次次要版本升级,这个月将发布1.7 版本,具体参见 https://github.com/dapr/dapr/issues/4170。
[2]可靠性模式: https://docs.microsoft.com/zh-cn/azure/architecture/framework/resiliency/reliability-patterns
[3][提案] 跨所有构建块的弹性策略: https://github.com/dapr/docs/issues/2059
Dapr 弹性的策略的更多相关文章
- 分布式应用运行时 Dapr 1.7 发布
Dapr 是一个开源.可移植的.事件驱动的运行时,可以帮助开发人员构建在云和边缘上运行的弹性的.微服务的.无状态和有状态应用程序,并且关注于业务逻辑而不用考虑分布式相关的问题. 分布式相关的问题交给D ...
- NET Core微服务之路:弹性和瞬态故障处理库Polly的介绍
前言 上一节中我们介绍了Ocelot的常见使用配置,通过json配置文件,实现API网关的请求处理.和一个使用DownStream扩展下游中间件,来实现Http转RPC的简单实现,功能不算强大,但可以 ...
- 精准容量、秒级弹性,压测工具 + SAE 方案如何完美突破传统大促难关?
作者 | 代序 阿里云云原生技术团队 本文整理自<Serverless 技术公开课>,"Serverless"公众号后台回复"入门",即可获取系列文 ...
- Effective HPA:预测未来的弹性伸缩产品
作者 胡启明,腾讯云专家工程师,专注 Kubernetes.降本增效等云原生领域,Crane 核心开发工程师,现负责成本优化开源项目 Crane 开源治理和弹性能力落地工作. 余宇飞,腾讯云专家工程师 ...
- SmartIDE v0.1.19 - 码云(Gitee)最有价值开源项目奖项、工作区策略、类虚拟机镜像VMLC、Server安装手册
SmartIDE v0.1.19 (CLI Build 3909, Server Build 3890) 已经发布,本次Sprint主要完成2个重要特性,工作区策略和类虚拟机容器(VM Like Co ...
- Android的Adapter用法
1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的View(ListView,GridView)等地方都需要用到Adapter.如下图直 ...
- 百度云曲显平:AIOps时代下如何用运维数据系统性地解决运维问题?
百度云智能运维负责人 曲显平 本文是根据百度云智能运维负责人曲显平10月20日在msup携手魅族.Flyme.百度云主办的第十三期魅族技术开放日<百度云智能运维实践>演讲中的分享内容整理而 ...
- 微服务监控之一:Metrics让微服务运行更透明
摘要 让微服务运行状态清晰可见. 嘉宾演讲视频回顾及PPT:http://t.cn/R8b6i85 Metrics是什么 直译是“度量”,不同的领域定义有所区别,在微服务领域中的定义: “对微服务的某 ...
- 深度剖析:最新云端开发工具如何实现敏捷+DevOps开发落地
相信很多软件开发人员们对今年国内新兴的云端开发工具——华为软件开发云都有耳闻,有些人可能还免费体验过,由于它5人以下的团队是免费使用的,很庆幸本人的这个项目正好5个人,就注册使用了.下面就自己的使用心 ...
随机推荐
- JavaScript的内存管理
JavaScript的内存管理 1.什么是内存管理? 在了解JavaScript的内存管理之前,可以先大致熟悉一下什么是内存管理,不管什么样的编程语言,在其代码执行的过程中都是需要为其分配内存的. 不 ...
- android 安装gcc环境
看到了一篇关于Android上利用终端来使用gcc编译C/C++源程序的文章,我感到无比兴奋,所以立刻将我自己的安装过程记下来.那个后记也很有用的. gcc编译源代码需要创建临时文件,而gcc又只能安 ...
- JVM学习五:性能监控工具
一.系统性能监控 系统性能工具用于确定系统运行的整体状态,基本定位问题所在. Linux – uptime • 系统时间 • 运行时间 n 例子中为7分钟 • 连接数 n 每一个终端算一个连接 • 1 ...
- Java泛型T与?
感谢大佬:http://m.mamicode.com/info-detail-2657551.html 一.区别 单独的T 代表一个类型 ,而 Class<T>代表这个类型所对应的类, C ...
- php 递归目录
转载请注明来源:https://www.cnblogs.com/hookjc/ $TheFilePath='';function file_list($path){ global $TheFilePa ...
- 区区牛马蹉跎 ,不要向生活低下头 Linux的账号和管理
账户和管理权限 1.管理用户账号和组账号 2.管理目录和文件的属性 1.Linux基于用户身份对资源访问进行控制:用户账号(超级用户.普通用户.程序用户) 组账号(基本组.附加组).UID (用户标识 ...
- go基础——if语法
package main import "fmt" /* 条件语句:if 注意点: 1.if后的{,要与if条件写在同一行: 2.else要跟在}之后,不能另起一行: 3.if和e ...
- Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/zeppelin/server/ZeppelinServer : Unsupported major.minor version 52.0
在启动Zeppelin时遇到了该问题: [root@quickstart bin]# ./zeppelin-daemon.sh restart Please specify HADOOP_CONF_D ...
- ajax请求egg用nginx转发跨域问题
火狐浏览器报的 谷歌浏览器报的 前提: npm i egg-cors --save config 文件下的pulgin.js 已经添加 //启用跨域支持 exports.cors = { enable ...
- Solution -「Gym 102759C」Economic One-way Roads
\(\mathcal{Description}\) Link. 给定一个含 \(n\) 个点 \(m\) 条边的简单无向图,每条边的两种定向方法各有权值,求使得图强连通且定向权值和最小的方法. ...