企业如何从 0 到 1 构建整套全链路追踪体系

作者 | 涯海、白玙今天,我来跟大家分享 ARMS 在全链路追踪领域的最佳实践,分享主要分为四部分。首先,是对分布式链路追踪的整体简介。其次,是对 ARMS 在分布式链路追踪领域的核心能力进行介绍。然后,介绍如何从 0 到 1 构建整套全链路追踪体系。最后,介绍一些最佳实践案例。什么是分布式链路追踪首先,什么是分布式链路追踪。我对分布式链路追踪的理解就是跟踪请求在分布式系统中的流转路径与状态,从而协助开发人员能够进行故障诊断、容量评估、性能瓶颈分析等工作。 我们可以看到典型的链路轨迹追踪例子:比如用户通过手机做了一个下单动作,这个请求会通过移动端来到网关,再到应用层,比如说有交易、下单、支付等等一系列的应用,然后中间也会穿插到去调用云基础设施,这样用户的行为轨迹是能够被清晰还原出来的。为了更方便的理解这个概念,我们可以把链路追踪和物流追踪做对比。在发送快递物流时,每个快递包裹都会赋予一个唯一的快递单号,对于系统请求来说就是全局唯一的 TraceId。通过快递单号来查询快递途径哪些站点,是否有延迟或丢件情况。那么,也同样可以通过 TraceId 来查询请求在每个系统之间的流转路径和状态。除了快递订单查询之外,还可以把整个物流状态,按照站点去进行汇总统计,来看每个站点吞吐,从而进行物流提效的优化工作。对于链路追踪来说也是一样的,我们可以把链路数据进行一个统计,然后去看每一个应用或接口的状态,或者去梳理它们之间的强弱依赖。那么,什么样的系统更加需要链路追踪呢?当微服务架构拆分的越精细,服务间依赖越复杂的系统,就更加的需要链路追踪技术,比较典型的就是电商这种。 接下来我们看一下链路追踪作为可观测的三元组之一,就是 Traces、Metrics 和 Logs。其最大价值就是实现了除机器和时间维度之外的用户行为的确定性关联。怎么理解这个事情呢?就是在没有 Tracing 之前,比如说通过指标或者日志,只能根据数据在同一台机器上,并且在同一个时间点,判断它们应该是在一起的。但这只是弱关联,并不是强关联。而调用链会很明确说明这个请求就是这个数据,就是来到了这个节点,这个信息是一定准确的。通过这种确定性的关联,除了可以将服务应用接口层面的数据关联起来之外,还可以通过打标上下文传递的方式,把一些业务的标签,比如说来自于什么渠道、订单金额等这种直接、间接的数据都关联起来,发挥 1+1>N 的价值。 接下来再看一下链路追踪的应用场景,我对它做了一个初步分级。从下往上看,最基础级就是通过调用链来还原单次请求的轨迹状态,这是最基本的应用。再往上,可以对链路数据去做预聚合或后聚合统计的分析,去看整个链路在概率分布上的一些信息,比如说整个服务维度的监控数据,上下游整体的依赖,这是第二级——聚合分析。 第三等级,就是除了调用链数据本身具备的这些链路数据之外,还可以更进一步发挥关联性作用,把一些间接的业务数据,包括容器或者 JVM 的一些指标信息或者是一些变更的日志事件,也能够通过调用链紧密的关联在一起,形成多维数据关联和分析,最终来实现我们根因定位的能力。再往后有点像自动驾驶,有了这么多数据,能不能够自动发现其中一些问题?可以结合领域专家经验和恰当的算法,来实现整个诊断流程自动化或者半自动化。 最后一步就是诊断问题的最终目标--保障系统稳定。能不能够把问题诊断和系统恢复两个事关联在一起?从而实现整个系统的故障自愈,进一步提升稳定性。这个就需要与管控系统去融合。目前开源 Tracing 系统大概是在 L1 到 L3 的等级。ARMS 我们那边沉淀了很多领域专家经验以及算法可以做到 L4 等级,ARMS 再加上一些应用托管服务进行自动流控降级、弹性扩缩容,把监控和管控系统结合在一起,从而实现故障自愈能力。接下来我们再看看链路追踪的发展趋势。在 2010 年,随着谷歌论文发表,拉开了整个链路追踪的技术序幕,很多厂商都纷纷实现了自己的链路追踪技术。当然,在谷歌之前也有很多其他探索,但谷歌给了后续实现者比较完整的理论基础。同时,通过自身实践,证明了链路追踪的企业级价值,这是开山鼻祖式的奠基。到了 2016 年,因为之前大家厂商纷纷实现自己的链路追踪,这个标准没有统一,就为迁云、上云带来很多问题。因此,开源社区发起了 OpenTracing 项目,定义了相对比较完善标准的链路的通用规范,也发展出了类似 Jaeger 这种符合 OpenTracing 规范的开源实现。到了2019年,大家考虑到可观测逐渐向一体化发展,光有 Tracing 也不够,需要把Tracing和指标和日志能够关联在一起,OpenTracing 定义就相对比较狭隘,不能满足可观测的需求。所以在 2019 年,就是 OpenTeleMetry,然后提出了这样的一个开源项目。将 OpenTracing 和 OpenCensus 进行了融合,能够致力于去解决 Logs 和 Traces、Metrics 三者有机统一。ARMS 的链路追踪到底具备哪些能力接下来,我们看一下 ARMS 的链路追踪到底具备哪些能力。首先,我把 ARMS 的能力抽象为四个点:解决接入难的问题。比如说企业有很多不同类型应用,不同语言的应用。除了前端后关联,服务端也有很多如 Java 、Go 等应用。ARMS可以更有效地去完成这些应用的追踪接入。解决诊断难的问题。ARMS 可以提供各种各样的,比如说日志和 Trace 的全息排查,或者是线程剖析这种深度的诊断的能力来帮助你去定位根因。解决运维难的问题。在大规模场景下,链路的探针管理、升级都是比较困难的事情,包括服务端的稳定性托管, ARMS 可以提供稳定可靠的全托管、免运维能力。解决成本高的问题。ARMS 作为云上产品可以按需按量地来使用。随着业务爆发式增长,只需要按量地去付费就可以,也不需要一开始就购买一大批机器或投入比较大人力。接下来,我们逐一介绍下这四个方面:首先就是接入难, ARMS 目前提供了 Java 无侵入的探针技术方式,如果你是 Java 应用就可以很快地接入 ARMS。比如说通过一个 -javaagent 的命令,或者是在 ACK 容器服务环境下,通过一个 Annotation 就可以很快地接入。如果是非Java语言,也可以利用开源 SDK 通过修改 Endpoint 快速地接入到 ARMS,从而实现全链路追踪,基本上相当于是开箱即用的。我们对语言组件的覆盖也是相对比较齐全的,主流组件基本上都有支持。同时, ARMS 完全兼容开源的 OpenTracing、 OpenTelemetry 等各种开源格式。如已接入,迁移到  ARMS 也是非常的方便。其次,诊断难。在生产环境去诊断问题时,有时不仅仅需要调用链,还需要很多其他的数据一起结合。比如说发现某个应用接口或者是业务出现问题,根据各种各样条件来去筛选出想要的调用链,通过调用链来去追溯上下游,看看问题大概瓶颈点在哪里。如果这个时候出现了比较慢的一些情况,就是接口粒度还不足以定位问题的时候,我们可以通过 ARMS 的线程剖析功能,自动地帮你把慢调用本地完整的方法栈能够获取下来,能够实现代码级定位。如果是业务上出错了,还可以跟业务日志进行关联绑定,能够看到每次调用,每笔请求关联背后业务的行为和日志是什么样的。如果前面这四步仍然不足以去定位根因,还可以结合内存快照或是线程池分析,常见的就是数据库连接打满,或者是线程池打满等。 除了上面这一整套诊断能力帮助团队完成定位之外,ARMS 也能够通过自动诊断能力解决常见问题。比如说我们经常会遇到一些数据库 MySQL 问题,数据库 MySQL 有很多原因比方说服务端原因,服务端的连接池打满,或者是客户端的连接池打满,或者是客户端一次查了特别多数据需要分批等等。面对这些常见的原因,ARMS 都可以自动诊断出来。解决完诊断难,接下来就是运维难的问题。越是体量越大的公司,这个问题会越严重。ARMS 作为阿里鹰眼的升级,在双十一场景下结合多年验证与优化,沉淀了大量经验,比如说我们的 Agent 是会经过多轮、各种级别的灰度验证,保证我们客户端侧稳定。服务端也会支持比如说多可用区容灾或者是全链路端的 SLO 体系建设,还有包括我们多级的客户支持和 Oncall 应急值班,这些都是可以直接享受到这样的服务,而不需要重新的去建设这样的体系。在大部分场景下,除了稳定性之外,还经常会遇到海量数据场景下查询性能问题,当数据达到每天几百 TB,数据存储和数据查询的索引可能已失效,无法满足业务要求。ARMS 沉淀了多种性能加速方案,比如说可以实现最基础的就是租户地域隔离,其次数据可以通过应用去做路由存储,如果应用级还不够,还可以再继续根据数据的一些特定的特征,如 TraceId 或者其他特征进一步打散,从而提高并发查询的效率。第四点就是大家比较关心的成本问题,ARMS 除了自身按需存储之外,还通过冷热数据分离和精准采样方案,进一步降低用户成本。比如说我们可以把热数据,比如说 30 分钟内数据我们会经常查询,我们可以把它存在热存储里面,满足全量的分析的需求。30 分钟之后的数据进行持久化,比方说 15 天、30 天。这个时候可以仅把其中错、慢或者满足一定业务特征(比如说 VIP 用户的一些链路)存储下来,这样整个存储成本就会比较低,并保持查询体验。当然,在做链路采样时就无可避免的会遇到指标数据不准的情况。ARMS 通过在客户端完成预聚合,来保证链路数据无论怎么去采样,即使千分之一,但依旧保证指标数据精准性。这里做个简单对比,如果采用开源方案,最起码需要存储以及流计算处理服务器建设,这种 ES 和 ECS 的成本大概 200 元/天。但如果直接使用 ARMS 的按量付费,每天大概只需要十几块钱。每 GB 成本可能只要 1 毛 9 不到 2 毛钱,远远低于开源自建成本。值得一提的就是,ARMS 进入 Gartner APM 象限,也是国内唯一的云厂商,Gartner 对 ARMS 的 APM 评价是中国影响力最强,对开源集成性也非常好,成本也是非常大优势。如何从 0 到 1 建设追踪体系介绍完产品核心能力之后,来讲讲如何从 0 到 1 建设追踪体系。我们大概可能需要完成这样 4 步:第一步,完成整个应用的全链条全链路的上下文透传,从端侧设备开始到后端,然后网关或者是应用等等。这里面的话其实就涉及到异构语言的数据打通和前后端的透传,这一套方案 ARMS 是都已实现了。第二步,完成了客户端的这种全链路埋点之后,我们数据要上报上来,就会面临存储和计算的成本,最好的方式就是说能够按需去存储数据,只存有价值的数据来降低成本。第三步就是数据存储下来之后,肯定还要通过查询再发挥它的价值。这时候遇到的问题就是数据之间的格式不统一,能不能把所有的指标数据转化成一个比方说 Prometheus的这种格式,这样指标数据格式相对统一了,Traces 能不能支持这种 OpenTelemetry 的格式,然后是日志支持 Loki 这种方案。如果数据格式跟开源保持统一再去做第 4 步,释放价值就会比较容易。除了产品提供的预置大盘之外,还可以灵活自定义用户档案。当然还可以按照用户的使用习惯,也可以做一些自定义的控制台。同样道理,告警也是一样的,我们可以去用 PromQL 做一个灵活的自定义的告警,同时我们也支持把数据路由到用户名下的一些存储,比如说 SLS 下面,这样你想去做一些二次的批量的分析,这些都可以支持。这就是我们从 0 到 1 去建设链路追踪体系的大概步骤。接下来,每个步骤都单独来看。第一步,就是要完成异构应用的全链路的追踪,比如说前端或者说整个透传的格式,或需要采用统一格式,比如说我们可以选择统一的 Jaeger 格式来透传来我们的协议头,我们前端接入比如说我们可以采用 CDN 或者 NPM 两种的这种低代码的接入方式,可以支持外部小程序等各种各样的场景,我们后端如果是 JAVA 的话,就会优先推进使用 ARMS Agent 来完成无侵入的这样的一个代码的接入。并且在 JAVA 的应用上面,我们会提供很多比如说边缘诊断、无损统计的这样一些高阶的能力,非 JAVA 的话就可以比方说我们可以通过开源的 Agent 和 SDK 来接入,然后并且上报到我们的 Endpoint 上面,当然 ARMS 也在去兼容 SkyWalking 的协议格式。第二步,正如刚才所讲,数据打通之后,需要去进行精准采样和冷热存储分离。但是对于使用者来说,需要去定义我们尾部采样策略,比如说默认的除了错慢全采之外,有没有需要根据业务特征进行采样,或者是按需的去调整数据存储周期。第三步,就是需要去自定义监控大盘,就除了 ARMS 提供的默认大盘之外,你还可以基于 Grafana,把业务数据、应用数据,甚至容器数据放在一起,来去定制统一监控大盘。比如说双 11 大促,或日常线上应急场景,都可以去快速地浏览整个业务线的表现,能够快速地定位到问题的大致范围。第四步,当建立监控之外,还需要有一个比较有效的告警机制,因为大家平时也不太会去一直盯着监控或者是 Trace 控制台,肯定需要有应急入口,告警其实就是我们运维的第一入口。在这里介绍三个比较典型的告警实践。比如说公司或者是团队在刚起步或新产品刚上线的时候,很多东西都是比较缺失的。这个时候,我们可以通过 ARMS 的告警模板能力,把比较通用的应用、容器、中间件的告警能力能够快速地构建出来,解决从 0 到 1 的问题。当团队或者是公司一步步成长起来,数据会越来越多,系统会越来越多。等到膨胀到一定程度时,告警可能分散在多个系统之中。这个时候又会带来效率问题,就可以使用 ARMS 的告警能力,把多个告警源的数据放在一起去分析,甚至可以去做组合过滤规则。比如,当流量突然激增,性能后端的耗时变高,CPU 打满的时候,发出建议扩容或是建议降级的告警通知。当企业进一步地发展,发展得很好,团队越来越多,人员越来越多。这个时候,可能一个系统会有很多个团队来共同的去协作运维,我们不仅仅需要解决数据爆炸问题,还需要解决人员协同的问题。这个时候就可以基于 ARMS 的 ChatOps 能力来解决应急协同问题。第五步,即使前面都做了之后,还有很多公司有建设自己专属平台的意愿,因为可能大家已经有了比较好的可观测或监控报警方面的经验以及场景沉淀,只需扩充部分这样的能力,是完全可以基于 ARMS 这种开放数据的能力。无论是通过外部页面的嵌入,还是 Open API 建设,或是直接把存储开放出来,进行批量数据分析,都可以更好地完成二次开发。最佳实践最后,我们来介绍常见实践案例。比如,调用链通常聚合成一个应用维度的拓扑,或者是服务维度的拓扑,但这个时候往往还不够,还可能会更关注某特定场景。同样是下单场景,有时候关注整体的下单还不够,可能还需要关注某个新渠道或新上线品类。我们可能需要看某个线下零售的渠道,它的下单链路情况是怎么样的。或者是某个新品类,需要把这一部分业务场景单独剥离出来,去做链路染色,从而能够实现这一部分特定业务场景的应用和依赖的梳理。这个就是通过无侵入的业务染色实现的。第二部分,ARMS Agent 除了做可观测数据之外,同时也具备安全数据、安全行为检测与保护的能力,面对最近比较火的 Log4j2 高危核弹级漏洞,基于 RASP 技术就可以有很好的自我防护能力。即使不改代码,也可以通过动态配置的方式,完成安全防护。除了安全防护之外,RASP 也可以提供攻击溯源或者漏洞定位分析等等能力,相比于传统的防火墙式保护会更有效一些。因为它跟 IDC 防火墙的区别,有点像我们戴口罩和打疫苗这样的一个区别。第三个场景,在容器场景下实现全景监控,可以把来自于 Prometheus 或者 Loki 或者 eBPF、APM 等端到端数据放在一起,通过 2D、3D 拓扑,进行全程展示和端到端链路的下端分析。同时,我们还提供定期巡检,或是基于专家经验和算法的问题自动诊断和上报,这个就是我们在容器场景下的一个全景监控的最佳实践。第四个场景,一些架构比较复杂的用户,具备多云以及跨云部署;出于数据安全考虑,也可能会去自建机房进行混合云部署。为了解决前后端、多语言、跨云部署的问题,ARMS 的全链路追踪帮助用户完成复杂场景的全链路追踪挑战,把各种场景的链路串联在一起,最大化去释放链路跟踪价值。第五部分,就是说 ARMS 最近新上线了 Trace Explore 功能,相对于传统调用链查询和应用服务统计、监控之外,还提供实时获取和分析能力。举个简单例子,我们经常要看耗时大于三秒的请求分布在哪些接口或者是哪些 IP 上面,从而进行慢接口的处理,或单机故障排查诊断。这个时候我们在预聚合的时候,肯定没办法把耗时大于三秒或者是某一个特定的过滤条件等于什么的场景之下,去做一个预先统计。这个时候我们就需要一个灵活的后聚合分析的能力。这个就是 Trace Explorer 能够提供这样的一个价值。除了我们刚刚说的这种单机慢接口之外,如果我们再结合我们的业务指标,比如说我们把我们的一些用户的等级也打到我们的 Attributes 里面对吧?我们就可以去按不同的用户等级来去分析它的一些流量的情况,它响应的一些时延,就能够更方便的低代码的去完成这样的一个自定义的分析。当然,这里还举了一个灰度监控,如果我们在重启之前,比方说我们在环境变量里面注入我们当前的版本,我们就可以看到不同版本之间一个流量和性能的变化。最后,给出了一些 ARMS 相对于开源做的更好的最佳实践。比如说接口偶发性超时的时候,接口级的调用链,还不足以诊断更新,我们需要完整的方法栈,但是那个问题现场已经过去了,怎么能够自动帮你保存下来呢?那就是可以通过 ARMS 线程剖析自动诊断的这样的一个能力。当我们微服务或者是数据库的性能值打满时,这个时候可能所有的请求都会变慢,但是你在调用链上也很难直观的去反映出来,因为这种资源类的问题是很难通过链路去记录下来的。这个时候 ARMS 提供的这种池化监控,能够直接分析每一类线程当前情况,并配置告警。除此之外比如说你想分析一些内存泄漏的问题,或者是一些线上运行代码和本地行为不一致的问题,都可以通过白屏化的内存诊断,或者是 Arthas 这种在线调试的这样的一个能力,帮你快速的去定位你的根因。以上就是今天我们对链路追踪整体的介绍,也涉及到我们对整个全链路追踪的一些最佳的实践,感谢大家!

全面公测|Grafana服务:一张图表胜过千行指标&日志

作者 | 白玙、珂帆对于运维人而言,随着互联网行业野蛮生长逐渐结束,“如何降本提效”、“用数据说话”或已成为当下工作的核心主题。纵观纷繁复杂的日常运维场景,其背后大多有着明晰的导向目标,比如对产品服务质量负责的要求,对资源使用效率提升的要求,对技术成本控制的要求。为达成上述目标,运维人在聚焦日常运维平台搭建之余,也开始逐渐重视数据建设,以期通过数据驱动运维。我们一定都听过「增长黑客」,但数据驱动运维又是什么?在这里,我们姑且笼统定义为通过对业务目标、运维流程的识别,借助全栈不同数据源的整合,将业务应用和基础设施关联在一起,构建完整数据分析体系,从而精准量化评估运维全过程以及服务质量,最大限度降低服务运行的成本,保障服务运行的安全。这样的定义听起来似乎跟运维人的日常工作习惯与流程并无二致,那接下来我们具体来聊聊「数据驱动运维」。我们为什么需要数据驱动运维?首先,那下面的几个常见运维场景,运维人一定不意外:缺少跨系统监控的统一视图企业历史积淀的监控系统较多,既有如云资源监控、网络资源监控、存储资源监控等通用基础监控,也有如业务监控、数据库监控、各种中间件监控等定向监控。这些监控背后数据种类多、格式不统一,且分散在各自系统中。各系统拥有独立的权限管理方式以及数据展现方式,导致在故障发生时,缺少统一的视图汇总各类数据,无法有效辅助运维人员进行故障分析。运维人员无法直观地判断异常指标间的关联关系,需要各个系统不断跳转并反复查看,手工进行数据整合和分析判断。缺少业务视角的指标关联在故障发生时,往往最先反应在业务指标上,然而业务指标通常缺少与其他各种类型运维监控数据、告警数据关联关系,导致运维人员在故障处理的过程中效率较低。监控工具缺少与业务数据、告警数据和系统关系数据的有效整合,使得故障定位的过程需要多个系统运维人员共同参与分析,很难直接从业务角度来发现监控数据之间的关系。缺少纵深交互的分析能力系统故障无法完全避免,故障管理的重点是对故障快速响应和恢复服务。通常运维人员在故障定位时,很大程度上依赖运维经验,而监控工具更多是提供单一层面、单一指标的排查方式,无法有效结合应用架构及相关指标进行关联分析。导致在故障定位时存在根因定位不准确、定位不够及时等情况。随着系统复杂度不断增加,系统可用性要求不断提升,监控工具不再单纯是统一的整合和展示,还需要更有效的分析手段,通过关联、下钻等交互方式辅助查找故障根源。缺少针对场景的定制能力特定行业的业务场景相对较为固定,监控工具缺少针对具体运维场景进行数据整合和展示,以及定制数据关联和分析的功能,使得运维人员在特定场景下的故障处理效率较低。数据驱动运维背后的价值到底是什么?当我们考虑建立数据驱动的运维数据分析体系,或许以下几点价值让大家更容易接受:1、业务支撑。通过将全栈数据打通与统一呈现,完整展现用户体验、产品业务和应用服务的关联关系,运维人可以快速了解业务场景的全局视图,量化产品业务健康度的同时,掌握应用服务异常对用户体验、产品业务的影响。增加运维与业务的交互,展现运维对产品业务的支撑价值。2、跨团队协同。从基础设施、上层组件、应用服务、第三方接口到用户体验,基于应用的拓扑架构汇聚各类指标、事件,统一到同一平台展现。通过共享数据看板让不同职能、不同团队的协作方对数据口径、数据定义达成一致,进一步提升日常协作的沟通效率,避免无效的对焦扯皮。3、故障管理。全面采集基础设施、平台组件、应用服务、业务流程等不同来源对应的告警信息按照资源、性能类型等不同维度进行可视化展现。让各类问题的统计分析更加多元、直观的展现给运维人员。在进行故障修复时,可以更快速的定位故障源头。4、辅助决策。借助全栈数据打通与统一展现提高数据丰富度,进行针对性的运维数据分析,挖掘更细颗粒度的指标与数据。通过数据整合关联,辅助精准分析和决策,为最终业务结果提供有效支撑。想要数据驱动运维,建立面向业务、面向用户的端到端运维数据分析体系成为不可或缺的环。但我们又需要哪些数据?我们需要哪些数据?想要解决以上场景,我们就需要大量的数据去进行分析,从而实现数据驱动运维。但数据驱动运维是一个不断演进的动态过程,我们很难在运维数据可视化分析体系的搭建初期就清晰的规划,我们需要哪些数据,又要摒弃哪些数据。因此,我们采集尽可能多的数据,再进行分门别类的整合。在这一过程中,我们尝试进行以下分类:面向业务对于运维来说,端是非常重要的数据采集点。端采集的数据可以更直接反映用户对产品的感知。这其中涵盖面向运营的产品业务数据,也包括面向运维的产品技术指标。通过相互关联,可以让运维人在某些场景下,快速找到事件相关性。比如说当前资源容量规划与业务增长之间的关系,订单支付成功率与服务调用的关系等等。面向服务 & 接口作为面向应用的能力封装,各类服务的特征和采集都与传统资源采集方法截然不同。不同的服务需要关注的指标都非常不同。用户在客户端发生请求之后,会产生大量的调用。虽然接口调用数据存在数据量大、不同语言不同采集方式等问题,但在故障发现和运维优化等方面,接口调用数据最有说服力,直观展现相关服务健康度。面向资源产品在向用户提供相关服务的背后,CPU、内存、磁盘 IO 等资源决定着服务的支撑力度。虽然云原生帮助企业实现更加迅捷地扩缩容。但运维扔需要建立相应容量模型来计算资源使用率,以应对业务突发情况。我们如何选型数据可视化平台?有了数据以及对应的面向业务、面向用户的端到端运维数据分析模型,我们该如何将之具像化呢?数据可视化的前提是监控数据的整合,在数据展示方面,Kibana 和 Grafana 是目前比较成熟的开源技术方案,适合利用日志和指标数据进行各种定制化图表的配置和展示。但两者存在一定的差异:KibanaKibana 技术应用于日志数据分析及展示场景,在展现 Elasticsearch 存储的日志数据方面有很大优势,可以轻松地执行高级数据分析,并以各种图标、表格和地图形式进行数据可视化展示。Kibana 使得理解海量日志数据变得很容易,它简单的、基于浏览器的界面能够快速创建和共享动态仪表板,实时显示 Elasticsearch 的查询结果。GrafanaGrafana 技术应用于海量指标数据的分析和展示场景,它是一个跨平台的开源度量分析和可视化工具,作为云原生可观测性的统一展示解决方案,其主要特性包括灵活且易用性强的客户端图表,丰富的仪表盘插件,具备实时查询海量指标数据并以热图、折线图、图表等多种方式进行展示的能力。这其中包括支持指定指标、图表类型、时间范围以及数据聚合方式的自定义配置以满足各种具体监控场景的需要。包括 Graphite、InfluxDB、OpenTSDB、Prometheus 和 Elasticsearch 等不同时序的数据源接入,并在同一面板展示不同数据源,将来自不同数据源,但同一业务的数据集中展示。通过 Grafana,任何人都可以创建和共享动态仪表盘,以促进协作和透明度,高效协同数据分析、故障排除。Grafana 主要包括以下几个部分:数据源对于 Grafana 而言,Prometheus 这类为其提供数据的对象均称为数据源(Data Source)。目前,Grafana 官方提供了对 Graphite、InfluxDB、OpenTSDB、Prometheus、Elasticsearch,、CloudWatch 的支持。对于 Grafana 管理员而言,只需要将这些对象以数据源的形式添加到 Grafana 中,Grafana 便可以轻松实现对这些数据的可视化工作。仪表盘通过数据源定义好可视化的数据来源之后,可以通过数据看板来组织和管理数据可视化图表。在数据看板中最基本的可视化单元为一个 Panel(面板)。Panel 通过如趋势图,热力图的形式展示可视化数据。并且在数据看板中每个 Panel 是一个完全独立的部分。通过 Panel 的 Query Editor(查询编辑器)我们可以为每一个 Panel 自己查询的数据源以及数据查询方式,以 Prometheus 作为数据源举例,那在 Query Editor 中,实际使用的是 PromQL,而 Panel 则会负责从特定的 Prometheus 中查询出相应数据并可视化。由于每个 Panel 完全独立,因此在一个数据看板中,往往可能会包含来自多个数据源的数据。Grafana 通过插件形式提供了多种 Panel 实现如:Graph Panel、Heatmap Panel、SingleStat Panel、Table Panel 等。用户还可通过插件安装更多类型 Panel 面板。组织管理作为一个可视化工具,Grafana 除了提供灵活的可视化定制能力以外,还提供面向企业的组织级管理能力。在 Grafana 中,数据看板是属于一个组织。例如企业创建多个组织,用户可以属于一个或多个不同组织。并且在不同组织下,为用户赋予不同的权限,根据企业组织架构定义整个管理模型。看到这里,大抵会觉得 Grafana 开源版本简直是最佳选择,但在平台搭建过程中,运维人依旧会遇到很多开源项目的通病:搭建前期,购买机器、配置网络、构建环境、安装部署、准备域名和 IP 地址等前期繁琐的准备工作;使用过程中,使用了非常多云服务之后,数据接入困难,不知如何下手;由于 SLA 无法保障,在关键时刻监控平台服务无法使用;想要连接专有网络 VPC 内各自建数据源,并通过邮件、短信等渠道进行告警触达,需要自行详细配置。相较于开源版本,阿里云Grafana服务优势是什么?为了帮助大家更加快速的构建 Grafana,我们对众多使用开源版本的用户进行了相应调研,我们发现开源版本的用户需求主要集中在以下几点:全托管的自动弹性(免服务器运维、高可用);支持多方数据源(ARMS、Prometheus、SLS、用户自建数据源)、报警功能集成;阿里云及其他云厂商的官方数据源预建数据大盘;数据访问安全(云账户管理 /子账号授权 / 用户组/用户授权)提供多种版本选择、插件版本选择、 企业级插件支持提供独立的访问域名/链接自建 Grafana 迁移至托管 Grafana 的便利性(迁移工具/配置导入)对此,阿里云推出 Grafana 托管服务,让运维能够更快速的搭建数据可视化平台。除去以上几点,我们在打造 Grafana 托管服务时也进行了以下的改进与优化:为了更好的运维管理和成本考虑,托管服务集群采用 ACK 集群;为了保证各用户数据隔离安全和数据库升级迁移维护的便利性,我们采用独立数据库方案,其他如服务状态机设计、云服务接入、用户鉴权、授权、独立域名等都是经过考虑权衡。因此,我们可以看到阿里云 Grafana 服务包括以上优势:默认集成各种云服务:默认集成 ARMS、Prometheus、云监控、SLS 等监控服务,更提供 MySQL、RocketMQ、ElasticSearch 各种云服务数据源配置,实现运维监控统一大盘展现。海量插件任意选:近百种数据源插件覆盖主流技术产品,轻松连接已有数据源并实时展现相关数据,无需数据迁移或摄取。自定义报警体系:一键快速创建报警,并整合相关所有报警,轻松搭建报警体系,让报警管理更高效。多维度数据查询:支持跨不同查询与数据源的汇总、组合等计算,让数据查询更加灵活。自建数据源整合:打通同地域多 VPC,并添加到同一数据源、工作区,实现统一查询展示与告警,降低数据管理成本。快速创建看板:轻松配置、自定义和浏览所有面板,让运维可视化建设更加简单。场景实践云原生一体化大盘监控场景挑战监控范围非常繁杂,各类监控难以互相融合;对线上服务,如 HTTP、数据存储、消息队列等服务进行监控,出现异常时快速报警。最佳方案结合阿里云 Prometheus,全面覆盖日志监控、调用链路监控、指标监控等多种方式,为实际生产中排查问题提供重要支持,并满足基础监控、运行时监控、错误监控等不同需求。借助阿里云 Grafana 服务,所提供的预置的丰富的 Kubernetes 基础监控以及常用服务预设看板,节省自建监控面板的时间成本;应用监控场景挑战基于前端、应用、业务自定义等维度,迅速便捷地为企业构建秒级响应的应用监控能力。最佳方案结合 ARMS 应用监控,无需修改代码,只需为应用安装一个探针,快速定位出错接口和慢接口、重现调用参数、发现系统瓶颈,从而大幅提升线上问题诊断的效率。借助阿里云 Grafana 服务,将应用运行过程实时呈现在面前。自定义的账号场景挑战涉及多人团队,多角色,多账号管理,有的团队直接使用微软的体系办公,有的团队公司自有 OA 系统,需要使用自定义的账号体系对接到监控系统。最佳方案通过 Grafana 身份验证能力接入,除了谷歌、微软等预设 OAtuh2 配置,支持自建系统通过 OAtuh2 对接。另外通过 Grafana 服务中账号管理,可以使用阿里云账号、子账号进行权限控制以及登陆。除上述场景,Grafana 帮助运维人员轻松处理各类运维过程中遇到的各类数据可视化与分析难题。目前阿里云 Grafana 服务全面免费公测,帮助企业轻松构建运维数据可视化平台,轻松实现数据驱动运维!点击立刻试用!

小米电商 Apache Dubbo-go 微服务实践

作者 | 董振兴背景2021 年是小米中国区电商部门变动调整较大的一年,小米中国区早期电商、服务体系建立在 Go 语言构建的微服务体系之上,由内部自研的 Go 语言微服务框架 koala 支撑起数以千计的微服务应用。随着业务的发展,新零售体系的成立以及业务中台普及与推广,我们更倾向于拥有丰富生态的 Java 为主的微服务体系技术选型,新项目及服务大多基于 Apache Dubbo、Spring Cloud 的微服务生态。考虑到服务迁移的巨大成本以及服务稳定性的保障,我们最终决定在大范围投入与使用以 Apache Dubbo 为主的服务体系的同时,保留原有 Go 微服务项目。由于原有跨部门的技术选型差异,留存的服务包含基于 Thrift、gRPC 等不同协议服务,我们希望多套微服务体系能够无缝稳定地融合。在经过大量调研之后,确定了以 Dubbo+Nacos+etcd+sidecar+mirpc+Dubbo-go 的为核心的一套互通的微服务体系。微服务治理1、相关组件mionemione 是一套由小米公司新零售效能团队开源的“项目创建->开发->测试->发布->运维” 端到端的系统服务和研发工具,支持物理机部署、docker 部署、K8s、dockerFile 部署等多种部署形态,通过人工智能、自动化技术的应用助力开发者提升研发效能,持续快速交付有效价值。详细了解可以通过官网目前内部基于 Java Dubbo 生态的微服务基本上都托管于 mione,并以 Nacos 为注册中心,这些服务作为 consumer 基本上通过 Apache Dubbo、side-car 两种方式实现调用。koalakoala 是小米内部自研的 Go 语言的微服务框架,基于 etcd 的注册中心以及 Thrift 协议。作为服务的提供方,服务注册将自身元数据等信息注册到 etcd 中,并对外提供 Thrift 的服务。Java Dubbo 的 consumer 服务则通过 side-car 兼容 Thrift/gRPC 协议,基于 etcd 进行服务发现调用。sidecarsidecar 同样是小米内部自研的用于服务注册及发现,支持跨服务调用的组件,名为 soa-agent ,以 side-car 的方式同服务部署于 mione 容器中,服务借助该组件实现兼容协议的 RPC 调用,具体技术细节这里不做详细介绍。Apache Dubbo-go我们以 side-car 的方式解决了 Java 服务的 consumer 到 Go 服务基于 Thrift/gRPC 的调用,而 Go 服务到新项目,即基于Apache Dubbo 生态的 Java 服务的调用,在经过大量调研与参考后,决定使用还在不断进行迭代的 Apache Dubbo-go。Apache Dubbo-go 是当前 Apache Dubbo 多语言支持中较为热门的项目,社区也较为活跃。Apache Dubbo-go 由 Go 语言实现,继承了 Apache Dubbo 的设计理念与架构,拥有较好的可扩展性。它能够架起 Java 和 Go 之间的桥梁,与 gRPC/Apache Dubbo 生态互联互通,这正式对于是我们当前痛点较好的解决方案,所支持的 Nacos 注册中心也与我们当前中间件的技术选型契合。Apache Dubbo-go的应用经过调研后,我们选用了当时较为稳定的 v1.5.7 版本进行接入。Apache Dubbo 官方文档中提供了使用 Apache Dubbo-go 的一般调用方式,但该方式需要业务方调用方严格遵守切合服务方提供的接口格式、数据格式,因此我们选择使用泛化的方式进行调用。对于一个 Java 的 Apache Dubbo 服务提供的接口如下:public interface DubboHealthService { List<Health> health(); String ping(String param,int param2); AaRes health1(List<AaReq> list); Health health2(AaReq aaReq); //impl @Service(timeout = 1000, group = "dev", version = "4.0") public class DubboHealthServiceImpl implements DubboHealthService { ...... }在 Apache Dubbo-go 的 client 配置文件中,需要的核心配置如下:# registry config registries: "demoNacos": protocol: "nacos" timeout: "3s" address: "xxx.xxx.xxx" username: "****" password: "****" references: "UserProvider": registry: "demoNacos" protocol: "dubbo" interface: "com.xiaomi.youpin.test0930.api.service.DubboHealthService" cluster: "failover" version: "4.0" group: "dev" generic: true methods: - name: "health" retries: 0 timeout: "0.5s" ......首先配置对应注册中心,包括选型及地址,Nacos/zookeeper 等,其次配置需要调用的具体接口,方法、超时时间等信息。由于我们使用泛化调用,需要进行配置 generic: true。这里我们在使用 v1.5.7 版本时发现了关于泛化调用下方法级别超时时间并不生效的情况,进行了修复,详细可以参考该 pr配置完成后,泛化调用的方式我们进行了一定的封装://...... var paramTypes []string var paramVals []interface{} for _, param := range req.Params { paramTypes = append(paramTypes, param.GetKey()) paramVals = append(paramVals, param.GetVal()) //添加context信息 m := make(map[string]string) m["xxx(generic_flag)"] = "xxx(flag)" //服务端返回json字符串 m["xxx(return_flag)"] = "true" ctx = context.WithValue(context.Background(), constant.DubboCtxKey("attachment"), m) //invoke调用 response, err = config.GetRPCService(req.AppName).(*config.GenericService).Invoke(ctx, []interface{}{req.MethodName, paramTypes, paramVals}) if err != nil { err = fmt.Errorf("dubbo call request appName: %s methodName: %s rpc invoke failed,err:%+v", req.AppName, req.MethodName, err) return }这里实际上业务只需要传入需要调用的 Apache Dubbo 方法,参数列表例如  ["java.lang.String"] 以及参数值即可。为了切合业务需要,我们在内部维护的 Java Dubbo 版本中也做了一定程度的兼容与改造,Apache Dubbo-go 中通过 context,即 attachment 可以带上两个特殊标识,服务端的 Java Dubbo 版本中将根据该特殊标识接收处理与返回以 json 格式的数据。这样一来,留存的 Go 服务就能够使用 Apache Dubbo 协议与 Java Dubbo 生态的服务达到互联互通,同时也由于 Apache Dubbo 的优势,也具备了一定程度的服务治理能力。在线上运行该版本 Apache Dubbo-go 时,也发现了 Apache Dubbo-go 提供的像黑名单机制等的一些不太合理之处,例如该机制下,当服务端出现报错后,调用方会将该服务端的 ip 记录黑名单,再进行调用时可能出现 no provider 的情况,而实际上服务端可能仅是针对某个请求的处理报错,服务实际上能够正常运行,那么这时候该机制便有待商榷,我们实际使用时也是进行了摘除。详细细节可见该 pr。现状与未来发展1、当前架构目前小米新零售已经基于上述 mione 的体系以及上述介绍的这一部分组件,建立了一套较为完善的,包括微服务标准化、可持续集成部署、以及可见可控的观测性平台的服务治理体系。在传统的微服务体系下,我们通常需要满足两个服务治理的基本的需求:一站式的服务治理平台、普适性的服务开发框架。前者我们通过 mione 实现了包括但不限于基于容器化的 CICD、服务的标准化定义、服务的生命周期管理(服务上下线、扩缩容等)、服务的基本通信和链路治理(如重试、限流降级熔断等);而后者我们借助了 Apache Dubbo 、Apache Dubbo-go 等开源 RPC 框架,结合像 Springboot 这样的传统开发框架提供了较为标准化的服务搭建开发流程。同时,我们内部自研了一套可见可观测性体系,帮助我们获取更多有价值的数据来反馈于服务治理,对服务做到更全面准确的把控。这实际上包括了 3 个层次的工具集合:Logging(日志系统)、Metric(度量系统) 以及 Tracing(分布式链路追踪系统)我们通过上述的架构与设计实际上已经基本上满足了传统方式下对微服务治理需求,然而,这还不够。未来方向1、Service Mesh 与 ServerlessService Mesh首先什么是 Service Mesh?Service Mesh 是一个致力于解决服务间通信的基础设施层,它负责在现代云原生应用的复杂服务拓扑下实现请求的可靠传递,它通常实现为一组轻量级的网络代理,与应用服务部署在一起,对应用服务透明。我们上面架构组件中的 sidecar soa-agent 实际上就是一个 service mesh 的雏形,这个组件目前承担了包括服务发现、配置托管等一些能力,当然,他能够做到的应当更多。对于业务应用服务的透明以及零侵入是 service mesh 的一大优势,也是当前它正备受推崇的主要原因。综合来看,Service Mesh 主要能够解决当下传统微服务体系的几大痛点:1、完善的微服务基础设施service mesh 能够将微服务的通信下沉到基础设施层,它屏蔽了微服务处理各种通信问题的复杂度。对于业务开发者来说,实际上他并不关心像 Rpc 通信、服务注册与发现这样的非功能性细节。但传统微服务下,拿 Thrift 举例,作为开源的一套性能较高的 Rpc 框架,由于它缺乏一些基本的服务治理能力,Thrift 很多时候并无法做到开箱即用,在早期小米电商的基础架构团队就对 Thrift 做了定制化的二次开发,在生成的桩代码中加入了服务发现、打点等功能,这些代码再与自研的开发框架 koala 耦合来实现服务的闭环调用。而这些框架代码以及生成的桩代码,与业务代码也并没有明显的隔离与区分,甚至业务能够直接修改框架代码以及桩代码,实际上埋下了较大的隐患,也造成后续升级困难、严重阻塞等问题。而 service mesh 则可以完美的解决像这样的痛点,通过对这些能力的下沉,他们将对业务服务屏蔽实现细节,业务服务也就不再需要关心包括服务发现、负载均衡、流量调度、限流降级熔断、监控统计等一切细节。2、语言无关的通信和链路治理实际上 service mesh 在功能上并没有提供对于服务治理的任何新的特性和能力,它所能够提供的能力在 service mesh 之前其实都能够找到。service mesh 改变的是通信和服务治理能力的提供方式,它将这些能力从业务层面解耦,下沉到基础设施中,以更加标准化和通用的方式来提供,这样一来它便能屏蔽不同语言、不同平台的差异性,在多语言、多技术栈的团队环境中,它能够提供胶水般的融合与协同能力。这也是我们上面小米电商微服务调用架构图中 sidecar 所做到的,为跨语言的调用提供了解决方案。3、通信和服务治理的标准化通过标准化,带来一致的服务治理体验,减少多业务之间由于服务治理标准不一致带来的沟通和转换成本,提高全局服务治理的效率。鉴于以上 service mesh 带来的好处,小米电商微服务的架构在未来会进一步在已有基础上更多的调研、参考以及参与该技术落地。但是,硬币总有正反面,service mesh 也绝不是仅有优点的万能膏药。实际上,引入多一层的组件代理转发请求,本身就不可避免地带来更多的资源消耗,在一定程度上会降低系统的通信性能。其次,基础功能与服务解耦有解耦的绝对优势,但侵入式框架反而在支持业务的定制与扩展能力上反而有先天优势,这点在系统的设计中也应当考虑。第三,系统中对于组件的引入本身也带来一定的风险,业务将及其依赖 service mesh 的稳定性,在保障 service mesh 的稳定性上将带来更多的技术考验。目前我们对于 service mesh 的用法实现设计如下图所示,我们通过 Sidecar 的方式,将服务发现、负载均衡、集群策略、健康检查以及部分的监控打点等下沉到该组件中,该组件对于不同的服务部署方式部署方式稍有不同。例如对于早期的裸物理机部署的老服务来说,该组件与服务部署在同一台物理机,而对于例如 K8s 这样的容器部署方式,只需要部署在同一个 Pod ,即共享同一个 ip 即可。Sidecar 中开放了一些 OpenAPI,部署在一起的服务只需要访问 localhost 对应端口的 OpenAPI 即可达到相应的服务治理能力。未来小米新零售效能团队也将在大量的考量与取舍中,更进一步地参与与适配该技术的落地,其中关键的一步也将会有对于 Apache Dubbo、Apache Dubbo-go 等底层框架的适配与融合,必要地情况下将进行一些定制化的改造。2、Serverless什么是 Serverless? Serverless(无服务器架构)指的是由开发者实现的服务端逻辑运行在无状态的计算容器中,它由事件触发, 完全被第三方管理,其业务层面的状态则被开发者使用的数据库和存储资源所记录。这也是当下比较热门的方向。Serverless 是云原生技术发展的高级阶段,使开发者更聚焦在业务逻辑,而减少对基础架构的关注。它与我们之前说的 service mesh 实际上并不在同一理念上,service mesh 倾向于将基础能力下沉,业务服务与代理一同部署。而 Serverless 则干脆希望开发者不再关注服务器,不再关注服务所需资源,这些资源与能力将由 Serverless 的厂商来提供。开发者只需要编写业务函数即可(函数即服务 FaaS)。相同的是,两者的目的都是为了业务开发能够仅专心于业务逻辑。目前我们小米新零售效能团队也正在尝试对一些服务进行 Serverless 化,并提供了一些基础的能力。这些 Serverless 化的服务在开发中同样不需要再关心底层的协议,无论是 Apache Dubbo、Apache Dubbo-go 都会在我们后端的 Serverless 系统中进行兼容与适配,同样以上的一些列服务治理的能力也将由 Serverless 系统全权托管。上图就是我们目前对于服务 Serverless 化的一个基本的支持逻辑,我们定义了成为 Serverless 服务的 Function 必须实现的接口 execute :public interface Handler { Result execute(Event var1, Context var2); default void init(Object... objs) { default String version() { return "0.0.1"; }业务仅需要实现该接口,并通过平台配置管理该服务的 git 库等信息,就可以以 Serverless 的方式开始提供服务,Serverless 系统将自动拉取该 Function 的代码信息,编译打包等,提交到核心池中等待执行。并且同时,服务将无感知地接入系统提供的服务治理、可观测性等能力。总结Dubbo 作为一个老牌的、强大的微服务框架与体系,提供了跨语言的支持,这帮助我们将内部不同的技术栈实际上形成了闭环。而 Apache Dubbo-go 作为 Apache Dubbo 生态中一个还在不断迭代发展的开源项目,会存在一些待完善的小问题,但更能够切实地帮助到我们搭建与发展整个云原生微服务体系。同样的,我们在完善传统的微服务体系架构的同时,我们也关注与尝试目前微服务技术的一些发展方向,像 Serverless、service mesh 这些较为热门的方向,我们也都将持续的跟进与参与落地。我们将不断与像 dubbogo 等开源社区合作,积极反馈我们使用的经验,参与完善,推动更多此类开源项目的发展。 作者介绍董振兴,目前就职于小米中国区新零售技术部-零售中台-研发效能组,负责小米中国区新零售微服务中间件体系及效能相关研发工作。欢迎对 Apache Dubbo-go 感兴趣的同行到 dubbogo 社区 钉钉群 23331795 进行交流。

Dubbo 3.0 规模化落地基石 - 社区持续集成机制解析

作者 | 熊聘背景Dubbo 3.0 在阿里巴巴各条业务线包括淘宝、考拉、饿了么、钉钉、达摩院等已全量或开始分批上线,社区企业如小米、工商银行、平安健康等也纷纷引入了 3.0 版本的新特性。支持如此大规模的体量的业务平稳运行,对 Dubbo 3.0 的稳定性有很高的要求,尤其是考虑到社区极高的活跃度,这个挑战就更大了。目前社区有超过 600 位 contributor,近一年以来每天有大约 60 个 commits,陆续支持了 Triple 协议、多实例等功能,这些功能都会涉及到大量的代码变更。每一次提交代码的质量对 Dubbo 3.0 版本的质量、稳定性、可靠性等方面有着至关重要的影响。现状Dubbo 保证提交代码的质量主要体现在以下几个方面:dubbo 代码仓库中的单测dubbo-samples 中的集成测试dubbo-benchmark 中的性能测试code review 机制其中,dubbo 的单测主要针对 Dubbo 代码单元的独立测试,侧重点在功能、分支覆盖等方面,是最基本的测试。dubbo-samples 主要是对 Dubbo 中常用的功能组合和场景进行测试,同时也会对齐 2.7.x 和 3.0 版本之间的功能。dubbo-benchmark 主要是在每次有重大版本升级变更的时候对性能进行压测。code review 机制是在每一次提交的代码都通过所有的单测和集成测试以后由社区的 contributor 和 committer 对提交的 pr 进行 review,当大家的意见不一致会在社区内进行讨论最终达成一致。问题集成测试和 benchmark 测试都是独立的代码仓库,进过 Dubbo 社区多年的演进,相对来说变更较少已经比较稳定了。code review 机制主要是通过人的主观判断来对代码的质量进行评估,Dubbo 社区一直在不断吸纳更多优秀的 contributor 加入,理论上这方面的质量是在不断提高的。相对而言,dubbo 的单测集中在 100 多个 module 中,是变更最多、最频繁的,也是最容易出问题的地方。目前 dubbo 的单测存在以下几个问题:1、耗时长dubbo 的单测会在 Ubuntu 和 Windows 上分别对 JDK8 和 11 进行测试,其中 Ubuntu 和 Windows 上运行单测的超时时间分别是 40 分钟和 50 分钟,但是我们发现经常会出现超时的情况。2、多注册中心场景无法覆盖dubbo 支持多注册中心,但是在单测中很难覆盖到与多注册中心相关的逻辑。dubbo 支持的注册中心包含 zookeeper、nacos、apollo 等,多种不同注册中心的混合场景更加难以覆盖。分析通过对单测运行日志进行抽查和分析我们发现,dubbo 单测的耗时主要集中在与 zookeeper 相关的 module 中。TestcaseTime elapsed(s)org.apache.dubbo.rpc.protocol.dubbo.ArgumentCallbackTest76.013org.apache.dubbo.config.spring.ConfigTest61.33org.apache.dubbo.config.spring.schema.DubboNamespaceHandlerTest50.437org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest44.678org.apache.dubbo.rpc.cluster.support.AbstractClusterInvokerTest29.954org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClientTest25.847org.apache.dubbo.config.spring.beans.factory.annotation.MethodConfigCallbackTest25.635org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListenerTest24.866org.apache.dubbo.remoting.zookeeper.curator5.Curator5ZookeeperClientTest19.664导致这一问题的最主要原因是因为我们在写单测的时候通常会使用 zookeeper 作为注册中心和元数据中心,而在运行单测的过程中要对 zookeeper 进行频繁的 start 和 stop 操作。每一个单测希望彼此之间互不干扰,都采用了独立的 zookeeper 作为注册中心和元数据中心。当将单测并行运行时又会出现 zookeeper 端口冲突的问题。现在需要解决的问题是:如何处理 dubbo 单测与注册中心和元数据中心的依赖问题。解决方案这个问题看似比较简单,但是在实践过程中却发现比想象的要复杂的多,分别对各种解决方案进行了尝试:1、TestingServerTestingServer 是 curator-test 包中提供的专门用来 mock zookeeper 的工具类,目前 dubbo 单测中大量使用了 TestingServer。对与多注册中心的场景是通过同时启动两个 TestingServer 对外暴露不同的端口的方式来实现的。代码如下:class ZookeeperRegistryCenter extends AbstractRegistryCenter { * Initialize the default registry center. public ZookeeperRegistryCenter(int... ports) { this.ports = ports; this.instanceSpecs = new ArrayList<>(this.ports.length); this.zookeeperServers = new ArrayList<>(this.ports.length); private static final Logger logger = LoggerFactory.getLogger(ZookeeperRegistryCenter.class); * The type of the registry center. private static final String DEFAULT_REGISTRY_CENTER_TYPE = "zookeeper"; private int[] ports; private List<InstanceSpec> instanceSpecs; private List<TestingServer> zookeeperServers; private AtomicBoolean started = new AtomicBoolean(false); * start zookeeper instances. @Override public void startup() throws RpcException { try { if (started.compareAndSet(false, true)) { logger.info("The ZookeeperRegistryCenter is starting..."); for (int port : this.ports) { InstanceSpec instanceSpec = this.createInstanceSpec(port); this.instanceSpecs.add(instanceSpec); this.zookeeperServers.add(new TestingServer(instanceSpec, true)); logger.info("The ZookeeperRegistryCenter is started successfully"); } catch (Exception exception) { started.set(false); throw new RpcException("Failed to initialize ZookeeperRegistryCenter instance", exception); * destroy the zookeeper instances. @Override public void shutdown() throws RpcException { logger.info("The ZookeeperRegistryCenter is stopping..."); List<RpcException> exceptions = new ArrayList<>(this.zookeeperServers.size()); for (TestingServer testingServer : this.zookeeperServers) { try { testingServer.close(); logger.info(String.format("The zookeeper instance of %s is shutdown successfully", testingServer.getConnectString())); } catch (IOException exception) { RpcException rpcException = new RpcException(String.format("Failed to close zookeeper instance of %s", testingServer.getConnectString()), exception); exceptions.add(rpcException); logger.error(rpcException); this.instanceSpecs.clear(); this.zookeeperServers.clear(); if (!exceptions.isEmpty()) { logger.info("The ZookeeperRegistryCenter failed to close."); // throw any one of exceptions throw exceptions.get(0); } else { logger.info("The ZookeeperRegistryCenter close successfully."); }1、优点实现简单启动和停止 zookeeper 速度快2、缺点无法模拟真实的 zookeeper无法测试 Curator 和 zookeeper 的版本兼容性问题nacos 和 apollo 没有提供这种 embedded 的方式,无法适用于所有类型的注册中心2、Github ActionsGitHub Actions 是 GitHub 上的 CI/CD,所有提交代码的单测都会在这上面运行。通过各种 action 来制定 workflow,可以在 workflow 中可以初始化运行的环境,所以想在初始化环境的时候将 zookeeper(或者 nacos 和 apollo)部署起来,然后再运行单测。当尝试这种方案的时候,我们进行了大量的尝试,也踩了不少的坑。1、dockerzookeeper、nacos 和 apollo 的镜像都有官方的版本,如果我们通过 docker 来拉起这些镜像,这个问题就迎刃而解了。通过查看 GitHub Actions 的官网发现 GitHub 提供的环境是内置了 docker 环境的,所以这条道路貌似比较容易,但是当 yml 文件写好以后发现在 Ubuntu 上是可以正常运行的,在 Windows上 会报错,错误信息如下:ERROR: no matching manifest for windows/amd64 in the manifest list entries通过研究发现这个问题主要是由于 Linux 上的镜像在 Windows 上无法识别,需要 Switch to Linux Container,这 GitHub Actions 中只能通过命令来实现,具体命令为:"C:\Program Files\Docker\Docker\DockerCli.exe" -SwitchLinuxEngine,但是执行这条命令后需要重启一下 docker。如果是在自己的 Windows 机器上这么操作是可行的,但是在 Github Actions 中操作显然是行不通的。当然,还有另一个思路:那就是 build 一个基于 Windows 版本的镜像。很快我们也尝试了这种方案,发现 Windows 上创建 zookeeper 的镜像与 Windows 系统的版本密切相关,并不适用于所有版本的 Windows 操作系统。同时,创建镜像一般都是采用 Powershell 脚本,这种脚本相比 shell 脚本来说使用的要少很多,必然会给后面的维护带来了很多的隐患。在编写 GitHub workflows 是还要考虑两个不同分支的问题。最后,我们通过修改现有的镜像生成脚本创建了基于 Windows 系统的 zookeeper 镜像,这个问题貌似总算是解决了。不幸的是,当我们运行单测的时候发现,在 Ubuntu 环境下拉起 zookeeper 镜像的耗时大约是 20 秒,而在 Windows 环境下需要 2 分钟左右,完全不是一个量级,这是我们完全不能接受的。通过分析我们发现,zookeeper 在 Ubuntu 上的镜像大小为 100MB 以内,而在 Windows 上却是 2.7G 左右,在 Windows 上拉取镜像的耗时最多,同时 zookeeper 在 Ubuntu 上的启动时间要比 Windows 快。2、shell 脚本docker 的方式既然行不通,那是不是可以尝试一下使用脚本部署的方式呢?考虑到 Windows 和 Linux 环境上脚本的差异,事先查了一下 Github Actions 上看看在不通操作系统上对脚本支持的情况:我们可以看到在 Windows 上对 bash shell 的支持仅仅是 Git for Windows 附带的 bash shell,往往一些复杂一点的 bash shell 命令就不支持了。由于我们使用的都是比较常见的 bash shell 命令,所以想试一试,于是就开始撸起了 shell 脚本。ZOOKEEPER_BINARY_URL="https://archive.apache.org/dist/zookeeper/zookeeper-$ZK_VERSION/apache-zookeeper-$ZK_VERSION-bin.tar.gz" case $1 instart) echo "Setup zookeeper instances...." # download zookeeper instances mkdir -p $ZK_2181_DIR $ZK_2182_DIR $LOG_DIR/2181 $LOG_DIR/2182 # download zookeeper archive binary if necessary if [ ! -f "$DIR/zookeeper/apache-zookeeper-$ZK_VERSION-bin.tar.gz" ]; then wget -P $DIR/zookeeper -c $ZOOKEEPER_BINARY_URL fi # setup zookeeper with 2182 tar -zxf $DIR/zookeeper/apache-zookeeper-$ZK_VERSION-bin.tar.gz -C $ZK_2181_DIR cp $ZK_2181_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo_sample.cfg $ZK_2181_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg # mac OS if [ "$(uname)" == "Darwin" ] then sed -i "_bak" "s#^clientPort=.*#clientPort=2181#g" $ZK_2181_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg sed -i "_bak" "s#^dataDir=.*#dataDir=$LOG_DIR/2181#g" $ZK_2181_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg else sed -i "s#^clientPort=.*#clientPort=2181#g" $ZK_2181_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg sed -i "s#^dataDir=.*#dataDir=$LOG_DIR/2181#g" $ZK_2181_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg fi echo "admin.serverPort=8081" >> $ZK_2181_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg # setup zookeeper with 2182 tar -zxf $DIR/zookeeper/apache-zookeeper-$ZK_VERSION-bin.tar.gz -C $ZK_2182_DIR cp $ZK_2182_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo_sample.cfg $ZK_2182_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg # mac OS if [ "$(uname)" == "Darwin" ] then sed -i "_bak" "s#^clientPort=.*#clientPort=2182#g" $ZK_2182_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg sed -i "_bak" "s#^dataDir=.*#dataDir=$LOG_DIR/2182#g" $ZK_2182_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg else sed -i "s#^clientPort=.*#clientPort=2182#g" $ZK_2182_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg sed -i "s#^dataDir=.*#dataDir=$LOG_DIR/2182#g" $ZK_2182_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg fi echo "admin.serverPort=8082" >> $ZK_2182_DIR/apache-zookeeper-$ZK_VERSION-bin/conf/zoo.cfg echo "Start zookeeper instances...." $ZK_SERVER_2181 start $ZK_SERVER_2182 start ;;stop) echo "Stop zookeeper instances...." $ZK_SERVER_2181 stop $ZK_SERVER_2182 stop rm -rf $DIR/zookeeper ;;status) echo "Get status of all zookeeper instances...." $ZK_SERVER_2181 status $ZK_SERVER_2182 status ;;reset) echo "Reset all zookeeper instances" $ZK_CLIENT_2181 -timeout 1000 -server 127.0.0.1:2181 deleteall /dubbo $ZK_CLIENT_2182 -timeout 1000 -server 127.0.0.1:2182 deleteall /dubbo ;;*) echo "./zkCmd.sh start|stop|status|reset" exit 1 ;;esac脚本写完以后发现,在 Mac 和 Linux 系统上运行都是正常的,但是这个脚本在 Windows 上的 git-bash 却是行不通的。主要原因是对 wget、sed 命令不支持。wget 通过 curl 命令来替换可以实现下载的功能,但是 sed 命令确实很难替换。最后,在赫炎大佬的提示下,在 Github Workflows 中安装了 msys2 插件,msys2 可以建立一个简单易用的统一环境,也就是说可以在 Windows 上运行 bash shell,经过验证发现这一方案确实可行。steps: - name: "Set up msys2 if necessary" if: ${{ startsWith( matrix.os, 'windows') }} uses: msys2/setup-msys2@v2 with: release: false # support cache, see https://github.com/msys2/setup-msys2#context优点使用全局 zookeeper 来作为注册中心和元数据中心,大大降低了注册中心的启动和销毁次数代码无侵入,写单测的时候不用维护注册中心的生命周期更接近生产环境可以支持多版本、不同类型的注册中心混用缺点代码在本地运行时需要手动启动注册中心一切看似很完美,但是如果在本地运行单测的时候强制要求开发者在本机启动注册中心,这貌似违背了单测的原则。为了解决这一问题,我们又尝试了新的解决方案。3、TestExecutionListenerTestExecutionListener 是 Junit5 在运行单测的过程中对外提供的一个接口,可以通过这个接口获取所有单测启动、所有单测全部结束、单个单测启动、单个单测结束等相关的事件。/** * Register a concrete implementation of this interface with a {@link Launcher} * to be notified of events that occur during test execution. * <p>All methods in this interface have empty <em>default</em> implementations. * Concrete implementations may therefore override one or more of these methods * to be notified of the selected events. * <p>JUnit provides two example implementations. * <ul> * <li>{@link org.junit.platform.launcher.listeners.LoggingListener}</li> * <li>{@link org.junit.platform.launcher.listeners.SummaryGeneratingListener}</li> * </ul> * <p>Contrary to JUnit 4, {@linkplain org.junit.platform.engine.TestEngine test engines} * are supposed to report events not only for {@linkplain TestIdentifier identifiers} * that represent executable leaves in the {@linkplain TestPlan test plan} but also * for all intermediate containers. However, while both the JUnit Vintage and JUnit * Jupiter engines comply with this contract, there is no way to guarantee this for * third-party engines. public interface TestExecutionListener { * Called when the execution of the {@link TestPlan} has started, * <em>before</em> any test has been executed. * @param testPlan describes the tree of tests about to be executed default void testPlanExecutionStarted(TestPlan testPlan) { * Called when the execution of the {@link TestPlan} has finished, * <em>after</em> all tests have been executed. * @param testPlan describes the tree of tests that have been executed default void testPlanExecutionFinished(TestPlan testPlan) { * Called when the execution of a leaf or subtree of the {@link TestPlan} * has finished, regardless of the outcome. * <p>The {@link TestIdentifier} may represent a test or a container. * <p>This method will only be called if the test or container has not * been {@linkplain #executionSkipped skipped}. * <p>This method will be called for a container {@code TestIdentifier} * <em>after</em> all of its children have been * {@linkplain #executionSkipped skipped} or have * {@linkplain #executionFinished finished}. * <p>The {@link TestExecutionResult} describes the result of the execution * for the supplied {@code TestIdentifier}. The result does not include or * aggregate the results of its children. For example, a container with a * failing test will be reported as {@link Status#SUCCESSFUL SUCCESSFUL} even * if one or more of its children are reported as {@link Status#FAILED FAILED}. * @param testIdentifier the identifier of the finished test or container * @param testExecutionResult the (unaggregated) result of the execution for * the supplied {@code TestIdentifier} * @see TestExecutionResult default void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) { }我们通过实现 TestExecutionListener#testPlanExecutionStarted 的接口启动注册中心,TestExecutionListener#testPlanExecutionFinished 接口用来销毁注册中心,在每个单测运行结束以后,通过 TestExecutionListener#executionFinished 的接口来重置注册中心中的数据。通过这种方式就可以解决开发者在本地运行单测的时候需要手动启动注册中心的问题了。但是实现起来却是并不是那么简单。我们将注册中心的生命周期抽象成以下几个部分:初始化:这个过程包括下载 zookeeper 的 jar 包、解压 jar 包和修改配置文件 3 个过程启动:启动多个注册中心重置:每次单测运行结束后重置注册中心中的数据销毁:关闭多个注册中心1、初始化下载文件、解压和修改配置这几个过程看似简单,但是想实现的比较优雅却还是要花一番工夫的。需要考虑异步下载、重复下载、重复解压、并行解压、无网络或者网络不稳定情况下的解决方案、端口占用等一系列问题。2、启动启动 zookeeper 在 Windows 上是通过 zkServer.cmd 脚本,而在 Linux 上是通过 zkServer.sh 脚本,这两个脚本实现的方式是截然不同的。同时,我们希望注册中心是运行在单独进程中,这就需要使用 ProcessBuilder 的方式来启动 zookeeper。在 Linux 上相对简单一点,代码如下:protected Process doProcess(ZookeeperContext context, int clientPort) throws DubboTestException { logger.info(String.format("The zookeeper-%d is starting...", clientPort)); List<String> commands = new ArrayList<>(); Path zookeeperBin = Paths.get(context.getSourceFile().getParent().toString(), String.valueOf(clientPort), context.getUnpackedDirectory(), "bin"); commands.add(Paths.get(zookeeperBin.toString(), "zkServer.sh") .toAbsolutePath().toString()); commands.add("start"); commands.add(Paths.get(zookeeperBin.getParent().toString(), "conf", "zoo.cfg").toAbsolutePath().toString()); try { return new ProcessBuilder().directory(zookeeperBin.getParent().toFile()) .command(commands).inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE).start(); } catch (IOException e) { throw new DubboTestException(String.format("Failed to start zookeeper-%d", clientPort), e); }通过检测 Process 中输出的日志来的关键词来判断是否启动成功。在 Windows 上会比较复杂一点,因为 Windows 上运行 zkServer.cmd 脚本的时候会弹出一个黑框,需要采用后台的方式来运行。同时,当这个黑框关闭以后 zookeeper 就被关闭了。同样尝试使用 ProcessBuilder 的方式来实现发现遇到不少问题,特别是通过 start /b cmd.exe /c zkServer.cmd 命令来启动 zookeeper。最后通过 commons-exec 包中的 Executor 来实现了在 Windows 环境启动 zookeeper。protected void doProcess(ZookeeperWindowsContext context) throws DubboTestException { ...... for (int clientPort : context.getClientPorts()) { logger.info(String.format("The zookeeper-%d is starting...", clientPort)); Path zookeeperBin = Paths.get(context.getSourceFile().getParent().toString(), String.valueOf(clientPort), context.getUnpackedDirectory(), "bin"); Executor executor = new DefaultExecutor(); executor.setExitValues(null); executor.setWatchdog(context.getWatchdog()); CommandLine cmdLine = new CommandLine("cmd.exe"); cmdLine.addArgument("/c"); cmdLine.addArgument(Paths.get(zookeeperBin.toString(), "zkServer.cmd") .toAbsolutePath().toString()); context.getExecutorService().submit(() -> executor.execute(cmdLine)); }这里需要提醒的是,启动 Process 以后需要保存 pid,后面销毁的时候会用到。3、重置这个功能是最简单的,因为现在注册中心已经启动了,只需要连接上注册中心删除注册上去的节点即可。public void process(Context context) throws DubboTestException { ZookeeperContext zookeeperContext = (ZookeeperContext)context; for (int clientPort : zookeeperContext.getClientPorts()) { CuratorFramework client; try { CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder() .connectString("127.0.0.1:" + clientPort) .retryPolicy(new RetryNTimes(1, 1000)); client = builder.build(); client.start(); boolean connected = client.blockUntilConnected(1000, TimeUnit.MILLISECONDS); if (!connected) { throw new IllegalStateException("zookeeper not connected"); // 删除dubbo节点 client.delete().deletingChildrenIfNeeded().forPath("/dubbo"); } catch (Exception e) { throw new DubboTestException(e.getMessage(), e); }4、销毁通过研究 zookeeper 的 zkServer.cmd 和 zkServer.sh 脚本发现,在执行 zkServer.sh stop 命令的时候其实是找到 zookeeper 的 pid 然后再 kill 掉。stop) echo -n "Stopping zookeeper ... " if [ ! -f "$ZOOPIDFILE" ] echo "no zookeeper to stop (could not find file $ZOOPIDFILE)" $KILL $(cat "$ZOOPIDFILE") rm "$ZOOPIDFILE" sleep 1 echo STOPPED exit 0 在 Linux 上相对简单一点,代码如下:protected Process doProcess(ZookeeperContext context, int clientPort) throws DubboTestException { logger.info(String.format("The zookeeper-%d is stopping...", clientPort)); List<String> commands = new ArrayList<>(); Path zookeeperBin = Paths.get(context.getSourceFile().getParent().toString(), String.valueOf(clientPort), context.getUnpackedDirectory(), "bin"); commands.add(Paths.get(zookeeperBin.toString(), "zkServer.sh") .toAbsolutePath().toString()); commands.add("stop"); try { return new ProcessBuilder().directory(zookeeperBin.getParent().toFile()) .command(commands).inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE).start(); } catch (IOException e) { throw new DubboTestException(String.format("Failed to stop zookeeper-%d", clientPort), e); }但是在 Windows 上却有所不同,需要将之前记录的 pid 杀掉,代码如下:protected void doProcess(ZookeeperWindowsContext context) throws DubboTestException { logger.info("All of zookeeper instances are stopping..."); // find pid and save into global context. this.findPidProcessor.process(context); // kill pid of zookeeper instance if exists this.killPidProcessor.process(context); // destroy all resources context.destroy(); }在这个过程中需要考虑重重复销毁的问题,所以在销毁之前会先查一下 pid 然后再销毁。查找 pid 是通过 netstat 命令实现的,代码如下:private void findPid(ZookeeperWindowsContext context, int clientPort) { logger.info(String.format("Find the pid of the zookeeper with port %d", clientPort)); Executor executor = new DefaultExecutor(); executor.setExitValues(null); ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream ins = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(ins.toByteArray()); executor.setStreamHandler(new PumpStreamHandler(out, null, in)); CommandLine cmdLine = new CommandLine("cmd.exe"); cmdLine.addArgument("/c"); cmdLine.addArgument("netstat -ano | findstr " + clientPort); try { executor.execute(cmdLine); String result = out.toString(); logger.info(String.format("Find result: %s", result)); if (StringUtils.isNotEmpty(result)) { String[] values = result.split("\\r\\n"); // values sample: // Protocol Local address Foreign address Status PID // TCP 127.0.0.1:2182 127.0.0.1:56672 ESTABLISHED 4020 // TCP 127.0.0.1:56672 127.0.0.1:2182 ESTABLISHED 1980 // TCP 127.0.0.1:56692 127.0.0.1:2182 ESTABLISHED 1980 // TCP 127.0.0.1:56723 127.0.0.1:2182 ESTABLISHED 1980 // TCP [::]:2182 [::]:0 LISTENING 4020 if (values != null && values.length > 0) { for (int i = 0; i < values.length; i++) { List<String> segments = Arrays.stream(values[i].trim().split(" ")) .filter(str -> !"".equals(str)) .collect(Collectors.toList()); // segments sample: // TCP // 127.0.0.1:2182 // 127.0.0.1:56672 // ESTABLISHED // 4020 if (segments != null && segments.size() == 5) { if (this.check(segments.get(1), clientPort)) { int pid = Integer.valueOf(segments.get(segments.size() - 1).trim()); context.register(clientPort, pid); return; } catch (IOException e) { throw new DubboTestException(String.format("Failed to find the PID of zookeeper with port %d", clientPort), e); }通过 killtask 命令来销毁进程,代码如下:protected void doProcess(ZookeeperWindowsContext context) throws DubboTestException { for (int clientPort : context.getClientPorts()) { Integer pid = context.getPid(clientPort); if (pid == null) { logger.info("There is no PID of zookeeper instance with the port " + clientPort); continue; logger.info(String.format("Kill the pid %d of the zookeeper with port %d", pid, clientPort)); Executor executor = new DefaultExecutor(); executor.setExitValues(null); executor.setStreamHandler(new PumpStreamHandler(null, null, null)); CommandLine cmdLine = new CommandLine("cmd.exe"); cmdLine.addArgument("/c"); cmdLine.addArgument("taskkill /PID " + pid + " -t -f"); try { executor.execute(cmdLine); // clear pid context.removePid(clientPort); } catch (IOException e) { throw new DubboTestException(String.format("Failed to kill the pid %d of zookeeper with port %d", pid, clientPort), e); }至此,彻底解决了单测在本地运行时需要手动启动注册中心的问题了。优点支持多种类型注册中心的混用。如果需要支持 nacos,只要按照这个方案针对 nacos 实现一遍即可。最大限度的模拟生产环境开发者使用无感代码无倾入缺点依赖网络环境针对无网络或者网络不稳定的情况,可以把下载好的 zookeeper 二进制文件 copy 放到指定的目录下即可。总结通过代码测试优化,Dubbo 3.0 的单测运行耗时在 Ubuntu 环境下从 40 分钟下降到 24 分钟,在 Windows 环境下从 50 分钟下降到 30 分钟左右,也很好的解决了多注册中心无法覆盖的问题。提高 Dubbo 3.0 版本的质量、稳定性和可靠性一直是 Dubbo 社区契而不舍的目标。这一次的优化仅仅只是向前迈出了一小步,后续还会朝着这个方向不断改进,也希望有更多对 Dubbo 感兴趣的同学积极参与社区贡献!在此也非常感谢赫炎和河清两位大佬的指导!Dubbo 社区刚刚发布了 3.0.5 版本,Go 语言的首个 3.0 正式版本也已发布。欢迎更多的 Dubbo 3 用户在此登记,以便能更好的与社区交流使用问题。https://github.com/apache/dubbo/issues/9436对 dubbogo感兴趣的同学,可加入钉钉群 23331795 进行交流。作者介绍熊聘,Apache Dubbo Committer,Github 账号:pinxiong微信公众号:技术交流小屋。关注 RPC、Service Mesh 和云原生等领域。现任职于携程国际事业部研发团队,负责市场营销、云原生等相关工作。

基于 Mesh 的统一路由在海外业务的实践

作者 | 深简、天千背景Service Mesh 从 2016 年被提出来到现在,无论是应用探索,还是技术演进,都已经有了长足的发展,国内也有多家互联网大厂进行了 Mesh 化的落地实践。阿里巴巴做为早期在 Mesh 领域投入的厂家之一,在集团内部经历过技术验证,价值探索,规模落地,技术红利释放等阶段,期间解决了不少和阿里集团规模化相关的难题挑战,也见证了这一技术带来的革新变化:一方面阿里巴巴的服务和节点规模特别大,istio + envoy 方案难以支持如此大规模的服务,因为我们在性能优化上做了很多工作;另外在技术支撑体系上,阿里巴巴很多基础实施都是基于 Java 技术栈的,为了接入阿里巴巴相对较完善的技术体系,我们也花了很大的精力用 C++和 Golang 重写了很多内部的组件;在价值探索方面,我们在短期价值和长期价值上和业务方做了很多平衡和取舍。本文主要介绍我们最近在利用 Service Mesh 架构解决海外业务问题中一些实践和价值探索。我们在海外业务引入 Mesh 架构过程中,充分利用 Istio 的基于 yaml 来描述和定义路由的抽象能力,制定了企业流量治理标准,并将集团海外业务发展多年的多种路由模块统一成使用 Mesh 的统一路由框架,且在今年双十一支撑了全量的海外业务。也希望通过我们的经验介绍,可以给其他还在探索如何落地 Mesh 的同仁一些参考。海外业务的路由复杂性在阿里巴巴集团,海外业务对于路由的要求远比国内业务更为复杂,因此海外业务团队基于现有微服务框架定制了很多路由能力,每一种路由能力都独立实现了一个模块,比如切流、容灾、演练、灰度等各种维度的流量调度,这样形成了很多独立的模块,使用方式也各不相同,如有的是通过配置调度,有的是修改代码调度等。维护这些模块的成本很高,路由方式不够灵活且粒度较大,基于这样的一个大背景我们开始在海外业务引入 Mesh,通过 Mesh 化的统一路由来解决这些业务痛点。通过对业务抽象我们归纳出海外业务路由的三个基本过程:流量打标、集群归组、条件路由,可以简单描述为符合某些条件的流量,路由到对应集群下的某个组。这样问题本质就变成了如何划分集群节点组以及怎么识别符合条件的流量。对应到 Isito 就是 Virtual Service 和 Destination Rule。前者可以根据请求中的一些 header、上下文等条件来选择一个预先定义好的分组,而后者则是根据机器的 label 来划分组。路由模型有了,接下来就是将海外业务的各种路由模块映射到 Virtual Service 和 Destination Rule。但事实上的路由比我们预期的还要复杂,除了需要支持路由叠加,还需要有各种条件的 Fallback,最终就像一个大漏斗一样,每一个路由模块都要在上一个路由模块的基础上再根据自己的条件过滤出一批符合要求的节点。因此我们在 Istio 的基础上进行了改进,提出了 RouteChain 和 RouteGroup 的概念,一组 Virtual Service 和 Destination Rule 是一个 RouteGroup,用来定义一类路由,多个 RouteGroup 通过 RouteChain 进行任意编排形成一个大漏斗(如下图)。在标准 Istio 实现上,Destination Rule 实际上是通过在控制平面根据一些 label 划分出一个组,然后给这个组创建一个集群再下发给 Envoy。如果一个集群要划分多个组,而且每个组之间会有一些相交那么实际上会导致下发给 Envoy 的节点膨胀,例如一个节点属于三个组,那么这个节点在 Envoy 内部会保存三份。在阿里巴巴内部节点数的规模一般都很大,叠加 Istio 这种归组方式就会导致 Envoy 内存膨胀,因此我们在内部也针对这种情况做了一个优化,将整个 Destination Rule 归组的逻辑进行了下沉,由 Envoy 在集群内部自己来完成归组。整套方案和 Envoy 社区的 Subset LoadBalancer 机制很类似,节点只存放一份,每一个归组实际上只是一组指向节点的指针。通过这样的方式最后我们成功将海外业务的所有路由都成功映射到我们的这套统一路由的方案中。分层构建统一流量调度对于业务方来说,始终关注的是路由功能和场景,例如灰度场景、切流场景等;而 Mesh 底层提供的是一个个路由原子能力,可以将一个集群按照机器分组、按照地域、按照环境等等分组,可以根据请求中的 header、上下文等信息进行路由到某个分组。这两者之间存在一个 gap:如何使用 Mesh 提供的路由原子能力,构建出有业务语义的调度场景。为此我们和业务方一起实施了基于分层的统一流量调度方案,整个方案分成了三层:最底层是提供原子路由能力的 Mesh 化底座,包括 RouteGroup、RouteChain 等基本的原子路由能力;中间一层则是具有平台属性的产品能力,封装了 Mesh 提供的底层原子能力,针对业务场景提供定制化的标准模型,可以定义路由策略,编排路由组合等;最上面一层则是具有业务属性的一个个流量调度场景。整个统一流量调度的架构如下:通过这套统一流量调度方案使得整个海外的路由都收敛到一个平台上,并且后续新增路由场景都可以做到不需要代码变更就可以完成,切流的粒度也可以做到服务粒度。相比于之前只能做到应用维度,粒度更细,效率更高。路由可视化除了价值探索之外,我们在 Mesh 化过程中也解决了许多工程实践问题,例如Mesh路由过程可视化就是其中一个例子。在引入 Mesh 之前,业务方的路由问题都是由各个功能团队解决,而 Mesh 化之后,所以路由维护的责任都转移到了 Mesh 团队,这样 Mesh 团队答疑和问题排查的工作量变得很大,再加上海外业务路由可叠加与自由编排的属性,如何确保路由配置符合预期也是一件非常耗时的事。为了解决这个问题,我们开发了路由仿真平台,通过该平台可以对线上流量进行镜像、解析和回放并生成选路过程记录,最终再返回给路由平台,通过这样的一个闭环仿真过程,内部经过了哪些 RouteGroup,匹配到了哪个路由分组,最后选择了哪台机器都在一个选路图上呈现,路由过程直接图形化。例如有如下路由请求:通过仿真平台模拟,可以得到与线上选路完全一致的路由执行图,选路过程和结果都一目了然,效果如下:结束语通过落地业务增量价值,与业务方共同探索和解决 Mesh 化进程中的各种问题,从而共同成长,这给规模化落地 Service Mesh 提供了可行的推广路径。目前我们已经围绕 Service Mesh 构建了完善的产品体系,除了支持阿里集团内部大量电商业务,也在开源和云上进行了多项能力输出;未来,我们会持续在价值探索、落地路径、流量治理标准、高性能服务网格等方面持续投入,并及时将阿里巴巴在 Mesh 领域所积累的经验与业界共享,在构建这一面向未来的新技术的道路上,期待看到 Service Mesh 百花齐放的盛况。

ASI 2021 年双十一万级别超大规模集群的高性能提升

作者 | 韩堂 幻云 川义等缘起统一调度和弹性调度ASI 是 Alibaba Serverless infrastructure 的缩写,是针对云原生应用设计的统一基础设施。为了实现最大化利用云的能力,通过统一调度,实现了 ASI 成为阿里集团所有业务的底座,包括新加入到统一调度架构的搜推广业务,实时计算 Flink 业务,FaaS 业务,中间件,新计算 PAI 等,以及通过统一调度来进行架构升级的 MaxCompute 业务, 泛电商业务等。ASI 通过一套架构成为所有业务和基础服务的底座,带来的是整体阿里集团的站点交付在容器和调度层面完成大一统,今年在云侧的交付效率提升,在 9.15 完成建站压测验收发挥了非常重要的作用。图 1:统一调度的合作模式在这个过程当中,统一调度是 ASI 技术底座,一层调度和各个二层调度,业务方一起通力合作(如图1),从研发,测试,发布一起完成技术大升级,以及通过业务迁移实施最终实现千万级核的规模,确保了双十一 9.15 的云侧顺利交付,并完成双十一大考。在统一调度的架构基础上,通过弹性调度体系来完成资源和能效优化的目标。包括 CPUShare,CPU 归一化,VPA 垂直伸缩,Federation 集群联邦,重调度技术的规模化铺开,以及 HPA 横向扩缩,ECI 弹性调度的探索。统一调度架构的升级,弹性调度体系的建设对集群规模化都提出了更高的需求,单集群规模化的需求成为了今年最大的挑战。如搜推广在离线集群实际达到了万级别的节点数,十万级别的 pod 数,调度吞吐千级别 pod/s;MaxCompute 业务 Task 链路达到了每秒十万级别的调度频次;在快上快下大促当天通过在大数据离线集群中快速拉起在线站点场景中,完成了大促当日多个交易导购单元站点的快速拉起和释放。apiserver/scheduler/etcd/webhook/kubelet 上完成了大量的性能优化,具备行业领先性。统一调度架构在线场景下应用服务的资源约束多,追求最佳部署:既要保障应用服务的高可用性,还要保障应用服务的运行时效果,调度吞吐一般比较慢;离线场景下,尤其是以 MaxCompute 为代表的大数据计算场景任务规模大、任务规格小、运行周期短,就要求调度离线任务时需要具备很高的调度吞吐能力(十万级别的调度频次)。针对在线以及搜索的离线我们采用的 K8s 原生的 pod 链路或 pod 兼容链路。针对 MaxCompute 采用自研的 Task 链路。MaxCompute 单集群上万台机器时,每秒十万级别的调度频次带来这样高频的资源流转对 Kube ApiServer 消息转发以及 etcd 造成很大压力,我们通过性能分析以及压测得出,K8s 的原生 pod 链路能力无法满足 MaxCompute 的性能需求。因此 ASI 统一调度在 K8s 原生 pod 链路上,创造出了基于 Pod 和 Task 双链路的统一调度架构。统一调度架构规模化对 ASI 底座带来的全方位挑战ASI 在统一调度中完成 2 个重要的角色,第一个是供给云原生资源,为业务提供 pod 对应的计算资源;第二个是提供状态数据库,为业务提供状态信息存储。基于 ASI 构建的搜推广等上面跑的离线业务,Blink、PAI、Holo 等新计算平台,APICallLatency  已经成为其计算链路服务 SLO 的关键部分,大促建站,快上快下的在线站点快速交付,APICallLatency 也成为其 Pod 交付 SLO 的关键部分。图 2:性能 SLO 体系&服务调用管理大图-APICallLatency 成为 SLO 的关键部分图 3:社区版本 K8s 的规模限制面对社区 K8s 5000 的能力现状,ASI 需要满足统一调度万级别节点需要做些什么呢?会面临哪些挑战呢?1)资源层面:随着集群规模增大,业务形态的变化,以 IP、云盘为代表的核心资源会打破已有计划性的资源供应,间断性的突发增长,造成资源短缺,出现云资源申请超时问题,造成 Pod 交付失败。日常单集群每天十万级别的扩缩容量级,如果采用社区版本单机的 DaemonSet 直接访问阿里云 openapi 和 K8s api,对 ASI 的压力都是非常巨大的,都会很容易触发 ASI 或云 openapi 的限流,造成 Pod 交付超时失败。同时在 Serverless 场景下,对这块的扩容效率有更高的要求。2)节点层面:随着节点规模增大,kubelet 无法及时更新 node 心跳时间问题,导致节点状态 NotReady,导致容器调度受影响,特别影响到训练作业的生产以及迁移。3)APIServer 层面:随着 Pod 规模的增大,WatchCache 的大小满足不了 Pod 访问的要求,出现了大量的watch Error 及 relist 情况。随着集群资源变化更大时,watch 的性能压力会越大,而在统一调度中,离线的单机客户端也会 watch pod,这意味着 pod 的 watch 请求直接翻倍。在快上快下场景下,需要数十分钟级别快速拉起 10 万 级别 pod,大规模的 event 推送延迟会更加严峻。4)ETCD 层面:随着集群中资源对象数据量的增大,ETCD 存储的数据规模过大,引起 Latency 大幅上涨。伴随着 Mesh、Dapr、ingress、安全 sidecar 等云原生的需求产生,也包括集团场景以及历史需求的适配和兼容, Pod Size 变得越来越大,阿里面临 50Kb 的 pod Size,远远超过 etcd 2k 性能边界。同时伴随着单集群组件数量的暴增,超过 100 个以上组件,通过逐层的读写放大,最终造成请求量过多引起的 TooMany Request 问题也此起彼伏。性能瓶颈的分析思考统一调度项目对 ASI 单集群的规模化能力是强依赖的。首先是搜推广独立集群年初计划数十个集群即将迁移 ASI,并进一步迁移统一调度协议。它上面的集群需要跑大量离线任务,这些离线任务扩缩容接口 QPS 将预计达到千级别 QPS。同时搜推广业务对管控面的可用性依赖比较高,管控面不可用中断时间过长可能会导致 P1、P2 级别故障,需要将管控面性能抖动或者异常恢复时长控制在安全时间范围内。另外是 ODPS&电商混部场景,快上快下(大促当日在数分钟内完成站点的拉起和释放)第一次在 ASI 场景落地,另外快上快下第一次在 ASI 上进行落地,研发,性能优化和稳定性保障都面临挑战,新的链路对周边系统的系统压力变化也是优先要关注,并推动相关依赖方进行优化,包括实际我们发现快上快下会打满云底层存储云盘,统一调度多了一倍的离线组件,预计增加 1 倍 pod watch 等压力,这些都是需要重点解决的问题。图 4:统一调度带来的挑战分析同时除了要支撑今年双十一统一调度规模和吞吐等性能要求外,这次规模化建设当中,需要解决一个问题,就是能够持续回答 ASI 的 SLO,覆盖整个链路核心组件,通过具备性能压测常态化能力,能够持续对 ASI 进行模拟压测,回答在一定的规模下,ASI SLO 是多少?同时针对每个版本的压测性能情况,回答是否能满足 SLO。同时在整个压测过程中,除了像之前关注的最核心的 SLO 外,需要关注整个链路涉及到的相关组件,包括资源消耗怎么样的,组件的 failover 消耗时间是咋样的,稳定性风险在哪里(需要囊括运维组件,如监控等,核心的控制器等)。ASI常态化压测-性能SLO可持续性保障在面对统一调度规模化的需求时,我们首先做的是规模化推演,推演集群的压力,从数据推演压力和潜在的解决方案。但光有这些不够,重要的是建立起全链路的压测环境,这个我们基于 Kubemark 搭建了大规模集群模拟的平台,通过一个容器启动多个Kubemark 进程的方式,使用了 数百 个 4c 的容器模拟万级别节点的 kubelet。同时我们构建了多套稳定持续的压测环境,能够去根据不同的 K8s 版本进行仿真度提升,最终支撑线上的压测场景。图 5:常态化压测能力的重点突破针对不同场景,综合抽象出需要重点加强模拟的基础能力,包括:1)大规模的节点模拟;2)相关的组件,包括存储和网络组件等;3)业务 Sidecar 容器的模拟;4)统一调度离在线场景中的影子实例模式;5)大促快上快下的离线退涨水模拟等。结合这些需要模拟增强的基础能力,以及需要的压测环境外,我们重点针对常态化压测,进行整个压测服务的平台能力建设,包括原子压测能力,可随意定制组合的压测模板能力,压测流水线,以及压测自动报告分析产出的能力。图 6:常态化压测平台的设计在实际规模化优化压测验证过程,对 etcd 内核进行升级改造,测试版本验证过程中可能出现数据一致性问题导致集群不可用,集群数据恢复起来困难且耗时。为了减少 etcd 存储后端升级验证的效率,为了避免压测过程中升级的版本对压测环境进行破坏,保障常态化压测服务的稳定性,我们对压测环境进行改造,每一套压测环境是类似 kok 的架构,addon 组件都部署在 base 集群,指向压测集群,这样压测集群核心管控组件就可高频的恢复重建,加快优化的步伐。图 7:常态化压测环境的高可用部署设计通过压测环境,仿真度提升,以及压测平台的建设,单集群的压测丰富度能够很好的满足 ASI 集团双十一的需求,运行稳定,而且时间上有大幅降低,并且这些能力能够被其他场景所复用。图 8:常态化压测建设后的效率提升ASI优化实践从管控的核心链路来看,主要的瓶颈点在于中心的组件,主要包括 APIServer,Etcd,Webbook,Controller(Operator)以及业务侧。除了 Etcd 外,其他 ASI 内部组件都具备一定的横向扩展能力。当然 APIServer 也不能无限制扩容,否则也会对 Etcd 造成过多的压力。我们可以从管控 Master 的角度来看,优化的策略是怎么样的:1)客户端侧,包括 webhook,controller,operator,kubelet,各路 daemonset 等。针对客户端可以做 cache 优化,让各个 client 优先访问本地 informer cache,也需要做负载均衡优化,主要包括对 apiserver 的负载均衡,当然要想降低对存储侧的压力,需要控制器和 kubelet 进行优化合并写请求,减小对 ASI 链路的写放大,降低对 etcd 的写压力。同时针对客户端对服务端的各种压力,可以通过组件性能规范来完成改造,在组件启用,准入的时候进行规范校验是否满足,进而推动最佳实践的落地,包括推动组件的合并,下线,以及组件不合理 QPS 整改,json 转 pb 等。2)服务端侧,可以从访问层,缓存层,存储层 3个层次进行优化。在访问层上重点建设了基于 ua limiter 和 api 的精细化限流能力等;在缓存层,我们重点建设了 cache 的索引优化以及 watch 优化,包括今年重点对 watch 的多索引优化,在存储层上重点通过 snappy 压缩算法对 pod 进行数据压缩。3)存储侧,主要指的是 etcd 侧,一方面通过管控的其他组件降低对 etcd 的读写压力外,自身主要通过内核升级外,更多通过 etcd 的数据进一步分片,基于硬件的升级方案改造;其他也包括通过无阻塞 compact,multi boltdb,存储引擎切换来降低 etcd compact 的带来的抖动等。4)业务侧,主要包括 ASI 上层的各个平台,以及具体的业务。这方面主要包括降低 pod 数据量大小,如 mesh 对 pod yaml 的改造,搜推广 C2 平台降低 pod yaml 的大小以及 pod 的个数,并推动业务侧基于 ASI 提供的基础防护能力和业务特征做更符合业务安全特性的防护能力,包括限流,限额等。图 9:ASI 优化策略大图APIServer性能优化TipsASI APIServer  Kubernetes 集群的所有外部请求访问入口,以及 Kubernetes 集群内部所有组件的协作枢纽。APIServer 具备了以下几方面的功能:1)屏蔽后端数据持久化组件 etcd 的存储细节,并且引入了数据缓存,在此基础上对于数据提供了更多种类的访问机制。2)通过提供标准 API,使外部访问客户端可以对集群中的资源进行 CRUD 操作。3)提供了 list-watch 原语,使客户端可以实时获取到资源的状态。图 10:ASI APIServer 优化大图为了应对如此多的变量对大规模集群带来的复杂影响,我们采用了探索问题本质以不变应万变的方法。为了可以全面而且系统化地对 APIServer 进行优化,我们由下到上把  apiserver 整体分为二个层面,分别为存储层(storage+cache)、访问层。底层的 etcd 是 Kubernetes 元数据的存储服务,是 apiserver 的基石。存储层中的 storage 提供 apiserver 对 etcd 访问功能,包括 apiserver 对 etcd 的 list,watch,以及 CRUD 操作。存储层中的 cache 相当于是对 etcd 进行了一层封装:1)提供了一层对来自客户端且消耗资源较大的 list-watch 请求的数据缓存,以此提升了 apiserver 的服务承载能力。2)同时,它也提供了按条件搜索的能力。上面的访问层提供了处理 CRUD 请求的一些特殊逻辑,同时对客户端提供各种资源操作服务。1、数据压缩优化在 K8s 中,所有的对象最终均会作为 key/value 存入 etcd,当 value 较大时,会对 etcd 造成很大的压力。由于业务的复杂性,阿里巴巴电商的 Pod 相比于社区的 Pod,复杂庞大的多,社区的 pod 存入 etcd 最终可能就1kb,但电商的 Pod 可能达到 20kb,而且由于 Service Mesh 技术的引入,他们会注入额外的 sidecar 容器,最终导致 ASI 的许多 Pod 都达到了 50K。为了降低对 etcd 的压力,我们引入了 snappy 压缩优化:更新创建 pod 时,先用 snappy 压缩 pod 数据再写入 etcd读取 pod 时,从 etcd 读取数据,snappy 解压后再返回给客户端有人或许担心引入 snappy 算法带来的额外的 CPU 消耗和延时,考虑到 K8s 对象本身的序列化开销和访问 etcd 的延时,解压缩的 CPU 消耗和延时几乎可以忽略不计。优化后,一般的pod的大小可以压缩为原来的 1/2,对于注入 sidecar 容器的 pod,由于 pod 内容同质化内容较多,可以压缩为原来的 1/3。引入压缩优化后,由于底层数据格式的变化,如何上线、回滚变的尤为棘手,一般的做法是 关闭集群->数据格式转换->启动集群。为了保证集群不停服,我们采用热升级的方式开启或者关闭优化,确保开启snappy压缩优化后,kube-apiserver 也可以读取未压缩数据,关闭 snappy 压缩优化后,kube-apiserver 可以识别解压 snappy 数据。022、watch索引优化watch 是整个 K8s 体系通信的核心,所有的控制器均是通过 ListWatch 拿到 K8s 对象的最新信息干活。当集群资源变化越大时,watch 的性能压力会越大,而在统一调度中,离线的单机客户端也会 watch pod,这意味着 pod 的 watch 请求直接翻倍。在快上快下场景下,我们碰到了大规模的 event 推送延迟,导致刚开始无法满足客户要求。首先看一下 watch 的推送原理。首先 kube-apiserver 针对每一种资源会发起一个连接到 etcd,同时建立一个 event chan,接受 etcd 的 event,每一个客户端 watch apiserver 时,kube-apiserver 会为每个 client 建立一个 watcher chan,event 被 dispatch 到各个 watcher,各个 watcher 负责 filter 事件并推送出去。图 11:watch 索引优化图解为了解决 kubelet 这一类 watch 请求,kube-apiserver 引入了 triggerFunction 优化功能,他类似一个对 watcher 的索引,比如一个 pod 只能属于 kubelet,kube-apiserver dispatch 事件时,只需要将 event 推送至所属的 kubelet,其他 kubelet 的 watcher chan 可以直接忽略,这样可以大大降低 kube-apiserver 的性能消耗。而在统一调度下,单机离线客户端的 watch 请求并没有做索引,且原生的 kube-apiserver 只支持设置单索引,导致了推送的大规模延时。我们原有的 triggerFunction 基础上,引入了 MultipleTriggerFunctions,支持设置多个索引。单个 event 的 99 分位推送延时从 5ms 降低至 0.1ms,CPU 的消耗从原有的 70 个 CPU 降低只 30 个 CPU,顺利满足了快上快下的需求。033、etcd多client并发优化Kubernetes 针对每一种资源会创建一个 grpc 连接至 etcd,所有的读/写/watch 请求均通过该通道完成,当集群规模变大、QPS 增加到一定程度时,我们发现 etcd 出现较大的访问延时,对比了 etcd 服务端的延时,发现客户端和服务端延时相差较大,客户端延时明显大于服务端延时。我们对所有资源的均创建了多个 client,并发访问 etcd,而针对部分访问需求较多的资源(pods 等)额外加大了并发,降低了 etcd 访问延时。4、精细化限流和限流管理我们引入了精细化限流方式,可以从 user agent(kubelet/kub-scheduler 等)、resource(pods/nodes 等)、verb(get/list/update)等不同维度限流。List 操作是对 kube-apiserver 性能影响最大的操作,数次对 Pod 的全量 List 就可以导致 kube-apiserver 直接 OOM,绝大多数的 List 请求可能只是读取部分符合条件的 pod。因此我们进一步精细化了 List 限流保证 kube-apiserver 的稳定性。此外我们还开启了社区最新的 APF 限流,可以控制不同等级的组件获得不同的并发访问量,优先保证核心链路组件的访问质量。图 12:限流策略对比,结合社区,可管理性我们选择了 APF 和 UA-Limiter限流策略如何管理,数百套集群,每套集群规模都不太一样,集群节点数、pod 数都是不同的,内部组件有近百个,每个组件请求的资源平均有 4 种,对不同资源又有平均 3 个不同的动作,如果每个都做限流,那么规则将会爆炸式增长,即便做收敛后维护成本也非常的高。因此我们抓最核心的,核心资源 pod\node、核心动作(创建、删除、大查询);最大规模的,daemonset 组件、PV/PVC 资源。并结合线上实际流量分析,梳理出二十条左右的通用限流策略,并将其纳入到集群交付流程中实现闭环。当新的组件接入,我们也会对其做限流设计,如果比较特殊的,则绑定规则并在集群准入和部署环节自动下发策略,如果出现大量的限流情况,也会触发报警,由 SRE 和研发去跟进优化和解决。055、protobuf 改造服务器端的优化是一方面,客户端的优化也很重要。protobuf 改造就是是其中一项重要的优化,客户端可以通过 json/yaml/protobuf 多种格式获取 kube-apiserver 数据,protobuf 相比 json 的序列化效率相比快了 5 倍,因此让使用了 protobuf 协议可以更快的全量 List 数据。这在控制器的 ListWatch 场景显得尤为重要,ListWatch 的机制是首先 List 全量数据,然后发起 Watch 请求获取增量数据,假如 List 的 latency 过长,会直接导致 Watch 失败,进而导致 ListWatch 失效,控制器开始反复 List 数据,造成系统雪崩。因此我们通过组件规范,推动所有的客户端以 protobuf 格式访问 kube-apiserver 的核心资源(pods/nodes)。后续我们可能考虑在 http 这一层引入 snappy 压缩算法,来进一步降低客户端和服务器端的 List 延时。6、多路 apiserver 架构核心方案就是通过对 apiserver 进行分组,通过不同的优先级策略进行对待,从而对服务进行差异化 SLO 保障。通过分流以降低主链路 apiserver 压力,针对 P2 及以下组件接入旁路 apiserver,并可以在紧急情况(如自身稳定性收到影响)下,做整体限流。图 13:APIServer 多路架构Etcd优化Tipsetcd 是 K8s 集群中存储元数据,是 K8s 的基石,它的性能往往影响着整个集群的响应时间。当集群规模突破一定规模时,曾出现如下性能瓶颈问题:etcd 出现大量的读写延迟,延迟甚至可达分钟级kube-apiserver 查询 pods/nodes/configmap/crd 延时很高,导致 etcd oometcd list-all pods 时长可达 30 分钟以上控制器无法及时感知数据变化,如出现 watch 数据延迟可达 30s 以上等event 压力大影响 lease 数据,进而引起组件频繁选主。1、Etcd 内核升级我们深入研究了 etcd 内部的实现原理,并发现了影响 etcd 扩展性的一个关键问题在底层 bbolt db 的 page 页面分配算法上:随着 etcd 中存储的数据量的增长,bbolt db 中线性查找“连续长度为 n 的 page 存储页面”的性能显著下降。为了解决该问题,我们设计了基于 segregrated hashmap 的空闲页面管理算法,hashmap 以连续 page 大小为 key,连续页面起始 page id 为 value。通过查这个 segregrated hashmap 实现 O(1) 的空闲 page 查找,极大地提高了性能。在释放块时,新算法尝试和地址相邻的 page 合并,并更新 segregrated hashmap。通过这个算法改进,我们可以将 etcd 的存储空间从推荐的 2GB 扩展到 100GB,极大的提高了 etcd 存储数据的规模,并且读写无显著延迟增长。我们也和谷歌工程师协作开发了 etcd raft learner(类 zookeeper observer)/fully concurrent read 等特性,在数据的安全性和读写性能上进行增强。这些改进已贡献开源。2、Etcd单资源拆分进一步,我们通过将 API Server 中不同类型的对象存储到不同的 etcd 集群中。从 etcd 内部看,也就对应了不同的数据目录,通过将不同目录的数据路由到不同的后端 etcd 中,从而降低了单个 etcd 集群中存储的数据总量,提高了扩展性。实际大集群中,我们是这样进行拆分的:1)把访问最核心的资源放在了一起,如 pod,configmap,endpoint,lease 等;CRD 资源放在了第二个 etcd 集群;Event 放在了一个独立集群。图 14:etcd 拆分整个拆分主要考虑安全原则和数据热点,这样既能提高性能,又能减少核心主 etcd 故障因素,包括:1)重要数据白名单机制从原来的集群中迁出,用于重点保护,如 pod,node 数据;2)观察数据例如 CR 等从原来集群中迁出,避免对原有集群核心数据的影响;3)考虑热点 key 负载打散;4)考虑延时和增长情况;5)考虑各个资源对象数据的情况以及增长情况,如 Node 数,Pod 数,service 数,CR 数等。2、Etcd 硬件升级etcd 集群对磁盘 IO 时延非常敏感,我们对比了云盘,本地盘(nvme, optane, AEP)的性能,最终发现 optane 和 AEP 的设备性能有很大提升。考虑到长期维护问题,因此我们选择了云上标准的 AEP 机型。但 AEP 机型属于本地盘,它也存一些劣势,在故障迁移时会面临更多挑战,特别是 etcd 的故障迁移,处理时长,冷热备数据的安全性,我们在本地盘基于自研的 operator 增加了这部功能,并配置相应的 1-5-10 能力。033、Etcd 参数调优1)etcd 使用 boltdb 作为底层数据库存储 kv, 它的使用优化对整体性能影响很大。通过调节不同的 batch size 和 interval, 使我们可以根据不同硬件和工作负载优化性能。2)compact的压缩周期044、multi boltdb当这种单一集群 etcd 性能承压的情况下,我们需要水平扩展多个 etcd 集群。目前我们已经使用了 K8s apiserver 的不同资源拆分到不同 etcd 的能力实现了基本的拆分功能,实现了不错的效果。但是我们看到还有一些新的需求例如单一 pod 资源本身就会有非常大的存储压力的场景,我们需要进行进一步的优化,这里我们在 etcd server 层做数据拆分。etcd 内部单一使用一个存储 boltdb 底层数据库,利用单一 WriteTX, ReadTX 进行读写。当数据量超大时,单一 db 压力很大。我们在前期测试中发现 compact 清理时,boltdb 上清理压力很大,进而导致整个集群出现堆积,造成验收不符合预期。因此,我们将 etcd 底层存储层 boltdb 进行水平拆分扩展,类似常见的数据库分库分表,具体内部使用 hash 策略进行存储对象的分配策略。具体设计如下图:图 15:multi boltdb在这里,etcd 内部新加入一层中间层 MultiTX 层统一处理上层对底层 boltdb 的读写功能,并将这些请求按照 hash 策略路由读写请求到不同的底层 boltdb。compact 也分别在不同 boltb 里独立进行,分担压力。Webhook&Controller优化Tipswebhook 承接 api-server 操作完资源后的回调,类似于一个 http 请求所经过的中间件。在 ASI 集群中大量注入逻辑和验证 都是 webhook 做的,例如 pod 的 sidecar 注入, postStartHook 注入,failizer 的注入, 级连删除的校验等。所以,webhook 在集群中属于核心链路组件。webhook 的不可用会导致集群中所有资源的变更都不可用。webhook 的延迟会导致 apiserver 的延迟,因此 webhook 的性能直接影响了 api-server 的性能,从而影响整个集群的规模化能力。1、使用 protobuf 协议请求 APIServerwebhook&controller 在请求 API-Server 的时候,如果是 get/list 操作,会优先请求本地 informer。在建立和更新本地 informer 的过程中,webhook&controller 会全量 list APIServer。此时使用 protobuf 协议 相对于 json 协议可以消耗更少的资源,更快的建立 informer 本地缓存。2、减少深拷贝操作通过本地 Informer, webhook&controller 通过 list 方法获取数据时,避免了请求 APIServer,但是依然要对获取到的数据进行 DeepCopy 操作。但是这个 DeepCopy 操作并非一定需要的,只有对资源进行修改操作时,才需要 DeepCopy。为此,webhook&controller 在 List 方法里减少了 DeepCopy 操作,业务在获取到 List 对象之后再按需进行深拷贝操作 。3、减少序列化/反序列操作一次 webhook 回调请求中,会有多个 plugin 针对同一个资源进行 admit 操作。如果每一次操作都需要进行反序列化解析,那么会带来重复性计算。为此,webhook 每一次 admit 操作基于上一次操作的结果,这样反序列就可以减少到一次。在返回给 APIServer 的序列化的过程中,webhook 根据 admit 后的对象跟传入的对象相比,如果没有发生改变,那就直接返回给 APIServer,不需要经过序列化计算。4、优化反序列操作webhook&controller 存在大量的字符串发序化操作,其占据了 65%以上的 cpu 资源, 30%以上的内存资源。为此,我们从业务的角度出发,按需反序列化解析。对于没有使用到的字段,就不进行反序列化。同时,我们采用了 社区的 json-iterator/go 包代替了 golang 提供的 encoding/json 包。这样整体操作下来,json 相关的反序列化操作资源消耗降低到了 30%以下。5、合并写请求,减少写放大频繁请求 Api-Server 的原因在于在处理 reconcile 中存在着多次跟 api-server 交互请求,例如读取 all-namespace. 修改 annotation, 修改 fialnaizer,update 对象时遇到 reconflict 冲突。这些都会导致跟 api-server 的交互请求,我们针对扩缩容核心链路的写请求进行分析降低了 30%。6、快速 failovercontroller 中存储着近百万的对象,从 API Server 获取这些对象并反序列化的开销是无法忽略的,重 Controller 恢复时可能需要花费几分钟才能完成这项工作,这对于阿里巴巴规模的企业来说是不可接受的。为了减小组件升级对系统可用性的影响,我们需要尽量的减小 controller 单次升级对系统的中断时间,这里通过提前加载数据的方案来解决这个问题:1)预启动备 controller informer,提前加载 controller 需要的数据;2)主 controller 升级时,会主动释放 Leader Lease,触发备立即接管工作。Kubelet优化Tips1、对APIServer负载均衡高可用集群实际的运行中,可能会出现多个 API Server 之间的负载不均衡,尤其是在集群升级或部分节点发生故障重启的时候。这给集群的稳定性带来了很大的压力,原本计划通过这样高可用的方式分摊 API Server 面临的压力,但在极端情况下所有压力又回到了一个节点,导致系统响应时间变长,甚至击垮该节点继而导致雪崩。在 API Server 测增加 SLB,所有的 kubelets 连接 SLB,这个也是阿里云 ACK 的标准做法。我们针对 client,特别是大量的 kubelet 节点增加一个核心功能:定期地重建连接切换 API Server 完成洗牌;同时在 kubelet 上针对一个时间段内频繁的收到 429 时,尝试重建连接切换 API Server。022、降低写放大K8s pod 写放大问题非常严重,给 apisever/etcd 带来很大压力,泛电商一般场景 23 次,搜推广 2.5 协议大概 5 次,3.0 协议 host 网络 9 次、非 host 网络 15 次,可以通过合并请求优化,在搜索高吞吐场景中,目前 kubelet 侧优化从 5 次降低为 1 次。业务侧专项改造举例业务侧包括搜索 c2,mesh, faas 等合作方都进行了很多的改造。这里列一下安全为例:安全基于 Mesh 的 Sidecar 改造1)对接上文中提到的 APIServer 多路架构中的旁路;2)CR 资源治理,包括把各个资源的数量从 O(n))降低为 O(1)常数级别;3)  Pod 资源优化,主要通过合并容器,环境变量,挂载合并等缩小 pod yaml 大小等。ASI 作为云原生的引领实施者,它的高性能,高可用,它的稳定性影响着甚至决定着阿里集团和云产品的业务的发展,真诚希望容器领域感兴趣的同学进行深入交流,更期待大家的加入,一起在云端构建云的新界面,让我们的用户用好云,感兴趣的同学欢迎来撩:zhiqing.ht@alibaba-inc.comen.xuze@alibaba-inc.comhantang.cj@taobao.com

如何低成本玩转微服务敏捷开发

微服务敏捷开发不简单安得环境千万套,大庇开发小哥俱欢笑微服务给大家带来了敏捷开发的特性,基于敏捷开发带来的便利,让我们可以在同一个时间内多个迭代/feature 并行开发。但微服务架构本身也给开发环境带来了一定的复杂性:每个 feature 的修改点都可能会被分散在多个应用中,需要多个应用互相配合才能完成整体的逻辑。这些应用既需要互相配合好,又不能让他们互相影响,所以敏捷开发有时候也不是那么容易。相信实践过微服务敏捷开发的同学都曾经遇到过以下情况:开发接口时,应用无法独立地联调测试,需要依赖于下游的返回,所以一般都需要一个完整的开发环境,这个环境需要包含所有的其他应用。A 同学辛辛苦苦,终于开发好了一个接口,但是部署到开发环境后,发现返回值一直是错的,就是不符合预期,百思不得其解。最终根据日志、arthas 层层跟踪下去,发现原来是另一个同事更新了下游应用的代码,导致原有逻辑发生了变更。A 同学准备开始联调测试了,这时候他要找到开发 B 和 C 吼一嗓子确认:“我要开始测试了哈兄弟们,你们都别动环境,不要重启和 debug 哈”。B 同学 和 C 同学一脸懵逼:“我自己这还有个逻辑没理清楚呢,刚改完代码准备测一发,你这一测试联调我就不能动环境了,我这功能得等到什么时候才能开发好”。排查问题好麻烦啊,要不直接 debug 一下吧,这 IDEA 远程 debug 刚连上去呢,立马就传来了同事的声音:“谁 XX 又在瞎动环境啊,怎么刚刚还能跑的接口现在就出错了”。以上这些问题显然会影响项目的进度,非常容易造成项目延期。对于此刻的开发小哥哥而言,拥有一套属于自己的独立环境,带来的幸福感也许比有一套属于自己的小房子还大。流量闭环是微服务敏捷开发的基础 上文中提到的问题,其实都是因为没有在开发环境中,精准地控制流量在 feature 环境内流转。为什么精准地控制流量如此重要?举个最简单的微服务架构图来说明,这里假设应用的调用链路为 A ---> B ---> C ---> D ,现在同时开发两个 feature, feature1 和 feature2 。feature1 需要修改 A 和 C 的代码, feature2 需要修改 B、C 和 D 的代码。为了方便表述,我们用 A、B、C、D 来代指 A、B、C、D 的线上稳定版本,也叫做基线版本;A1、C1 来代指 feature1 环境中的 A 和 C ;B2、C2、D2 来来代指 feature2 环境中 B、C、D。那么开发测试 feature1 的同学会要求他的请求,准确地在 A1 ---> B ---> C1 ---> D 中流转。为什么一定要这样,我们来简单分析一下:如果流量走到 A 或者 C 的基线环境,因为他们都没有包含 feature1 相关的代码,所以肯定是无法正常测试和联调 feature1 对应的功能。如果流量走到 B2、D2 环境,大多数情况下是可以正常工作的,因为正常情况下 B2 和 D2 中的修改是不会影响 feature1 的。但是因为 feature1 和 feature2 可能是由不同的同学开发的,或者有不同的开发排期和节奏,他们有自己的开发、重启、debug 节奏,所以大概率还是会出现上文中提到的场景。综上所述,让流量在 feature 环境内流转非常重要,是微服务敏捷开发的基础。如何准确地让请求在 feature 环境内流转呢?最简单的办法是每个迭代/Feature 的都享有一套独立的完整环境,这套独立的环境包含了整个微服务应用集所有的应用,包含注册中心和接入层,这样就能确保流量在 feature 环境里闭环,不用担心应用之间互相影响。这个解决方案虽然简单,但是问题也很显而易见,成本比较大。我们假设微服务应用有10 个,每个应用只部署一台,以 java 为例,部署一个 java 应用按 2C4G 的 共享标准型 ECS 进行计算,维护一套环境一年的成本是 10 × 140 × 12 = 16800 元,如果同时有 4 套环境,即只支持两个迭代并行开发,每个迭代只有 2 个 feature,这样一年的成本就是 67200 元,而且我们可以发现,这里面计算公式使用的是乘法,当应用增加和环境增加时,成本的增加是成倍的。注意,这里只是单纯地计算了应用使用的 ECS 的成本,其他周边的配套设施我们还没有计算,因为我们的开发、联调、测试是需要确保端到端的全流程都是足够顺利的,那这里就还会涉及到 域名/SLB/网关/注册中心这些资源,这些资源一般比较固定,不会需要进行大的修改,但是在多套环境的方案下这些资源也需要维护多套,成本还会进一步上升。那么,有没有一个比较优雅地方式,既能享受到微服务架构带来的敏捷开发的便利,又不会给日常开发环境的搭建带来很大的成本呢?基于 MSE(微服务引擎 MSE,以下简称 MSE)标签路由功能使用开发环境隔离方案是您的不二之选。如何低成本玩转敏捷开发什么是 MSE 开发环境隔离,简单地说就是将 feature 环境的隔离方式从简单的物理隔离转为逻辑隔离。借助于 MSE 提供的逻辑隔离,您只需要维护一套完整的基线环境,在增加 feature 环境时,只需要单独部署这个 feature 所涉及到改动的应用即可,而不需要在每个 feature 环境都部署整套的微服务应用及其配套设施。我们称这唯一的一套完整的环境为基线环境。基线环境包含了所有微服务应用,也包含了服务注册中心、域名、SLB、网关 等其他设施,而 feature 环境中只包含了这个 feature 中需要修改的应用。这样维护 n 套 feature 环境的成本,就变成了加法,而不是原来的乘法,由 n × m 变成了 n + m。差不多相当于零成本增加 feature 环境,这样我们就可以放心地扩容出多套 feature 环境,每个开发小哥哥都可以轻松拥有属于自己的独立环境,尽情地享受微服务敏捷开发。从上图中我们可以看到,feature1 对应的流量,在发现 feature1 中存在 A1 应用时,一定会去往 A1 节点,A1在调用B的时候发现 feature1 环境中不存在 B1 ,则会将请求发到 基线版本的 B 中;B在调用C时,发现 feature1 环境存在 C1 应用,又会返回到 feature1 环境中,依次类推,确保了流量会在 feature1 环境中闭环。注意,在这个过程中,您不需要修改任何代码和配置,直接接入 MSE 微服务治理即可使用,不会给您增加任何开发成本。如何使用 MSE 开发环境隔离场景分析在描述如何使用开发环境隔离之前,我们先分析一下目前常用的开发环境具体的场景,这里选了三种典型的场景。场景一所有的开发环境都在本地,或者说公司内自建的 IDC ,这类场景下开发环境的所有应用都部署在本地的机房。场景二公司通过专线打通了办公网与阿里云上的 VPC ,两边的网络实现了互联互通。开发、测试环境主要部署在阿里云,但是正在开发的工程,有一部分是跑在本地办公网的,甚至是直接跑在开发同事的个人电脑上。场景三公司内并没有专线来打通了办公网与阿里云上的 VPC。但是希望能让本地启动的应用,连接上阿里云上的开发测试集群,并且实现精准的流量隔离。首先说一下结论,这上面的三个场景,目前都是可以完整的支持的。其中场景一和场景二都不涉及到网络打通这部分的内容,其实只需要根据基本的 MSE 接入方式和 MSE 打标方式即可直接使用起来。场景三比场景一和场景二多了一个网络打通的功能,所以会多一个端云互联的步骤,这里面会要求注册中心需要使用 MSE 提供的 Nacos。在这个最佳实践中,我们会以场景三来实操。如果您的使用场景不是场景三,那么您可以忽略,同时也不需要关注端云互联相关的操作。一 开通 MSE 微服务治理专业版登录MSE治理中心控制台,如果您尚未开通 MSE 微服务治理,请根据提示开通专业版。如果您已经开通了MSE 微服务治理基础版,请根据概览页中右侧的提示,升级到 专业版。二 完成基线环境接入1. 接入 MSE 治理首先,您需要将基线环境的所有应用接入到 MSE 中,接入方式与您开发环境中应用部署环境有关。这里我们使用的是阿里云容器服务 ACK。更多接入场景请参考 MSE 帮助文档 MSE 微服务治理快速入门。在ACK中安装MSE治理中心组件登录容器服务控制台。在左侧导航栏单击市场 > 应用目录。在应用目录页面搜索并单击ack-mse-pilot。在ack-mse-pilot页面右侧集群列表中选择集群,然后单击创建。安装MSE微服务治理组件大约需要2分钟,请耐心等待。创建成功后,会自动跳转到目标集群的发布页面,检查安装结果。如果出现以下页面,展示相关资源,则说明安装成功。为ACK命名空间中的应用开启MSE微服务治理登录MSE治理中心控制台。在左侧导航栏选择微服务治理中心 > K8s集群列表。在K8s集群列表页面搜索框列表中选择集群名称或集群ID,然后输入相应的关键字,单击 🔍 图标。单击目标集群操作列的管理。在集群详情页面命名空间列表区域,单击目标命名空间操作列下的开启微服务治理。(如果您的基线环境部署在 default 这个 namespace 中,则目标命名空间为 default)在开启微服务治理对话框中单击确认2. 部署基线应用首先,我们将分别部署 spring-cloud-zuul、spring-cloud-a、spring-cloud-b、spring-cloud-c 这四个业务应用,模拟出一个真实的调用链路。 Demo 应用的结构图下图,应用之间的调用,既包含了 Spring Cloud 的调用,也包含了 Dubbo 的调用,覆盖了当前市面上最常用的两种微服务框架。这些应用都是最简单的 Spring Cloud 、 Dubbo 的标准用法,您也可以直接在 https://github.com/aliyun/alibabacloud-microservice-demo/tree/master/mse-simple-demo 项目上查看源码。您可以使用 kubectl 或者直接使用 ACK 控制台来部署应用。部署所使用的 yaml 文件如下。注意,上文中提到,使用端云互联的前提是注册中心使用的是 MSE 中的 Nacos,所以请您在部署之前修改 yaml 文件中的 spring.cloud.nacos.discovery.server-addr 和 dubbo.registry.address 为您自己购买的 MSE Nacos 地址,否则应用是无法正常运行的。若您使用的是 MSE Nacos 域名为公网域名,还需要确保开启了白名单。# 部署业务应用# 部署业务应用---apiVersion: apps/v1kind: Deploymentmetadata:  name: spring-cloud-zuulspec:  selector:    matchLabels:      app: spring-cloud-zuul  template:    metadata:      annotations:        msePilotCreateAppName: spring-cloud-zuul      labels:        app: spring-cloud-zuul    spec:      containers:        - env:            - name: JAVA_HOME              value: /usr/lib/jvm/java-1.8-openjdk/jre            - name: spring.cloud.nacos.discovery.server-addr              value: 'mse-xxxxxxx-nacos-ans.mse.aliyuncs.com:8848'          image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.0          imagePullPolicy: Always          name: spring-cloud-zuul          ports:            - containerPort: 20000---apiVersion: v1kind: Servicemetadata:  annotations:    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small    service.beta.kubernetes.io/alicloud-loadbalancer-address-type: internet  name: zuul-slbspec:  ports:    - port: 80      protocol: TCP      targetPort: 20000  selector:    app: spring-cloud-zuul  type: LoadBalancerstatus:  loadBalancer: {}---apiVersion: apps/v1kind: Deploymentmetadata:  name: spring-cloud-aspec:  selector:    matchLabels:      app: spring-cloud-a  template:    metadata:      annotations:        msePilotCreateAppName: spring-cloud-a      labels:        app: spring-cloud-a    spec:      containers:        - env:            - name: JAVA_HOME              value: /usr/lib/jvm/java-1.8-openjdk/jre            - name: spring.cloud.nacos.discovery.server-addr              value: 'mse-xxxxxxx-nacos-ans.mse.aliyuncs.com:8848'            - name: dubbo.registry.address              value: 'nacos://mse-xxxxxxx-nacos-ans.mse.aliyuncs.com:8848'          image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:1.0.0          imagePullPolicy: Always          name: spring-cloud-a          ports:            - containerPort: 20001          livenessProbe:            tcpSocket:              port: 20001            initialDelaySeconds: 10            periodSeconds: 30---apiVersion: apps/v1kind: Deploymentmetadata:  name: spring-cloud-bspec:  selector:    matchLabels:      app: spring-cloud-b  template:    metadata:      annotations:        msePilotCreateAppName: spring-cloud-b      labels:        app: spring-cloud-b    spec:      containers:        - env:            - name: JAVA_HOME              value: /usr/lib/jvm/java-1.8-openjdk/jre            - name: spring.cloud.nacos.discovery.server-addr              value: 'mse-xxxxxxx-nacos-ans.mse.aliyuncs.com:8848'            - name: dubbo.registry.address              value: 'nacos://mse-xxxxxxx-nacos-ans.mse.aliyuncs.com:8848'          image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:1.0.0          imagePullPolicy: Always          name: spring-cloud-b          ports:            - containerPort: 20002          livenessProbe:            tcpSocket:              port: 20002            initialDelaySeconds: 10            periodSeconds: 30---apiVersion: apps/v1kind: Deploymentmetadata:  name: spring-cloud-cspec:  selector:    matchLabels:      app: spring-cloud-c  template:    metadata:      annotations:        msePilotCreateAppName: spring-cloud-c      labels:        app: spring-cloud-c    spec:      containers:        - env:            - name: JAVA_HOME              value: /usr/lib/jvm/java-1.8-openjdk/jre            - name: spring.cloud.nacos.discovery.server-addr              value: 'mse-xxxxxxx-nacos-ans.mse.aliyuncs.com:8848'            - name: dubbo.registry.address              value: 'nacos://mse-xxxxxxx-nacos-ans.mse.aliyuncs.com:8848'          image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:1.0.0          imagePullPolicy: Always          name: spring-cloud-c          ports:            - containerPort: 20003          livenessProbe:            tcpSocket:              port: 20003            initialDelaySeconds: 10            periodSeconds: 303. 验证基线环境接入成功完成上述步骤后,您的基线环境就已经部署好了。您可以在 MSE 控制台中找到对应的 Region 查看应用列表,以及应用详情页的节点情况。在本地配置好 K8s 集群对应的 kubeconfig 文件,执行命令,结果如下➜  ~ kubectl get svc,deployNAME                 TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGEservice/kubernetes   ClusterIP      192.168.0.1             443/TCP        7dservice/zuul-slb     LoadBalancer   192.168.87.95   47.94.143.53   80:31983/TCP   9m30sNAME                                READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/spring-cloud-a      1/1     1            1           9m30sdeployment.apps/spring-cloud-b      1/1     1            1           9m30sdeployment.apps/spring-cloud-c      1/1     1            1           9m30sdeployment.apps/spring-cloud-zuul   1/1     1            1           9m30s在这里我们执行一下 curl http://47.94.143.53:80/A/a 发起调用,并查看返回结果➜  ~ curl http://47.94.143.53:80/A/aA[10.242.0.90] -> B[10.242.0.91] -> C[10.242.0.152]%三 IDEA 启动的应用接入 feature 环境在这一步中,我们将演示如何在网络没有打通的情况下,将你本机启动的应用接入到 feature 环境。首先您需要将您 K8s 集群的 kubeconfig 文件保存到本机,并进行如下操作。1. 下载源码本工程所有源码都在 https://github.com/aliyun/alibabacloud-microservice-demo 中,将代码 git clone 到本地,并且找到 mse-simple-demo 文件夹中的 A、B、C、gateway 四个应用,就是本次最佳实践所使用的公测。2. 安装 CloudToolkit 插件安装最新版本的 Cloud Toolkit,安装详情请参考官网 https://www.aliyun.com/product/cloudtoolkit。3. 填写阿里云 AK、SK由于使用端云互联功能的时候,需要访问您 MSE 的资源,所以这里需要您填写您的 AK、SK,并确保此 AK、SK拥有访问 MSE 资源的权限。点击 IDEA 的 Tools 中找到 Preference ,找到 Alibaba Cloud Toolkit 中 Accounts ,配置 Access Key ID 和 Access Key Secret 信息,并点击保存。4. 配置 MSE 参数点击 IDEA 的 Tools 中找到 Preference ,找到 Alibaba Cloud Toolkit 中 Microservice 下的 MSE ,点击 开启微服务治理,并安装下图的方式进行配置即可。对图中的几个参数做一下说明LicenseKey您阿里云账号对应的 MSE 产品的 LicenseKey ,请在https://mse.console.aliyun.com/#/msc/app/accessType 中的选择 ECS 集群,在 安装 MSE Agent 章节找到 LicenseKey 的值。注意:请您做好 LicenseKey 的保密工作。注意:各个 Region 的 LicenseKey 值可能不一致,请选择对应的 Region,并和基线环境接入的 Region 保持一致。App Name应用在接入 MSE 时所使用的应用名,请根据实际业务情况进行配置,注意这个值需要和本次所启动的应用保持一致。Tag此应用所属的环境 Tag,基线不用填,其他请根据实际业务情况进行填写。如果此应用属于 feature1 环境,请填写 feature1。Agent 地址选择自己应用所在的地域,需要和 LienseKey 所在的地域、以及基线环境接入的地域 都保持一致。开启 RPC 灰度 ✅支持对 Spring Cloud 和 Dubbo 近5年内的所有版本的流量进行精准控制。默认情况下请开启,除非您明确知道关闭此选项的使用场景,否则请勿关闭此选项。开启标签染色 ✅推荐开启,开启后经过此应用的流量就只会在对应的 Tag 环境中流转。开启消息灰度 ✅请根据业务实际情况选择是否开启,目前仅支持 RocketMQ 4.5 及以上版本。更多消息灰度相关的信息,请参考全链路灰度,消息部分。5. 配置端云互联参数我们已经知道,在网络未打通的时候,联通本机环境和云上 K8s 集群需要使用 端云互联功能,所以这里我们需要配置一下端云互联。首先需要配置一下代理模式为 K8s,点击 IDEA 的 Tools 中找到 Preference ,找到 Alibaba Cloud Toolkit 中 Microservice 下的 Proxy ,点击 AddProfile 增加一个名称为 k8s 的代理。然后点击右侧的 Add 按钮,选择代理类型 为 Kubernetes,并选择正确的 配置文件地址 和 命名空间。 然后,点击 IDEA 的 Tools 中找到 Preference ,找到 Alibaba Cloud Toolkit 中 Microservice 下的 MicroService ,找到 端云互联 功能打 ✅。选择产品为 微服务引擎 MSE,并选择与上面部署时一致的 Region 、 实例 和 命名空间 ,代理选择刚刚配置好的 k8s,如果您的应用是 Spring Cloud 应用,还必须在 本地 Spring Cloud 服务端口中 配置 Tomcat 的启动端口。四 启动应用,轻松开始联调和测试1. 验证接入成功完成上述配置之后,我们启动应用。首先,启动应用的时候,您会看到这两个提示,证明端云互联功能已经生效。同时为了验证 MSE 微服务治理是否接入成功,我们可以登录 MSE 控制台的应用列表界面进行查看。在控制台中我们也可以看到,我的本机应用已经成功接入到 MSE ,并且成功打上了 feature1 的标签。2. 发起流量调用假设我们发往网关的请求是 http 请求,希望这个请求再 feature1 中完成闭环,只需要在请求的 header 中添加 x-mse-tag=feature1 即可,流量会自动在 feature1 环境内完成闭环。注意这里的 key 为 x-mse-tag 为固定值,feature1 则需要和环境的标签(即上文中配置的 alicloud.service.tag)保持一致。如果您的请求来源为 Dubbo,则需要在 RpcContext 中增加 Attachment ,内容也是 x-mse-tag=feature1。➜  ~ curl http://47.94.143.53:80/A/aA[10.242.0.90] -> B[10.242.0.91] -> C[10.242.0.152]%➜  ~ curl http://47.94.143.53:80/A/aA[10.242.0.90] -> B[10.242.0.91] -> C[10.242.0.152]%➜  ~ curl -H"x-mse-tag:feature1" http://47.94.143.53:80/A/aAfeature1[xx.xxx.12.118] -> B[10.242.0.91] -> C[10.242.0.152]%➜  ~ curl -H"x-mse-tag:feature1" http://47.94.143.53:80/A/aAfeature1[xx.xxx.12.118] -> B[10.242.0.91] -> C[10.242.0.152]%➜  ~ curl -H"x-mse-tag:feature1" http://47.94.143.53:80/A/aAfeature1[xx.xxx.12.118] -> B[10.242.0.91] -> C[10.242.0.152]%如果您不方便在请求中增加 header 的话,还可以在 MSE 控制台配置规则,比如设置成 name=xiaohong 或 xiaohua 的流量进入到 feature1 环境。如下图所示。开启流量规则之后,我们继续验证,可以看到,满足条件的请求会被转发到 feature1 环境。➜  ~ curl http://47.94.143.53:80/A/aA[10.242.0.90] -> B[10.242.0.91] -> C[10.242.0.152]%➜  ~ curl http://47.94.143.53:80/A/a\?name\=xiaohongAfeature1[30.225.12.118] -> B[10.242.0.91] -> C[10.242.0.152]%➜  ~ curl http://47.94.143.53:80/A/a\?name\=xiaohuaAfeature1[30.225.12.118] -> B[10.242.0.91] -> C[10.242.0.152]%特别地,如果您的网关应用不属于 Java 体系,则需要在网关层配置一下规则,目前已经支持 MSE云原生网关,Nginx,K8s Ingress 等,详细的接入方式可以参考 MSE 全链路灰度配置 。

如何构建一个流量无损的在线应用架构 | 专题尾篇

作者 | 孤弋、十眠-全系列查看-如何构建流量无损的在线应用架构 | 专题开篇如何构建流量无损的在线应用架构 | 专题尾篇前言上两篇我们说完了流量解析、流量接入、流量服务三大块的内容,这一篇主要从数据交换的维度阐明数据交换的过程如何影响到线上流量;最后会引入两个常用的防范措施:全链路压测和安全生产演练。我们先来说说数据交换部分:数据当流量在应用集群中流转完毕之后,他行至的终点一般是将数据与各种类型的数据服务进行交换,如:从缓存读取数据返回、将订单记录存储在数据库中、将交易数据与外围的支付服务进行数据交换等。但是只要是和外面的服务进行数据访问,就会出现外围服务不可用的情况,常见的一些情况比如:因为被依赖过重或数据过载而导致雪崩,因为数据中心整体不可用导致大面积瘫痪。比如最近一个比较有名的事件就是 Meta 公司的大规模宕机事件,其原因正是下发了一条错误的配置切断了数据中心之间的主干路由。1、常用解决方案:分库分表针对国内互联网公司海量数据的场景,当我们的业务成长到一定的阶段就会带来缓存或者 DB 的容量问题,以 MySQL 举例子,当单表的容量在千万级别的时候,如果这张表还需要和其他表进行关联查询,就会出现数据库在 IO、CPU 各方面的压力。此时就需要开始考虑分库分表的方案。但是分完了之后并不是一蹴而就,他会引入诸如分布式事务、联合查询、跨库 Join 等新的问题,每个问题如果人肉去搞定会更加的棘手,不过好在市面上针对这些领域也出现了很多优秀的框架,比如社区的 Sharding JDBC,阿里云刚刚开源的 PolarDB-X 等。2、常用解决方案:数据中心容灾为防止数据中心出现整体不可用的情况,一个常规的思路是需要针对性建设好容灾多活的高可用能力,数据中心级别的容灾常见的是同城和异地,但一个数据中心部署的服务很可能是分布式服务,针对每一个分布式服务的容灾策略都略有不同,本篇以常见的 MySQL 来举例子说一些常见的思路。容灾的核心是需要解决 CAP 中的两个问题,即:C(数据一致性)、A(服务可用性),但是根据 CAP 理论我们只能保 CP 和 AP 中的一个,所以这里到底选择什么样子的策略,其实是需要根据业务形态来制定的。对于同城 IDC 级别的容灾而言,由于他的 RT 一般都很小,数据一致性上能最大的得以满足。只是在 Paxos(MySQL 中的一致性算法)的 Master 节点所在的机房如果挂掉的情况下,会面临再次选主,如果集群较大可能会因为选主造成的几十秒级别 DB 不可用的情况。而对于异地场景而言,由于数据链路太长的问题,他的数据一致性基本上不可能满足,所以业务必须配合改造,做到业务级别的横向切分,如:华南数据中心服务华南客户群体,华北数据中心服务华北客户群体。而分片的数据再通过数据同步的方式做到最终一致性。防范到这里基本上说完了在线上应用的四个核心环节中,尤其提及了容易由于架构设计、基础设施脆弱等原因而造成的流量有损的点,也列举了对应场景下的解决方案。不过站在安全生产的角度上,一切安全生产的目的都是防范于未然。在互联网的系统中相比较于传统的软件产品,我们推荐两个在生产级别进行防范的方法:全链路压测和安全生产线上演练(也叫故障演练)。1、全链路压测在软件产品的生产体系中,任何一个即将上线的系统,我们都会进行各种目标的测试,其中就包括压力测试,即:使系统处于一个颇为严苛的环境中,来观看系统的表现。而一般的压力测试,只会针对性的构造相应的接口对线下部署的环境服务进行相应的压力测试,而且测试报告不出意外都是很完美的;但这样的压力测试会有几个问题:由于线上线下的依赖环境差异很大,而评估不到真实的线上系统容量。压测过程的数据不丰富,覆盖面窄而造成场景遗漏。由于压测的流量或者工具不够健全,只能评估到单台机器或服务,而非整个生产集群。如果要做到全面、系统、且真实的流量评估,我们推荐直接使用生产环境针对性的进行性能压测,但要想做到这样的全链路的压力测试,有很多的技术瓶颈需要突破,其中包括:有一套能力强大能构建出丰富场景的工具体系或产品。整体服务链路上,支持从流量入口开始的压测标示传递。系统中使用的中间件能识别正常流量与压测流量。业务需要针对压测流量作出业务改造(如影子表),以免压测数据影响到线上的真实数据。但是在执行过程中,由于全链路的影响面太大,在正式开始大流量的压测之前,需要逐步实施前期的准备工作,其中包括:压测方案制定、预跑验证、压测预热,最后才是正式压测。压测完毕还需要针对压测结果进行分析,以确保整个系统符合预先设定的目标。2、安全生产演练与全链路压测的思路类似,为了尽可能的贴近生产环境,安全生产演练我们也是推荐在线上完成。演练的目的是检验系统在各种不可预知的服务不可用、基础实施故障或者依赖失效的情况下,来检验系统的行为表现是否依然健壮。通常演练的范围从单应用到服务集群,甚至到整机房基础设施依次上升。演练场景可以从进程内(如:请求超时)、进程级别(如:FullGC)、容器(如:CPU 高),再到 Kubernetes 集群(如:Pod驱逐、ETCD 故障等)各个场景叠加,根据业务系统的反脆弱能力,针对性的作出选择。结语至此,三篇关于如何构建一个流量无损的线上应用系统就全部说完了,文中很多场景和技术点都是来源于真实的线上系统的真实故障。我们将这些年在每一个环节中的相应解决方案,以产品化的方式沉淀到企业级分布式应用服务(EDAS)中。EDAS 致力于解决在线应用的全流程流量无损,经过 6 年的精细打磨,已经在流量接入与流量服务两个关键位置为我们的客户提供了流量无损的关键能力,我们接下来的主要目标也是将这一能力贯穿应用的全流程,让您的应用默认能具备全流程的流量无损,极力保障商业能力的可持续性。接下来 EDAS 将围绕开发、测试继续构建一个完整的技术中台;我们也在筹备免费下载的版本,让您可以轻松的在自己的任意一个环境中享受到诸多默认流量无损的能力。在交付侧,将打通多集群、多应用批量交付,打通线上公共云、线下免费输出以及混合云之间的交付能力。敬请期待。

云原生微服务技术趋势解读

作者 | 彦林随着开源和云计算的推进,云原生微服务作为核心的技术保持着 20%左右的高速增长;随着微服务技术的成熟,门槛大幅降低,开始渗透到各行各业;一方面人力成本不断上涨,采用微服务提高研发效率势在必行;另一方面 90 后成为研发主力,微服务独立、敏捷的优势更受年轻人欢迎。微服务技术逐渐成熟,微服务核心架构分层愈加清晰,技术标准化和产业化正在形成,火热的服务网格技术逐渐回归理性,云原生网关作为下一代网关技术逐步成型,微服务技术整体进入深水区。微服务行业趋势(无处不在)微服务行业发展迅速从行业报告和微服务开源产品关注度上看微服务领域保持 20%+的高速增长,而且国内未来空间依然很大。2018-2023 年,全球微服务市场 CAGR 22.4%,2023 年预计达到$1.8Billion,亚太区市场规模市场份额 35%,仅次于北美地区。(数据来源:Marketsandmakets)。阿里微服务领域开源产品的关注度提升 20%左右,Star 数在过去一年陆续突破 2 万,关注度持续提升。微服务技术平民化早期采用微服务架构需要一个庞大微服务专业团队和自研一个微服务技术栈,因此只有部分互联网大厂采用,然而随着开源推进,大部分公司只需要选择一个适合自己的开源技术栈,大幅降低技术门槛;随着云厂商推动成本进一步大幅降低,只需 1 万块钱左右就可以具备微服务能力和专业的服务保障,因此数字化升级的各行各业都逐渐采用了微服务架构快速演进。微服务场景更广泛由于微服务技术门槛和复杂度导致采用成本比较高,早期研发人数仅 10 人左右,子系统超过 5 个才比单体架构效率更高,但是随着微服务技术成熟,微服务和单体应用效率发生变化的点左移,目前研发人数 5 个人左右,子系统超过 3 个做微服务都能获得更高的性价比,并且随着 Serverless 推进,一个 Fuction 就是一个服务,使用场景在不断扩大。微服务投入产出比更高随着人力成本不断上涨,机器成本不断下降,人力成本比机器成本要高的多,采用微服务能让企业拥有更高的研发协同效率,提升研发人员生产力;企业竞争现在更多是速度的竞争,采用微服务能让数字化系统迭代速度更快,在市场竞争中保持先发优势。微服务更受年轻人欢迎随着 90 后成为研发主体,他们更喜欢独立、自主、敏捷的研发模式,微服务让他们更加自由的协作,提升研发和协同效率,更快的完成产品迭代。微服务技术趋势(标准化)微服务架构分层逐渐清晰微服务架构分层逐渐形成,后端 BAAS 化,客户端轻量化,业务侧 Serverless 化,让业务更加聚焦业务开发,进一步提升研发效率。微服务技术标准逐步形成Istio/Envoy 成为服务网格控制面和数据面的事实技术标准,微服务竞争进入深水区,服务网格,服务治理,分布式事务,零信任会成为差异化竞争力。数据面 SidecarProxy 与 Proxyless 模式的融合由于部分链路 RT 敏感、升级环境受限等因素,Sidecar 模式不能很好的解决,随着 Sidecar 发展推动了数据面的标准化,目前 gRPC 已经支持 xDS 协议,Dubbo 也已经初步具备 xDS 协议的服务发现能力,预计在 3 月份 Dubbo 社区将提供完善的 xDS 服务治理能力支持,完成 SidecarProxy 与 Proxyless 模式的融合。服务治理数据面透明化,控制面标准化服务治理数据面将会逐步下沉,与业务逻辑逐步解耦,透明的实现治理技术的演进和升级。在数据面的形态上来看,存在多种形态并存,针对 Java 语言,以 Java Agent 为形态的的服务治理技术正在兴起并逐步成为趋势,针对非 Java 语言,基于 Sidecar 的 Service Mesh 技术正在被越来越多的企业采用,而在控制面,以一套控制面去控制不同数据面的形态成为主流,将逐步统一到以 K8s CRD 为中心的服务治理控制面中。服务治理的范围扩展到以开发,测试,发布,运维,安全等多场景的全生命周期。分布式事务从多样化到标准化数据是企业数字化转型中的核心资产沉淀,在微服务架构中应用架构层数据不一致性问题尤为突出。通过框架的方式快速帮助架构开发人员解决数据不一致可能导致的资损商誉问题,使其专注于业务本身的设计和开发是分布式事务的核心价值。在过去实现分布式事务方案复杂多样难以统一,方案与业务耦合严重难以复用,复杂场景一致性难以保证,缺少大厂背书和大规模流量验证难以推动实施,使分布式事务成为了大家能避则避的问题,这也导致了分布式事务领域的发展长期停滞不前。随着阿里 Seata 的开源,对分布式事务的概念、角色、模型和模式进行了延展和抽象,使其符合微服务的架构设计。通过工程框架的抽象进一步演化为事务的标准,使多种事务方案按照事务标准融合为一站式标准化的事务解决方案。多语言解决方案标准化在 Java 领域 阿里微服务 DNS 是最佳实践。Dubbo+Nacos+Spring-cloud-alibaba/Sentinel/Seata当然在过去的一年里,我们完成了多语言生态的布局,包括对服务网格/Dapr 生态/Golang 生态的无缝支持,让各种语言都能享受云原生微服务的红利。服务网格技术回归理性2020 年,27% 的公司正在生产中使用服务网格(比 2019 年增加了 50%),同时也有 23% 的公司目前正在评估服务网格技术(引自 CNCF),相比前几年的热度,与微服务整体增长速度相当,服务网格逐渐回归理性,用户更多在多语言场景和新的业务领域尝试。云原生网关逐步成型2020年,37% Ingress 实现选择 Envoy(比 2019 年增加了 116%),大量公司基于 Envoy 构建下一代网关技术(引自 CNCF)随着 K8s 通过 Ingess 将网关标准化,Ingress 作为容器、微服务的连接点,以 Istio 为控制面向下聚合 K8s,Nacos 多种服务,对上控制 Ingress(Edge)/ Sidecar(Runtime)东西南北流量。随着 Ingress 将网关标准化,网关呈现高集成发展趋势,云原生网关作为下一代网关将流量网关和业务网关二合一,降低 50% 资源成本;集成安全能力从入口建立安全防线;集成服务治理和可观测能力,从入口提高整个网站的高可用;支持单体应用,Nacos,K8s,Serverless 多种服务发现来源,统一接入,统一认证登陆。总结随着微服务技术门槛大幅下降,随着企业数字化升级步伐加速,随着云计算的迅速发展,微服务将无处不在;随着行业成熟度逐步提升,随着开源和标准推进,微服务的标准逐步形成,标准形成将进一步助力微服务产业发展,未来可期,因为相信,所以看见!!!点击文末链接,了解更多阿里云微服务产品详情。https://www.aliyun.com/product/aliware/mse

第二届云原生编程挑战赛圆满落幕!

今天是 2022 年的第一个月中最特别的一天,因疫情影响而姗姗来迟的第二届云原生编程挑战赛终于在上海圆满落幕。跨越了重重阻碍,克服了各个难题的选手们交上了他们满意的答卷,也捧回了属于他们荣耀的奖杯。再次感谢选手们的辛勤付出,也让我们祝贺他们未来在云原生技术领域中继续发光发热,越来越好!获奖名单大赛背景为了让更多的技术人深入了解云原生,并掌握用云原生的方法、技术、产品来解决问题,阿里云云原生应用平台在去年将已经成功举办 5 届的“中间件性能挑战赛”正式升级为“云原生编程挑战赛”,并在今年举办了第二届云原生编程挑战赛。本次大赛是由阿里云主办,云原生应用平台、天池联合承办的云原生顶级品牌大赛。在 2020 年已有超过 10000 支团队报名参赛,6 年来共吸引超过 23000 支队伍,覆盖 10 余个国家和地区。今年共有 13940 支队伍报名参赛,超过 14200+人参与其中,覆盖中国、美国、德国、加拿大、新加坡等 11 个国家和地区,汇聚 420+国内外顶尖高校和 260+领先企业,企业选手占比达 31%,已然刷新了去年的记录创造了参与热度的新高峰!本次比赛围绕着“挑战 Serverless 创新实践”展开,选手们将继续深度探索 RocketMQ、Dubbo 3、Serverless 三大热门技术领域。历时 3 个月的激烈角逐后,最终三大赛道的 TOP 3, 9 支战队脱颖而出,共计 16 位选手冲入决赛,展开了巅峰对决,争夺冠亚季军!获奖感言很庆幸自己参加了这次比赛,再一次感受到了云原生技术带来的冲击。也很庆幸自己正处在这么一个“原生万物,云上创新”的时代,技术的革命正在给这个世界带来前所未有的巨变。 我们是簇拥在技术浪潮里的一粒沙,用青春和热情拥抱着潮汐的变化。 荣耀只属于过去,未来需更加努力,为了成就更加优秀的自己,也为了携手共建更加美好的世界。 奔跑吧,云原生,我们永远和你在一起!——赛道1冠军 Ninety Percent(陈林江)这一切的起点从去年遇见云原生开始,那时的酷暑还未褪去,大赛的消息应期而来,从最初的磕磕碰碰,到之后的逐渐适应,而那每次成绩的提升都是对我莫大的鼓励,并支撑着我来到了云原生大会,获得了这样一份可观的成绩。感谢云原生大会以及阿里云提供这个平台,让我遇到很多志同道合的新朋友,也让我能够感受到技术发展的新前沿。——赛道2冠军 哇蛤蛤(吴文彪)非常高兴评委老师对我们工作的认可。云原生是当前最为前沿的构建软件的方法论。我们可以预知,在可见的未来会有越来越多的软件,包括业务层的软件和更为底层的系统软件,将基于云原生的思想设计开发。而Serverless则是一条通向云原生架构的捷径。感谢阿里云天池提供的平台,让我们能有机会探索Serverless在工程方面的应用。未来我们将尝试探索更多通过Serverless实现系统软件云原生化的方案,欢迎大家关注北京航空航天大学计算机学院ACT实验室以及十行笔记这款产品。——赛道3冠军 cn_lhc (刘瀚承)感谢大家一路的陪伴和见证!云原生编程挑战赛,我们下一届见!

成功报名须知 | 云原生 Serverless 技术实践营南京站

如果您已经收到报名成功的短信通知,请了解本次活动的注意事项:1、活动时间和地址:1月13日(周四)、9:30-16:30,南京市鼓楼区湖南路47号凤凰台饭店(原地址是南京阿里中心,因报名客户较多,更换至凤凰台饭店);2、请搜索钉群群号:32960855,入群会审核,若您使用钉钉不频繁,也可以添加工作人员微信:zjjxg2018,我们会拉您进微信群;3、本次活动免费,采取报名审核制,中午含餐,完成下午的动手实操,颁发阿里云官方认证证书,请确保报名时的姓名是填写准确的,我们会提前制作好认证证书,现场颁发;4、参与动手实操的客户,请带好笔记本电脑,无须提前安装相关程序,我们提供了工程化较好的体验沙箱,动手实操活动是免费的,无须在云上支出费用;6、请遵循当地疫情政策,进入酒店出示健康码和行程码,佩戴口罩。任何疑问,您也可以钉群内或微信咨询工作人员。活动议程介绍:https://developer.aliyun.com/article/839630

成功报名须知 | 云原生最佳实践Workshop 深圳站

行前准备:1、活动时间和地址:1月7日(周五)、9:30-18:00,深圳市南山区科苑南路(深圳湾段)3331号阿里中心T4栋 3楼-天满城;2、请扫描末尾二维码加入钉群,以获取本次活动的最新资讯;3、本次活动免费,采取报名审核制,中午含餐,完成下午的动手实操,颁发阿里云官方认证证书;4、我们会提前发送访客码至您的报名手机号上,请您提前完成身份证实名认证,凭访客码入园;5、参与动手实操的客户,请带好笔记本电脑,无须提前安装相关程序,我们提供了工程化较好的体验沙箱,动手实操活动是免费的,无须在云上支出费用;6、园区地下车库提供访客免费车位,停车之后凭访客短信到一楼大堂登记即可,但是车位数量有限,建议您乘坐公共交通,低碳出行;7、请遵循当地疫情政策,入园出示健康码和行程码,佩戴口罩。活动当天:1、行前确认:1)身份证、口罩;2)有WIFI的笔记本电脑,阿里云个人账号(非公司子账号);3)7号多云,无需雨具;4)建议地铁出行【2号线-登良地铁站】。2、签到:T4号楼1楼领取访客证,并在签到台签到,3楼会议室。第一步:请佩戴口罩携带身份证,完成实名认证后可刷脸进入,或凭短信在机器领取访客证(全天出入请佩戴)。第二步:三楼楼进入培训室。3、上课:本次课程由讲师精心准备,请大家全心投入,调整手机静音或至教室外接听电话。1)欢迎大家参与互动,互动设置奖励。2)下午的环节,会需要现场使用电脑实操。3)凭访客手机号获取wifi接入,登录阿里云账号4)跟随讲师步骤,现场操作,并在最后一步完成截屏晒群。5)完成全部课程后可获得阿里云官方培训证书。4、课后:给我们进行评价建议。大家一起合影留念,愉快的返程!现场联系人:紫泷18126153085,营火18626862517

专访 KubeVela 核心团队:如何简化云原生复杂环境下的应用交付和管理

作者 | Infoq Tina背景12 月 9 日,在 2021 年 KubeCon 云原生技术峰会上,CNCF 开源项目 KubeVela 宣布推出了 1.2 版本。 KubeVela 是一个简单易用且高度可扩展的应用交付和管理平台,基于 Kubernetes 与 OAM 技术构建。其核心功能是让开发人员方便快捷地在 Kubernetes 上定义与交付现代微服务应用,而无需了解任何 Kubernetes 本身相关的细节。 KubeVela 于 2020 年 11 月开源,2021 年 4 月发布 1.0 版本。2021 年 7 月,KubeVela 和 OAM 项目整体捐赠给 CNCF 基金会托管。 在 1.2 版本中,KubeVela 新增了以应用为中心的控制面板 UI 功能,使应用组装、分发、交付流程变得更简单,并可以通过 UI 控制台及时了解整个交付链路状态,简化多云/混合环境交付方式。另外还新增了基于订阅模型的开源应用交付系统 ,使企业和云原生应用开发者只需要在 GitHub/Gitlab 上修改代码,就可以自动完成云原生应用交付的整个链路。 从开源到现在已经有一年多,KubeVela 社区取得了什么样的进展?有了哪些落地实践?1.2 版本中为什么会新增加这两个功能,适合于什么场景?为解答这些问题,InfoQ 采访了 OAM/KubeVela 产品和开源社区负责人曾庆国。嘉宾简介:曾庆国(花名:悦达),阿里云技术专家,目前负责 OAM/KubeVela 产品和开源社区,从事云原生、应用交付、开源领域研究和实践多年,致力于推动云原生应用标准化和云原生技术“亲民化”。 02专访问答Aliware01InfoQ:目前基于 Kubernetes 的云原生应用交付还存在哪些挑战和难点?业界对应的有哪些解决方案?曾庆国:如今 Kubernetes 逐渐成为了基础设施的标准集成界面,云原生生态的繁荣也为我们提供了近乎无限的基础设施能力。然而众多的选择是礼物,也是研发工程师的噩梦,大量复杂的知识需要学习,就好比一个业务研发工程师需要了解操作系统底层的系统调用一样。然而应用的高效、安全交付,才是工程师真正的诉求。如何用好云原生繁荣的技术生态,又能降低用户的使用门槛,同时安全可靠的交付应用,成为了业界新的挑战。 业界的典型做法主要分为三类,一类是容器平台模式,原汁原味的透出底层组件,灵活性很强,但平台使用者需要学习组件大量的技术细节;第二类是在针对不同的业务场景构建内部的平台,但是由于顶层设计不足,拉通难度大,不同垂直场景成为互相独立的烟囱而无法做到能力复用、统一管理;第三类则是基于 CI/CD 系统,以脚本、配置等构建简单的抽象体系简化使用,这个方式的问题在于无法满足大规模场景的需要,脚本和配置文件散落各处,其上手和维护的门槛非常高,也有安全隐患。02InfoQ:KubeVela 在 Kubernetes 生态系统中处于什么位置?初心是解决什么样的问题?现在的目标与最初相比有所变化? 曾庆国:今天,无论是 Kubernetes 本身还是现有的各类应用交付系统,都缺乏一个统一的面向应用交付过程的上层抽象。这种缺乏往往同底层基础设施紧密耦合,导致用户心智负担很重并且严重依赖于用户个人的经验和能力。这不仅会大幅影响用户体验、降低生产效率,甚至还会导致错误和故障的发生。KubeVela 是针对这个问题的开源、标准又不失灵活度的解法。 KubeVela 在 Kubernetes 生态系统上层建立了“以应用为中心”的视角,业务层的开发者可以直接使用 KubeVela 作为开箱即用的 CI/CD 工具对接包括 Kubernetes 和云资源,完成应用交付和管理。对于中大型的公司,KubeVela 是一个具备充分可扩展性的应用交付和管理引擎,这些公司可以基于 KubeVela 标准化的扩展机制,针对自身业务场景扩展应用交付能力,快速构建自己的应用管理平台。 这个初心一直没有变化,我们从应用标准 OAM 到如今 KubeVela v1.2 即将推出的 UI 控制台,这一系列的工作都是在推动云原生社区从基础设施向应用层不断发展和演进,最终实现开发者自助的应用交付和管理模式,最终期望为业界带来标准和统一的云原生应用管理层,普惠云计算的开发者。03InfoQ:从中立客观的角度来讲,您们认为 PaaS 解决方案和 KubeVela 各有什么样的优缺点?曾庆国:说到经典的 PaaS 解决方案,业界最出名的就是 Heroku 和 Cloud Foundry,它们提供完整的应用程序部署和管理功能,为业务开发人员提供了非常好的体验和开发效率。但是云原生的崛起带来了技术的全面升级,也带来了云计算的巨大繁荣。传统的 PaaS 平台通过提供一层应用封装和抽象为用户带来好的体验,但这层封装往往缺少良好的定制化扩展能力,平台演进不得不完全依靠平台团队开发,无法应对业务新的个性化需求,无法应对新技术发展的敏捷集成。  KubeVela 和它们最大的区别在于其可扩展性,KubeVela 从设计的第一天就以高可扩展为原则,以此为核心提供端到端的抽象和用户体验。它的交付工作流乃至整个应用交付与管理能力集都是由独立的可插拔模块构成的,这些模块可以随时通过编写 IaC 配置模板的方式进行增减、重定义,且变更会即时生效。借助这种从核心模型到 UI 呈现都能够快速变更的技术,使得 KubeVela 能够兼顾“使用简单”和“技术先进性”。 此外,KubeVela 是一个独立于运行时集群的应用交付控制平面,天然支持多集群、多云混合环境(这是我们认为的下一代 PaaS 系统的合理形态),而现有的 PaaS 则往往选择以插件形式部署在运行时集群当中。InfoQ:基于 Helm 的应用交付方案,和 KubeVela 解决方案相比,两者有哪些不同?曾庆国:Helm 是 Kubernetes 的包管理器,它能够以 Chart 为一个单元,提供打包、安装和升级的一组 YAML 文件的能力。 KubeVela 是一个完整的应用交付系统,它借助扩展能力可以部署各种制品类型,当然也包括 Helm Chart,除此之外还包括 Kustomize、Terraform Modules 等。KubeVela 支持 Kubernetes 和云服务等多种运行平台。同时它也涵盖了多集群交付的能力,包括跨环境部署的各类编排能力。例如,你可以使用 KubeVela 定义一个由 WordPress Chart 和阿里云 RDS 实例组成的应用,编排这两个组件之间的顺序关系,然后将它们按照一定的策略分发到多个 Kubernetes 集群当中。 我们也在社区里见到了一些基于传统 CI/CD 工具 和 Helm 做应用部署的解决方案,这类方案通常会通过类似 Jenkins/Gitlab 这样的 Pipeline ,将应用制品打包成 Helm Chart,然后直接部署到 Kubernetes 集群中。这种模式看似简单,实际上存在三个方面的问题: 手工维护工作量大,比如由于突发的网络原因、或者由于 pipeline 系统的某个故障,就会中断所有的发布并且需要人工介入,缺乏自愈能力,一旦场景有变化,就要修改脚本,比较难维护。没有一个统一的模型描述完整的应用交付过程,不同的人可以从多处入口对系统进行变更,例如有的通过 CI/CD 系统,有的直接改 Kubernetes,时间久了系统的配置会出现很大的不一致,容易引发故障。存在安全风险,CI/CD 安全域不隔离,基础设施多个集群的秘钥全都在 CI/CD 系统中存储,一旦被黑客突破容易引发非常大的系统安全风险。KubeVela 是面向终态的应用交付和管理控制平面,KubeVela 的交付引擎具备自愈、幂等、收敛以及确定这四大特性,同时 KubeVela 背后有一个完整的应用模型(OAM),这个可以作为统一的应用入口,避免配置漂移等问题。KubeVela 自身也具备完整的 GitOps 以及多集群自治的功能,可以保证环境独立管理,安全域隔离。InfoQ:社区针对小规模集群或个人开发者的场景有所疑问,认为无论是增加 API 层还是还需编码,KubeVela 的方向在复杂化应用交付和集群管理,对此您们有何看法? 曾庆国:KubeVela 从一开始就诞生于开源社区,演进至今已有上百位贡献者参与代码贡献,吸纳了来自阿里、腾讯、字节、第四范式、Gitlab 等一系列不同领域公司的工程实践。KubeVela 从一开始的设计目标是保证充分的可扩展性,这样才能满足用户的多样化场景需求,充分利用云原生领域百花齐放的技术生态红利。 对于个人开发者或中小型科技企业,他们的实际需求必然是希望使用云原生技术就像使用 iOS 操作系统一样,低门槛,易用且好用。把端到端的体验做成闭环才能更好满足他们,无论增加 API 层还是需要编码,都不是这类用户想要关心的话题。 客观的说,在 KubeVela 最初的几个版本,由于要把面向可扩展性的核心设计做实,用户看到的形态更多是偏框架一层的实现。在发展到 v1.1 版本以后,我们就陆续加入了很多端到端的集成案例,包括 GitOps、Jenkins CI/CD、Helm 包的完整部署等,即将发布的 v1.2 就更是一个面向小规模集群和个人开发者直接开箱即用的平台了,用户可以直接操作 KubeVela 的 UI 控制台就可以完成应用交付的完整体验。 InfoQ:1.2 版本中,基于订阅模型的应用交付主要是解决什么场景下的问题?曾庆国:基于订阅模型的应用交付主要解决以下几个维度问题: 1、区域隔离,安全自治完整的应用交付链条分为 CI 过程、配置过程和部署过程。在订阅模型中,控制平台支持自动从制品库发现制品的变更,从配置仓库发现配置的变更,从而执行后续的部署动作,Runtime 集群区域主动从管控平台获取到部署任务执行。每一个环节都独立工作,自成体系,每一个环节都根据需要进行授权和审核,安全可靠。 2、网络隔离,云边协同订阅模型采用 PULL 的模式,仅需要单向通信网络即可工作,在边缘应用交付中这是一个必需的选项。KubeVela 可以统一编排和管理云端和边缘端应用,实现云边协同。 3、集中管理,充分自动化刚才我们提到,每一个阶段都是独立自动化工作的,且具备自愈、幂等、收敛以及确定这四大特性。让我们的管理侧实现统一。 另一方面,在 KubeVela 1.2 版本中,主要打造了在多集群、多环境下微服务应用的统一管理解决方案。用户通过操作 UI 控制台,实现集群接入、租户分配、环境规划和应用交付等完整用户故事。07InfoQ:目前 KubeVela 社区发展情况如何?未来的路径规划是什么?曾庆国:KubeVela 是一个从第一天就诞生在云原生社区的开源项目,KubeVela 背后的应用模型就是 OAM。自 2019 年阿里和微软发布 OAM 模型以来,OAM 模型以及 KubeVela 项目已被阿里、Oracle、Salesforce、腾讯、字节跳动、网易游戏等 40+ 家不同行业的领先企业应用在实际生产环境,帮助他们在不同场景下实现更高效的云原生应用的交付和管理。展望KubeVela 项目发展也非常迅速,至今已经累计有上百位开发者参与贡献,社区有上百万的镜像下载。2021 年 7 月,KubeVela 和 OAM 项目也已经整体捐赠给 CNCF 基金会托管,所以这也是一个完全中立的社区。KubeVela 在社区用户中的大规模实践,也正在促进 OAM 成为混合云/多云/分布式云领域应用交付的事实标准,并在阿里、微软、Oracle Cloud、腾讯等多家国内外厂商中被采用。2021 年 5 月,以 OAM 模型为核心的《云计算开放应用架构》标准文件也已经由阿里云和信通院等 10 余家单位联合发起并在“云原生产业大会”现场发布。 随着 v1.2 版本的发布, 未来 KubeVela 将更多的提供端到端的完整用户体验,丰富更多垂直场景下的能力,朝着开发者能够自助完成应用交付的方向演进,让混合环境下的应用交付就像我们今天使用 App Store 一样简单。您可以通过如下材料了解更多关于 KubeVela 以及 OAM 项目的细节:项目代码库:github.com/oam-dev/kubevela 欢迎 Star/Watch/Fork!项目官方主页与文档:kubevela.io ,从 1.1 版本开始,已提供中文、英文文档,更多语言文档欢迎开发者进行翻译。项目钉钉群:23310022;Slack:CNCF #kubevela Channel

一文读懂蓝绿发布、A/B 测试和金丝雀发布的优缺点

作者 | 扬少背景目前,业界已经总结出了几种常见的服务发布策略来解决版本升级过程中带来的流量有损问题。本文首先会对这些普遍的发布策略进行简单的原理解析,最后结合阿里云的云原生网关对这些发布策略进行实践。发布策略被业界广泛采用的服务发布策略包括蓝绿发布、A/B 测试以及金丝雀发布。1、蓝绿发布蓝绿发布需要对服务的新版本进行冗余部署,一般新版本的机器规格和数量与旧版本保持一致,相当于该服务有两套完全相同的部署环境,只不过此时只有旧版本在对外提供服务,新版本作为热备。当服务进行版本升级时,我们只需将流量全部切换到新版本即可,旧版本作为热备。由于冗余部署的缘故,所以不必担心新版本的资源不够。如果新版本上线后出现严重的程序 BUG,那么我们只需将流量全部切回至旧版本,大大缩短故障恢复的时间。待新版本完成 BUG 修复并重新部署之后,再将旧版本的流量切换到新版本。蓝绿发布通过使用额外的机器资源来解决服务发布期间的不可用问题,当服务新版本出现故障时,也可以快速将流量切回旧版本。如图,某服务旧版本为 v1,对新版本 v2 进行冗余部署。版本升级时,将现有流量全部切换为新版本 v2。当新版本 v2 存在程序 BUG 或者发生故障时,可以快速切回旧版本 v1。蓝绿部署的优点:1、部署结构简单,运维方便;2、服务升级过程操作简单,周期短。蓝绿部署的缺点:1、资源冗余,需要部署两套生产环境;2、新版本故障影响范围大。2、A/B 测试相比于蓝绿发布的流量切换方式,A/B 测试基于用户请求的元信息将流量路由到新版本,这是一种基于请求内容匹配的灰度发布策略。只有匹配特定规则的请求才会被引流到新版本,常见的做法包括基于 Http Header 和 Cookie。基于 Http Header 方式的例子,例如 User-Agent 的值为 Android 的请求 (来自安卓系统的请求)可以访问新版本,其他系统仍然访问旧版本。基于 Cookie 方式的例子,Cookie 中通常包含具有业务语义的用户信息,例如普通用户可以访问新版本,VIP 用户仍然访问旧版本。如图,某服务当前版本为 v1,现在新版本 v2 要上线。希望安卓用户可以尝鲜新功能,其他系统用户保持不变。通过在监控平台观察旧版本与新版本的成功率、RT 对比,当新版本整体服务预期后,即可将所有请求切换到新版本 v2,最后为了节省资源,可以逐步下线到旧版本 v1。A/B 测试的优点:1、可以对特定的请求或者用户提供服务新版本,新版本故障影响范围小;2、需要构建完备的监控平台,用于对比不同版本之间请求状态的差异。A/B 测试的缺点:1、仍然存在资源冗余,因为无法准确评估请求容量;2、发布周期长。3、金丝雀发布在蓝绿发布中,由于存在流量整体切换,所以需要按照原服务占用的机器规模为新版本克隆一套环境,相当于要求原来1倍的机器资源。在 A/B 测试中,只要能够预估中匹配特定规则的请求规模,我们可以按需为新版本分配额外的机器资源。相比于前两种发布策略,金丝雀发布的思想则是将少量的请求引流到新版本上,因此部署新版本服务只需极小数的机器。验证新版本符合预期后,逐步调整流量权重比例,使得流量慢慢从老版本迁移至新版本,期间可以根据设置的流量比例,对新版本服务进行扩容,同时对老版本服务进行缩容,使得底层资源得到最大化利用。如图,某服务当前版本为 v1,现在新版本 v2 要上线。为确保流量在服务升级过程中平稳无损,采用金丝雀发布方案,逐步将流量从老版本迁移至新版本。金丝雀发布的优点:1、按比例将流量无差别地导向新版本,新版本故障影响范围小;2、发布期间逐步对新版本扩容,同时对老版本缩容,资源利用率高。金丝雀发布的缺点:1、流量无差别地导向新版本,可能会影响重要用户的体验;2、发布周期长。实践接下来,我们会基于阿里云的容器运维平台 ACK 以及 MSE 云原生网关对以上介绍的三种发布策略进行实践。这里我们采用最简单的业务架构来展示,即一个云原生网关、一个后端服务(响应中返回当前版本信息)和注册中心。注册中心决定了业务架构中服务发现方式,我们会分别以 K8s 容器服务和 Nacos 两种服务发现机制来实践不同的发布策略。1、前提条件创建了阿里云容器运维平台 ACK创建了 MSE 云原生网关创建了 MSE 注册中心 Nacos(服务发现方式为 Nacos 时需要)2、服务发现方式:K8s 容器服务在这个例子中,我们使用 K8s 原生的服务发现方式,即通过声明式 Service API 资源将后端服务注册到 CoreDNS。例子中的后端服务提供一个查询当前版本的接口/version,并且当前版本为 v1。云原生网关深度集成 ACK,可以实时动态地从 ACK 集群中获取服务信息,方便通过云原生网关将该后端服务暴露给外部用户。业务架构如下图:1、部署将以下资源(Service和Deployment)应用到 ACK 集群,完成后端服务的部署和发布,当前应用版本为 v1。apiVersion: v1 kind: Service metadata: name: httpbin spec: ports: - port: 8080 protocol: TCP selector: app: httpbin apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v1 spec: replicas: 3 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: containers: - image: specialyang/spring-cloud-httpbin-k8s:v1 imagePullPolicy: Always name: spring-cloud-httpbin-k8s ports: - containerPort: 8080在云原生网关的服务管理->来源管理中,添加目标 ACK 集群。在服务管理中导入要暴露给云原生网关的服务 httpbin。在 httpbin 服务的策略配置中添加服务版本 v1,注意需要选择对应的标签来筛选出 v1 版本的节点,因为目前我们只部署了 v1 版本,所以 v1 版本的节点数占总实例数 100%。在路由管理中为该服务创建一条路由规则,从而将服务暴露给外部用户。httpbin 服务暴露的 api 的 path 为/version,请求转发至服务 httpbin 的 v1 版本。执行以下脚本测试请求的响应结果。for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v12、蓝绿部署蓝绿部署需要按照服务当前版本所占用的资源状况为服务新版本申请同样的资源规格,部署完毕之后将流量整体切换到服务新版本。利用 K8s 的声明式 API 资源部署 httpbin 服务的新版本 v2,副本数同样是 3。apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v2 spec: replicas: 3 selector: matchLabels: app: httpbin version: v2 template: metadata: labels: app: httpbin version: v2 spec: containers: - image: specialyang/spring-cloud-httpbin-k8s:v2 imagePullPolicy: Always name: spring-cloud-httpbin-k8s ports: - containerPort: 8080在 httpbin 服务的策略配置中添加服务版本 v2,注意需要选择对应的标签来筛选出 v2 版本的节点,集群中现在 v1 和 v2 版本的节点数一致,所以各占 50%。现在,我们开始利用蓝绿发布的思想将流量从 v1 整体切换至 v2,仅需要之前修改上面创建的路由规则中目标服务即可。执行以下脚本测试请求的响应结果。for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2 version: v2现在我们发现访问 api 资源/version 的请求的流量已经全部从 v1 切换至 v2。3、A/B测试A/B 测试基于用户请求的元信息将流量路由到新版本,换句话说,就是可以根据请求内容来动态路由。举个例子,我们希望 User-Agent 的值为 Android 的请求 (来自安卓系统的请求)可以访问新版本,其他系统仍然访问旧版本。我们仍然利用上面实践中部署的 httpbin 的 v1,v2 的 deployment。此外,需要创建两条路由规则:匹配 path 为/version 的请求访问服务版本 v1匹配 path 为/version,且 User-Agent 头部含有 Android 的请求访问服务版本 v2注意相比 version 路由规则,version-v2 的路由规则中需要增加请求头匹配规则。通过以下脚本测试 A/B test 的效果。// user agent中不含有 android curl ${GATEWAY_EXTERNAL_IP}/version version: v1 // user agent中含有 android curl -H "User-Agent: Mozilla/5.0 (Linux; Android 4.0.3)" ${GATEWAY_EXTERNAL_IP}/version version: v2可以看出,当前请求会按照来源的操作系统对流量进行分流。4、金丝雀发布金丝雀发布允许引流一小部分流量到服务新版本,待验证通过后,逐步调大流量,直至切流完毕,期间可伴随着新版本的扩容,旧版本的缩容操作,达到资源利用率最大化。在金丝雀发布策略中,服务新版本的副本初始部署数无需与原始保持一致。仅需保持资源始终满足灰度流量,所以我们将新版本的副本数调为 1,可以在服务策略中服务版本模块看到当前各版本节点数的占比情况。清除掉其他发布策略遗留的路由规则,我们新创建一条路由规则,在目标服务中按照权重将流量转发至新旧版本。其中,目标服务需要配置两个目的地,httpbin 的 v1 和 v2 版本,并设置对应的流量比。通过以下脚本测试金丝雀发布的效果。for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done version: v1 version: v1 version: v1 version: v1 version: v1 version: v2 version: v1 version: v2 version: v1 version: v1在以上测试结果中,可以发现 10 个请求中,有 2 个是访问的新版本 v2,其流量比确实符合期望的 8:2。在真实业务场景中,新版本验证完毕后,就可以继续调大访问新版本的流量权重,期间注意对新版本扩容,按需对旧版本缩容。3、服务发现方式:Nacos 注册中心Kubernetes 平台为容器化应用带来了动态弹性,加快了应用交付进程,提高了底层资源的利用率,但在服务发现能力上,相比其他主流注册中心 Nacos、Consul 等,其功能完整性、可用性上略显不足。因此,即使大部分业务应用已经迁移至 Kubernetes 运维平台,但仍然选择为业务保留了原始的注册中心。针对这种业务场景,我们额外举例当使用 Nacos 注册中心时,如何为服务进行蓝绿发布、A/B 测试和金丝雀发布。例子中的后端服务提供一个查询当前版本的接口/version,并且当前版本为 v1。云原生网关深度集成 MSE Nacos 注册中心,可以实时动态地从 Nacos 实例中获取服务信息,方便通过云原生网关将该后端服务暴露给外部用户。业务架构如下图:1、部署将以下资源(Deployment)应用到 ACK 集群,完成后端服务的部署,并将服务发布到 Nacos 注册中心,当前应用版本为 v1。需要注意以下几点:1、该 yaml 资源中变量${NACOS_SERVER_ADDRESS}需要替换为你的 MSE Nacos 地址,如果和网关在一个 VPC,那么内网域名即可;否则,你需要配置公网域名。2、在 K8s Service 服务发现中,Pod 中 Labels 信息可看做是节点的元数据信息。而在 Nacos 注册中心中,节点的元数据信息取决于服务注册时携带的信息。在 Spring Cloud 框架中,通过环境变量 spring.cloud.nacos.discovery.metadata.xxx 无侵入式为节点添加元数据信息,在该例子中,我们以 version 作为版本标用来区分不同版本的节点。因此,需要为业务容器添加环境变量 spring.cloud.nacos.discovery.metadata.version=v1。apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v1 spec: replicas: 3 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: containers: - image: specialyang/spring-cloud-httpbin-nacos:v1 imagePullPolicy: Always name: spring-cloud-httpbin-nacos ports: - containerPort: 8080 - name: spring.cloud.nacos.discovery.server-addr value: ${NACOS_SERVER_ADDRESS} - name: spring.cloud.nacos.discovery.metadata.version value: v1在云原生网关的服务管理->来源管理中,添加目标 MSE Nacos 注册中心集群。在服务管理中导入要暴露给云原生网关的服务 httpbin,注意服务来源选择 MSE Nacos 注册中心。与 K8s Service 服务发现的例子一样,在策略配置中添加服务版本 v1,标签名和标签值可以选择为我们在 httpbin 服务注册时添加的元数据信息 version=v1。之后配置路由匹配 path为/version 的请求转发至 httpbin 服务的 v1 版本。执行以下脚本测试请求的响应结果。for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo ""; done version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v1 version: v12、蓝绿部署其发布策略如下图所示:部署 httpbin 服务的新版本 v2,注意注册中心与上面保持一致,同时为业务容器增加环境变量 spring.cloud.nacos.discovery.metadata.version=v2,业务应用启动时会向指定 Nacos 注册服务,同时携带上用户自定义的元数据信息。云原生网关可以利用这些元数据信息来对节点区分不同的版本。apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v2 spec: replicas: 3 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: containers: - image: specialyang/spring-cloud-httpbin-nacos:v2 imagePullPolicy: Always name: spring-cloud-httpbin-nacos ports: - containerPort: 8080 - name: spring.cloud.nacos.discovery.server-addr value: ${NACOS_SERVER_ADDRESS} - name: spring.cloud.nacos.discovery.metadata.version value: v2与 K8s Service 的例子中蓝绿发布操作一样,在 httpbin 服务的策略配置中添加服务版本 v2,然后将路由规则中的目标服务 httpbin 的 v1 版本修改为 v2 版本,发布成功之后,查看请求结果全部为 version: v2。3、A/B 测试其发布策略如下图所示:我们同样用之前的例子,User-Agent 的值为 Android 的请求 (来自安卓系统的请求)可以访问新版本,其他系统仍然访问旧版本。涉及的路由规则的操作、与验证方式与 K8s Service 的例子一致。4、金丝雀发布其发布策略如下图所示:同样,涉及的路由规则的操作、与验证方式与 K8s Service 的例子一致。总结本文对常见的发布策略进行了简单介绍和原理解析,并以图文并茂的方式对每个发布策略进行了详细探讨,总结如下:蓝绿发布:简单理解就是流量切换,依据热备的思想,冗余部署服务新版本。A/B 测试:简单理解就是根据请求内容(header、cookie)将请求流量路由到服务的不同版本。金丝雀发布:是一种基于流量比例的发布策略,部署一个或者一小批新版本的服务,将少量(比如 1%)的请求引流到新版本,逐步调大流量比重,直到所有用户流量都被切换新版本为止。云原生网关以托管的方式来作为您的流量入口,提供了丰富的流量治理能力,支持多种服务发现方式,如 K8s Service、Nacos、Eurake、ECS 和域名,并以统一的模型支持了服务版本以及灰度发布能力。在上面的实践中,可以发现两种服务发现方式仅仅是元数据信息所处的位置不同,但服务版本管理以及路由规则中的灰度发布模型都是一致的,您可以轻松学会为不同服务发现方式的服务进行灰度发布,确保版本升级过程中平滑无损。最后,对微服务领域感兴趣的同学,可以钉钉搜索群号 34754806 加入用户群交流、答疑。

Sealer - 把 Kubernetes 看成操作系统集群维度的 Docker

作者 | 中弈写在开头身为一名技术人员,总是喜欢把自己的作品打造成理想状态呈现给别人,我非常荣幸能把集群镜像这样一个卓越的想法变成现实, 也非常开心用户使用我们的作品时对我们的高度认可。Sealos 虽然已经超过 5k 星,数千家客户在生产环境中使用,不乏很多一线互联网公司和大厂。曾经 sealos 也令我很激动,我把一件复杂的事情做到的极简,这是核心竞争力,即便如此我还是不会夸它,因为在 sealer 面前它黯然失色。Sealer为什么会诞生1、云的背景与趋势从应用的视角看,云的发展历程就是一个不断屏蔽底层细节让应用更关注业务逻辑本身的一个过程。Openstack 让开发者不用再关心物理机复杂的管理问题,但是并未在应用本身管理在有任何改善,对于应用开发者依然需要和操作系统打交道。Docker 的出现掀起了一场云架构的革命,穿透了传统的 IaaS、PaaS,让分层变模糊,此时已经帮助应用实现一些打包隔离工作,一定程度让应用变得更容易管理。Kubernetes 的出现让云从分层架构走向“云内核”架构,云操作系统逐渐显现,对下实现计算网络存储这些资源的抽象,对上实现应用的编排管理。此时应用的配置管理,服务发现,资源配置变得更为简单,发布分布式应用变得像发布单机应用一样流畅。Serverless FaaS 的出现就让应用更聚焦于业务逻辑本身了,只是目前还没能出现像 Kubernetes 一样的实际标准性的东西,还处在百家争鸣的阶段。有意思的地方的区块链领域的智能合约,以太坊的 EVM 第一代合约天生就是 serverless,运行在以太坊这个世界计算机上。而以 Polkadot solana near ICP 这样为代表的二代合约支持了 WASM 打破了 EVM 的场景局限,让合约走向更通用的场景。所以非常期待云和链技术最终能在一个地方统一,实现真正意义上的“世界计算机”,所有应用都在这台“超级电脑上”运行。2、交付领域的痛点与刚需我们希望让 Kubernetes更简单,顺应技术大趋势让基于 Kubernetes 的交付变得更干净利索。目前专有云交付面临的三大困局,Docker、Kubernetes、Helm 这些技术虽然解决掉了一部分痛点,但是并不彻底:Docke r仅解决了单个应用的镜像化问题,对于软件整体来说是包含非常多分布式组件的,这块 docker 不管;Kubernetes 很好的解决了分布式应用管理和资源的抽象问题,应用之间复杂的应用如何编排,但是庞杂的编排配置如何管理?Helm 只是把编排文件打包和参数的抽离,但是并不会把所有依赖都管理起来。所以即便你使用了上述技术,一旦到了真实场景,一样会焦头烂额。对于很多用户而言安装 Kubernetes 本身可能比装业务还复杂,那么多容器镜像如何管理,到了客户环境需要的依赖没人怎么办,一个一个组件安装人工误操作导致出问题概率大大提升。所以非常需要一个集群整体打包成镜像的技术,在集群维度保障一致性。3、优秀的设计理念只有在伟大的想法诞生时你会为之激动,充满热情,想尽一切办法让它变成现实。在设计 sealer 时想尽一切办法让它变得简洁干净但是还需要满足各种能力,就像要把很多复杂的技术融入到一个手机里一样,做减法才是考验一个人设计能力的地方。Sealer 的理念也把大道至简和高度抽象阐述到了极致,确实以优雅的方式解决了很痛点的问题,符合行业大趋势且能创造巨大的生态价值。Sealer 的价值1、帮助企业实现规模化交付对于专有云交付类的公司而言,sealer 最终能帮你实现的就是实现规模化交付,扩大营收,降低成本,提高利润。采用 sealer 技术的公司可以在规模化竞争中取胜,降低单次产品交付价格,创造核心价格优势。以现有的交付类项目现状来看几乎都是几十万上百万起步,这几乎就把客户群体限制在头部客户了,但是对于中小企业需求是真实存在的,由于交付成本高导致出现这种有需求无市场的情况。如果价格能降低到数千或者几万,那新的市场就会完全被打开。对于甲方来说也是一样,采购一套软件到落地都是数月的时间,和销售沟通、poc、交付等等,整个链路非常长。因为乙方的交付成本变低,相应甲方的采购成本也会降低。在 sealer 出现之前想一年线下交付一万套复杂软件对于绝大多数企业而言几乎不可能完成,像小时级别的交付更是异想天开,但是 sealer 可以实现自助化,交付规模不再受技术水平限制,还能实现快速一键交付。2、打破协作壁垒Docker 出现之前就已经有非常多的容器技术了,为什么都没有出现席卷之势和颠覆效应?很大一部分原因是标准的出现让生态之间的协作成为可能。Docker 镜像的出现让软件的生产者与交付者之间完美协同,我需要的任何东西都可以在仓库中找到,而我不再需要去关心里面的实现细节,使用者真的像一个老板一样只要结果。需要任何软件都无脑 docker run...然而很多人尝试建立标准,绝大多数都失败了,但 docker 却成功了,为什么?因为一个标准快速普及在我看来通常需要满足一些基本原则:第一:切中痛点第二:简单极致第三:不失强大满足以上三点成为公认的标准的可能性会大大提升。Docker 镜像标准把进程所有依赖打包,保障其一致性,这是交付中非常痛的地方。同时满足 2 和 3 是非常困难的,Dockerfile 简简单单几条指令,你会发现虽然简单但是几乎可以打包任何东西。这就非常容易被广泛接受,如果一个标准动辄大几百页文档,用户看一眼就吓跑了更别说遵循了……Sealer 的设计同样遵循以上三点。痛点方面,sealer 取 docker 设计思想之精髓,能 docker 所不能,因为现代的软件几乎都是分布式应用,docker 并不关心分布式应用如何做成镜像,sealer 就专门以 K8s 为集群操作系统,把 docker 的思想衍生到集群维度,实现分布式软件的构建、打包、交付、运行等等。简单极致,sealer 把奥卡姆剃刀运用到极致,指令删减到比 dockerfile 指令还少,也遵循 docker 的指令设计以更容易让用户接受,如果三分钟还没看懂 sealer 的 Kubefile 那就是 sealer 设计的失败。sealer 简单但并非简陋,你会发现简单几条指令几乎可以帮助用户构建任何复杂的自定义 Kubernetes 集群和自定义分布式应用镜像,然后一键运行。所以 sealer 必将建立成功的集群镜像交付标准,有了标准之后大家就可以相互更好的协作了。在 sealer 出现之前,复杂应用设计的开发人员与交付人员之间总会有数不清的恩怨,前线交付人员不理解数十个业务之间的关系是怎样的,研发人员不知道前线的交付环境有多复杂,一旦出问题,就拉十几个人的在线会议……最后老板发现三个和尚没水喝。有了 sealer 之后,研发人员制作好集群镜像,交付人员闭着眼睛 sealer run...如果失败那就是研发人员镜像没制作好,锅甩回去就行,有了标准分工明确。另外对于交付人员的要求也会变的极低,实习生培训半天上岗。3、灵活的定制性、自由组合、复用性、一致性与兼容性我们会制作很多基础镜像供你直接“拿来主义”:各种 Kubernetes 版本,各种架构 ARM、AMD…包含各种 CNI、CSI 实现的镜像,calico、flannel、openlocal、openebs…各种生态软件镜像,高可用的mysql、redis、prometheus...这些镜像并非是 docker 镜像,而是集群镜像,pull 下来就直接可以运行出一个集群!更变态的能力是我们支持这些镜像的自由组合,比如你需要 calico+redis+mysql 的组合,那只需要 sealer merge 命令就可以把三个镜像合并在一起供你的业务使用。集群镜像就像玩泥巴一样,把几坨泥巴捏在一起还是一坨泥巴,高度的抽象能力令人叹为观止……更更变态的能力是即便这些都不能满足你,你也只需要像写一个 Dockerfile 一样简单的去自定义你自己的集群里面包含什么,比如你想把自己软件的前后端服务也打到集群镜像中。而且你可以 FROM 已有的基础镜像来复用别人提供的能力。而且 sealer 低层技术保障了这些镜像具备非常好的兼容性,可以在任何平台丝滑的运行起来。如何把想法变成现实sealer 仅发展半年多时间,就在社区吸引了四十多名开发者,三十多家试用客户,在两家生产环境中落地。起初花了半年多的时间去做设计,写设计文档,这中间推翻了 N 个版本的设计,不断精简优化,每个指令设计都精雕细琢,严格遵循如无必要勿增实体。设计完成之后还几乎是光杆司令,此时在一个月内迅速集结队伍,大部分是兄弟组成员,生态公司的开发者,如和谐云沟通时,非常认可我们的想法并决定投入人力,最终一个七人的虚拟组织诞生。密集的开发三个月之后诞生了首个版本并完成开源。开源之后发展就更迅速了,快速聚集开源社区力量,吸引了很多外部开发者让项目快速收敛稳定,很快吸引了一批用户尝试,可见需求之强烈以及用户对于 sealer 理念的认可。1、极简的用户使用接口设计遵循大道至简的设计理念,我们吸取 docker 的设计思想,让集群镜像的制作和运行也变得非常简单。构建集群镜像的 Kubefile,类似 Dockerfile 但是更简单,比如制作一个包含 calico 的集群镜像:FROM kubernetes:v1.19.8-alpine COPY etc . RUN wget https://docs.projectcalico.org/manifests/tigera-operator.yaml CMD kubectl apply -f etc/tigera-operator.yaml CMD kubectl apply -f etc/custom-resources.yaml如何启动集群的 Clusterfile,类似 Docker-compose:apiVersion: sealer.cloud/v2 kind: Cluster metadata: name: default-kubernetes-cluster spec: image: kubernetes:v1.19.8 passwd: xxx hosts: - ips: [192.168.0.2,192.168.0.3,192.168.0.4] roles: [master] - ips: [192.168.0.3] roles: [node]只需要配置集群镜像名称和服务器 IP 地址 ssh 信息即可拉起一个集群。这里面的每一行都透射出精雕细琢,ip 为什么使用列表,roles 如何灵活的分组等。当然还有一些其他的字段没有展示出来,原则上不给不需要关注其它功能的用户增加负担,需要用什么样的能力才去关心什么样的参数。2、优秀的插件机制我们一些总会遇到一些非常奇葩的需求,极不通用,但是又是客户刚需,你支持的话又会让你的架构变乱,让整个产品变得“不优雅”,影响到别的用户使用体验。这个时候就必须通过强大的设计能力把这些功能剥离开,让不需要用它的人完全感知不到它的存在。所以 sealer 设计出了强大的插件机制,让你爱干啥干啥但别影响别人。。比如有些人非要想用 sealer 修改主机名,这其实压根也不属于 sealer 关心的范畴,那么就可以开发一个插件去做这个事,用户配置了这个插件就激活了这个功能:还有用户说我想开发一个专用插件,但是不想把代码贡献给 sealer 社区,因为极不通用的能力,贡献也没有意义。这样的场景我们支持 golang plugin 机制,载入.so 文件实现插件的动态加载。3、极致的性能极致追求虽然我们在集群构建的过程中已经速度非常之快了,几分钟六节点几乎是性能的极限了,然而用户体验是否丝滑,这一块的影响非常之大,所以并没停止性能方面的追求。比如 terraform 对接公有云需要 2-3min 起基础设施,我们觉得这太不可接受,自己重新写了 driver 把这个时间缩短到了 30s 以下,这已经几乎是极限了,再要提升就受限于服务端启动虚拟机速度了。我们做了退避等待与更合理的并发机制达到这种性能。比如集群镜像如 docker 一样会分层拉取镜像,提高层复用提升性能。文件拷贝的过程占用非常大的时间,我们做了一些按需拷贝的功能。未来准备对接 nydus 的一些能力实现懒加载和 P2P 分发集群镜像,进一步提升性能。比如 Build 集群镜像过程中需要缓存容器镜像,传统的做法是 pull 再 push 显然多做了一些无用功,我们就采用代理直接 cache 下来,pull 的过程直接缓存,但是 build 的时候需要起 registry 还是不够极致,未来我们会直接集成核心代码,在不启动 registry 的情况下即可缓存。以上种种,说明我们为了用户的极致体验,可谓是煞费苦心……写在最后简单又强大的产品总是能抓住用户的心,sealer 不仅需要解决核心的痛点问题,还需要让用户获得极佳的使用体验。功能上 sealer 已经完成了“集群维度的 Docker”这一设定,未来在生态发展上会增加更多的投入,创造更多更优质的官方镜像,建立更多的合作伙伴,真正把软件的提供者与使用者连接起来,高效的协作。作者介绍中弈:阿里云技术专家,sealos 作者,sealer 项目发起人。

《Nacos 架构与原理》| Nacos社区首本电子书免费下载

作者 | 于怀  Nacos 发起人 & Maintainer一、Nacos 开源诞生2018年 7 月 21 日,完成在 github 进行最后检查工作,凌晨 2 点 Nacos 在 github 上正式发布对外宣布 Nacos 正式开源,产品脱身于阿里巴巴在分布式领域多年的沉淀的经验,定位于一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。从那年夏天开始,Nacos 的社区也就正式成立了。经过 3 年多的时间,Nacos 已经成长为国内服务发现和配置管理首选的开源中间件。18年双 11,Nacos首次亮相二、Nacos 发展从初创期向社会基础设施发展初创期赢得广泛关注Nacos的成长包括了三个阶段,第一个是初创期,Nacos 最早的关注也都来自于业内对于阿里巴巴分布式系统架构的好奇,当时 Nacos 赶在凌晨发布也正是兑现对外界的承诺。这个阶段正是大家的新奇给了 Nacos 一个表现的机会,相比之前开源比较成熟的 Zookeeper、Eureka、Consul等,在易用、稳定、实时、规模上都有不错的表现,赢得了大家后续的持续关注。能力NacosEurekaConsulCoreDNSZookeeper一致性协议CP+APAPCP---CP健康检查TCP/HTTP/MYSQL/Client BeatClient BeatTCP/HTTP/gRPC/Cmd---Keep Alive负载均衡策略权重/metadata/SelectorRibbonFabioRoundRobin—雪崩保护有有无无无自动注销实例支持支持支持不支持支持访问协议HTTP/DNS/GRPCHTTPHTTP/DNSDNSTCP监听支持支持支持支持不支持支持多数据中心支持支持支持不支持不支持跨注册中心同步支持不支持支持不支持不支持Spring Cloud集成支持支持支持不支持支持Dubbo集成支持不支持支持不支持支持K8s集成支持不支持支持支持不支持发展期产品快速迭代第二阶段是发展期,随着持续的关注和产品表现,Nacos 吸引了用户,这个时间点 Nacos 经过快速迭代,在首次的 Nacos meetup 上发布了 Nacos1.0 GA版本,在这个时候其实已经有大量的用户开始在公司使用 Nacos 了,GA 版本增加了更多人对 Nacos 的兴趣和信心。目前 Nacos 已经经过了 40+ 版本的迭代,无缝支持Dubbo/Spring-Cloud/ 服务网格生态。根据《GitHub 2020 数字洞察报告》,在GitHub 2020 年中国项目活跃度 Top 20,Nacos 社区活跃度跻身前十。Nacos社区共吸引了 200 多位优秀贡献者,积累了虎牙、好未来、小米等多家企业案例,Nacos 的 github 的star 数已经增长突破了 2w。在近日开源中国发布的 2021 年度 OSC 中国开源项目评选中,Nacos 被评为云原生领域人气指数 Top5 的项目,国内企业已经普遍开始使用 Nacos 。目前 Nacos 已经发布了 2.0 版本,并且已经有普遍的生产使用经验,在性能大幅度提升的前提下,稳步的进行技术迭代。Nacos3.0 的架构社区内已经开始逐步规划,预计不久也会跟大家见面。全面应用期面向社会基础设施演进正处于被大规模使用的 Nacos 的第三阶段是成为基础设施,面向于基础设施进行演进,帮助企业数字化转型,深度的拥抱各个领域内的场景,并且更深度的帮助企业解决问题。面向这个阶段,我们决定在这个时候发布电子书,计划发布一系列围绕着 Nacos 原理和使用的电子书,《Nacos 架构与原理》是电子书系列的第一部分,用于向大家更好的解释 Nacos 的设计理念和架构原理,书中凝聚着社区以及用户的大量经验,目的帮助更多的人和更多企业,更快速的熟悉和使用 Nacos,解决在实际应用中出现的问题。该系列的电子书是以非盈利为目的,内容是有社区和用户共同完成,免费开放下载。电子书封面2021年 12 月 21 日,Nacos 社区通过直播的方式,在线举办了《Nacos架构与原理》电子书在线发布会,直播覆盖 6w 开发者,内容上通俗易懂,从 Nacos 的起源开始讲起,让读者更了解 Nacos 发展历程,主体内容讲述 Nacos 的整体架构设计,以及服务发现和配置管理的内核设计原理,并且概述内核设计在可用性、安全性、易用性等方面思考,帮助读者能更快的了解 Nacos 一些设计的初衷。本书也深度介绍了 Nacos 生态圈以及和紧密融合生态,包含 Spring、Dubbo、Kubernetes和 Mesh 等主流生态。额外包含了企业级落地的场景下最佳实践,配置管理和服务发现场景下一些实用的限流和使用上的实践经验沉淀。电子书免费下载地址:https://developer.aliyun.com/topic/download?id=8230整本书目前免费开放下载,希望带来三方面的好处:规范化:希望本书帮助个人和企业快速的规范使用 Nacos ,让 Nacos 不仅易用,还要按照自己的想法好用,规范使用。分布式经验延展:既要知其然也要知其所以然,对个人在以后的架构设计中有重要的意义,帮助社区和用户更深入的了解 Nacos 的设计和思考,这个背后有阿里在微服务领域10几年沉淀的经验,并且也融合了其他公司场景的经验和最佳实践,帮助个人和企业成长。帮助更多企业:通过学习电子书沉淀下来的内容,能进一步提升 Nacos 易用性,让更广泛的企业和用户使用 Nacos ,Nacos 要做到面向基础设施发展后要把架构和原理以及实践向更多人传播,并且参与其中。三、社区共建内容《Nacos 架构与原理》是 Nacos 电子书系列计划的第一步,并且这部分内容希望和社区共同创作,社区会推动 Nacos 电子书持续更新迭代,也欢迎更多小伙伴能加入 Nacos 社区一起创作。我们把电子书文档通过语雀公开文档像社区开放评论和更新,希望大家针对于内容共同进行校对,并且也欢迎进行投稿,把经验向社区更多个人和企业进行分享。Nacos 电子书语雀共建库:https://www.yuque.com/nacos/ebook(PC端浏览、下载体验更好)四、结尾在此阶段要做的事情很多,开放电子书也是其中的一个原点,随着后续产品的更新和社区的壮大,我们会向用户发布更多内容。至此感谢所有参与 Nacos 的社区同学,也感谢所有使用 Nacos 的用户,也是你们让 Nacos 每个阶段走的更有意义。点击下方“阅读原文”,免费下载电子书https://developer.aliyun.com/topic/download?id=8230

成功报名须知 | 云原生技术实践营长沙站

如果您已经收到报名成功的短信通知,请了解本次活动的注意事项:1、活动时间和地址:1月7日(周五)、9:30-16:30,长沙市开福区富兴金融中心T3栋27层阿里中心岳麓书院;2、请搜索钉群群号:31790420,入群会审核,若您使用钉钉不频繁,也可以添加工作人员微信:zjjxg2018,我们会拉您进微信群;3、本次活动免费,采取报名审核制,中午含餐,完成下午的动手实操,颁发阿里云官方认证证书,请确保报名时的姓名是填写准确的,我们会提前制作好认证证书,现场颁发;4、我们将在会前1天发送访客码至您的报名手机号上,完成身份证实名认证,凭访客码入园,短信中实名认证链接;5、参与动手实操的客户,请带好笔记本电脑,无须提前安装相关程序,我们提供了工程化较好的体验沙箱,动手实操活动是免费的,无须在云上支出费用;6、请遵循当地疫情政策,入园出示健康码和行程码,佩戴口罩。任何疑问,您也可以钉群内或微信咨询工作人员。活动议程介绍:https://developer.aliyun.com/article/839641

成功报名须知 | 云原生技术实践营武汉站

如果您已经收到报名成功的短信通知,请了解本次活动的注意事项:1、活动时间和地址:1月5日(周三)、9:30-16:30,武汉市武昌区万达尊A座24楼阿里中心2402白鹭书院;2、请搜索钉群群号:31622163,入群会审核,若您使用钉钉不频繁,也可以添加工作人员微信:zjjxg2018,我们会拉您进微信群;3、本次活动免费,采取报名审核制,中午含餐,完成下午的动手实操,颁发阿里云官方认证证书,请确保报名时的姓名是填写准确的,我们会提前制作好认证证书,现场颁发;4、我们将在会前1天发送访客码至您的报名手机号上,完成身份证实名认证,凭访客码入园,短信中实名认证链接;5、参与动手实操的客户,请带好笔记本电脑,无须提前安装相关程序,我们提供了工程化较好的体验沙箱,动手实操活动是免费的,无须在云上支出费用;6、请遵循当地疫情政策,入园出示健康码和行程码,佩戴口罩。任何疑问,您也可以钉群内或微信咨询工作人员。活动议程介绍:https://developer.aliyun.com/article/839630

如何构建一个流量无损的在线应用架构 | 专题中篇

作者 | 孤弋、十眠-全系列查看-如何构建流量无损的在线应用架构 | 专题开篇如何构建流量无损的在线应用架构 | 专题尾篇前言上一篇如何构建流量无损的在线应用架构 | 专题开篇 是我们基于下图,讲解了流量解析与流量接入两个位置做到流量无损的一些关键技术,这一篇我们主要从流量服务的维度,详细聊聊正式服务过程中会影响线上流量的一些技术细节。服务最近我们分析了某大型互联网公司最近一年的线上故障原因,其中,产品自身质量问题(设计不合理、BUG 等)占比最高,为 37%;由于线上发布、产品和配置变更引起的问题占比 36%;最后是依赖服务的高可用类的问题如:设备故障,上下游的依赖服务出现问题或者资源瓶颈等。基于左侧的原因分析可以看出,如何治理好变更、产品质量、和高可用类的问题,是服务如何做到流量无损的关键所在。我们把这个几点原因结合应用的生命周期划分成为了几个关键阶段:应用变更态:当我们的服务(应用)进行版本发布、配置变更的整个过程中,我们需要有确切的手段做保护。运行服务态:当我们的变更完毕后,一开始是一个 “冷”的状态,如何在正常流量甚至超常规流量到来之前的,让系统平稳度过?高可用依赖态:当我们服务的某些节点出现问题,或者我们外部的依赖(如 其他微服务、DB、缓存)等出现瓶颈时,是否有相对应的办法?为了从容地应对以上这些场景,我们将分别列举相关例子来探讨相应的解决方案。1、变更态:应用优雅下线应用变更时有一步,是需要将原有的应用停止。而在生产环境中的在线应用停止之前,需要将服务流量的服务下线。我们常说的流量主要有两种:1)同步调用的流量,如:RPC、HTTP 请求等;2)另外一种是异步流量,如:消息消费、后台任务调度等。以上两种流量,如果在服务端还存在未处理完的请求时将进程停止,都会造成流量损失。要想解决这一种情况,通常情况需要分两步进行:1)将现有节点在相应的注册服务中摘除,场景有:将 RPC 服务在注册中心的节点中摘除、将 HTTP 服务在上游的负载均衡处摘除、将后台任务(消息消费等)的线程池尝试关闭,不再进行新的消费或服务。2)停顿一段时间(依据业务情况而定),确保进程中已经进来的流量能得到很好的处理之后,再将进程关闭。2、变更态:应用调度变更过程中另外一个动作就是选择资源(机器或容器)之后发起一次部署,如何选择资源就是我们通常意义上理解的【调度】,如果是传统的物理机或者调度能力欠缺的虚拟机的情况,调度这一层没有太多的发挥空间,因为他的资源基本上都是固定的;但是容器技术(尤其后来的 Kubernetes 技术的普及)的出现除了给交付领域带来了诸多的变化之外,他也给调度领域带来了的不一样的故事,即他从传统的规划资源分配引领到了灵活调度的时代。在 Kubernetes 中,默认可以根据应用使用的资源(CPU、内存、磁盘等)信息,来选择一个最为合适的节点进行调度。如果我们更进一步,也可以根据自身应用的流量特征定制一个调度器,比如尽量让流量大的应用不聚集在相同的节点上,这样就能避免因为抢占带宽而造成的流量损失。3、变更态:应用优雅上线当应用调度到了相应的资源之后,接下来是部署和启动应用。和应用停止的场景类似,应用在完全初始化完成之前,我们的节点很可能已经被注册,后台任务的线程池也很可能开始启动了。此时上游服务(如 SLB 开始路由、消息开始消费)就会有流量调度进来。但是在应用被完全初始化完成之前,流量的服务质量是无法得到保证的,比如一个 Java 应用启动之后的前几次请求,基本上是一个“卡顿”的状态。如何解决这个问题呢?和应用的优雅下线动作序列相反,我们需要有意识的将服务注册、后台任务线程池、消息消费者线程池的初始化动作滞后。要确保等到应用完全初始化之后再进行。如果有外置的负载均衡路由流量的场景,还需要应用部署的自动化工具进行相应的配合。4、变更态:应用服务预热系统完成上线之后,有时如果遇到流量突增,可能会令系统水位瞬间升高进而导致崩溃。典型场景如大促时的零点,洪峰涌入时,应用实例会瞬间进入大量的流量,这些流量会触发诸如 JIT 编译、框架初始化、类加载等底层资源优化的问题,这些优化会在短时间之内给系统造成高负载的问题,进而造成业务流量损失。为了解决这个问题,我们需要控制流量缓慢增加,通过开启类加载器并行类加载,框架提前初始化,日志异步化等方式提升刚启动应用的业务容量,从而实现大流量场景下的扩容、上线等操作的流量无损。5、变更态:Kubernetes 服务结合从 2020 年开始,我们看到一个明显的趋势就是 Spring Cloud  + Kubernetes 已经成为了微服务体系中最流行的配搭。而在一个基于 Kubernetes 构建的微服务体系中, 如何将微服务体系和 Kubernetes 进行有效的结合是很有挑战的一个点,Kubernetes 中的 Pod 生命周期管理本身就提供了两个探测点:RreadinessProbe,用于探测一个 Pod 是否就绪接受流量,探测失败将会在 Kubernetes Service 中摘取该节点,且该节点的状态为 NotReady 。LivenessProbe,用于探测 Pod 是否健康,如探测失败将会重启 Pod。如果我们的应用没有配置 readinessProbe ,默认只会检查容器内进程是否启动运行,而对于进程中运行的业务是否真的健康是很难考量的。在发布的过程中,如果我们使用的是滚动发布策略,那么当 Kubernetes 发现新起的 Pod 中的业务进程已经启动了,Kubernetes 就会开始销毁老版本的 Pod,看起来这个过程是没有什么问题的。但我们仔细想一下,“新起的 pod 中的业务进程已经启动”,并不代表“业务已经启动就绪”,有的时候如果业务代码存在问题,那么我们的进程启动了,甚至业务端口也已经暴露了,但是由于业务代码等异常情况,导致进程起来后服务还没来得及注册。可此时老版本的 Pod 已经销毁。对于应用的消费者来说,可能会出现 No Provider 的问题,从而导致在发布的过程中出现大量的流量损失。同样,如果我们的应用没有配置 livenessProbe ,Kubernetes 默认只会检查容器内进程是否存活,而当我们的应用的某个进程由于资源竞争、FullGc、线程池满或者一些预期外的逻辑导致其处于假死的状态时,进程虽然存活,但是服务质量低下甚至是为 0。那么此刻进入到当前应用的全部流量都会报错,出现大量的流量损失。此刻我们的应用应该通过 livenessProbe 告诉 Kubernetes 当前应用的 Pod 处于不健康且已经无法自己恢复的状态,需要对当前 Pod 进行重启操作。readinessProbe 和 livenessProbe 的配置,目的是及时且灵敏地反馈当前应用的健康情况,以此来保证 Pod 内的各个进程都处于健康状态,从而保证业务的流量无损。6、变更态:灰度一次版本的迭代,我们很难保证新的代码经过测试后,在线上就没有任何问题。为什么大部分的故障和发布相关?因为发布是整体业务发布到线上的最后一个环节,一些研发过程中累计的问题,很多时候最后发布环节才会触发。换句话说,一个潜规则就是公认线上发布基本上不可能没有 BUG,只是大小而已,但是发布环节要解决的问题就是:既然肯定会有问题,那如何将问题的影响面降至最小?答案是灰度。如果有一些没有测试到的问题,恰巧我们线上也是全量一批发布的,那么错误将会因为全网铺开而被放大,出现大量且长时间的线上流量损失。如果我们系统具备灰度能力(甚至全链路灰度),那么我们就可以通过灰度发布的方式将问题的影响面控制到最低。如果系统具备完整的灰度过程中的可观测能力,那么发布就会稳定且安全得多。如果灰度能力可以打通全链路流程,那么即使是同时面对多个应用的发布都可以有效保证线上流量无损。7、运行态:服务降级当应用遇到业务高峰期,发现下游的服务提供者遇到性能瓶颈,甚至即将影响业务时。我们可以对部分的服务消费者进行服务降级操作,让不重要的业务方不进行真实地调用,直接返回Mock的结果甚至异常返回,将宝贵的下游服务提供者资源保留给重要的业务调用方使用,从而提升整体服务的稳定性。我们把这个过程叫做:服务降级。当应用依赖的下游服务出现不可用的情况,导致业务流量损失。您可以通过配置服务降级能力,当下游服务出现异常时,服务降级使流量可以在调用端 "fail fast",有效防止雪崩。8、运行态:自动离群摘除与服务降级类似,自动离群摘除是在流量服务的过程中,遇到单个服务不可用时自动将节点进行摘除的能力,他区别于服务降级主要是体现在两点:1)自动完成:服务降级是一种运维动作,需要通过控制台进行配置,并且指定对应的服务名才能做到相应的效果;而【自动离群摘除】能力是会主动探测上游节点的存活情况,在这条链路上整体做降级。2)摘除粒度:服务降级降级的是(服务+节点 IP),以 Dubbo 举例子,一个进程会发布以服务接口名(Interface)为服务名的微服务,如果触发到这个服务的降级,下次将不再调用这个节点的此服务,但是还是会调用其他服务。但是【离群摘除】是整个节点都不会去尝试调用。9、高可用:注册中心容灾注册中心作为承担服务注册发现的核心组件,是微服务架构中必不可少的一环。在 CAP 的模型中,注册中心可以牺牲一点点数据一致性(C),即同一时刻每一个节点拿到的服务地址允许短暂的不一致,但必须要保证的是可用性(A)。因为一旦由于某些问题导致注册中心不可用,连接他的节点可能会因为无法获取服务地址而对整个系统出现灾难性的打击。除了常见的高可用手段,注册中心特有的容灾手段还有:1)推空保护:数据中心网络抖动或者在发布的过程中,会经常出现批量闪断的情况,但这种情况其实不是业务服务的不可用,如果注册中心识别到这是一种异常情况(批量闪断或地址变空时),应该采取一种保守的策略,以免误推从而导致全部服务出现"no provider"的问题,所有微服务会因此导致大量的流量损失。2)客户端缓存容灾:与推空保护一样,站在客户端的角度逻辑同样适用,我们经常遇见客户端和注册中心出现网络问题时将地址更新的情况,客户端也不能完全相信注册中心反馈的所有结果,只有明确告知的是正常的结果才能将内存中的地址更新,尤其遇到最后一个地址时采取的策略更要慎重;同时拿到地址之后,也不能完全相信,因为很可能注册中心推送下来的地址根本就不可达。此时要有类似于心跳保活的策略可动态调整对端服务是否可用,以免将服务直接发往无法连接的地址导致流量损失。3)本地缓存容灾:注册中心容灾了,客户端也容灾了是否足够?通常情况如果不做变更是足够的,但是如果有一个应用在进行变更时注册中心不可用的话,会发生什么事情呢?一个是本身地址注册不上,另外一个就是如果有服务发生依赖调用时,流量进来后会出现"no provider"而导致流量损失,甚至根本就无法启动。如果我们把注册中心的依赖简化理解为就是对一个服务名字的地址解析的话,其实我们可以将这个解析结果保存在本地做成容灾备份,这样就能有效避免在变更过程中因为注册中心不可用而导致流量损失。10、高可用:同城多机房容灾同城的特点是 RT 一般处在一个比较低的延迟(< 3ms 以内),所以在默认情况下,我们可以基于同城的不同机房搭建起来一个大的局域网,然后把我们应用跨机房分布在多个机房中,以此来应对单机房出现故障时的流量受损风险。相比异地多活,这种基础设施的建设成本较小,架构变动也比较小。不过在微服务体系之下,应用之间的链路错综复杂,随着链路深度越来越深,治理的复杂度也会随之增加,如下图所示的场景就是前端流量很有可能因为在不同的机房相互调用而导致 RT 突增,最终导致流量损失。要解决上面的问题,关键是在服务框架层面需要支持同机房优先路由的能力,即:如果目标服务和自己所在机房相同,则优先将流量路由至和我同机房的节点。要实现这个能力的方法大致是注册服务时将自身所在的机房信息上报,机房信息也当成元信息推送至调用方,调用方在路由时通过定制服务框架的 Router 的能力,优先选择和自己相同机房的地址作为目标地址路由。结语本篇是整个《如何流量无损的在线应用架构》系列的第二篇,这一系列共三篇,旨在使用最为朴素的语言将影响在线应用流量稳定性的技术问题做一个归类,这些问题的解决方案有的只是一些代码层面的细节,有的需要工具进行配合,有的则需要昂贵的解决方案,如果您的应用想在云上有一个【流量无损】的一站式体验,可以关注阿里云的《企业级分布式应用服务(EDAS)》这个云产品,EDAS 也将会持续向默认接入流量无损的方向演进.下一篇,我们将从数据服务交换的角度进行讲解,更重要的是下一章还会点出重点预防的两把钥匙。

企业如何从 0 到 1 构建整套全链路追踪体系

作者 | 涯海&白玙今天,我来跟大家分享 ARMS 在全链路追踪领域的最佳实践,分享主要分为四部分。首先,是对分布式链路追踪的整体简介。其次,是对 ARMS 在分布式链路追踪领域的核心能力进行介绍。然后,介绍如何从 0 到 1 构建整套全链路追踪体系。最后,介绍一些最佳实践案例。 什么是分布式链路追踪首先,什么是分布式链路追踪。我对分布式链路追踪的理解就是跟踪请求在分布式系统中的流转路径与状态,从而协助开发人员能够进行故障诊断、容量评估、性能瓶颈分析等工作。 我们可以看到典型的链路轨迹追踪例子:比如用户通过手机做了一个下单动作,这个请求会通过移动端来到网关,再到应用层,比如说有交易、下单、支付等等一系列的应用,然后中间也会穿插到去调用云基础设施,这样用户的行为轨迹是能够被清晰还原出来的。为了更方便的理解这个概念,我们可以把链路追踪和物流追踪做对比。在发送快递物流时,每个快递包裹都会赋予一个唯一的快递单号,对于系统请求来说就是全局唯一的 TraceId。通过快递单号来查询快递途径哪些站点,是否有延迟或丢件情况。那么,也同样可以通过 TraceId 来查询请求在每个系统之间的流转路径和状态。除了快递订单查询之外,还可以把整个物流状态,按照站点去进行汇总统计,来看每个站点吞吐,从而进行物流提效的优化工作。对于链路追踪来说也是一样的,我们可以把链路数据进行一个统计,然后去看每一个应用或接口的状态,或者去梳理它们之间的强弱依赖。那么,什么样的系统更加需要链路追踪呢?当微服务架构拆分的越精细,服务间依赖越复杂的系统,就更加的需要链路追踪技术,比较典型的就是电商这种。接下来我们看一下链路追踪作为可观测的三元组之一,就是 Traces、Metrics 和 Logs。其最大价值就是实现了除机器和时间维度之外的用户行为的确定性关联。怎么理解这个事情呢?就是在没有 Tracing 之前,比如说通过指标或者日志,只能根据数据在同一台机器上,并且在同一个时间点,判断它们应该是在一起的。但这只是弱关联,并不是强关联。而调用链会很明确说明这个请求就是这个数据,就是来到了这个节点,这个信息是一定准确的。通过这种确定性的关联,除了可以将服务应用接口层面的数据关联起来之外,还可以通过打标上下文传递的方式,把一些业务的标签,比如说来自于什么渠道、订单金额等这种直接、间接的数据都关联起来,发挥 1+1>N 的价值。 接下来再看一下链路追踪的应用场景,我对它做了一个初步分级。从下往上看,最基础级就是通过调用链来还原单次请求的轨迹状态,这是最基本的应用。再往上,可以对链路数据去做预聚合或后聚合统计的分析,去看整个链路在概率分布上的一些信息,比如说整个服务维度的监控数据,上下游整体的依赖,这是第二级——聚合分析。 第三等级,就是除了调用链数据本身具备的这些链路数据之外,还可以更进一步发挥关联性作用,把一些间接的业务数据,包括容器或者 JVM 的一些指标信息或者是一些变更的日志事件,也能够通过调用链紧密的关联在一起,形成多维数据关联和分析,最终来实现我们根因定位的能力。再往后有点像自动驾驶,有了这么多数据,能不能够自动发现其中一些问题?可以结合领域专家经验和恰当的算法,来实现整个诊断流程自动化或者半自动化。 最后一步就是诊断问题的最终目标--保障系统稳定。能不能够把问题诊断和系统恢复两个事关联在一起?从而实现整个系统的故障自愈,进一步提升稳定性。这个就需要与管控系统去融合。目前开源 Tracing 系统大概是在 L1 到 L3 的等级。ARMS 我们那边沉淀了很多领域专家经验以及算法可以做到 L4 等级,ARMS 再加上一些应用托管服务进行自动流控降级、弹性扩缩容,把监控和管控系统结合在一起,从而实现故障自愈能力。接下来我们再看看链路追踪的发展趋势。在 2010 年,随着谷歌论文发表,拉开了整个链路追踪的技术序幕,很多厂商都纷纷实现了自己的链路追踪技术。当然,在谷歌之前也有很多其他探索,但谷歌给了后续实现者比较完整的理论基础。同时,通过自身实践,证明了链路追踪的企业级价值,这是开山鼻祖式的奠基。到了 2016 年,因为之前大家厂商纷纷实现自己的链路追踪,这个标准没有统一,就为迁云、上云带来很多问题。因此,开源社区发起了 OpenTracing 项目,定义了相对比较完善标准的链路的通用规范,也发展出了类似 Jaeger 这种符合 OpenTracing 规范的开源实现。到了2019年,大家考虑到可观测逐渐向一体化发展,光有 Tracing 也不够,需要把Tracing和指标和日志能够关联在一起,OpenTracing 定义就相对比较狭隘,不能满足可观测的需求。所以在 2019 年,就是 OpenTeleMetry,然后提出了这样的一个开源项目。将 OpenTracing 和 OpenCensus 进行了融合,能够致力于去解决 Logs 和 Traces、Metrics 三者有机统一。 ARMS 的链路追踪到底具备哪些能力接下来,我们看一下 ARMS 的链路追踪到底具备哪些能力。首先,我把 ARMS 的能力抽象为四个点:解决接入难的问题。比如说企业有很多不同类型应用,不同语言的应用。除了前端后关联,服务端也有很多如 Java 、Go 等应用。ARMS可以更有效地去完成这些应用的追踪接入。解决诊断难的问题。ARMS 可以提供各种各样的,比如说日志和 Trace 的全息排查,或者是线程剖析这种深度的诊断的能力来帮助你去定位根因。解决运维难的问题。在大规模场景下,链路的探针管理、升级都是比较困难的事情,包括服务端的稳定性托管, ARMS 可以提供稳定可靠的全托管、免运维能力。解决成本高的问题。ARMS 作为云上产品可以按需按量地来使用。随着业务爆发式增长,只需要按量地去付费就可以,也不需要一开始就购买一大批机器或投入比较大人力。接下来,我们逐一介绍下这四个方面:首先就是接入难, ARMS 目前提供了 Java 无侵入的探针技术方式,如果你是 Java 应用就可以很快地接入 ARMS。比如说通过一个 -javaagent 的命令,或者是在 ACK 容器服务环境下,通过一个 Annotation 就可以很快地接入。如果是非Java语言,也可以利用开源 SDK 通过修改 Endpoint 快速地接入到 ARMS,从而实现全链路追踪,基本上相当于是开箱即用的。我们对语言组件的覆盖也是相对比较齐全的,主流组件基本上都有支持。同时, ARMS 完全兼容开源的 OpenTracing、 OpenTelemetry 等各种开源格式。如已接入,迁移到  ARMS 也是非常的方便。其次,诊断难。在生产环境去诊断问题时,有时不仅仅需要调用链,还需要很多其他的数据一起结合。比如说发现某个应用接口或者是业务出现问题,根据各种各样条件来去筛选出想要的调用链,通过调用链来去追溯上下游,看看问题大概瓶颈点在哪里。如果这个时候出现了比较慢的一些情况,就是接口粒度还不足以定位问题的时候,我们可以通过 ARMS 的线程剖析功能,自动地帮你把慢调用本地完整的方法栈能够获取下来,能够实现代码级定位。如果是业务上出错了,还可以跟业务日志进行关联绑定,能够看到每次调用,每笔请求关联背后业务的行为和日志是什么样的。如果前面这四步仍然不足以去定位根因,还可以结合内存快照或是线程池分析,常见的就是数据库连接打满,或者是线程池打满等。 除了上面这一整套诊断能力帮助团队完成定位之外,ARMS 也能够通过自动诊断能力解决常见问题。比如说我们经常会遇到一些数据库 MySQL 问题,数据库 MySQL 有很多原因比方说服务端原因,服务端的连接池打满,或者是客户端的连接池打满,或者是客户端一次查了特别多数据需要分批等等。面对这些常见的原因,ARMS 都可以自动诊断出来。解决完诊断难,接下来就是运维难的问题。越是体量越大的公司,这个问题会越严重。ARMS 作为阿里鹰眼的升级,在双十一场景下结合多年验证与优化,沉淀了大量经验,比如说我们的 Agent 是会经过多轮、各种级别的灰度验证,保证我们客户端侧稳定。服务端也会支持比如说多可用区容灾或者是全链路端的 SLO 体系建设,还有包括我们多级的客户支持和 Oncall 应急值班,这些都是可以直接享受到这样的服务,而不需要重新的去建设这样的体系。在大部分场景下,除了稳定性之外,还经常会遇到海量数据场景下查询性能问题,当数据达到每天几百 TB,数据存储和数据查询的索引可能已失效,无法满足业务要求。ARMS 沉淀了多种性能加速方案,比如说可以实现最基础的就是租户地域隔离,其次数据可以通过应用去做路由存储,如果应用级还不够,还可以再继续根据数据的一些特定的特征,如 TraceId 或者其他特征进一步打散,从而提高并发查询的效率。第四点就是大家比较关心的成本问题,ARMS 除了自身按需存储之外,还通过冷热数据分离和精准采样方案,进一步降低用户成本。比如说我们可以把热数据,比如说 30 分钟内数据我们会经常查询,我们可以把它存在热存储里面,满足全量的分析的需求。30 分钟之后的数据进行持久化,比方说 15 天、30 天。这个时候可以仅把其中错、慢或者满足一定业务特征(比如说 VIP 用户的一些链路)存储下来,这样整个存储成本就会比较低,并保持查询体验。当然,在做链路采样时就无可避免的会遇到指标数据不准的情况。ARMS 通过在客户端完成预聚合,来保证链路数据无论怎么去采样,即使千分之一,但依旧保证指标数据精准性。这里做个简单对比,如果采用开源方案,最起码需要存储以及流计算处理服务器建设,这种 ES 和 ECS 的成本大概 200 元/天。但如果直接使用 ARMS 的按量付费,每天大概只需要十几块钱。每 GB 成本可能只要 1 毛 9 不到 2 毛钱,远远低于开源自建成本。值得一提的就是,ARMS 进入 Gartner APM 象限,也是国内唯一的云厂商,Gartner 对 ARMS 的 APM 评价是中国影响力最强,对开源集成性也非常好,成本也是非常大优势。如何从 0 到 1 建设追踪体系介绍完产品核心能力之后,来讲讲如何从 0 到 1 建设追踪体系。我们大概可能需要完成这样 4 步:第一步,完成整个应用的全链条全链路的上下文透传,从端侧设备开始到后端,然后网关或者是应用等等。这里面的话其实就涉及到异构语言的数据打通和前后端的透传,这一套方案 ARMS 是都已实现了。第二步,完成了客户端的这种全链路埋点之后,我们数据要上报上来,就会面临存储和计算的成本,最好的方式就是说能够按需去存储数据,只存有价值的数据来降低成本。第三步就是数据存储下来之后,肯定还要通过查询再发挥它的价值。这时候遇到的问题就是数据之间的格式不统一,能不能把所有的指标数据转化成一个比方说 Prometheus的这种格式,这样指标数据格式相对统一了,Traces 能不能支持这种 OpenTelemetry 的格式,然后是日志支持 Loki 这种方案。如果数据格式跟开源保持统一再去做第 4 步,释放价值就会比较容易。除了产品提供的预置大盘之外,还可以灵活自定义用户档案。当然还可以按照用户的使用习惯,也可以做一些自定义的控制台。同样道理,告警也是一样的,我们可以去用 PromQL 做一个灵活的自定义的告警,同时我们也支持把数据路由到用户名下的一些存储,比如说 SLS 下面,这样你想去做一些二次的批量的分析,这些都可以支持。这就是我们从 0 到 1 去建设链路追踪体系的大概步骤。接下来,每个步骤都单独来看。第一步,就是要完成异构应用的全链路的追踪,比如说前端或者说整个透传的格式,或需要采用统一格式,比如说我们可以选择统一的 Jaeger 格式来透传来我们的协议头,我们前端接入比如说我们可以采用 CDN 或者 NPM 两种的这种低代码的接入方式,可以支持外部小程序等各种各样的场景,我们后端如果是 JAVA 的话,就会优先推进使用 ARMS Agent 来完成无侵入的这样的一个代码的接入。并且在 JAVA 的应用上面,我们会提供很多比如说边缘诊断、无损统计的这样一些高阶的能力,非 JAVA 的话就可以比方说我们可以通过开源的 Agent 和 SDK 来接入,然后并且上报到我们的 Endpoint 上面,当然 ARMS 也在去兼容 SkyWalking 的协议格式。第二步,正如刚才所讲,数据打通之后,需要去进行精准采样和冷热存储分离。但是对于使用者来说,需要去定义我们尾部采样策略,比如说默认的除了错慢全采之外,有没有需要根据业务特征进行采样,或者是按需的去调整数据存储周期。第三步,就是需要去自定义监控大盘,就除了 ARMS 提供的默认大盘之外,你还可以基于 Grafana,把业务数据、应用数据,甚至容器数据放在一起,来去定制统一监控大盘。比如说双 11 大促,或日常线上应急场景,都可以去快速地浏览整个业务线的表现,能够快速地定位到问题的大致范围。第四步,当建立监控之外,还需要有一个比较有效的告警机制,因为大家平时也不太会去一直盯着监控或者是 Trace 控制台,肯定需要有应急入口,告警其实就是我们运维的第一入口。在这里介绍三个比较典型的告警实践。比如说公司或者是团队在刚起步或新产品刚上线的时候,很多东西都是比较缺失的。这个时候,我们可以通过 ARMS 的告警模板能力,把比较通用的应用、容器、中间件的告警能力能够快速地构建出来,解决从 0 到 1 的问题。当团队或者是公司一步步成长起来,数据会越来越多,系统会越来越多。等到膨胀到一定程度时,告警可能分散在多个系统之中。这个时候又会带来效率问题,就可以使用 ARMS 的告警能力,把多个告警源的数据放在一起去分析,甚至可以去做组合过滤规则。比如,当流量突然激增,性能后端的耗时变高,CPU 打满的时候,发出建议扩容或是建议降级的告警通知。当企业进一步地发展,发展得很好,团队越来越多,人员越来越多。这个时候,可能一个系统会有很多个团队来共同的去协作运维,我们不仅仅需要解决数据爆炸问题,还需要解决人员协同的问题。这个时候就可以基于 ARMS 的 ChatOps 能力来解决应急协同问题。第五步,即使前面都做了之后,还有很多公司有建设自己专属平台的意愿,因为可能大家已经有了比较好的可观测或监控报警方面的经验以及场景沉淀,只需扩充部分这样的能力,是完全可以基于 ARMS 这种开放数据的能力。无论是通过外部页面的嵌入,还是 Open API 建设,或是直接把存储开放出来,进行批量数据分析,都可以更好地完成二次开发。最佳实践最后,我们来介绍常见实践案例。比如,调用链通常聚合成一个应用维度的拓扑,或者是服务维度的拓扑,但这个时候往往还不够,还可能会更关注某特定场景。同样是下单场景,有时候关注整体的下单还不够,可能还需要关注某个新渠道或新上线品类。我们可能需要看某个线下零售的渠道,它的下单链路情况是怎么样的。或者是某个新品类,需要把这一部分业务场景单独剥离出来,去做链路染色,从而能够实现这一部分特定业务场景的应用和依赖的梳理。这个就是通过无侵入的业务染色实现的。第二部分,ARMS Agent 除了做可观测数据之外,同时也具备安全数据、安全行为检测与保护的能力,面对最近比较火的 Log4j2 高危核弹级漏洞,基于 RASP 技术就可以有很好的自我防护能力。即使不改代码,也可以通过动态配置的方式,完成安全防护。除了安全防护之外,RASP 也可以提供攻击溯源或者漏洞定位分析等等能力,相比于传统的防火墙式保护会更有效一些。因为它跟 IDC 防火墙的区别,有点像我们戴口罩和打疫苗这样的一个区别。第三个场景,在容器场景下实现全景监控,可以把来自于 Prometheus 或者 Loki 或者 eBPF、APM 等端到端数据放在一起,通过 2D、3D 拓扑,进行全程展示和端到端链路的下端分析。同时,我们还提供定期巡检,或是基于专家经验和算法的问题自动诊断和上报,这个就是我们在容器场景下的一个全景监控的最佳实践。第四个场景,一些架构比较复杂的用户,具备多云以及跨云部署;出于数据安全考虑,也可能会去自建机房进行混合云部署。为了解决前后端、多语言、跨云部署的问题,ARMS 的全链路追踪帮助用户完成复杂场景的全链路追踪挑战,把各种场景的链路串联在一起,最大化去释放链路跟踪价值。第五部分,就是说 ARMS 最近新上线了 Trace Explore 功能,相对于传统调用链查询和应用服务统计、监控之外,还提供实时获取和分析能力。举个简单例子,我们经常要看耗时大于三秒的请求分布在哪些接口或者是哪些 IP 上面,从而进行慢接口的处理,或单机故障排查诊断。这个时候我们在预聚合的时候,肯定没办法把耗时大于三秒或者是某一个特定的过滤条件等于什么的场景之下,去做一个预先统计。这个时候我们就需要一个灵活的后聚合分析的能力。这个就是 Trace Explorer 能够提供这样的一个价值。除了我们刚刚说的这种单机慢接口之外,如果我们再结合我们的业务指标,比如说我们把我们的一些用户的等级也打到我们的 Attributes 里面对吧?我们就可以去按不同的用户等级来去分析它的一些流量的情况,它响应的一些时延,就能够更方便的低代码的去完成这样的一个自定义的分析。当然,这里还举了一个灰度监控,如果我们在重启之前,比方说我们在环境变量里面注入我们当前的版本,我们就可以看到不同版本之间一个流量和性能的变化。最后,给出了一些 ARMS 相对于开源做的更好的最佳实践。比如说接口偶发性超时的时候,接口级的调用链,还不足以诊断更新,我们需要完整的方法栈,但是那个问题现场已经过去了,怎么能够自动帮你保存下来呢?那就是可以通过 ARMS 线程剖析自动诊断的这样的一个能力。当我们微服务或者是数据库的性能值打满时,这个时候可能所有的请求都会变慢,但是你在调用链上也很难直观的去反映出来,因为这种资源类的问题是很难通过链路去记录下来的。这个时候 ARMS 提供的这种池化监控,能够直接分析每一类线程当前情况,并配置告警。除此之外比如说你想分析一些内存泄漏的问题,或者是一些线上运行代码和本地行为不一致的问题,都可以通过白屏化的内存诊断,或者是 Arthas 这种在线调试的这样的一个能力,帮你快速的去定位你的根因。以上就是今天我们对链路追踪整体的介绍,也涉及到我们对整个全链路追踪的一些最佳的实践,感谢大家!

给 K8s 装上大数据调度引擎:伏羲架构升级 K8s 统一调度

作者 | 冯亦挥引言基于 K8s 的统一调度是阿里集团的核心项目,随着2021年双十一落下帷幕,这个历时一年多,汇集了蚂蚁、电商、搜索、计算平台等几大调度团队的联合项目在生产场景得到了终极验证。作为统一调度项目的核心团队,伏羲成功地将 MaxCompute 弹内几万台机器、数百万核计算资源接入了统一调度系统,全程对业务和用户完全无感,无一故障,无一破线,完美实现了“飞行中更换引擎”的目标。统一调度在 MaxCompute 场景的规模化落地,为今年丝般顺滑地支撑双十一洪峰提供了强力保障。通过统一调度项目,伏羲也实现了架构上的再次升级,全面融入 K8s 统一调度架构,让 K8s 生态兼具在线服务和离线大数据的调度能力。过去几年,阿里技术人一直在探索如何在一个资源池上让不同业务形态的应用在时空上“削峰填谷”,以提升利用率、降低成本、极致资源弹性;另一方面,飞天伏羲在长期的架构演进中,也一直在寻求如何兼容开源生态,更好地为开源引擎提供资源调度服务。基于 K8s 的统一调度,是阿里集团多年混部方案自然演进的结果,也是伏羲拥抱开源的终极形态。本文将从集团混部项目开始谈起,介绍基于 K8s 的统一调度方案,以及 MaxCompute 迁移统一调度的过程。始于混部,终于统一调度阿里集团需要一个庞大的资源系统支撑线上丰富的业务形态,搜索、电商、大数据、数据库等,我们观察到电商纯在线集群长期处于低水位的状态,常态利用率在 10%以下,而以 MaxCompte 为代表的大数据离线集群长期处于高水位,平均利用率 70-80%。以集团 10 万台(2017 年数字)在线机器为例,通过混部,理论上可以将机器利用率由 10%提升到 45%,这意味着每年可以额外提供 7.8 万台同等计算能力的机器,这是一笔巨大的收益。但混部的挑战也是巨大的,其中最核心的挑战是如何提供一套资源共享机制(全局、单机),在保障各应用 SLA 的前提下,达成集群利用率提升的目标。011、基于资源静态划分的混部集团混部项目从 2015 年 9 月正式立项,在经历了初期的技术栈整合和隔离技术的探索后,2017 年正式进入核心生产。当时 0 层作为资源展板,按机器粒度划分在线和离线资源的比例,管理机器的混部角色和状态,而在线离线两个一层调度器基于 0 层分配的资源进行各自业务场景的调度。2017 年双十一,电商和蚂蚁两个混部场景均平稳完成了大促的目标,但也有明显缺点:1)离线作业的资源使用没有保障,可能被在线应用无条件抢占;2)在线离线调度器静态划分资源,缺乏灵活性;3)大促期间,离线全部降级,在更大规模场景下,很难保障离线核心业务的稳定性。2、混部的进阶:规模化混部2018 年年初,集团调度系统要全面提升混部能力,将电商混部扩大到万台规模,并全力保障离线作业的运行质量。为此,混部项目提出了资源优先级的概念,通过资源优先级划分,使离线的高优先级作业(Latency Critical)与在线应用在资源保障上处于同等位置,其运行时的稳定性也得到了保障,而离线的普通作业(Best Effort)则继续起着“削峰填谷”,提升集群利用率的作用。为了加强资源管控,原有的 0 层功能也得到了增强:1)记录在离线两个调度器资源使用情况的资源“账本”,并在资源冲突时进行仲裁;2)接受一层调度器的资源请求,并保证“账本”上的资源信息与单机的资源配置保持一致。3、基于 K8s 的统一调度混部项目希望在一个资源池上让不同业务形态的应用在时空上充分“削峰填谷”,从而提升资源利用率,而 0 层作为辅助模块,协同了两个一层调度器的资源使用。但毕竟是两个调度器,由于彼此间无法高效地交互细粒度信息,阻碍了混部效果的进一步提升。如果基于一套调度系统,不仅可以简化部署运维流程,还可以构建统一的资源视图,在相同的资源协议下,通过动态感知各应用运行时的特性,使调度效果逼近全局最优,最终实现资源利用率提升的目标。Kubernetes(简称 K8s)作为容器应用集群化管理系统,为容器化应用提供了自动化的资源调度,容器部署,动态扩容、滚动升级、负载均衡,服务发现等功能,已成为了容器编排的事实标准,因此基于 K8s 的统一调度自然成为了混部系统下一阶段演进的方向。1、核心挑战但 K8s 本身的调度器具有功能和性能上的缺陷:以 APIServer 为中心的消息同步机制(List-Watch),更适用于调度频度较低的在线服务场景,对于以 MaxCompute 为代表的大数据计算场景(每秒 10 万次的调度频度),无法提供极致的性能保障;默认的调度器无法提供灵活的多租户队列管理功能;默认的调度器采取的是静态资源配额管理,不能做到“削峰填谷”,不利于实现集群资源的高利用率;Scheduler 整体上是中心式调度,扩展空间有限,缺乏分布式协同调度能力。伏羲与 K8s 关键指标比较为了解决上述问题,需要让 K8s 具备伏羲在规模和性能上的能力,而如何降低 API Server 在高并发场景下的压力成了关键,我们采取了以下方案:1)将调度相关的信息拆解成资源、执行和状态三部分,非关键信息不落盘;2)批量更新,减少更新频次。在统一调度架构设计上,我们遵循了以下原则:新增组件和功能尽量以插件的形式,减少对 K8s 体系的破坏支持在线离线多种业务形态的混部,在保留 K8s 原生 Pod 语义的同时,针对离线高频调度的特性,扩展了 task 链路协议。既做到了调度上统一,也同时兼顾了在线离线运行时不同的特点。设计上支持 sharding 作为所有 master 的后续规模扩展手段2、统一的调度算法和流程如何通过一个调度器,满足集团多个场景不同业务形态的调度需求,这是设计上的最大挑战。历时 2 个多月,项目组分别从资源账本、调度流程、队列管理、资源协议等维度进行了抽象设计,同时我们也充分参考了 K8s 社区 scheduler framework 插件化机制,通过灵活的调度框架让不同的调度团队可以定制各自的调度需求。3、统一的资源分类和作业优先级在资源池的分类上,我们将资源分成了 Prod/Batch/BE 三大类,统一了不同业务部门资源使用的预算口径,而 Batch/BE 资源的定义,则为集群利用率的提升提供了理论依据。在资源分类的基础上,我们进一步将作业优先级在全局打通(蚂蚁、电商、搜索、计算平台),原则上 Prod 的优先级>Batch 的优先级>BE 的优先级,其中 Prod 优先级对应[9000-9999],Batch 优先级对应[6000-6999],BE 优先级对应[3000, 3999]。统一的作业优先级,为混部场景下不同业务形态应用 SLA 的保障提供了参考依据。4、统一的多租 Quota 机制不同部门的资源配额如何管理,这是 Quota 管控系统要解决的问题。我们提供了任意多层的 Quota Tree 机制,能同时兼容集团几大业务场景的需求,例如在 MaxCompute 场景下支持任意层 Quota 架构,其中只有叶子节点挂具体的作业,非叶子节点用于圈定一批 QuotaGroup 统一管理和调配(管理者称为接口人)。每个 QuotaGroup 有 MinQuota 和 MaxQuota,MinQuota 是 Guaranteed,MaxQuota 则是业务可申请的资源的上限(可以类比 Kubernetes Pod 的 requests 和 limits)。多租 Quota 机制除了要保证不同租户间资源使用的公平性,还有一个重要的功能是提供资源弹性能力,即当用户的请求处在波谷时,其 Quota 也能被其他用户共享。我们参照了灌水模型来实现租户间资源的动态弹性,通过“削峰填谷”机制让不同用户充分共享集群资源,最大化集群资源利用率。如果说集团各大调度平台像几辆并驾齐驱的跑车,统一调度的目标则是给它们找到一个共同的底盘,在调度算法流程、资源分类和作业优先级、多租 Quota 机制等调度基础设施上给出了统一的定义,同时为不同业务场景的调度需求保持了一定的灵活性,一个松紧有度的调度框架也为后续各业务线应用的迁移创造了条件。MaxCompute 迁移统一调度伏羲作为阿里云计算平台的核心底座,通过 MaxCompute,支撑了阿里集团海量大数据计算需求,目前已管理了超过十万规模的计算节点,平均每天调度千万级别的作业,在几百万核的计算单元上运行几十亿级别的 worker,处理 EB 级别的数据。将 MaxCompute 业务从伏羲迁移到统一调度是一个浩大的工程,一方面线上业务正在跑,调度特性不能有丝毫的回退,我们必须在极短的时间内把过去十多年大数据的调度能力重新长在统一调度上;另一方面,为了不降低平台体验,迁移过程要做到对用户透明,需要对系统的调用链路做细致的梳理,前期的方案设计和后期的步骤实施都要做到谨小慎微,非常考验我们的工程能力。1、也要性能极致通常在线应用是启动一次,长时间运行,因此 Kubernetes 的调度器在并发和性能上的表现并不出色, 而以 MaxCompute 为代表的大数据计算场景,每秒就有成千上万次资源在流转,对调度器的性能有着极高的要求。如何在大数据计算高并发场景下,让调度性能做到极致,这是统一调度项目的最核心的挑战。1、task 链路通信协议优化大数据场景资源的高频流转会在 API Server 侧产生极大的压力,导致整体调度性能随着规模的扩大而迅速衰减。通过进一步性能分析,我们发现 API Server 有如下假设:1)数据到达的顺序要和推送到 watch 的顺序全局严格一致;2)数据同步落盘后才能开始向 watch 推送。由于 Task(task 链路的资源对象)的局部特性,只会被一个 TaskGroup(一个调度单元,相当于 pod)订阅,因此我们对 task 链路的通信协议进行了以下改进:以去中心化(peer to peer)方式直接在角色间进行通信,并将其封装成了 tasklib,支持标准的 K8s list/watch 机制。在相同的压力场景下,无论是 e2e 的效果还是稳定性都有了明显的改善,基本解决了大规模高并发场景下通信链路瓶颈的问题。2、task 链路调度性能优化资源调度是将请求和资源相互匹配的过程,常见做法是将请求从队列中取出,然后经过 Filter/Score 等插件依次进行过滤打分,选出合适的机器后进行分配,这是请求查找资源的过程。对于压力较小、调度延时不太敏感的在线调度场景,上述方式通常能给出局部最优解;但对于大数据计算场景,由于作业本身的短时特性,需要调度延时尽量小,通过资源的高速流转使集群保持高吞吐率,当机器资源释放出来后,需要快速地查找能够使用这批资源的请求,这是资源查找请求的过程。针对离线场景的这种调度需求,我们在在线 BestFit 流程的基础上,引入了 FirstFit 流程:当 UniRequest 初次进入调度系统,在执行完请求查找资源的逻辑后,如果仍未满足,则将请求插入到 Mach->UniRequest 的 Queue 中,Queue 按 Quota 组聚合(Quota 组内有序)当机器有资源变化时,触发 Mach->UniRequest 流程,从某个 Quota 组队列中查找合适的 UniRequest(在寻找过程中执行 Filter 逻辑)同一台机器同一时刻只触发一个 Queue 的调度,同一个 Queue 同一时刻只能被一台机器触发调度由于是按机器粒度触发调度,上述方式天然不存在资源冲突,可以全速并发执行。另外,我们还通过树结构加速了请求与多维资源匹配的过程,虽然也存在无效遍历导致的回溯,但整体表现依然十分出色。2、飞行中更换引擎统一调度从设计第一天就考虑了各个业务方如何进行系统升级,参考之前系统架构升级的经验,我们对本次统一调度系统升级的要求也非常明确,即平滑热升级,全程对用户透明无感。但在 MaxCompute 技术体系中,伏羲一方面是分布式系统的资源管理和调度的组件,需要与上层作业执行引擎(AppMaster)进行资源交互,另一方面也是各种运维管控(比如大数据运维平台 Tesla)的数据源,复杂的模块依赖决定了系统升级是一件非常艰巨的事情,如果将 MaxCompute 比作一架高速飞行的飞机,统一调度升级就是要给这架飞行中的飞机更换引擎,难度可想而知。为此,我们对资源交互协议进行了适配改造,并专门开发了一套热升级系统。1、协议改造资源交互协议是调度系统中比较繁琐的一个部分,由于架构上的差异,原生伏羲的资源调度协议与统一调度的资源交互协议存在着较大差异,而协议变更需要对上层 AppMaster 业务逻辑透明,为此我们基于 cgo+jni 封装了一套 UnischedulerAppMasterLib 接入层,自动识别本地执行系统是伏羲还是统一调度系统,实现了上层引擎一份代码可以在多套环境无差别运行。2、热升级系统与大家熟悉的在线系统不同,离线的升级通常没有 buffer 机器,在这种情况下,如何实现万台规模集群升级到统一调度系统呢?根据 MaxCompute 自身的业务特点,我们从以下两个维度进行了拆分:1)在资源维度,按机器粒度,逐步将机器从伏羲系统迁移到统一调度系统;2)在任务维度,按 Quota 组粒度,将作业从伏羲系统迁移到统一调度系统。在迁移过程中,这两个维度的调整要相互配合,以保证当前迁移的作业能在统一调度系统里稳定运行。统一调度热升级示意图结语在分布式调度领域,Google 用 Borg 实现了一套调度系统支撑多种应用引擎,并通过混部节省了 20%的机器资源,这一直为大家所津津乐道。实现统一调度一方面需要有强大的技术储备作支撑,同时也要考虑各种非技术的因素,比如公司不同发展阶段技术选型带来的历史包袱,多个调度团队分属于不同业务部门的现实因素,这将极大考验公司技术治理的决心。也是因为这些原因,国内的互联网公司大部分还是多个业务部门多套系统并存的局面,无法享受多种应用混部带来的资源红利。阿里巴巴蚂蚁、电商、搜索、计算平台等多个部门的调度团队在各自领域积累了丰富的调度经验,统一调度是阿里集团几大调度团队的一次技术大会战,让集团的业务跑在一个资源池的一个调度系统上,今天我们初步达成了目标,但这也仅仅是开始。简单的庆祝之后,也需要冷静地思考随之而来的问题,比如多个团队之间如何协作进行功能开发,如何进行版本管理和控制发布节奏,如何通过有效的测试保证各个场景的 feature 稳定可靠,这将非常考验项目组的集体智慧。但方法总是比问题多,随着时间的推移,相信这些问题都会得到很好的解决。在统一调度大规模集群成功上线的基础上,下一阶段我们可以尝试在集团范围推进更大规模的混部,进一步压榨集群的资源利用率,收割线上资源的红利。飞天伏羲作为有着十多年历史的调度团队,在服务好 MaxCompute 大数据平台的过程中,一直在不断通过自我革新赶超业界先进水平,我们经历了 Fuxi 2.0 的这样的大规模升级,今天通过 K8s 统一调度项目又再次实现了系统架构的蜕变,将大数据平台强大的调度能力赋予 K8s 系统,同时去拥抱 K8s 周边丰富的生态。除了集团弹内集群,将来我们在公共云、专有云等多个场景,也会以 K8s 统一调度的方式进行输出,以更好地服务云上的用户,敬请期待!招贤纳士真诚希望与分布式调度领域感兴趣的同学进行深入交流,更期待大家的加入,一起在云端构建世界领先的的计算能力(联系我们:yihui.feng@alibaba-inc.com)。

云原生时代的运维体系进化

作者 | 易立云原生已经成为数字经济技术的创新基石,并且正在深刻地改变企业上云和用云的方式。云原生的用云方式可以帮助企业最大化获得云价值,也给企业的计算基础设施、应用架构、组织文化和研发流程带来新一轮变革。而业务和技术挑战也催生了新一代云原生运维技术体系。本文整理自阿里云资深技术专家、容器服务研发负责人易立在阿里云联合主办的“2021云上架构与运维峰会”中的演讲实录,分享了云原生时代运维技术发出的重要改变,以及源自阿里云超大规模云原生应用发展进程中的CloudOps实践。易立,阿里云资深技术专家、容器服务研发负责人新商业带来新机遇与新挑战阿里云对云原生的定义是因云而生的软件、硬件和架构,帮助企业最大化获得云价值。云原生技术带来的变化包含几个维度:首先是计算基础设施的变化,包含虚拟化、容器、函数计算的新的计算形态,帮助应用高效地运行在公共云、私有云、边缘云等不同的云环境。其次是应用架构的变化。利用微服务、服务网格等技术帮助企业构建分布式、松耦合、高弹性、高容错的现代化应用。最后是组织、文化和流程的变化。比如 DevOps、DevSecOps、FinOps、 SRE 等理念持续推动现代化的软件开发流程和组织升级。回顾云原生出现的时代背景,移动互联网的出现改变了商业的形态,改变了人与人沟通的方式,让任何人在任何时间、任何地点都可以轻松获取自己所需的服务。IT 系统需要能够应对互联网规模的快速增长,并且能够快速迭代、低成本试错。以 Netflix、阿里为代表的一系列互联网公司推动了新一代应用架构的变革,Spring Cloud、Apache Dubbo 等微服务架构应运而生。微服务架构解决了传统单体式应用存在的几个问题:每个服务可以独立部署和交付,大大提升了业务敏捷性;每个服务可以独立横向扩容,应对互联网规模的挑战。与传统单体应用相比,分布式的微服务架构具备更快的迭代速度、更低的开发复杂性和更好的可扩展性。但同时,它的部署和运维的复杂性却大大增加。我们需要如何应对?此外,“脉冲”计算成为常态。比如双十一大促期间,零点需要的算力是平时的数十倍;一个突发的新闻事件,可能让上千万用户涌向社交媒体。云计算无疑是处理突发流量洪峰的更加经济、高效的方式。如何上好云、用好云、管好云,如何让应用可以更加充分利用基础设施的弹性,成为企业运维团队的关注重点。这些业务和技术挑战也催生了云原生的运维技术体系 – CloudOps。云原生时代运维技术变革1、云原生运维解决之道CloudOps 要解决几个关键问题:标准化:标准化可以促进开发团队与运维团队的沟通和协同,标准化也有助于生态分工,推动更多自动化工具的出现。自动化:只有自动化运维,才能支撑互联网规模的挑战,才能持续支撑业务的快速迭代与稳定性。数智化:数据化、AI 增强的自动化运维成为未来发展的必然趋势2、容器 “应用集装箱”重塑软件供应链在传统的应用分发、部署过程中,常会由于缺乏标准导致工具碎片化,比如 Java 应用和 AI 应用的部署,需要完全不同的技术栈,交付效率低。此外,为了避免应用之间的环境冲突,我们经常需要将每个应用单独部署在一个独立的物理机或者虚拟机上,这也造成了很多资源浪费。2013 年开源的容器技术 Docker 出现,开创性地提出了基于容器镜像的应用分发和交付方式,重塑了软件开发、交付和运维的整个生命周期。就像传统的供应链体系为例,不管什么样的产品都是通过使用集装箱来进行运输,极大提升了物流效率,使得全球化的分工协同成为可能。容器镜像将应用和其依赖的应用环境一同打包。镜像可以通过镜像仓库进行分发,可以一致的方式运行在开发、测试和生产环境中。容器技术是一种轻量化 OS 虚拟化能力,可以提升应用部署密度,优化资源利用率,与传统的虚拟化技术相比,更加敏捷、轻量,具备更好的弹性和可移植性。容器作为云时代的“应用集装箱”,重塑了整个软件供应链,也开启了云原生技术浪潮。033、容器技术加速不可变基础设施理念落地在传统的软件部署和变更过程中,经常会出现因为环境间的差异导致应用出现不可用的问题。比如,新版本应用需要依赖 JDK11 的能力,而如果部署环境中没有更新 JDK 版本,就会导致应用失败。“It works on my machine”也成了开发人员打趣的口头禅。而且随着时间的推移,系统的配置已经不可考,采用原地升级的方式在变更的时候一不留神就会掉进坑里。不可变基础设施(Immutable Infrastructure)是由 Chad Fowler 于 2013 年提出的一个理念,其核心思想是“任何基础设施实例一旦创建,就变成为只读状态,如需要修改和升级,则使用新的实例进行替换。”这种模式可以减少配置管理的复杂性,确保系统配置变更可以可靠地、重复地执行。而且一旦部署出错时可进行快速回滚。Docker 和 Kubernetes 容器技术正是实现 Immutable Infrastructure 模式的最佳方式。当我们为容器应用更新一个镜像版本的时候,Kubernetes 会新创建一个容器,并且通过负载均衡将新请求路由到新容器,然后销毁老容器,这避免了令人头疼的配置漂移问题。044、Kubernetes:分布式资源调度的标准及 CloudOps 最佳载体目前,容器镜像已经成为了分布式应用交付的标准。Kubernetes 已经成为了分布式资源调度的标准。越来越多的应用,通过容器方式进行管理、交付:从无状态的 Web 应用,有状态的数据库、消息等应用,再到数据化、智能化应用。CNCF 2020 年调查报告指出,55%的受访者已经在生产中的容器中运行有状态应用;Gartner 预测到 2023 年,70%的 AI 任务会通过容器或 Serverless 模式构建。对比一下经典的 Linux 操作系统和 Kubernetes 的概念模型,他们的目标都是向下封装资源,向上支撑应用,提供了标准化的 API 来支持应用生命周期,并且提升应用的可移植性。不同的是,Linux 的计算调度单元是进程,调度范围限制在一台计算节点。而 Kubernetes 的调度单位是 Pod 一个进程组,它的调度范围是一个分布式集群,支持应用在公共云、专有云等不同环境间进行迁移。对于运维团队而言,Kubernetes 成为实现 CloudOps 理念的最佳平台。首先是 K8s 采用声明式 API,让开发者可以专注于应用自身,而非系统执行细节。比如,在 Kubernetes 之上,提供了 Deployment、StatefulSet、Job 等不同类型应用负载的抽象。声明式 API 是云原生重要的设计理念,有助于将系统复杂性下沉,交给基础设施进行实现和持续优化。此外,K8s 提供了可扩展性架构,所有 K8s 组件都是基于一致的、开放的 API 进行实现和交互。开发者也可通过 CRD(Custom Resource Definition)/ Operator 等方式提供领域相关的扩展,极大拓宽了 K8s 的应用场景。最后,K8s 提供平台无关的技术抽象:如 CNI 网络插件, CSI 存储插件等等,可以对上层业务应用屏蔽基础设施差异。055、为什么是 Kubernetes?Kubernetes 的成功背后的魔法就是控制循环,Kubernetes 有几个简单的概念。首先,一切都是资源,通过控制器对资源进行自动化管理。用户可以声明资源的目标状态。当控制器发现资源当前状态与目标状态存在不一致,就会持续调整,让资源状态趋近于目标状态。通过这个方法,可以统一处理各种情况,比如,根据调整应用副本数进行扩缩容,或者节点宕机后应用自动迁移,等等。正因如此,Kubernetes 支持资源范围已经远超容器应用。比如服务网格,可以对应用通信流量进行声明式管理;Crossplane 可以利用 K8s CRD 对 ECS,OSS 等云资源进行管理和抽象。6、云原生应用自动化管理探索与开源实践K8s 控制器 “把复杂留给自己,把简单交给用户”的理想非常美好,然而实现一个高效、健壮的控制器却充满技术挑战。OpenKruise 是阿里云开源的云原生应用自动化管理引擎,也是捐献到 Cloud Native Computing Foundation (CNCF) 下的沙箱项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,解决容器应用在大规模生产环境的自动化和稳定性挑战。OpenKruise 提供了增强的应用灰度发布,稳定性防护,Sidecar 容器扩展等多种能力。OpenKruise 开源实现和集团内部版本代码保持一致。支撑了阿里集团应用 100%云原生化,也已经在苏宁、OPPO、小米、Lyft 等企业得到广泛应用。欢迎大家社区共建和使用反馈。7、GitOps:声明式 API 催生的应用交付流程与协同新方式基础架构即代码(Infrastructure-as-Code,IaC)是一种典型的声明式 API,它改变了云上资源管理、配置和协同的方式。利用 IaC 工具,我们可以将云服务器、网络和数据库等不同云资源进行自动化的创建、组装和变配。将 IaC 概念进行延伸,可以覆盖整个云原生软件的交付、运维流程,即 Everything as Code。本图列出来云原生应用涉及的各种模型,从基础设施、到应用定义、到应用交付管理和安全体系,我们都可以通过声明式方式对应用的配置进行管理。比如,我们可以通过 Istio 来对应用流量切换进行声明式处理,可以利用 OPA(Open Policy Agent)来定义运行时安全策略等等。更近一步,我们可以将应用的所有环境配置都通过源代码控制系统 Git 进行管理,并通过自动化的流程进行交付和变更。这样就是 GitOps 的核心理念。首先,从应用定义到基础设施环境,所有的配置都以源代码的方式保存在 Git 中;所有变更、审批记录也记录在 Git 的历史状态中。这样 Git 成为 sourceof truth,我们可以追溯变更历史、可以回滚到指定版本。GitOps 与声明式 API、不可变基础设施相结合,保障了应用环境的可复现性,提升了交付与管理效率。GitOps 在阿里集团已经被广泛使用,在阿里云容器服务 ACK 中也有支持。目前 GitOps 开源社区也在不断完善相关的工具和最佳实践,大家可以关注相关进展。088、云原生催生稳定性思想变革分布式系统存在高度复杂性,在应用、基础设施、部署过程中任何一个地方的问题,都可能导致业务系统的故障。面对这样的不确定性风险,我们有两种做法:一种是“听天由命”,信佛祖,不宕机;一种是通过系统化的方法进行主动出击,提升系统的确定性。2012 年,Netflix 提出了“混沌工程”的理念,通过主动注入故障的方式,提前发现系统的薄弱环节,推进架构的改进,最终实现业务韧性。我们可以将混沌工程的工作方式比作疫苗,通过“接种灭活疫苗”的方式,让我们的免疫系统受到锻炼,具备抵挡 “疾病” 的能力。阿里双十一购物节的顺利成功,离不开全链路压测等对混沌工程的大规模实践,为此阿里团队在这个领域积累了丰富的实战经验。ChaosBlade 是一组遵循混沌工程理念的实验工具,具有场景丰富、简单易用等特点,已经成为 CNCF 沙箱项目。它支持 Linux、Kubernetes、Docker 等不同运行环境,以及 Java、NodeJS、C++、Golang 等多种语言。内置了 200 多个场景的测试方案。chaosblade-box 是新引入的混沌工程控制台,可实现实验环境平台化管理,进一步简化用户体验,降低使用门槛。欢迎大家加入 Chaosblade 社区共建,也可以使用阿里云应用高可用服务 AHAS 云服务。 云原生 CloudOps 之路最后我将结合阿里实践,介绍我们在 CloudOps 上的一些探索。在传统组织中,开发和运维角色是严格分开的。而不同业务线也构建了一个一个的烟囱化架构,从基础设施环境与运维,到应用运维与开发,都是独立的团队,缺乏良好的协同与复用。云时代的到来也在改变着现代 IT 组织和流程。首先,公共云、专有云成为了不同业务部门间共享的基础设施。然后,SRE (Site ReliabilityEngineering)理念开始得到广泛接受。是通过软件和自动化手段,来解决系统的运维复杂性和稳定性问题。由于 Kubernetes 的标准化、可扩展性和可移植性等优势,越来越多企业的SRE团队基于 K8s 管理云环境,极大提升了企业运维效率与资源效率。在此之上,平台工程团队开始浮现,基于 Kubernetes 构建企业的 PaaS 平台和 CI/CD 流程,支持中间件和不同业务部门的应用部署与运维。提升企业的标准化和自动化水平,进一步提升应用研发、交付效率。这样的分层结构中,向下的团队更多是通过 SLO 驱动,从而让上层系统对底层依赖技术具备更好的可预期性。越向上的团队更多是业务驱动,更好地支撑业务发展。011、阿里云容器服务 SRE 团队的最佳实践阿里云容器服务 SRE 团队一直也在践行 CloudOps 的最佳实践,简单总结如下:第一项是全局稳定性架构设计,让整个平台防范与未然:首先 Securityby-design:让系统做到默认安全,同时通过安全软件供应链保障全生命周期安全其次 Designfor failure:控制爆炸半径、提供限流/降级手段降低故障影响面第三 Designfor automation:类似扩缩容、故障恢复等工作尽可能自动化完成最后 Observabilityby-design:为每个生产应用定义 SLO,并建立相关的可观测性体系,持续关注请求量,延迟、错误数、饱和度等黄金指标第二项是建设稳定性应急体系,也就是我们日常所说的 1-5-10 快恢能力,它包含:1 分钟发现 - 包括通过黑盒、白盒监控能力5 分钟定位 - 提供诊断大盘,利用工具实现自动化根因定位10 分钟止损 - 包含系统化的预案的设计与持续积累,和自动化预案执行最后一项是日常稳定性保障,主要包含:变更管理规范化 – 所有发布做到可灰度、可监控、可回滚问题跟踪流程化 - 凡事有交代,件件有着落,做一个靠谱青年故障演练常态化 – 通过巡检、突袭、压测等手段查漏补缺,让故障预案持续保鲜2、拥抱云原生运维技术体系云原生已经成为势不可挡的技术趋势。Gartner 预测到 2025 年,95%数字化运维将通过云原生平台进行支撑。我们可以根据企业能力和业务目标选择合适的迁云之路,大致可以分为几个阶段:Rehost 新托管:简单地通过 lift-and-shift 方式,将线下物理机替换成为云上虚拟机或者裸金属实例,不改变原有的运维方式。Re-platform 新平台:利用托管的云服务替换线下自建应用基础设施,比如通过 RDS 数据库服务替换自建 MySQL,通过阿里云容器服务 ACK 来取代自建 K8s 集群。托管的云服务通常提供更好的弹性、稳定性和自治运维能力,可以让用户关注于应用而非基础设施管理。Refactor/Re-architect 重构/新架构:包括对单体应用的微服务架构改造、容器化和 Serverless 化等现代化改造。从 Rehost、Re-platform 到 Re-architect,我们可以看到迁移的复杂性和所需技能在增加,但是敏捷性、弹性、可用性、容错性等收益也在持续增加。阿里集团上云也经历了这样的历程,在去年业务 100%上公共云的基础之上,今年实现了应用 100%云原生化。帮助阿里业务的研发效率提升了 20%,资源利用率提升了 30%。最后做一个快速总结。基于容器、Kubernetes 等云原生技术,提供的开放社区标准、不可变基础设施、声明式 API 会成为企业 CloudOps 的最佳实践,也将在这个基础上推进数据化、智能化体系建设,将运维复杂性进一步下沉,让企业可以聚焦于自己的业务创新。阿里云也将持续向外输出自身在超大规模云原生实践和探索中的能力沉淀,与更多企业、开发者一起,躬身入局,全面拥抱云原生运维技术体系。

如何构建流量无损的在线应用架构 | 专题开篇

作者 | 孤弋、十眠-全系列查看-如何构建流量无损的在线应用架构 | 专题中篇如何构建流量无损的在线应用架构 | 专题尾篇前言Github 因为软件升级曾经导致过长达 6 个多小时的全球性服务中断 ...Meta(原名:Facebook) 也刚刚经历一起因为配置推送错误导致全球 6 个多小时的系统瘫痪 ...诸如此类的大型 IT 系统故障每隔一段时间都会出来一个。为企业搭建一个安全可靠的在线应用架构,是一个系统架构师主要责任,他除了将业务系统架构吃透以安全地应对当前的业务流量之外,还需要具备构建未来的能力,即所选取的架构需要能应对业务未来几年的业务增长。这种能力,和技术潮流无关,和所选择的技术的人才市场容量有关,和企业自身业务形态和增长方向有关。我们先抛开 IT 系统的基础设施和企业业务的具象,抽象到在线应用的两个关键衡量指标中去:流量和容量。容量的目标还是为了满足流量的基本需求,而我们不断优化的目标,就是一直在这个两个指标中找出一个能代表"技术先进性"的平衡点。这个平衡点意味着:高效且精确的将现有的资源(容量)服务于现有的,及其可预见的业务流量;高效意味着性能,精确则需无损。这系列文章一共三篇,旨在让技术回归到系统架构师们需要解决的本质问题:如何让在线应用最大化的流量无损。问题定义我们先参考一个通用业务的部署架构图(说明:由于笔者的技术背景是 Java,熟悉的基础设施也主要是云服务为主,所以其中很多的例子是使用 Java 体系中的一些技术架来和云服务进行阐述,一些细节点上可能不太具备其他编程语言的参考的意义。):这张图是一个典型而且很简单的一个业务架构,这个业务会服务于来自全球的用户,当用户的请求到达之后,经过负载均衡转入后面的微服务网关集群,微服务网关做完一些基础的流量清洗、鉴权、审计等工作之后再根据业务形态路由到后面的微服务集群中;整个微服务集群最终会和不同的数据服务进行数据的交换(读/写)操作。根据上面这一描述,我们暂且将整个流量请求服务的过程分为:流量解析、流量接入、流量服务、数据交换四个主要阶段。在这四个阶段中,都有可能发生流量损耗的可能性,而且每一种可能发生之后我们所采取的解决方案会是截然不同的,有的通过一些框架配置就能解决,而有的可能需要整体架构的重构。我们会通过三篇系列文章对这四个阶段,一一进行剖析,开篇主要讲的是流量解析和流量接入。流量解析解析的场景的本质还是通过一个服务名称获取一个服务的地址,这一过程是我们常规意义上的 DNS 解析。但是传统域名解析在目前各个服务商的管理策略影响下,经常会遇到域名缓存、域名转发、解析延迟、跨服务商访问等问题。尤其在面向全球的互联网业务中,Web 服务通过传统 DNS 解析时,不会判断终端用户的来源,随机选择其中一个 IP 地址返回给终端用户,这不仅会可能由于跨服务商解析而降低了解析效率,而且还会导致终端用户可能因为跨洋访问而导致速度变慢。上面的这些问题都有可能会直接导致我们的流量受损。为应对上述的场景,常用的解决方案有智能解析和 HTTP DNS 技术,分别阐述如下:1、智能解析智能解析,一开始主要用来解决不同运营商之间跨网络解析而引起网络不通的问题,他主要是根据访问端的地址,选择对应网络下的接入点,从而达到解析正确的地址的目的。随着这一技术的持续迭代和演进,有的产品在此基础上加入了不同地域的网络质量监测节点,可以从一组机器中根据不同节点的服务质量,进行更智能的解析。目前阿里云上的智能解析依托于云的基础设施,甚至可以以应用为单位动态扩缩节点池中的节点,最大化的在这一领域发挥了云上弹性的价值:(图片来源于阿里云云解析文档)2、HTTPDNSHTTPDNS 顾名思义,就是使用 HTTP 协议代替 DNS 的发现协议;一般由服务商(或者自建)提供一个 HTTP 服务器,这个服务器提供一个极其简练的 HTTP 接口,客户端在发起访问之前,由 HTTPDNS SDK 先行发起解析,解析失败再 Fallback 回原来的 LocalDNS 解析。HTTPDNS 在解决 DNS 劫持、域名缓存 等场景下特别有效,缺点就是大部分方案还需要客户端侵入 SDK;同时 Server 的建设成本会有点高昂。不过在随着云厂商在这一领域的持续迭代,已经涌现出来了越来越多更加轻量的解决方案;这也会帮助 HTTPDNS 这种技术成为今后 DNS 领域演进的主流趋势之一。流量接入当 DNS 解析到正确的地址之后,便进入到了流量接入这个核心的入口,这个过程的主角是网关,一个网关通常意义上扮演的角色重要有路由、鉴权、审计、协议转换、API 管理、以及安全防护等重要的功能。业界常见的CP是负载均衡和微服务网关的结合,但是这个两个组件配合起来往往有一些场景比较容易忽略,以下图为例,我列举三个容易忽略的场景简单做一些介绍,分别是:流量安全、网关应用管控与流量路由。1、流量安全不安全的流量分为两类,第一类是攻击类型的流量;第二类是超过系统容量的流量。攻击类型流量的防范主要以软硬件的防火墙为主。这一类解决方案颇为成熟,这里不再赘述。这里比较难以甄别是超过系统容量的非攻击流量,如何在这种场景下,最大限度的保证正常流量得到相应的服务,还能保护极有可能雪崩的整个业务系统是抉择的难点。简单的尝试,是在网关这里按照请求 QPS、并发数、分钟请求数甚至接口参数等,做类似于 RateLimit 的流量控制。但是在此之前,是要求系统架构师能对系统的容量心中有数。我们推荐的做法是在做类似的安全防护之前,先要做到一个整体的容量评估,这里的评估不单单只是针对某些 API 做一次压力测试这么简单,是推荐针对生产环境做一次真正全链路的压测(第三篇中将有一节专门介绍),然后再针对性的作出安全策略的调整。2、网关应用管控网关归根结底还是一个应用,按照我们目前接触到的客户线上系统来看,一个完全是微服务架构的业务系统,这个应用会占用整个系统 1/6 - 1/3 不等的机器资源,这已经算得上是一个很大规模的应用了。既然是一个应用,它就会进行一些常规的运维管控操作如启动、停止、部署、扩容等。但是由于网关是一个业务系统的咽喉,他是不能做频繁的操作的,这意味着有几点原则要非常清晰的传导到开发团队内部:配置与代码解耦:能力(协议转发、限流配置、安全策略、路由规则等)是必须可配置,且可以动态下发的。不要夹杂业务逻辑:让网关回归到网关的本质,不要夹杂业务逻辑;一个自己不加戏的网关就是一个好网关!除了上述两点开发侧的原则之外,在运维侧也有相应的原则。运维上除了常规的监控和报警,还需要具备自适应的弹性能力。但是网关的弹性牵扯的点太多:比如需要配合前面的负载均衡一起操作(如:进行应用部署之前需要在负载均衡处将对应节点下线或降权,应用部署确保启动成功之后再将节点上线);同时弹性还需要和应用管控体系自动化的进行配合才能做到线上流量无损。3、流量路由经过网关的下一步,则是将应用路由到下一节点,互联网场景在有高可用多机房部署的情况下,为了服务质量,都会采取就近路由的原则。即如果网关入口在主机房,下一跳就希望路由到同机房的节点,同样的道理,在一个微服务集群中的下下一跳,还是希望可以路由到相同的机房。否则,如果出现了跨机房调用的请求时,RT 就会变的很长,最终因请求超时而导致流量有损,如下图:要想做到同机房调用的效果,我们需要对选择的服务框架有很好的理解。核心的原理是对于下一跳的路由时,需要优先选择相同机房的地址。而不同的框架和业务所在的部署环境,都需要作出一些针对性的定制开发才能做到严格意义上的同机房优先调用。结语本篇是整个《如何构建流量无损的在线应用架构》系列的第一篇,这一系列共三篇,旨在使用最为朴素的语言将影响在线应用流量稳定性的技术问题做一个归类,这些问题的解决方案有的只是一些代码层面的细节,有的需要工具进行配合,有的则需要昂贵的解决方案,如果您的应用想在云上有一个【流量无损】的一站式体验,可以关注阿里云的《企业级分布式应用服务(EDAS)》这个云产品,EDAS 也将会持续向默认接入流量无损的方向演进。下一篇,我们将从在线应用发布与服务治理的角度带来不一样的干货,敬请期待,我们下周见。点击“阅读原文”,查看更多内容!点击下方链接,查看实战峰会更多精彩内容!https://developer.aliyun.com/article/817767

ARMS 应用安全-你的应用运行时的隐形安全卫士

作者 | 坤硕&白玙随着互联网成为日常生活的基础设施,企业的应用与服务遭受安全威胁和侵害的风险不断增加。这里面的风险不仅仅是网络层面的安全问题,更有应用本身的安全。在传统网络架构下,应用位于 IDC 内,有清晰的边界,应用威胁主要来自外部,边界内风险忽略不计,防护只需要关注边界入口处的南北向流量,传统上一般采用 WAF(即 web 应用防火墙)技术来拦截危险流量。但随着微服务及容器化等技术发展,应用可以在 IDC/容器/公有云/私有云等多环境下部署,针对应用的威胁除了南北向还有来自东西向的横向威胁。网络环境日益复杂及漏洞攻击手段多样化,都造成产研团队牵扯更多精力修复问题,从而浪费公司大量研发成本。现阶段典型的安全痛点如下:审计不完的代码(数据统计显示平均 2 万行代码有 1 处漏洞,按照行业经验在交付的软件代码中 1000 行代码就有 1-25 处错误);升级不完的三方组件,例如 fastjson,jackson,shiro,tomcat,struts2 等爆出多个 0day 漏洞需要紧急修复;相同问题一犯再犯(例如注入,xss,csrf,broken auth 等依然在头部安全问题列表中反复出现);总是被遗漏掉的应用(一些边缘历史应用长期无人治理以及存在大量未知应用悄悄上线,形同定时炸弹不可控);网络架构约束下端到端加密、多重编码限制导致检测困难,以及被检测的流量需经过检测设备,否则可能会漏掉攻击);远不止于 HTTP 协议攻击(大部分WAF 往往只能防御 HTTP 协议攻击,还存在 dubbo/thrift/rmi 等非 HTTP 协议以及各种私有协议也有被利用进行漏洞攻击);代理攻击的无力(表现为一旦有一台内网机器被拿下,那么攻击者以这台主机为跳板,WAF 也无能为力);漏洞扫描不友好(主要表现为黑盒的扫描器在进行漏洞扫描时候会对测试环境造成大量脏数据以及影响功能卡顿)。如果我们的应用本身是否可以直接被加固,无需代码安全专家,无需额外代码修改,也无需复杂配置?对此,阿里云应用实时监控服务 ARMS 推出基于 RASP 的"应用安全"功能,让应用具备高水位的运行时安全防护,实现内生安全。RASP 是什么?2014 年,Gartner 将“Runtime Application Self-Protection”(简称 RASP)列为当年的应用安全关键趋势。作为在运行时检测应用程序攻击并进行自我保护的安全产品,RASP 将安全程序像疫苗一样注入到应用程序中,和应用程序融为一体,实时检测和阻断安全攻击,使应用程序具备自我保护能力。当应用程序遇到特定漏洞和攻击时,不需要人工干预就可以进行自动重新配置应对新的攻击。以人体病毒防护举例,我们通过口罩来隔绝外部病毒进入人体,防火墙通过分析识别阻隔外部危险流量来保护系统。而 RASP 技术类似于人体疫苗抗体无需关心病毒进入的途径,部署在在服务端点上伴随应用启动,可以直接识别并拦截攻击。RASP 旨在缩小应用安全安全测试和网络边界控制所留下的空白地带,深入应用运行环境内部,实时了解数据和事件流,以监测或者阻止开发过程中无法预见的新威胁。一般来说 WAF 在入口只能看到流量内容,即用户的原始请求,并不能感知应用最终会怎样执行这条请求。所以往往会产生一些误报漏报,例如用户在在线文档中上传一段 SQL 语句(误报)、利用PHP漏洞的报文打到了 JAVA 环境(虚报)、应用本身做过预编译,不存在 SQL 注入点(虚报)、ls 等短命令执行,极容易跟正常输入混淆(误报)。而相比之下,RASP 只上报能利用成功的有效攻击。从原理上来说,RASP 关注运行时行为,不关心流量来源及形式,无需修改代码,以 Agent 方式随着应用启动,Hook 应用的底层关键函数以及参数内容,结合请求上下文,语义分析,基线等手段,判断当前的应用行为是否存在风险。从策略上来说,由于应用行为相对于千变万化的攻击特征来说是可穷举的,因此 RASP 针对 0day 以及各种变形攻击手法的防御效果要远好于 WAF 等以"特征"为检测对象的手段。另外,加密马等手段本质上也是对输入内容做变形以绕过基于特征的检测,RASP 同理也会无视,形成降维打击。RASP 与 WAF 的差异我们可以看到 RASP 与 WAF 一样都能检测流量和内容,也能够终止用户会话,但两者之间的差别在哪里呢?接下来我们从场景,误漏报,维护性上等多个角度来对比 RASP 与 WAF 的差异特点。从上面的表格可以看到,例如 SQL 注入,XSS(跨站脚本),代码执行,webshell 等通用的 WEB 漏洞都具备一定的防御能力。由于 WAF 作为入口层比较擅长拒绝服务攻击,爬虫攻击,扫描器以及访问控制场景,而 RASP 与业务进程运行在一起,更擅长于  0day,复杂编码/加密流量,内存/加密码,非 HTTP 协议等场景,并具备以下特点:RASP 无视流量特征更关注应用行为,从误漏报上来说概率极低,只上报有效的攻击。RASP 部署在本地会消耗一部分服务器性能,而 WAF 仅消耗自身性能,对应用和源站无影响RASP 基本不依赖规则,无需联网,极少更新,反之 WAF 依赖规则需要联网更新或者进行云端运算漏洞修复方面,RASP 通过虚拟补丁进行漏洞修复,同时能定位到漏洞利用的代码行,更胜一筹总结来说,RASP 更接近云原生,可做为“分布式防火墙”,打破 WAF 边界防护局限性,符合零信任安全概念。而 WAF 基于边界安全,保护面广,RASP 针对 Nginx,Apache 等前置服务器的防护无法支持。所以 RASP 跟 WAF 有各自擅长的场景,结合自身场景,通过互补形成多层纵深防御,才能达到最好的效果。接下来,我们来了解下 ARMS 应用安全基于阿里云 RASP 能力提供了哪些安全防护手段以及通过一个反序列化漏洞来感受下功能。ARMS 应用安全随着业务容器技术、无服务器技术的发展,业务的研发周期和功能迭代频率越来越快,而安全能力的滞后性越来越明显。例如,存在漏洞的老旧中间件升级困难,引入三方组件评估不充分可能引入高危漏洞,代码存在安全漏洞需要快速溯源定位修复等。DevSecOps 作为 DevOps 的延伸,安全应该成为每个人的关注点,优秀的 DevSecOps 工具应该最大程度上实现安全的自动化能力,减小对业务侵入性。而 ARMS 应用安全关注应用发布上线以后阶段的安全,对 DevSecOps 友好,提供完整的运行时安全整体方案,提升业务 7x24 小时安全的同时不引入额外负担影响业务发展,一定程度上改变业务与安全的对立的局面。ARMS 应用监控探针集成了阿里云安全 RASP 技术,通过深度埋点技术,为您的应用注入"安全疫苗",只需要一键开启接入应用安全,就能够轻松识别黑客的危险攻击行为进行拦截告警,而不影响正常的客户请求,就像隐形的安全卫士一样时刻守护着您的应用运行安全。接下来我们详细看下攻击防护统计以及危险组件检测功能。1、攻击统计在很多场景下,我们在流量层面收到安全告警后,但很难与实际漏洞代码位置产生关联,而 ARMS 安全在应用监控探针中集成了阿里云安全 RASP 技术,用户开启安全防护后,一旦发生安全攻击,就可以收到攻击告警。目前支持命令执行漏洞,文件访问漏洞,网络访问漏洞、内存马绕过、JN 注入、恶意反射调用等多达 15 种类型攻击场景检测。ARMS 应用安全在攻击统计页面,提供了应用正常行为统计以及攻击行为统计数据,方便您了解近期是否存在攻击事件。如果被检测到攻击,在该页面还可以分页查看攻击发生时间、攻击类型、请求 URL、上下文数据以及本次攻击的处理结果(监控还是拦截取决于您的防护设置);点击详情可以查看攻击来源 IP、请求详细参数、机器等信息,通过分析代码堆栈进一步定位到代码漏洞位置进行修复。2、危险组件检测 在 JAVA 应用中,往往会依赖大量的三方开源组件以及各种中间件框架,往往这些组件存在未知漏洞难以发现和盘点,应用不清楚自身是否存在高危漏洞暴雷的可能。ARMS 应用安全提供的危险组件检测功能则可以帮助解除这方面的担忧,应用一旦集成探针并接入应用安全后,ARMS 会检测应用的三方组件依赖,自动分析关联权威的 CVE 漏洞库,并区分不同的漏洞危险等级。客户可以根据详情中的漏洞修复建议,优先升级组件解决高危漏洞。针对尚未纳入 CVE 的漏洞,当新的漏洞报出来时,客户还可以第一时间通过"全量组件自查"功能,利用关键词搜索快速检查自身依赖的组件版本是否涉及到该安全漏洞,做到心中有数,确定是否需要处理。漏洞防护示例接下来,我们通过 fastjson 反序列化漏洞的攻击场景来演示 ARMS 应用安全的实际防护效果,fastjson 的反序列化过程主要如下:User类:package com.test;public class User { private String name; public void setName(String Name) { this.name = Name; } public String getName() { return name; }}恶意类:package com.test;import java.io.IOException;public class Evil { //恶意Setter public void setCommand(String command) throws IOException { Runtime.getRuntime().exec(command); }}反序列化内容:{ "rand": { "@type": "com.test.Evil", "command": "open /System/Applications/Calculator.app/" }反序列化漏洞代码:public static void main(String[] args) { //指定User为所需要的类型,但成功反序列化了Evil类型,并执行了命令 User user = JSON.parseObject("{\"rand\":{\"@type\":\"com.test.Evil\",\"command\":\"open /System/Applications/Calculator.app/\"}}", User.class); }当执行上述代码时,在反序列时设置 User 属性时会触发命令执行,本文会打开某个内部应用程序,在真实攻击场景下可能会获取系统配置以及访问敏感信息等造成的危害更大。在开启了 ARMS 应用安全时,当发生上述反序列漏洞时,ARMS 应用安全会识别到序列化漏洞产生的命令执行行为,可以直接阻断该反序列化动作并发送告警通知,在攻击详情可以进一步分析攻击源以及漏洞代码位置。fastjson 反序列化的利用核心,还是在于寻找可以造成代码执行的类,实际上在 java 庞大的 jdk 类库以及第三方类库中存在着大量的可利用类,传统流量产品如 WAF,往往需要在防御时去穷举这些可能被利用的类(经常会出现遗漏),而 ARMS 应用安全基于 RASP 的上下文分析能力与基于行为的攻击发现方式,将会捕获掉所有由 fastjson 造成的代码执行、恶意文件上传、敏感文件读写等行为,而无需去针对特定代码实现做精准匹配,所以完全不会存在被绕过的可能性。结合以上案例,我们可以看到 ARMS 应用安全的整体产品优势,ARMS应用安全全面支持 0day 防御,攻击告警以及溯源,支持危险组件检测,并提供漏洞修复建议。一键开启接入,无需修改代码,支持软熔断逃生避免影响应用以及观察模式体验实际效果。通过压测来看,开启应用安全防护模式后 CPU 平均开销增加低于 1%,内存占用低于 30M,平均 RT 耗时毫秒级,对系统性能影响极低。通过防护设置您可以选择观察/拦截模式、自定义勾选攻击检测类型、自定义检测超时时间,进一步降低性能影响。通过集成 ARMS 应用安全运行时自我防护能力,为您的应用注入"疫苗",实现应用默认安全,抵御日常 OWASP 攻击,默认防御 fastjson 等新漏洞(0day)以及内存马,加密马等。还可以自动发现三方组件高危漏洞,溯源攻击行为精准定位修复问题。一键开关,稳定低消耗运行,运维无负担,为您的业务安全保驾护航!目前 ARMS 应用安全正在公测中,欢迎钉钉扫码加入钉群(34833427)或关注 Apache RocketMQ 官方公众号,了解更多产品详情。

Serverless 开年活动 | 云原生 Serverless 2022年首场技术实践营开启报名

阿里云云原生 Serverless 团队重磅推出“沉浸式”技术实践营,面向企业技术人员,分享 Serverless 的落地实践,多视角碰撞技术观点,实时互动答疑,共同探索 Serverless 企业落地更多的可能性。报名地址:https://survey.aliyun.com/apps/zhiliao/n6_465qFF温馨提示:参会免费,中午含餐,完成动手实操,颁发阿里云官方认证证书;采取报名审核制,仅限 150 人,审核通过后将收到通知短信。1月13日(周四),南京鼓楼区湖南路47号凤凰台饭店,沉浸式参会体验:想听就听,企业生产业务 Serverless 化分享想玩就玩,手把手体验万人打磨生产级场景想问就问,实时弹幕互动挑战答题,验证学习效果、赢大奖参与在左、纪念在右,颁发技术实践营结业证书

2022 年第一场云原生技术实践营开启报名

2021 年,我们在上海、深圳、广州、郑州、北京等地举办了不同主题的云原生技术实践营活动,和客户们共同交流、一起动手,体验容器、Serverless 等实实在在的云原生技术,实现降本增效。2022 年,我们将邀请更多的云原生布道师、更多反复打磨的动手场景,解锁更多城市。1 月 5 日(周三)武汉、1 月 7 日(周五)长沙、1 月 13 日(周四)南京...武汉站报名入口已经开启,报名地址:https://hd.aliyun.com/form/1067报名及参会免费,中午含餐,完成动手实操,颁发阿里云官方认证证书;因场地受限,报名采用审核制,仅限50人;审核通过后将收到报名成功短信,并会有工作人员拉您进活动钉钉群。

KubeCon China 2021 阿里云专场来了!这些首日亮点不容错过

2021 年 12 月 9 日-10日,阿里云携 10+ 技术专家正式亮相年度顶级云原生开源技术峰会 KubeCon + CloudNativeCon + Open Source Summit China 2021,并带来阿里云云原生专场,不仅汇聚行业发展方向的精彩主题演讲,在云基础设施、可观察性、存储、定制和扩展 Kubernetes、性能、服务网格、无服务器、容器运行时、CI/CD、网络等云原生与开源技术等各大专题中,从阿里云真实业务场景中走出来的云原生技术最佳实践也将一一呈现。下面我们就来看看大会正式启航第一天,阿里云云原生专场有哪些不容错过的亮点:多位阿里云与 Intel 专家联袂解读服务网格技术分享主题:使用阿里云服务网格 ASM 和 Intel Multi-Buffer 技术实现更快的应用服务间的加密通信分享嘉宾:王夕宁、曾宇星、刘阳 ,阿里云服务网格 ASM 团队、胡伟、郭栋、赵复生,英特尔软件和先进技术事业部分享时间:2021 年 12 月 09 日 11:00-11:15内容简介:服务网格作为一个云原生应用通信的基础设施层,已经成为用户应用服务内透明通信的首选通用架构模式。通过每个服务实例的 Sidecar 代理可以控制服务间的流量管理、通信、安全和监控。微服务和零信任安全可以让您的系统比使用单体应用程序时更安全。要实现零信任,可以使用双向 TLS 为服务发出的每个请求提供加密。本主题中将探讨如何使用阿里云服务网格 ASM 和 Intel Multi-Buffer 技术来实现两全其美, 即在服务网格部署中具有更快的服务通信响应时间的加密隧道, 确保应用程序基础设施服务之间快速、可靠和安全的通信。社区核心维护者分享如何让 KubeVela 和 OCM 玩儿到一起分享主题:以一致的经验构建和管理多集群应用分享嘉宾:冯泳,阿里云资深技术专家,OCM 社区核心维护者、孙健波,阿里云技术专家,OAM/KubeVela 社区负责人分享时间:2021 年 12 月 9 日 12:10-12:40内容简介:与在多集群环境中部署和管理应用程序相比,当前在本地环境中开发应用程序的用户体验存在巨大差距。我们将演示如何将 KubeVela 和 OCM(开放集群管理)结合起来解决阿里云中的问题,为用户提供在本地开发和多集群生产部署之间部署和管理应用程序的一致体验。我们将讨论这些用例、挑战以及相关的工作和经验。来自阿里云的 CNCF SIG Co-chair 与 Dynatrace 工程师共话 TAG 应用交付程序分享主题:介绍和深入了解 TAG 应用程序交付分享嘉宾:邓洪超,阿里云高级技术专家,CNCF App Delivery SIG Co-chair、Thomas Schuetz,Principal Cloud Engineer, Dynatrace  分享时间:2021 年 12 月 9 日 12:10-12:40内容简介:与在多集群环境中部署和管理应用程序相比,当前在本地环境中开发应用程序的用户体验存在巨大差距。我们将演示如何将 KubeVela 和 OCM(开放集群管理)结合起来解决阿里云中的问题,为用户提供在本地开发和多集群生产部署之间部署和管理应用程序的一致体验。我们将讨论这些用例、挑战以及相关的工作和经验。扫码图片二维码或点击下方链接,即可直达阿里云云原生专场!https://developer.aliyun.com/summit/alicloudnative/kccn2021

Spring Cloud Alibaba 2.2.7 版本正式发布

作者 | 铖朴什么是 Spring Cloud Alibaba?1、简介Spring Cloud Alibaba 是由阿里巴巴(后文简称:阿里)中间件团队于 2018 年 7 月开源,为业界提供的一套基于阿里内部分布式技术的一站式微服务构建解决方案。基于 Spring Cloud 微服务框架标准,针对微服务架构中的服务注册与发现、分布式消息、服务限流降级以及分布式事务等核心模块,都提供了相应的面向业界的成熟解决方案,与 Spring Cloud 之间的关系如下图所示:依托 Spring Cloud Alibaba,用户仅需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建稳定可靠的分布式应用系统。2、主要功能在 Spring Cloud 众多的实现方案中,Spring Cloud Alibaba 凭借其支持组件最多,方案最完善,在 Spring Cloud 生态家族中扮演了重要角色。Spring Cloud Alibaba 与 Spring Cloud 生态其他方案之间对比图如下:Spring Cloud Alibaba 所提供的一套微服务系统构建解决方案组件如下:Nacos:阿里开源的一款易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Sentinel:阿里开源的一款限流降级产品,将流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。RocketMQ:阿里捐献给 Apache 基金会的一款分布式消息产品,是一个基于 Java 的高性能、高吞吐量的分布式消息和流计算平台。Dubbo:阿里捐献给 Apache 基金会的一款高性能的 Java RPC 框架。Seata:阿里开源的一套易于使用的高性能微服务分布式事务解决方案。Alibaba Cloud OSS:阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。Alibaba Cloud SchedulerX:阿里中间件团队开发的一款分布式任务调度产品,支持周期性的任务与固定时间点触发任务。Alibaba Cloud SMS:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。3、快速上手为了让广大开发者,快速学习与上手。项目维护团队于 2020 年 12 月,联合阿里云知行实验室推出了 Spring Cloud Alibaba 入门系列课程与 Java 工程脚手架工具,方便让广大开发同学快速了解和构建 Spring Cloud Alibaba 项目。Spring Cloud Alibaba 入门系列课程可在知行实验室首页获取:基于阿里云 Java 脚手架,开发者可告别复杂的依赖管理,通过脚手架工具选择所需依赖,便可生成包含相关依赖的项目模板供开发者下载使用。相关项目构建过程如下图所示:新版本特性预览介绍完 Spring Cloud Alibaba 后,本次隆重发布的 Spring Cloud Alibaba 2.2.7 版本对其中包括注册配置中心、分布式消息等在内的众多组件进行重大升级:Nacos:升级 Nacos 客户端到 2.0 版本,注册发现过程支持 gRPC 长链接,可显著降低资源开销,提高系统吞吐量,在性能上有大幅提升。更多细节可参见Nacos 2.0 介绍资料。RocketMQ:将之前项目中的 RocketMQ 单独分支融入到了项目主分支,跟随大版本一起发布迭代,使用户可在最新 Spring Cloud Alibaba 中直接使用 RocketMQ 新支持的批量消息、异步消息回调处理、Push 模式下指定消费起始位等众多新特性。Spring Boot:升级 Spring Boot 版本到 2.3.12,相比于之前的 2.3.2,不仅升级了大量底层组件的依赖增加了一些新特性,并修复了很多遗留问题,提高了框架稳定性。Spring Cloud:升级 Spring Cloud 版本到 Hoxton.SR12,相比于之前的 Hoxton.SR9 在基础组件的稳定性方面有了进一步提升。除了组件升级,另外也修复了很多之前版本所存在的问题,进一步提升了 Spring Cloud Alibaba 使用的稳定性与健壮性。更多资料可参见发版公告。Spring Cloud Alibaba 与 Spring Cloud 和 Spring Boot 当前各版本对应关系可参见官网 Wiki 版本说明。回顾与展望经过三年多的飞速发展,截止到当前,Spring Cloud Alibaba 共发布了 26 个版本,在GitHub上的累计 star 数目超过了 2W,folk 数达到了 6.4k,用户数达到了 19.4k 之多,各项关键数据遥遥领先国内外各大云厂商推出的同类开源微服务项目。除了支撑阿里巴巴经济体日常复杂的微服务应用场景,Spring Cloud Alibaba也被数千家外部企业用户在生产场景中广泛使用。未来 Spring Cloud Alibaba 会继续对齐 Spring Cloud 主流版本发展演进,近期会同时支持以 Spring Cloud 2020.0.X 和 Hoxton 两个当前主流版本对应的 Spring Cloud Alibaba 2021.X 和 2.2.X 版本迭代。社区未来初步规划会持续在完善当前所支持的 Nacos、RocketMQ 和 Spring Cloud Dubbo 等组件的稳定性与丰富组件所支持的功能上持续努力。(也欢迎大家提 issue 告诉社区你所认为项目值得演进的具体方向哈:)最后,作为一个业界知名开源项目,未来发展还需要持续依托社区大家共同的努力,也非常欢迎新同学的加入!只要能贡献 3~5 次社区认可具有价值的 Pull requests,即可有机会被邀请成为社区 Collaborator,共同主导未来社区发展建设!Spring Cloud Alibaba 企业版除了开源的 Spring Cloud Alibaba 以外,针对企业级用户复杂繁重的微服务治理诉求,阿里云中间件团队推出的阿里云微服务引擎(Microservices Engine,MSE)提供了包括全链路灰度、无损上下线、服务预热、离群实例摘除等在内的大量企业级微服务治理功能,让用户可不改一行代码即可将应用接入 MSE 便捷、低成本地拥有企业级微服务治理能力。除了微服务治理,MSE 还提供了企业级的 Nacos 注册配置中心和企业级云原生网关等众多产品,帮助企业用户迅速拥抱云原生微服务。点击了解更多 Spring Cloud Alibaba 企业版相关内容:https://www.aliyun.com/product/aliware/mse

RocketMQ Streams:将轻量级实时计算引擎融合进消息系统

作者 | 袁小栋、程君杰随着各行各业移动互联和云计算技术的普及发展,大数据计算已深入人心,最常见的比如 flink、spark 等。这些大数据框架,采用中心化的 Master-Slave 架构,依赖和部署比较重,每个任务也有较大开销,有较大的使用成本。RocketMQ Streams 着重打造轻量计算引擎,除了消息队列,无额外依赖,对过滤场景做了大量优化,性能提升 3-5 倍,资源节省 50%-80%。RocketMQ Streams 适合大数据量->高过滤->轻窗口计算的场景,核心打造轻资源,高性能优势,在资源敏感场景中有很大优势,最低 1core,1g 可部署,建议的应用场景(安全,风控,边缘计算,消息队列流计算)。RocketMQ Streams 兼容 Blink(Flink 的阿里内部版本) 的 SQL,UDF/UDTF/UDAF,多数 Blink 任务可以直接迁移成 RocketMQ Streams 任务。将来还会发布和 Flink 的融合版本,RocketMQ Streams 可以直接发布成 Flink 任务,既可以享有 RocketMQ Streams 带来的高性能、轻资源,还可以和现有的 Flink 任务统一运维和管理。什么是 RocketMQ Streams?本章节从基础简介、设计思路和特点三方面对 RocketMQ Streams 进行整体介绍。1、RocketMQ Streams 简介1)它是一个 Lib 包,启动即运行,和业务直接集成;2)它具备 SQL 引擎能力,兼容 Blink SQL 语法,兼容 Blink UDF/UDTF/UDAF;3)它包含 ETL 引擎,可以无编码实现数据的 ETL、过滤和转存;4)它基于数据开发 SDK,大量实用组件可直接使用,如:Source、sink、script、filter、lease、scheduler、configurable 不局限流的场景。2、RocketMQ Streams 的特点RocketMQ streams 基于上述的实现思路,可以看到它有以下几个特点:轻量1 核 1g 就可以部署,依赖较轻,在测试场景下用 Jar 包直接写个 main 方法就可以运行,在正式环境下最多依赖消息队列和存储(其中存储是可选的,主要是为了分片切换时的容错)。高性能实现高过滤优化器,包括前置指纹过滤,同源规则自动归并,hyperscan 加速,表达式指纹等,比优化前性能提升 3-5 倍,资源节省 50%以上。维表 JOIN(千万数据量维表支持)设计高压缩内存存储数据,无 java 头部和对齐的开销,存储接近原始数据大小,纯内存操作,性能最大化,同时对于 Mysql 提供了多线程并发加载,提高加载维表的速度。高扩展的能力1)Source 可按需扩展,已实现:RocketMQ,File,Kafka;2)Sink 可按需扩展,已实现:RocketMQ,File,Kafka,Mysql,ES;3)可按 Blink 规范扩展 UDF/UDTF/UDAF;4)提供了更轻的 UDF/UDTF 扩展能力,不需要任何依赖就可以完成函数的扩展。提供了丰富的大数据的能力包括精确计算一次灵活的窗口,双流 join,统计,开窗,各种转换过滤,满足大数据开发的各种场景,支持弹性容错的能力。RocketMQ Streams的使用RocketMQ Streams 对外提供两种 SDK,一种是 DSL SDK,一种是 SQL SDK,用户可以按需选择;DSL SDK 支持实时场景 DSL 语义;SQL SDK 兼容 Blink(Flink 的阿里内部版本) SQL 的语法,多数 Blink SQL 可以通过 RocketMQ Streams 运行。接下来,我们详细的介绍一下这两种 SDK。01、环境要求1)JDK 1.8 版本以上;2)Maven 3.2 版本以上。022、DSL SDK利用 DSL SDK 开发实时任务时,需要做如下的一些准备工作:依赖准备<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-streams-clients</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>准备工作完成后,就可以直接开发自己的实时程序。代码开发DataStreamSource source=StreamBuilder.dataStream("namespace","pipeline"); source.fromFile("~/admin/data/text.txt",false) .map(message->message + "--") .toPrint(1) .start();其中:1)Namespace 是业务隔离的,相同的业务可以写成相同的Namespace。相同的Namespace 在任务调度里可以跑在进程里,也可以共享一些配置;2)pipelineName 可以理解成就是 job name ,唯一区分 job;3)DataStreamSource 主要是创建 Source,然后这个程序运行起来,最终的结果就是在原始的消息里面会加"--",然后把它打印出来。丰富的算子RocketMQ streams 提供了丰富的算子, 包括:1)source 算子:包括 fromFile、fromRocketMQ、fromKafka 以及可以自定义 source 来源的 from 算子;2)sink 算子: 包括 toFile、toRocketMQ、toKafka、toDB、toPrint、toES 以及可以自定义 sink 的 to 算子;3)action 算子:包括 Filter、Expression、Script、selectFields、Union、forEach、Split、Select、Join、Window 等多个算子。部署执行基于 DSL SDK 完成开发,通过下面命令打成 jar 包,执行 jar,或直接执行任务的 main 方法。mvn -Prelease-all -DskipTests clean install -U java -jar jarName mainClass &03 3、SQL SDK依赖准备 <dependency> <groupId>com.alibaba</groupId> <artifactId>rsqldb-clients</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>代码开发首先开发业务逻辑代码, 可以保存为文件也可以直接使用文本:CREATE FUNCTION json_concat as 'xxx.xxx.JsonConcat'; CREATE TABLE `table_name` ( `scan_time` VARCHAR, `file_name` VARCHAR, `cmdline` VARCHAR, ) WITH ( type='file', filePath='/tmp/file.txt', isJsonData='true', msgIsJsonArray='false' -- 数据标准化 create view data_filter as select from ( select scan_time as logtime , lower(cmdline) as lower_cmdline , file_name as proc_name table_name where lower(proc_name) like '%.xxxxxx' or lower_cmdline like 'xxxxx%' or lower_cmdline like 'xxxxxxx%' or lower_cmdline like 'xxxx' or lower_cmdline like 'xxxxxx' CREATE TABLE `output` ( `logtime` VARCHAR , `lower_cmdline` VARCHAR , `proc_name` VARCHAR ) WITH ( type = 'print' insert into output select aegis_log_proc_format_raw ;其中:1)CREATE FUNCTION:引入外部的函数来支持业务逻辑, 包括 flink 以及系统函数;2)CREATE Table:创建 source/sink;3)CREATE VIEW:执行字段转化,拆分,过滤;4)INSERT INTO:数据写入 sink;5)函数:内置函数,udf 函数。SQL 扩展RocketMQ streams 支持三种 SQL 扩展能力,具体实现细节请看:1)通过 Blink UDF/UDTF/UDAF 扩展 SQL 能力;2)通过 RocketMQ streams 扩展 SQL 能力,只要实现函数名是 eval 的 java bean 即可;3)通过现有 java 代码扩展 SQL 能力,create function 函数名就是 java 类的方法名。SQL 执行你可以从下载最新的 RocketMQ Streams 代码并构建。cd rsqldb/ mvn -Prelease-all -DskipTests clean install -U cp rsqldb-runner/target/rocketmq-streams-sql-{版本号}-distribution.tar.gz 部署的目录解压 tar.gz 包, 进入目录结构tar -xvf rocketmq-streams-{版本号}-distribution.tar.gz cd rocketmq-streams-{版本号其目录结构如下:1)bin 指令目录,包括启动和停止指令2)conf 配置目录,包括日志配置以及应用的相关配置文件3)jobs 存放 sql,可以两级目录存储4)ext 存放扩展的 UDF/UDTF/UDAF/Source/Sink5)lib 依赖包目录6)log 日志目录执行 SQL#指定 sql 的路径,启动实时任务 bin/start-sql.sh sql_file_path执行多个 SQL如果想批量执行一批 SQL,可以把 SQL 放到 jobs 目录,最多可以有两层,把 sql 放到对应目录中,通过 start 指定子目录或 sql 执行任务。任务停止# 停止过程不加任何参数,则会将目前所有运行的任务同时停止 bin/stop.sh # 停止过程添加了任务名称, 则会将目前运行的所有同名的任务都全部停止 bin/stop.sh sqlname日志查看目前所有的运行日志都会存储在 log/catalina.out 文件中。架构设计及原理分析1、RocketMQ Streams设计思路在了解完  RocketMQ Streams 的基本简介,接下来,我们看下 RocketMQ Streams 的设计思路,设计思路主要从设计目标和策略两个方面来介绍:设计目标1)依赖少,部署简单,1 核 1g 单实例可部署,可随意扩展规模;2)打造场景优势,重点打造大数据量->高过滤->轻窗口计算的场景,功能覆盖度要全,实现需要的大数据特性:Exactly-ONCE、灵活的窗口(滚动、滑动、会话窗口);3)要在保持低资源的前提下,对高过滤有性能突破,打造性能优势;4)兼容 Blink SQL,UDF/UDTF/UDAF,让非技术人员更容易上手。策略(适配场景:大数据量>高过滤/ETL>低窗口计算)1)采用 shared-nothing 的分布式架构设计,依赖消息队列做负载均衡和容错机制,单实例可启动,增加实例实现能力扩展,并发能力取决于分片数;2)利用消息队列的分片做 shuffle,利用消息队列负载均衡实现容错;3)利用存储实现状态备份,实现 Exactly-ONCE 的语义。用结构化远程存储实现快速启动,不等本地存储恢复。4)重力打造过滤优化器,通过前置指纹过滤,同源规则自动归并,hyperscan 加速,表达式指纹提高过滤性能2、RocketMQ Streams Source 的实现1)Source 要求实现最少消费一次的语义,系统通过 checkpoint 系统消息实现,在提交 offset 前发送 checkpoint 消息,通知所有算子刷新内存。2)Source 支持分片的自动负载和容错数据源在分片移除时,发送移除系统消息,让算子完成分片清理工作;当有新分片时,发送新增分片消息,让算子完成分片初始化。3)数据源通过 start 方法,启动 consuemr 获取消息;4)原始消息经过编码,附加头部信息包装成 Message 投递给后续算子。3、RocketMQ Streams Sink 的实现1)Sink 是实时性和吞吐的一个结合;2)实现一个 sink 只要继承 AbstractSink 类实现 batchInsert 方法即可。batchInsert 的含义是一批数据写入存储,需要子类调用存储接口实现,尽量应用存储的批处理接口,提高吞吐;3)常规的使用方式是写 message->cache->flush->存储的方式,系统会严格保证每次批次写入存储的量不超过 batchsize 的量,如果超过了,会拆分成多批写入;4)Sink 有一个 cache,数据默认写 cache,批次写入存储,提高吞吐(一个分片一个 cache);5)可以开启自动刷新,每个分片会有一个线程,定时刷新 cache 数据到存储,提高实时性。实现类:DataSourceAutoFlushTask;6)通过调用 flush 方法刷新 cache 到存储;7)Sink 的 cache 会有内存保护,当 cache 的消息条数>batchSize,会强制刷新,释放内存。044、RocketMQ Streams Exactly-ONCE 实现1)Source 确保在 commit offset 时,会发送 checkpoint 系统消息,收到消息的组件会完成存盘操作,消息至少消费一次;2)每条消息会有消息头部,里面封装了 queueld 和 offset;3)组件在存储数据时,会把 queueld 和处理的最大 offset 存储下来,当有消息重复时,根据 maxoffset 去重;4)内存保护,一个 checkpoint 周期可能有多次 flush(条数触发),保障内存占用可控。5、RocketMQ Streams Window 实现方式1)支持滚动、滑动和会话窗口,支持事件时间和自然时间(消息进入算子的时间);2)支持 Emit 语法,可以在触发前或触发后,每隔 n 段时间,更新一次数据;比如1小时窗口,窗口触发前希望每分钟看到最新结果,窗口触发后希望不丢失迟到一天内的数据,且每 10 分钟更新数据。3)支持高性能模式和高可靠模式,高性能模式不依赖远程存储,但在分片切换时,有丢失窗数据的风险;4)快速启动,无需等待本地存储恢复,在发生错误或分片切换时,异步从远程存储恢复数据,同时直接访问远程存储计算;5)利用消息队列负载均衡,实现扩容缩容容,每个 queue 是一份组,一个分组同一刻只被一台机器消费;6)正常计算依赖本地存储,具备 flink 相似的计算性能。RocketMQ Streams 在安全场景的最佳实践011、背景从公共云转战专有云,遇到了新的问题。因为专有云像大数据这种 SaaS 服务是非必须输出的,且最小输出规模也比较大,用户成本会增加很多,难落地,导致安全能力无法快速同步到专有云。022、解决办法RocketMQ Streams 在云安全的应用-流计算1)基于安全场景打造轻量级计算引擎,基于安全高过滤的场景特点,可以针对高过滤场景优化,然后再做较重的统计、窗口、join 操作,因为过滤率比较高,可以用更轻的方案实现统计和 join 操作;2)SQL 和引擎都可热升级。业务结果1)规则覆盖:自建引擎,覆盖 100%规则(正则、join、统计);2)轻资源,内存是公共云引擎的 1/24,cpu 是 1/6,依赖过滤优化器,资源不随规则线性增加,新增规则无资源压力,通过高压缩表,支持千万情报;3)SQL 发布,通过 c/s 部署模式,SQL 引擎热发布,尤其护网场景,可快速上线规则;4)性能优化,对核心组件进行专题性能优化,保持高性能,每实例(2g,4 核,41 规则)5000qps 以上。RocketMQ Streams 的未来规划1、打造 RocketMQ 一体化计算能力1)和 RocketMQ 整合,去除 DB 依赖,融合 RocketMQ KV;2)和 RocketMQ 混部,支持本地计算,利用本地特点,打造高性能;3)打造边缘计算最佳实践022、Connector 增强1)支持 pull 消费方式,checkpoint 异步刷新;2)兼容 blink/flink connector。033、ETL 能力建设1)增加文件,syslog 的数据接入能力;2)兼容 Grok 解析,增加常用日志的解析能力;3)打造日志 ETL 的最佳实践044、稳定性和易用性打造1)Window 多场景测试,提升稳定性,性能优化;2)补充测试用例,文档,应用场景。开源地址RocketMQ-Streams:https://github.com/apache/rocketmq-streamsRocketMQ-Streams-SQL:https://github.com/alibaba/rsqldb以上是本次对 RocketMQ Stream 的整体介绍,希望对大家有所帮助和启发。

RocketMQ Streams:将轻量级实时计算引擎融合进消息系统

作者 | 袁小栋、程君杰随着各行各业移动互联和云计算技术的普及发展,大数据计算已深入人心,最常见的比如 flink、spark 等。这些大数据框架,采用中心化的 Master-Slave 架构,依赖和部署比较重,每个任务也有较大开销,有较大的使用成本。RocketMQ Streams 着重打造轻量计算引擎,除了消息队列,无额外依赖,对过滤场景做了大量优化,性能提升 3-5 倍,资源节省 50%-80%。RocketMQ Streams 适合大数据量->高过滤->轻窗口计算的场景,核心打造轻资源,高性能优势,在资源敏感场景中有很大优势,最低 1core,1g 可部署,建议的应用场景(安全,风控,边缘计算,消息队列流计算)。RocketMQ Streams 兼容 Blink(Flink 的阿里内部版本) 的 SQL,UDF/UDTF/UDAF,多数 Blink 任务可以直接迁移成 RocketMQ Streams 任务。将来还会发布和 Flink 的融合版本,RocketMQ Streams 可以直接发布成 Flink 任务,既可以享有 RocketMQ Streams 带来的高性能、轻资源,还可以和现有的 Flink 任务统一运维和管理。什么是 RocketMQ Streams?本章节从基础简介、设计思路和特点三方面对 RocketMQ Streams 进行整体介绍。1、RocketMQ Streams 简介1)它是一个 Lib 包,启动即运行,和业务直接集成;2)它具备 SQL 引擎能力,兼容 Blink SQL 语法,兼容 Blink UDF/UDTF/UDAF;3)它包含 ETL 引擎,可以无编码实现数据的 ETL、过滤和转存;4)它基于数据开发 SDK,大量实用组件可直接使用,如:Source、sink、script、filter、lease、scheduler、configurable 不局限流的场景。2、RocketMQ Streams 的特点RocketMQ streams 基于上述的实现思路,可以看到它有以下几个特点:轻量1 核 1g 就可以部署,依赖较轻,在测试场景下用 Jar 包直接写个 main 方法就可以运行,在正式环境下最多依赖消息队列和存储(其中存储是可选的,主要是为了分片切换时的容错)。高性能实现高过滤优化器,包括前置指纹过滤,同源规则自动归并,hyperscan 加速,表达式指纹等,比优化前性能提升 3-5 倍,资源节省 50%以上。维表 JOIN(千万数据量维表支持)设计高压缩内存存储数据,无 java 头部和对齐的开销,存储接近原始数据大小,纯内存操作,性能最大化,同时对于 Mysql 提供了多线程并发加载,提高加载维表的速度。高扩展的能力1)Source 可按需扩展,已实现:RocketMQ,File,Kafka;2)Sink 可按需扩展,已实现:RocketMQ,File,Kafka,Mysql,ES;3)可按 Blink 规范扩展 UDF/UDTF/UDAF;4)提供了更轻的 UDF/UDTF 扩展能力,不需要任何依赖就可以完成函数的扩展。提供了丰富的大数据的能力包括精确计算一次灵活的窗口,双流 join,统计,开窗,各种转换过滤,满足大数据开发的各种场景,支持弹性容错的能力。RocketMQ Streams的使用RocketMQ Streams 对外提供两种 SDK,一种是 DSL SDK,一种是 SQL SDK,用户可以按需选择;DSL SDK 支持实时场景 DSL 语义;SQL SDK 兼容 Blink(Flink 的阿里内部版本) SQL 的语法,多数 Blink SQL 可以通过 RocketMQ Streams 运行。接下来,我们详细的介绍一下这两种 SDK。01、环境要求1)JDK 1.8 版本以上;2)Maven 3.2 版本以上。022、DSL SDK利用 DSL SDK 开发实时任务时,需要做如下的一些准备工作:依赖准备<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-streams-clients</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>准备工作完成后,就可以直接开发自己的实时程序。代码开发DataStreamSource source=StreamBuilder.dataStream("namespace","pipeline"); source.fromFile("~/admin/data/text.txt",false) .map(message->message + "--") .toPrint(1) .start();其中:1)Namespace 是业务隔离的,相同的业务可以写成相同的Namespace。相同的Namespace 在任务调度里可以跑在进程里,也可以共享一些配置;2)pipelineName 可以理解成就是 job name ,唯一区分 job;3)DataStreamSource 主要是创建 Source,然后这个程序运行起来,最终的结果就是在原始的消息里面会加"--",然后把它打印出来。丰富的算子RocketMQ streams 提供了丰富的算子, 包括:1)source 算子:包括 fromFile、fromRocketMQ、fromKafka 以及可以自定义 source 来源的 from 算子;2)sink 算子: 包括 toFile、toRocketMQ、toKafka、toDB、toPrint、toES 以及可以自定义 sink 的 to 算子;3)action 算子:包括 Filter、Expression、Script、selectFields、Union、forEach、Split、Select、Join、Window 等多个算子。部署执行基于 DSL SDK 完成开发,通过下面命令打成 jar 包,执行 jar,或直接执行任务的 main 方法。mvn -Prelease-all -DskipTests clean install -U java -jar jarName mainClass &03 3、SQL SDK依赖准备 <dependency> <groupId>com.alibaba</groupId> <artifactId>rsqldb-clients</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>代码开发首先开发业务逻辑代码, 可以保存为文件也可以直接使用文本:CREATE FUNCTION json_concat as 'xxx.xxx.JsonConcat'; CREATE TABLE `table_name` ( `scan_time` VARCHAR, `file_name` VARCHAR, `cmdline` VARCHAR, ) WITH ( type='file', filePath='/tmp/file.txt', isJsonData='true', msgIsJsonArray='false' -- 数据标准化 create view data_filter as select from ( select scan_time as logtime , lower(cmdline) as lower_cmdline , file_name as proc_name table_name where lower(proc_name) like '%.xxxxxx' or lower_cmdline like 'xxxxx%' or lower_cmdline like 'xxxxxxx%' or lower_cmdline like 'xxxx' or lower_cmdline like 'xxxxxx' CREATE TABLE `output` ( `logtime` VARCHAR , `lower_cmdline` VARCHAR , `proc_name` VARCHAR ) WITH ( type = 'print' insert into output select aegis_log_proc_format_raw ;其中:1)CREATE FUNCTION:引入外部的函数来支持业务逻辑, 包括 flink 以及系统函数;2)CREATE Table:创建 source/sink;3)CREATE VIEW:执行字段转化,拆分,过滤;4)INSERT INTO:数据写入 sink;5)函数:内置函数,udf 函数。SQL 扩展RocketMQ streams 支持三种 SQL 扩展能力,具体实现细节请看:1)通过 Blink UDF/UDTF/UDAF 扩展 SQL 能力;2)通过 RocketMQ streams 扩展 SQL 能力,只要实现函数名是 eval 的 java bean 即可;3)通过现有 java 代码扩展 SQL 能力,create function 函数名就是 java 类的方法名。SQL 执行你可以从下载最新的 RocketMQ Streams 代码并构建。cd rsqldb/ mvn -Prelease-all -DskipTests clean install -U cp rsqldb-runner/target/rocketmq-streams-sql-{版本号}-distribution.tar.gz 部署的目录解压 tar.gz 包, 进入目录结构tar -xvf rocketmq-streams-{版本号}-distribution.tar.gz cd rocketmq-streams-{版本号其目录结构如下:1)bin 指令目录,包括启动和停止指令2)conf 配置目录,包括日志配置以及应用的相关配置文件3)jobs 存放 sql,可以两级目录存储4)ext 存放扩展的 UDF/UDTF/UDAF/Source/Sink5)lib 依赖包目录6)log 日志目录执行 SQL#指定 sql 的路径,启动实时任务 bin/start-sql.sh sql_file_path执行多个 SQL如果想批量执行一批 SQL,可以把 SQL 放到 jobs 目录,最多可以有两层,把 sql 放到对应目录中,通过 start 指定子目录或 sql 执行任务。任务停止# 停止过程不加任何参数,则会将目前所有运行的任务同时停止 bin/stop.sh # 停止过程添加了任务名称, 则会将目前运行的所有同名的任务都全部停止 bin/stop.sh sqlname日志查看目前所有的运行日志都会存储在 log/catalina.out 文件中。架构设计及原理分析1、RocketMQ Streams设计思路在了解完  RocketMQ Streams 的基本简介,接下来,我们看下 RocketMQ Streams 的设计思路,设计思路主要从设计目标和策略两个方面来介绍:设计目标1)依赖少,部署简单,1 核 1g 单实例可部署,可随意扩展规模;2)打造场景优势,重点打造大数据量->高过滤->轻窗口计算的场景,功能覆盖度要全,实现需要的大数据特性:Exactly-ONCE、灵活的窗口(滚动、滑动、会话窗口);3)要在保持低资源的前提下,对高过滤有性能突破,打造性能优势;4)兼容 Blink SQL,UDF/UDTF/UDAF,让非技术人员更容易上手。策略(适配场景:大数据量>高过滤/ETL>低窗口计算)1)采用 shared-nothing 的分布式架构设计,依赖消息队列做负载均衡和容错机制,单实例可启动,增加实例实现能力扩展,并发能力取决于分片数;2)利用消息队列的分片做 shuffle,利用消息队列负载均衡实现容错;3)利用存储实现状态备份,实现 Exactly-ONCE 的语义。用结构化远程存储实现快速启动,不等本地存储恢复。4)重力打造过滤优化器,通过前置指纹过滤,同源规则自动归并,hyperscan 加速,表达式指纹提高过滤性能2、RocketMQ Streams Source 的实现1)Source 要求实现最少消费一次的语义,系统通过 checkpoint 系统消息实现,在提交 offset 前发送 checkpoint 消息,通知所有算子刷新内存。2)Source 支持分片的自动负载和容错数据源在分片移除时,发送移除系统消息,让算子完成分片清理工作;当有新分片时,发送新增分片消息,让算子完成分片初始化。3)数据源通过 start 方法,启动 consuemr 获取消息;4)原始消息经过编码,附加头部信息包装成 Message 投递给后续算子。3、RocketMQ Streams Sink 的实现1)Sink 是实时性和吞吐的一个结合;2)实现一个 sink 只要继承 AbstractSink 类实现 batchInsert 方法即可。batchInsert 的含义是一批数据写入存储,需要子类调用存储接口实现,尽量应用存储的批处理接口,提高吞吐;3)常规的使用方式是写 message->cache->flush->存储的方式,系统会严格保证每次批次写入存储的量不超过 batchsize 的量,如果超过了,会拆分成多批写入;4)Sink 有一个 cache,数据默认写 cache,批次写入存储,提高吞吐(一个分片一个 cache);5)可以开启自动刷新,每个分片会有一个线程,定时刷新 cache 数据到存储,提高实时性。实现类:DataSourceAutoFlushTask;6)通过调用 flush 方法刷新 cache 到存储;7)Sink 的 cache 会有内存保护,当 cache 的消息条数>batchSize,会强制刷新,释放内存。044、RocketMQ Streams Exactly-ONCE 实现1)Source 确保在 commit offset 时,会发送 checkpoint 系统消息,收到消息的组件会完成存盘操作,消息至少消费一次;2)每条消息会有消息头部,里面封装了 queueld 和 offset;3)组件在存储数据时,会把 queueld 和处理的最大 offset 存储下来,当有消息重复时,根据 maxoffset 去重;4)内存保护,一个 checkpoint 周期可能有多次 flush(条数触发),保障内存占用可控。5、RocketMQ Streams Window 实现方式1)支持滚动、滑动和会话窗口,支持事件时间和自然时间(消息进入算子的时间);2)支持 Emit 语法,可以在触发前或触发后,每隔 n 段时间,更新一次数据;比如1小时窗口,窗口触发前希望每分钟看到最新结果,窗口触发后希望不丢失迟到一天内的数据,且每 10 分钟更新数据。3)支持高性能模式和高可靠模式,高性能模式不依赖远程存储,但在分片切换时,有丢失窗数据的风险;4)快速启动,无需等待本地存储恢复,在发生错误或分片切换时,异步从远程存储恢复数据,同时直接访问远程存储计算;5)利用消息队列负载均衡,实现扩容缩容容,每个 queue 是一份组,一个分组同一刻只被一台机器消费;6)正常计算依赖本地存储,具备 flink 相似的计算性能。RocketMQ Streams 在安全场景的最佳实践011、背景从公共云转战专有云,遇到了新的问题。因为专有云像大数据这种 SaaS 服务是非必须输出的,且最小输出规模也比较大,用户成本会增加很多,难落地,导致安全能力无法快速同步到专有云。022、解决办法RocketMQ Streams 在云安全的应用-流计算1)基于安全场景打造轻量级计算引擎,基于安全高过滤的场景特点,可以针对高过滤场景优化,然后再做较重的统计、窗口、join 操作,因为过滤率比较高,可以用更轻的方案实现统计和 join 操作;2)SQL 和引擎都可热升级。业务结果1)规则覆盖:自建引擎,覆盖 100%规则(正则、join、统计);2)轻资源,内存是公共云引擎的 1/24,cpu 是 1/6,依赖过滤优化器,资源不随规则线性增加,新增规则无资源压力,通过高压缩表,支持千万情报;3)SQL 发布,通过 c/s 部署模式,SQL 引擎热发布,尤其护网场景,可快速上线规则;4)性能优化,对核心组件进行专题性能优化,保持高性能,每实例(2g,4 核,41 规则)5000qps 以上。RocketMQ Streams 的未来规划1、打造 RocketMQ 一体化计算能力1)和 RocketMQ 整合,去除 DB 依赖,融合 RocketMQ KV;2)和 RocketMQ 混部,支持本地计算,利用本地特点,打造高性能;3)打造边缘计算最佳实践022、Connector 增强1)支持 pull 消费方式,checkpoint 异步刷新;2)兼容 blink/flink connector。033、ETL 能力建设1)增加文件,syslog 的数据接入能力;2)兼容 Grok 解析,增加常用日志的解析能力;3)打造日志 ETL 的最佳实践044、稳定性和易用性打造1)Window 多场景测试,提升稳定性,性能优化;2)补充测试用例,文档,应用场景。开源地址RocketMQ-Streams:https://github.com/apache/rocketmq-streamsRocketMQ-Streams-SQL:https://github.com/alibaba/rsqldb以上是本次对 RocketMQ Stream 的整体介绍,希望对大家有所帮助和启发。

作业帮检索服务基于 Fluid 的计算存储分离实践

作者 | 董晓聪、张浩然引言:Fluid 是云原生基金会 CNCF 下的云原生数据编排和加速项目,由南京大学、阿里云及 Alluxio 社区联合发起并开源。本文主要介绍 Fluid 在作业帮检索服务下计算存储分离架构中的应用实践,基于 Fluid 的计算存储分离架构,作业帮显著够显著降低了大规模检索系统类服务的复杂度,成功实现分钟级百 T 级别的数据分发、原子性的数据版本管理和数据更新,并使检索服务能够像正常无状态服务一样,轻松通过 K8s HPA 实现横向扩展,为服务带来更高的稳定性和可用性。大规模检索系统一直都是各个公司平台业务的底层基石,往往是以千台裸金属服务器级别的超大规模集群的方式运行,数据量巨大,对于性能、吞吐、稳定性要求极为苛刻,故障容忍度很低。除了运行层面外,超大规模集群和海量数据场景下的数据迭代和服务治理也往往是一个巨大的挑战:增量和全量的数据分发效率,短期和长期的热点数据追踪等都是需要深入研究的问题。本文将介绍作业帮内部设计实现的基于 fluid 计算存储分离架构,能够显著降低大规模检索系统类服务的复杂度,使得大规模检索系统可以像正常在线业务一样平滑管理。大规模检索系统所面临的问题作业帮的众多学习资料智能分析和搜索功能中都依赖于大规模数据检索系统,我们的集群规模在千台以上,总数据量在百 TB 级别以上,整个系统由若干分片组成,每个分片由若干服务器加载相同的数据集,运行层面上我们要求性能达到 P99 1.Xms,吞吐量高峰百 GB 级,稳定性要求 99.999%以上。以往环境中为了提高数据读取效率和稳定性,更多的在考虑数据本地化存储,我们的检索系统每日产生索引项并需要进行 TB 级别的数据更新,这些数据通过离线建库服务产出之后,需要分别更新到对应的分片中,这种模式下带来了许多其他挑战,比较关键的问题集中在数据迭代和扩展性上:1、数据集合的离散:由于实际运行中,每个分片的每个节点都需要复制下来本分片所有数据,由此带来了同步数据下发困难的问题。实际运行中如果要同步数据到单服务器节点,需要使用分级下发,先下发一级(十级)由一级分发给二级(百级)再分发给三级(千级),这个分发周期长且需要层层校验来保证数据准确性。2、业务资源弹性扩缩较弱:原先的系统架构采用的是计算和存储紧耦合,数据存储和算力资源紧密捆绑,资源灵活扩展能力不高,扩容往往需要以小时为单位进行,缺乏应对突发峰值流量扩容能力。3、单分片数据扩展性不足:单分片数据上限受分片集群内的单机存储上限限制。如果达到存储上限,往往需要拆分数据集,而这种拆分不是由业务需求驱动的。而数据迭代和扩展性的问题又不得不带来了成本压力和自动化流程上的薄弱。通过对检索系统运行和数据更新流程的分析,当前面临的关键问题是由于计算和存储的耦合所带来的,因此我们考虑如何去解耦计算和存储,只有引入计算存储分离的架构才能够从根本上解决复杂度的问题。计算存储分离最主要的就是将每个节点存储本分片全量数据的方式拆分开,将分片内的数据存储在逻辑上的远程机器上 但是计算存储分离又带来了其他的问题,比如稳定性问题,大数据量下的读取方式和读取速度,对业务的入侵程度等等问题,虽然存在这些问题,但是这些问题都是可解决以及易解决的 基于此我们确认计算存储分离一定是该场景下的良方,可以从根本上解决系统复杂度的问题。计算存储分离架构解决复杂度问题为了解决上述计算存储分离所需要考虑的问题,新的计算存储分离架构必须能达到以下目标:1、读取的稳定性,计算存储分离终究是通过各种组件配合替换掉了原始文件读取,数据加载方式可以替换,但是数据读取的稳定性依然需要和原始保持同等水平。2、每个分片千节点同时数据更新场景下,需要最大限度的提升读取速度,同时对网络的压力需要控制在一定程度内。3、支持通过 POSIX 接口读取数据,POSIX 是最具备对各种业务场景的适应性的方式,这样无需侵入业务场景下,屏蔽了下游变动对上游的影响。4、数据迭代的流程的可控性,对于在线业务来说,数据的迭代理应被视为和服务迭代等同的 cd 流程,那么数据迭代的可控性就及其重要,因为本身就是 cd 流程的一部分。5、数据集合的可伸缩性,新的架构需要是一套可复制,易扩展的模式,这样才能面对数据集合的伸缩、集群规模的伸缩具备良好的应对能力。为了达成上述目标,我们最终选用了 Fluid 开源项目作为整个新架构的关键纽带。组件介绍Fluid 是一个开源的 Kubernetes 原生的分布式数据集编排和加速引擎,由南京大学、阿里云及 Alluxio 社区开源,主要服务于云原生场景下的数据密集型应用,例如大数据应用、AI 应用等。通过 Kubernetes 服务提供的数据层抽象,可以让数据像流体一样在诸如 HDFS、OSS、Ceph 等存储源和 Kubernetes 上层云原生应用计算之间灵活高效地移动、复制、驱逐、转换和管理。而具体数据操作对用户透明,用户不必再担心访问远端数据的效率、管理数据源的便捷性,以及如何帮助 Kuberntes 做出运维调度决策等问题。用户只需以最自然的 Kubernetes 原生数据卷方式直接访问抽象出来的数据,剩余任务和底层细节全部交给 Fluid 处理。Fluid 项目当前主要关注数据集编排和应用编排这两个重要场景。数据集编排可以将指定数据集的数据缓存到指定特性的 Kubernetes 节点,而应用编排将指定该应用调度到可以或已经存储了指定数据集的节点上。这两者还可以组合形成协同编排场景,即协同考虑数据集和应用需求进行节点资源调度。我们选择使用 Fluid 的原因1、检索服务已经完成容器化改造,天然适合 Fluid。2、Fluid 作为数据编排系统,使得上层无需知道具体的数据分布就可以直接使用,同时基于数据的感知调度能力,可以实现业务的就近调度,加速数据访问性能。3、Fluid 实现了 pvc 接口,使得业务 pod 可以无感知的挂载进入 pod 内部,让 pod 内可以像使用本地磁盘一样无感知 Fluid 提供元数据和数据分布式分层缓存,以及高效文件检索功能。4、Fluid+jindoruntime 内置了多种缓存模式(回源模式,全缓存模式),不同的缓存策略(针对小文件场景的优化等)和存储方式(磁盘,内存),对于不同的场景具备良好的适应性,无需太多修改即可满足多种业务场景。落地实践1、缓存节点和计算节点的分离: 虽然使用 fuse 和 worker 结合部署可以获得更好的数据本地性能,但是在在线场景下,我们最终选用了缓存和计算节点分离的方案,原因是通过延长一定的启动时间换来更优的弹性是值得的,以及我们并不希望业务节点稳定性问题和缓存节点的稳定性问题纠缠在一起。2、Fluid 支持 dataset 的可调度性,换言之就是缓存节点的可调度性,我们通过指定 dataset 的 nodeAffinity 来进行数据集缓存节点的调度,从而保证缓存节点可高效,弹性化的提供缓存服务。1、在线场景的高要求对于在线业务场景,鉴于系统对于数据的访问速度、完整性和一致性有较高的要求,因此不能出现数据的部分更新、非预期的回源请求等; 所以对数据缓存和更新策略的选择就会很关键。2、合适的数据缓存策略基于以上需求,我们选择使用 Fluid 的全缓存模式。在全缓存模式下,所有请求只会走缓存,而不在回源到数据源,这样就避免了非预期的长耗时请求。同时 dataload 的过程则由数据更新流程来把控,更安全和标准化。3、结合权限流的更新流程在线业务的数据更新也是属于 cd 的一种,同样也需要更新流程来管控,通过结合了权限流程的 dataload 模式,使得线上数据发版更安全和标准化。4、数据更新的原子性由于模型是由许多文件组成,只有所有的文件全部缓存起来之后,才是一份可以被使用的完整的模型;所以在全缓存无回源的前提下,就需要保证 dataload 过程的原子性, 在数据加载的过程中过,新版本数据不能被访问到,只有在数据加载完成之后,才可以读取到新版本数据。以上方案和策略配合我们自动化的建库和数据版本管理功能,大大提高了整体系统的安全性和稳定性,同时使得整个过程的流转更加智能和自动化。总结基于 Fluid 的计算存储分离架构,我们成功地实现了:1、分钟级百 T 级别的数据分发。2、数据版本管理和数据更新的原子性,使得数据分发和更新成为一种可管控,更智能的自动化流程。3、检索服务能够像正常无状态服务一样,从而能够轻松通过 k8s HPA 实现横向扩展,更快捷的扩缩带来了更高的稳定性和可用性。展望计算和存储分离的模式使得以往我们认为非常特殊的服务可以被无状态化,可以像正常服务一样被纳入 devops 体系中,而基于 Fluid 的数据编排和加速系统,则是实践计算和存储分离的一个切口,除了用于检索系统外,我们也在探索基于 Fluid 的 OCR 系统模型训练和分发的模式。在未来工作方面,我们计划继续基于 Fluid 优化上层作业的调度策略和执行模式,并进一步扩展模型训练和分发,提高整体训练速度和资源的利用率,另一方面也帮助社区不断演进其可观测性和高可用等,帮助到更多的开发者。作者介绍董晓聪:作业帮基础架构负责人,主要负责架构研发、运维、DBA、安全等工作。曾在百度、滴滴等公司负责架构和技术管理工作,擅长业务中台、技术中台、研发中台的搭建和迭代。张浩然:2019 年加入作业帮,作业帮基础架构-高级架构师,在作业帮期间,推动了作业帮云原生架构演进、负责多云 K8s 集群建设、K8s 组件研发、Linux 内核优化调优、底层服务容器化相关工作。

Dubbo-Admin 正式支持 3.0 服务治理

作者介绍程露,Java开发工程师,中间件开发爱好者,关注服务治理。严浩,Dubbo 贡献者,关注RPC、服务治理等领域。前言Dubbo 相信大家并不陌生,是一款微服务开发框架,它提供了 RPC 通信与微服务治理两大关键能力。大家在日常开发中更多使用的是 dubbo 提供的 RPC 通信这一部分能力,而对其提供的服务治理的能力使用相对少一些,本文的重点将放在服务治理这方面。dubbo 框架提供了极其丰富的服务治理的功能如流量控制、动态配置、服务 Mock、服务测试等功能,而 dubbo-admin 的作用在于将 dubbo 框架提供的服务治理能力提供一个开箱即用的平台。本文将介绍 dubbo-admin 所提供的功能,让大家快速了解和使用 dubbo-admin并对 dubbo 所提供的服务治理能力有个初步的了解。服务详情服务详情将以接口为维度展示 dubbo 服务所提供的服务信息,包含服务提供者、消费者信息和服务的元数据信息比如提供的方法名和参数列表。在最新版本支持了 dubbo 3.0 所提供的应用级发现模型,在注册来源用 应用级/接口级 进行区分。动态路由Dubbo-Admin 提供了三种路由的支持,分别是条件路由、标签路由、Mesh路由,所提供的功能可以轻松实现黑白名单、集群隔离、金丝雀发布等服务治理的诉求。下面将举例一一展示这一部分的功能。条件路由条件路由可以编写一些自定义路由规则实现服务治理的需求比如黑白名单、读写分离等。路由规则在发起一次RPC调用前起到过滤目标服务器地址的作用,过滤后的地址列表,将作为消费端最终发起RPC调用的备选地址。下图为一个简单的黑名单功能的实现,该路由规则的含义为禁止 IP 为 172.22.3.91 消费者调用服务 HelloService,条件路由规则的格式为:[服务消费者匹配条件] => [服务提供者匹配条件]。标签路由标签路由通过将某一个或多个服务的提供者划分到同一个分组,约束流量只在指定分组中流转,从而实现流量隔离的目的,可以作为蓝绿发布、灰度发布等场景的能力基础。在 provider 应用级别上创建规则,对应的静态打标为 dubbo.provider.tag=tag1 和 @DubboService(tag = "tag2")。Mesh路由Mesh路由是 dubbo 3.0 推出的全新的路由规则功能极其强大,使用mesh路由能够覆盖上诉两种路由的功能场景,并且还可以组合出更加复杂路由场景。Mesh路由将整个流量管理分成 VirtualService 和 DestinationRule 两部分,VirtualService 匹配入口流量,DestinationRule 匹配出口流量。下面将实现一个案例,通过对服务 HelloService 的 hi 方法通过入参 number 进行路由,实现入参为偶数的请求路由到 label 为 v1 的服务,入参为奇数的服务路由到 label 为 v2 的服务的功能。​public interface HelloService {​​   ​​    String hi(Integer number);​​​​​}​​服务实现返回服务提供方端口。​​public class HelloServiceImpl implements HelloService {​​​​​​​​​​    @Value("${dubbo.protocol.port}")​​​​    private String port;​​​​​​​​​​    @Override​​​​    public String hi(Integer number) {​​​​​​​​​​        return "hi " + number + ", my port is :" + port;​​​​    }​​​​}​​第一步:启动两个服务提供方参数分别为 port = 20883 、dubbo.application.parameters.test-version = v1 和 port = 20884 、dubbo.application.parameters.test-version = v2,通过 dubbo.application.parameters 定义的参数将会暴露到服务的URL上。​dubbo.application.parameters.test-version = v1​​dubbo.protocol.port=20883​第二步:创建 mesh路由规则,该路由规则定义了 VirtualService、DestinationRule 两部分。DestinationRule 部分将服务URL参数 test-version=v1 和 test-version=v2 分别划分为服务 v1 和 v2。VirtualService 则将匹配服务 HelloService#hi 方法的入参,将偶数路由到v1服务,奇数路由到 label 为 v2 的服务。​apiVersion: service.dubbo.apache.org/v1alpha1​​kind: VirtualService​​metadata:​​  name: demo/oddEvenRouter​​spec:​​  dubbo:​​  - routedetail:​​    - match:​​      - method:​​          argc: 1​​          args:​​          - index: 0​​            num_value:​​              oneof:​​              - exact: 0.0​​                mod: 2.0​​            type: int​​          name_match:​​            exact: hi​​      name: even-route​​      route:​​      - destination:​​          host: demo​​          subset: v1​​    - match:​​      - method:​​          argc: 1​​          args:​​          - index: 0​​            num_value:​​              oneof:​​              - exact: 1.0​​                mod: 2.0​​            type: int​​          name_match:​​            exact: hi​​      name: odd-route​​      route:​​      - destination:​​          host: demo2​​          subset: v2          ​​    services:​​    - exact: org.test.apache.dubbo.interfaces.HelloService                                ​​---​​apiVersion: service.dubbo.apache.org/v1alpha1​​kind: DestinationRule​​metadata:​​  name: test-route​​spec:​​  host: demo​​  subsets:​​    - name: v1​​      labels:​​        test-version: v1​​    - name: v2​​      labels:​​        test-version: v2​第三步:启动消费者进行测试,可以看见返回结果如我们期待的那样,通过上诉案例实现了一个简单的灰度功能,当然也可以轻松实现 A/B测试、金丝雀发布等功能。动态配置动态配置提供了无须重启可以动态调整 RPC 调用行为的一种能力。比如修改超时时间、权重、负载均衡策略调整、服务降级等。避免了为了调整 Dubbo 参数而需要重启服务的局面,下面将展示一些常见的参数调整情况。超时时间调整,超时时间调整为 6000 ms​configVersion: v2.7​​enabled: true​​configs: ​​  - addresses: [0.0.0.0]  # 0.0.0.0 for all addresses​​    side: consumer        # effective side, consumer or addresses​​    parameters: ​​      timeout: 6000       # dynamic config parameter​权重调整​configVersion: v2.7​​scope: application​​key: demo-provider​​enabled: true​​configs:​​- addresses: ["10.20.153.10:20880"]​​  side: provider​​  parameters:​​    weight: 200​负载策略调整​configVersion: v2.7​​scope: application​​key: demo-consumer​​enabled: true​​configs:​​- side: consumer​​  parameters:​​    loadbalance: random​文档与测试接口文档Dubbo-Api-Docs 是一个展示 dubbo 接口文档,测试接口的工具,相当于 swagger 对于 RESTful 风格的 Web 服务的作用。使用该功能需要 dubbo 服务引入相关包 dubbo-api-docs-annotations 和 dubbo-api-docs-core,使用使用通过注解的形式描述接口和参数信息。​<dependency>​​    <groupId>org.apache.dubbo</groupId>​​    <artifactId>dubbo-api-docs-annotations</artifactId>​​    <version>${dubbo-version}</version>​​</dependency>​​<dependency>​​    <groupId>org.apache.dubbo</groupId>​​    <artifactId>dubbo-api-docs-core</artifactId>​​    <version>${dubbo-version}</version>​​</dependency>​效果图如下服务测试服务测试相比 dubbo-api-docs 不需要引入任何依赖就能对 dubbo 服务进行测试,方便快速调整和验证 dubbo 服务,效果图如下:服务Mock服务Mock通过无代码嵌入的方式将Consumer对Provider的请求进行拦截,动态的对Consumer的请求进行放行或返回用户自定义的Mock数据。从而解决在前期开发过程中,Consumer所依赖的Provider未准备就绪时,造成Consumer开发方的阻塞问题。只需要以下两步,即可享受服务Mock功能带来的便捷:第一步:Consumer应用引入服务Mock依赖,添加JVM启动参数-Denable.dubbo.admin.mock=true开启服务Mock功能。​<denpendency>​​    <groupId>org.apache.dubbo.extensions</groupId>​​    <artifactId>dubbo-mock-admin</artifactId>​​    <version>last</version>​​</denpendency>​第二步:在Dubbo Admin中配置对应的Mock数据。小结本文介绍了 dubbo-admin 的大部分功能,覆盖开发、测试和线上整个阶段。希望本文能够给使用和入手 dubbo- admin 带来一些帮助,详细的使用细节还需要参考官网,也希望 dubbo-admin 能够给 dubbo 使用者带来一个全新的体验,更方便快速的使用 dubbo 所提供出来服务治理的能力。

互联网公司如何塑造一支有创业精神的技术团队?

作者 | 岩动01​引言我们经常会面对什么问题?在互联网公司带过技术团队的人,或多或少会遇到这样一些问题:1、 我们潜心研究的自认为高大上的项目成果,抬头看天的时候发现天已经变了,完全不能满足实际需要;2、面向高度竞争的赛道,我们有的业务很无情地被竞对逐步反超,或者在竞争中处于弱势,而且感觉很难突破;3、技术团队之间分工似乎永远都不那么清晰,而且不管中台怎么演化似乎永远也不能满足业务需要;4、总是感觉团队的效率很低,明明人才都不缺,就是各种掣肘,反倒跑得没有创业公司快;5、团队做事情提不起兴趣,既不能感觉到业务成就感,也感觉没有技术含量,离曾经的技术理想渐行渐远;6、当有满腔热情的高大上的技术理想,但是感觉有发挥不出来,始终在被繁琐的事情消磨时光等等。这些问题阿里的技术团队也会遇到,所以我们一直在思考到底发生了什么,我们应该怎么应对。我大概从时代背景和组织形势两个方面去找一些线索。02我们现在处于什么样的时代?要搞清楚这个问题,我们首先要看一下我们处于一个什么时代。我们身处的世界变化越来越快,知识边界不断被突破,信息的超饱和不断打破暂时达成平衡的局面。VUCA,是 Volatility(易变性)、Uncertainty(不确定性)、Complexity(复杂性)、Ambiguity(模糊性)的缩写,概括了后互联网时代商业世界的特征——一团乱麻。在各个领域,商业组织与个人,很容易发现自己处于烦絮的矛盾之中。      ——《哈佛商业评论》VUCA 时代已经到来,我们也不可避免的需要去面对 VUCA 的状况,这样就会发现很多情况:1、商业逻辑的复杂性越来越高,消费者、商家、平台、合作伙伴都会有诉求,考虑的角色和因素越来越多,商业链路越来越长,互联网的流量红利已经到了天花板,仅仅靠做一个售卖平台就可以解决问题的时代已经不存在了,赢得市场的方式越来越难;2、消费趋势,竞争形势,市场风向都处于不断变化性的过程中,我们很难再通过一种固定的打法和策略去赢得市场,就像零售的业态,一直在不断演化和升级;3、在面向未来的商业模式探索,竞对的参与,市场格局的变化过程中,项目的不确定性是比较高的,是否会失败,或者最终通过哪个方向成功,都存在不确定性,比如,是否存在一种效率最优的零售模式?这些 VUCA 的特征都会传导到技术团队,如果我们还在用以前平台化、确定性、单一性的思路去作战,会有非常多的不适应感。03组织成长上我们应该注意到什么趋势?1、协同的复杂性:随着公司组织规模的扩大,组织结构也变得越来越复杂,业务线,产品,技术,职能团队,各种上游和下游,一个项目运作协同的团队非常多,大家优先级可能对不齐,合作的时候各有各的目标,不可避免地存在组织内耗,相互踩脚;2、团队内部管理的复杂性:新的 90 后、95 后逐步登上舞台,他们更加活跃,追求工作的兴趣和快乐;新人与老人的交叉,职业诉求不完全相同;公司外部信息量很多很杂,包括一些负面的诸如内卷,PUA 之类的负面消息;同时外面诱惑很多,给我们的组织成长提出了新的挑战。04我们选择用“创业精神”来解决技术竞争力和组织能力激活的挑战在时代背景的变化和组织成长的新的形势下,我们有没有办法践行一套新的思路,来重新激活我们的团队?   在同城零售创业的这段时间,我们一直在思考和探索如何践行创业文化,去解决面对商业愿景的构建和组织能力激活的挑战,这段时间以来,看着我们的产品一天天长大,客户规模一天天变多,团队也在一天天成长,目前看起来取得了一些初步结果。在面向创业环境文化中,我们也踩了不少大坑,也慢慢摸索出了一套粗浅的思路,给业界技术同行们做个分享。愿景篇01对创业方向拥有坚定的信念要做成一件事情,首先是创始人得问问自己:你是不是相信这件事能做成?要是自己都不相信,那谁也救不了这个团队;唐僧师徒能够成功到达西天取经,最关键的因素是什么?是唐僧取经的信念是非常坚定的。拥有坚定的信念之所以这么重要,是因为创业所面对的复杂性,不确定性,多变性,必须要强大的心力才能走到最后,才可以在面对失败和痛苦的时候爬出泥潭,并且在大团队面对诱惑或者方向跑偏的时候能将方向拉回。拥有坚定的信念是和一般非创业技术团队的根本区别,没有信念的团队就是一个接需求、做项目的常规团队,只能随波逐流,成就平平。注意一个点,坚定的信念并非个人YY,而是各方面综合判断之后形成的方向认知。比如我对于我们团队创业的方向,是结合商业&技术趋势+公司战略需要+技术团队的兴趣与成长诉求,这三项因素的综合分析得出的结论。这个逻辑推理是非常严密的;所以这里面对技术 Leader 的知识视野、技术格局、战略定力有非常高的要求。“思考透彻,行动坚决”,是我比较相信的一种处事方式,想清楚了,就坚决地做下去。02拥有坚定的信念之所以这么重要,是因为创业所面对的复杂性,不确定性,多变性,必须要强大的心力才能走到最后,才可以在面对失败和痛苦的时候爬出泥潭,并且在大团队面对诱惑或者方向跑偏的时候能将方向拉回。创业要成功,不可能是创始人一个人在跳舞,面对如今商业世界的复杂度,创业项目的成功必须要有一支高度认同产品愿景的核心团队;这种高度认同是创业成功的关键力量!为什么核心团队的核心理念必须要高度认同?因为创业项目的生死随时命悬一线,在关键时刻是需要靠大家凝成一股绳去渡过难关,所以核心团队必须要在核心愿景、核心策略和核心价值观上面达成高度一致;反之如果核心团队如果调频不一致,哪怕核心同学中有一个人不一致,会造成团队成员心态上面的动荡和内耗。所以当核心理念对不齐的时候,一定要及时识别到,并且坐下来拉齐认知。当核心团队要引入新的伙伴,一定要把理念对齐;说得严重一点,如果核心理念完全不认可的同学,让他离开这个创业项目也是一个选择。那什么是核心理念,就是创业项目的核心愿景和方向、核心策略和核心价值观,我可以列举我们团队的一些核心理念大家感受一下:1、核心方向:坚持零售未来的方向是极致的消费体验和完善的商家配套服务;2、核心策略:坚持产品力的打磨;给商家带来真正的收益,而不是只看签约规模;3、核心价值观:坚持技术匠心精神和极客文化;坚持简单透明的团队沟通;而其他方面诸如人的性格差异、能力模型、工作方式有差别,这是可以兼容并包的,只要不涉及核心愿景、策略和价值观,关系都不大。策略篇跳出公司看行业跳出公司看行业,是与面向内部研发团队的视角上面的根本性差异,其核心理念是站在整个行业视角去看所处的创业方向,而非仅仅从公司自己的视角来看。1、眼光的要求。为什么创业团队一定要跳出公司看行业?很简单,因为创业是要帮公司去打下江山,眼光就不能局限在公司内部;你的客户、竞对、伙伴,都可能在公司之外,如果光盯着公司内部做事情,那自然是闭门造车,要么是故步自封;正所谓高维打低维,如果视角不拉高一个维度,就无法做出高于这个维度的事情;别只是盯着老板在想什么,管理层在想什么,多走出去看看,管理者们走出去看看真正的行业在发生着什么,可能更能够理解现在公司所处的市场格局。2、打破资源依赖性。什么是真正的创业精神?哈佛大学商学院对其的定义是:“创业精神就是一个人不以当前有限的资源为基础而追求商机的精神”。我们站在公司的肩膀上,可能很容易搞不清楚是我们自己牛,还是公司这个平台牛,如果单独把我们自己拿出去,会不会被竞对秒成渣?比如别人和你合作,是看重平台本身的资源,还是你的产品做得真的很好?所以要开创真正的格局,一定要忘记自己是谁,要有扔掉拐杖的勇气,自己就能够在市场中摸爬滚打一步步长大。那具体来说,应该怎么做呢?有几个参考点给大家:1、多看行业研究报告,多关注虎嗅,36kr 等行业资讯,了解外面的世界;2、把公司的业务融到大行业中去看,全局上看清楚;3、多与外部客户和生态接触,了解他们在如何做自己的生意和活动,他们当下的实际思考和痛点是什么;4、关注你的竞对在做什么,他们是如何思考商业模式与客户价值;他们的优势和劣势是什么,我们做的话如何超越对手;5、在做事情的时候,专注于产品力打磨,看一下自己的产品在没有公司资源的时候,是否还具备竞争力?02做客户的朋友做客户的朋友,是对客户价值的一种更高的要求,这一点在面向创业环境的时候更加重要,而且我们有着非常深刻的体感,都是一些是实战之后的经验:1、不要 YY 需求:搞的每一件事情都需要说清楚哪类真实的客户,什么痛点,什么诉求;这个点特别重要,客户的真实的场景,和我们的逻辑推理有很大的区别!在真正面向客户以后,你会发现我们靠推理想出来的痛点和路径,打准的概率是很低的;多去现场,涉及重要的线下交付,要去现场,去现场,去现场!现场会让你更加明白真实的现场和意向的场景有多大差别;2、让阳光同时晒到每一寸土地:缩短每个职能角色获得痛点和需求的路径,也就是打破惯常的瀑布式路径,每个角色都应该真真切切体会到客户的一手痛点,确保大家真正搞懂了客户的问题,客户的声音一定要让每一个职能的人听见;3、天使客户的成长:在产品初期打磨阶段,有客户愿意陪着你走,是很重要的,千万要保持良好的信任度,和客户一起成长。好的口碑和坏的口碑,都是很快会传导的!4、客户问题的响应速度绝对是第一优先级:比如对于 toB 的产品体系,逐步摸索出来,有几个机制特别重要:block 问题日清;每周固定 review 客户问题;每个客户建立专属服务群,业务、产品、开放、测试都在里面;5、看清楚客户真正如何在用我们的产品:不要光看上线数量,一定要看商家真正在怎么使用我们的系统,他们的数据究竟正常还是不正常;我们的产品力构建得怎么样,他们怎么在用我们的产品;03一个脚印一个脚印走扎实在大公司经常会有人画大图,摊大饼,但是换到创业环境,这种打法就不灵了,为什么?1、因为真正能够在市场竞争中胜出的产品,一定是要精细化打磨的,而资源始终是有限的,阵势铺得太大,就意味着每个产品都做不精。当每个产品都不能赢得市场,这个创业无疑是失败的;2、当极其粗糙的产品推向市场,对口碑是一种负面伤害,导致客户信任度降低,那可能是需要花成倍的代价去挽回;面向老板汇报,写 ppt,讲多大都行,但是真正面向市场,市场会无情地拿结果说话,一切包装都会打回原形,所有粗糙都会显露无疑。这是一个思维惯性要突破,但这就是真实的世界。所以,面向创业环境,就是要敢于做减法。清楚当下聚焦什么,不做什么。1、保持专注力非常重要:在一段时期,focus 一两个明确的主题去解决,给团队定义阶段性,比如这两个月就解决商家实施的痛点,这个月解决容错性上的挑战;确保每件事情拿到效果,确保做一个成一个。同时,这种方式其实很容易给团队建立大胜仗的信心,做得太多,事情都做不好,反倒士气会受影响。2、时间线理论:在合适的时间引入合适的产品,尤其是不要在客户完全没有接受度,或者商业条件不具备的情况下去引入不合时宜的产品 ;当然,一步一个脚印,不是说对路径和方向没有思考。我们仍然需要确保对路径的思考是清晰的,方向是坚定的,只是打法和策略上面的优先级选择方式。04反脆弱,在敲打中变强大当明确了当前重点攻关的重点后,是否就应该做到完美了才面对真实挑战呢?面向商业环境下的优秀的产品、技术系统和团队组织是敲打出来的,而不是象牙塔中构建的。为什么?这就是真实世界的逻辑的复杂性、多变性和不确定性导致的。好产品,好系统,好团队,都不可能是规划设计出来的。经历敲打,同时在敲打过程中建立免疫和防御性机制,反而会更加健壮。这就是反脆弱理论的精髓,也就是如何从“不确定性”中获益的一种方式。1、不要假想做一个 100%完美的系统,然后面对真实场景的时候就是 100% 完美的,去面对真实挑战,在挑战中调整和成长;就像系统如果没有面对真正的流量冲击,是无法真正知道逻辑、性能存在什么缺陷;2、能够反脆弱的前提是面对缺陷的时候能够及时修复并举一反三,比如一个系统问题的发生,是否连带了相关问题的防御机制形成,否则完全靠个地雷一个地雷的踩,效率就太低了,这种不叫反脆弱,这种叫浪费生命。实战 tips:问题 reivew 一定要重视,确保问题背后的因素都能够分析到,逐个进行根治,确保问题背后的因素不要再犯错。技术篇从领域构建思维到价值链构建思维领域构建思维是一种典型的构建技术平台的思想,基于一个领域把平台做大,是一种单点放大的思维,把一个领域从 0 到 1,然后逐步做深,实现从单客户到多客户,从固定逻辑到配置化,再到平台化;而价值链构建思维更加适合面向创业环境,因为构建商业的价值链,是一种串联思想,把各个技术能力进行串联,举个形象的比方,“把一颗颗散落的珍珠用项链串起来”。面向创业环境的时候,我们需要以更快速度去构建价值链,所以我们更应该从领域构建思维到价值链构建思维。为什么?当局限于领域构建思路的时候,很可能从领域构建所规划的技术内容,跟整体价值的匹配可能会出现问题,比如做库存域的同学肯定希望把“库存健康”这个事情做大,但是库存健康可能当下并非商家的核心诉求;这样就会导致能力和需求错位,有点类似于拿着锤子找钉子的做法。所以不管技术上面模块如何拆解,大家都必须要围绕价值链去规划技术,体现在两个点:1、确保业务的价值链对应的技术闭环能够形成,对客户交付价值闭环的产品,比如满足商超用户多渠道经营,门店、商品、库存、营销、订单、履约模块业务的完整性是必不可少的,少了任何一个节点,都无法实现交付;2、不一定每一个领域的构建都需要业务研发团队来做,如果中台能力是可以的,完全可以考虑进行串联,这一点心态上面一定要放开;比如,如果中台有底层的库存能力,那么创业团队评估可用的话,就可以整合到价值链中。02吃透商业逻辑背后的技术本质:数学模型可能很大一部分同学对业务项目的认知是:业务提需求,产品出 PRD,技术照着执行写方案和代码就行了。这就是很多技术团队被业务拖在后面跑疲于奔命的重要原因,因为他的技术逻辑是没有灵魂的,很难把握到核心的逻辑抽象脉络,看起来就是一坨坨堆砌的代码!长期在业务线摸爬滚打以后,我越来越意识到,商业背后都有着一套精密的数学模型;商业模式的变化一定对应了这套数学模型的计算逻辑或者控制变量发生了变化!这套数学模型就是就是商业逻辑的本质,抓住这套模型,就抓住了系统的核心设计模式。我们来举一些例子:“电商 GMV=用户规模*品类宽度*转化率*客单价*复购率”,如果提炼出这个公式,就能够知道提升电商 GMV 有哪些方法,相对应的技术建设的要点就有了;“经营成本=采购成本+营销费用+物流费用+商品损耗”,如果提炼出这个公式,就能够知道降本提效从哪些手段发力;不仅仅是上面这种大的公式,微观上也是一样可以用数学模型表达,比如:一个商品可售库存=实物库存+在途库存-安全保留库存-预占库存。Get 这个核心的数学模型以后,核心建模抽象、核心逻辑设计、扩展性设计、监控对账逻辑,全部都可以运用进去,迎刃而解。03技术选择的“CTO责任制”与决策逻辑面向创业团队,技术的选择就是一种“CTO 责任制”,这里的 CTO 责任制是打引号的,我们理解并定义为:“版块负责人要独立自主对版块进行技术选择”,而非一纸强制命令。为什么?这里面有个基本逻辑,就是版块负责人最清楚版块所面临的挑战和未来发展,同时他也是负责技术方案落地的人,所以他必须对自己的选择负责!(当然前提条件是这是一个符合要求的版块负责人,否则就是瞎决策)那么作为一个版块的 CTO,怎么样做出更好技术决策,我们的经验:1、最关键的决策考虑点是确保满足业务预期标准的落地,切不可因为其他干扰因素导致了最终的成品不满足业务所需要达到的标准。比方说因为选择了某个底层能力导致了性能和体验的下降,或者因为选择了某个技术导致带来了一个很重要的产品缺陷,不满足业务诉求,这都是不可取的;所以负责人必须要搞清楚所做事项的业务要求,一般判断的顺序是:功能性、体验与性能、安全与合规性、扩展性;2、要快速 get 所负责版块的“know-how”,其中最重要的是两个点:这件事情核心本质和逻辑是什么,以及这件事情有哪些不能踩的坑。怎么 get 呢?我一般是先去看公司内 ATA(阿里内网技术博客)文章,公司外行业的文章,然后进一步找到懂这行的人聊,并加上自己的分析和理解,就可以逐步掌握其中的精髓;3、时间线理论,基于当下业务成熟度,技术发展阶段去做选择。我们来举一个例子,比如用数字化的方式提升商家的零售经营效率,可能很多同学就直接联想到通过自动化的数据算法帮助商家做分析决策。但实际上我们的经验跑下来,自动化经营决策所需要的业务成熟度、信息采集量强相关,失败概率非常高!所以我们后来总结出关键的提升经营效率的生命周期:工具化(不带大脑,靠运营)-专家经验(把运营经验推广开)-规则化(基于简单规则判断)-智能化(智能决策)。这里面,每一种打法都有适合的场景!千万要注意,技术的高大上并不是选择标准,面向创业环境大家要牢记这个观点。04如何决策业务线技术与中台技术的协作关系大部分创业的项目都会考虑跟如何基于中台来做,跟中台如何合作?中台又应该提供什么样的合作模式,一直是被反复讨论的话题,由于我自己既做过中台,又做过业务,还是有比较多的体会。基于 CTO 责任制和中台要不要合作,如何合作,是版块负责人考虑业务诉求、能力现状,技术成本,未来的迭代和维护成本等指标进行综合决策;也就是不存一定要用或者一定不用的逻辑;也不存在一定要用某种技术合作方式的逻辑,甚至不同模块可以采用不同的决策;但是这种决策的后果也是 CTO 需要去承担的,所以往往如何决策是一个非常复杂的课题,需要经验上面的长期摸索。基于中台的合作,一般分为五类模式,我们用表格进行说明:中台合作模式实现方案选择建议托管式将某个领域面向客户的交付完全托管给中台这种方式一般仅限于创业项目完全不具备该领域知识并且领域通用性较强的情况,否则不建议采用这种思路;从我们的实际情况来看,中台直接交付一般带有较强的平台性复用思考,大概率不会为某条业务线做深度优化,还有个大问题是不同的平台之间体验完全不一样,拼合起来是一个拼凑的产品体验,交付体验一般不好,所以我们现在绝大部分场景不会考虑这种模式,除非时间真的很赶。扩展式中台提供扩展点,业务到中台系统中写扩展逻辑当中台能力具备较强的扩展能力,并且往往领域的垂直线差异体现在局部,主干逻辑通用性较强的情况,这种情况可以考虑基于中台的扩展点来做,最典型的扩展就是 TMF(阿里业务中台创建的一种多业务身份插件式扩展框架)思想;这种方式的优点是能够以较低的代价构建差异化逻辑,但是缺点是需要了解中台上手速度会更慢,受限制比较大,尤其无法独立部署的情况,整个发布排队会有非常明显的制约;适用于垂直线差异较少,并且扩展能力比较健全的领域。代码输出式中台提供核心代码给到业务团队这种方式适合业务团队需要较高的独立部署和系统隔离能力,但一般中台团队不愿意选择这种模式。可能业务独立发展意愿很强烈的时候去选择。服务化中台团队提供通用的服务化接口 api,由业务团队自行调用封装业务的差异性在业务团队垂直性的系统中自行构建,这种情况业务在复用了底层能力的基础上,也具备较好的扩展性,业务体验的提升和逻辑的优化都在业务团队内部可以闭环完成,是目前我们团队使用的主要模式。共建式直接在中台的系统上面开发往往在必须要使用中台能力,但是中台既没有扩展能力也没有服务化能力,这时候就只能采用业务团队出人在中台系统上面开发业务逻辑,这种模式适合短平快上线场景,不能长期选择。具体使用哪种模式,表格中提供了选择建议。05在快速奔跑中如何做更好的架构治理在创业项目快速奔跑的过程中,我们是否可以牺牲架构质量?这个话题永远是一个争议不断的话题。我们团队的经验是:技术架构的治理仍然是必须要考虑的一个因素。业务快速发展 VS 技术架构治理,不应该是 10:0,也就是绝不应该是先污染后治理!技术架构治理应该是属于长期有耐心坚持的事情,即使不占很大的比例,也不能中断,否则会带来无法挽回的后果!比如对于健壮性,对于最重要的一些逻辑和事务,在过程中就应该要有应对方案;对于扩展性,在业务需求中针对最有可能出现的扩展应该有适当预留;这样的方式可以避免系统架构腐烂到不可收拾的地步,导致重构带来巨大的工作量,反而影响了业务发展。在系统架构治理目标上,分为健壮性、业务扩展性、支撑规模化三个层面,不同的时期治理的重点是不同的。我们团队摸索出来的一套实践分享一下。1、健壮性应该是首先需要进行治理的内容,因为软件的健壮性能够大幅降低出问题的成本,实际上会降低团队疲于处理问题的时间消耗,效果会很显著,所以只要有一点点余力,提升系统健壮性一定是值得投入的;健壮性的处理重点:事务与数据一致性,逻辑严密性,可监控性,系统的容灾备份等。关于创业环境下的研发效能研发效能对创业团队来说是非常重要的,但是提升研发效率有各种高大上的手段,各种成体系的措施,我们自己摸爬滚打出来,有几个点特别关键:1、减少格式化流程,但是对于核心的重要节点,可从简但切不可省略。比如验收流程,非常重要;2、缩短一线需求到研发的路径是提升效率的好办法;3、自动化是非常重要的提升测试效率的好工具;4、问题根治是提升研发效能的好办法,很多时间就是消耗到了重复的问题处理中;5、TL 对影响研发效率的问题保持敏感度,比如部署环境、架构混乱、策略效率等,让一线研发从泥潭中解放。07创业环境下的技术文化构建创业环境下,技术文化构建依然是非常重要的一件事情,不管如何服务于商业,技术人仍然必须要找到技术人的兴趣和追求;为什么?因为创业必须要有热情,而技术文化是调动技术人热情的最原始的动力!我们的比较有经验的体感:1、技术 Leader 应该要是一个狂热的技术人,是一个基本原则,leader 的喜好对一个团队绝对是非常强烈的影响,要构建好的技术文化,leader 一定要亲身参与并热爱技术,维持技术理想的初心!2、极客精神是技术人应该最应保持的技术文化,在创业过程中,我们依然可以对代码优化、系统设计、领域模型、逻辑设计精益求精。3、从过程中去做落地,创业过程很忙,但是技术文化的构建其实不需要非常科班的流程,而是可以落实到团队的细微之处,去享受写每一段代码的时光,每一次方案脑暴和论证,每一次代码 review 的中的碰撞和探讨,这是一种发自内心的热爱;这里不论层级,应该都需要保留技术参与度;4、把团队的技术能力成长放在非常重要的位置,关注同学的技术能力和思维模式的成长;一定不要把同学当成“资源”,他们都是一个个技术理想主义者,希望有一日成为大神!所以业务再忙,一定要有技术氛围;5、看到最苦的技术同学们:TL 一定要鼓励对不在聚光灯下默默做技术底层活着技术优化的同学给予认可可尊重;6、对于技术含量的挖掘要坚持!有个误区是业务创业环节所用到的技术没有技术含量!这个观点我不敢苟同,技术走到一定的阶段,你会发现一个很重要的观点:“技术是理解和构建这个世界的终极手段”。很多商业层面的问题分析诊断思路,商业逻辑构建思路,本质上就是技术能力的综合运用,包括:逻辑推理和演绎能力、数学建模能力、分析归纳能力,抽象表象看本质的能力,场景扩展运用的能力,这里面的技术含量很深!这里面技术思考力是非常重要的一个训练维度。心态篇学会与对手赛跑如今我们所处的商业时代,很难有一个赛道是没有竞争对手的。我们经常是面对内部研发,实际上没有过多考虑过竞对;但是现在必须要考虑;因为竞争对手是真实存在的。反过来看,有对手,才不寂寞,当赛道中存在别的对手,也侧面验证我们的选择。所以从心态上需要去适应有对手一起赛跑。面对竞对的态度,关键点:1、保持敬畏,但也保持充分自信。2、敬畏是因为我们不能无视竞对,否则会过于傲慢,从速度和关键决策上面输给竞对。3、充分自信不等于盲目自信,来自于我们对行业和客户的深度思考,确保我们在业务模式设计,客户价值,产品技术能力上面领先对手一个身位。02学会面对未知的世界创业,顾名思义,就是去创造一个之前不存在的事业;既有乐趣,也有风险,因为探索未知世界,最大的恐惧就是不确定性,不确定是否有一天项目回死掉,不确定项目未来究竟可以靠哪一条路走通。面对未知的世界,正好就是团队的修炼的最佳时机,我们的经验是:谦卑、乐观、认知迭代。1、保持谦卑。面对未知的世界,一定要谦卑,因为你可能没有搞懂真正的市场和客户诉求,闭门造车,尤其是大公司的人可能带着平台惯性,在快速迭代的商业模式里面,死亡随时可能发生;2、保持乐观也非常重要。面对未知的世界,打破恐惧的方式来自于我们对于未来趋势的判断分析,对于愿景的追求,对于学习和变化的自我迭代,只有把握好这几个点,就是在不确定性中找到了确定性,恐惧就变成了往上成长的动力;3、保持认知的迭代。虽然创业的愿景是不变的,但是市场形势,客户需求,团队能力和状态都是在不断变化,团队一定要保持持续的认知迭代,尤其是时时刻刻要做做反省,及时思考当下的状况并及时做出调整。比如当下我们团队的某个思考逻辑是不是应该调整一下?文化篇面对创业环境,压力大,要求高,我们应该保持什么样的团队文化呢?建设团队各有各的方法,但我们创业团队有几个点特别重要:1、务实:问题驱动,直击命脉,少绕弯,少包装,因为创业环境是面向真枪实弹的竞争和挑战,不容许有假大空,必须要踏踏实实回归业务问题,客户诉求和技术能力!2、自主:我比较推崇“人人都是 CTO ”的思想,采取 CTO 责任制,自己对自己的板块负责;让每个人都把自己所负责的事情理解成一次创业,能够成为事情推进的发动机;这个点很重要,因为需要把团队成员的积极性充分调动起来;3、透明:确保每个人可以大胆沟通,直面问题,管理扁平化,Leader看见一线的细节,一线看见团队的远景,上下同欲;4、公正:这个道理很简单,能者多劳,多劳多得,让最努力的同学获得最大的回报;5、开心:创业绝不等于单向的工作压力增加,996 甚至 007,其实并不是这样的,团队一定要注意劳逸结合,找到能够放松团队,开心团队的方法,大伙心态是开心的,才会更加高效地做事情。总结技术团队在发展中会遇到很多问题,包括作战能力、兴奋感、成长性等各个方面,这是因为我们处于VUCA时代并面对更加复杂的管理挑战。我们选择了用创业团队的打法来尝试解决这个问题,初步取得了一些效果和经验。比较重要的经验是:创业精神首先要对创业方向有着坚定的信念,并训练出核心理念高度认同的核心团队;在策略上,跳出公司看行业,做客户的朋友,一个脚一个脚印走扎实,并在敲打中变得强大;在技术上,改变领域构建思维到价值链构建思维,用数学模型看商业逻辑,技术决策上 CTO 责任制,和中台打磨合作路径,在快速奔跑中坚持代码与架构治理,并在创业环境下提升研发效能,坚持技术文化;在心态上面需要学会与竞对赛跑,学会面对未知,保持谦卑,乐观和认知迭代;团队文化上,打造务实、自主、透明、公正和开心的团队文化;同时践行这套理论,一个很大的感慨:创业文化的探索,就是和一群志同道合的伙伴去不断探索未知世界,并实现个人与集体成长的过程。所以也非常渴望和志同道合的同学一起探讨交流!作者介绍岩动:阿里巴巴集团资深技术专家,技术极客精神与技术团队成长的探索者。

邀请函|2022云原生实战峰会,邀请您免费现场参会报名

1月11日14点 ,主题“原生万物 云上创新”2022云原生实战峰会正式召开广播通知--现场参会免费报名了:https://hd.aliyun.com/form/982?hid=30865&channelId=652&empId=云原生实战峰会是云原生产业发展的风向标,是企业落地云原生的最佳指南,助力企业云上创新,峰会现场 14 位重磅嘉宾,助力解说发展方向!现场4大亮点阿里云、信通院、分众传媒、韵达、作业帮等大咖云集,精彩观点碰撞,解密云原生落地最佳姿势!深入剖析云原生业界最新趋势、产业研究、热门技术发展分析!深度解构云原生在行业的经典应用场景,用户真正落地的实践案例!全面了解阿里云云原生为企业云上创新打造的新思路、新计划、新方案!2022实战峰会现场直播预约:https://tianchi.aliyun.com/specials/promotion/cloudnativesummit2021活动时间:2022年1月11日(周二)14:00-17:00峰会地点:上海浦东丽思卡尔顿酒店

解密 Dubbo 三大中心的部署架构

作者 | 华钟明01 部署架构Dubbo 作为一个微服务框架,Dubbo SDK 与应用服务绑定在同一个进程内,它跟随着应用服务被部署在分布式集群各个位置,为了在分布式环境下实现各个应用服务间的协作, Dubbo 定义了一些中心化组件,这包括:注册中心:协调 Consumer 与 Provider 之间的地址注册与发现配置中心:存储 Dubbo 启动阶段的全局配置,保证配置的跨环境共享与全局一致性负责服务治理规则(路由规则、动态配置等)的存储与推送。元数据中心。接收 Provider 上报的服务接口元数据,为 Admin 等控制台提供运维能力(如服务测试、接口文档等)作为服务发现机制的补充,提供额外的接口/方法级别配置信息的同步能力,相当于注册中心的额外扩展上图完整的描述了 Dubbo 微服务组件与各个中心的交互过程。但是以上三个中心并不是运行 Dubbo 的必要条件,用户完全可以根据自身业务情况决定都不启用,或者只启用其中一个,亦或者启用多个,以达到简化部署的目的。通常情况下,所有用户都会以独立的注册中心 开始 Dubbo 服务开发,而配置中心、元数据中心则会在微服务演进的过程中逐步的按需被引入进来。1、注册中心注册中心扮演着非常重要的角色,它承载着服务注册和服务发现的职责。目前 Dubbo 支持以下两种粒度的服务发现和服务注册,分别是接口级别和应用级别,注册中心可以按需进行部署:在传统的 Dubbo SDK 使用姿势中,如果仅仅提供直连模式的 RPC 服务,不需要部署注册中心。无论是接口级别还是应用级别,如果需要 Dubbo SDK 自身来做服务注册和服务发现,则可以选择部署注册中心,在 Dubbo 中集成对应的注册中心。在 Dubbo + Mesh 的场景下,随着 Dubbo 服务注册能力的弱化,Dubbo 内的注册中心也不再是必选项,其职责开始被控制面取代,如果采用了 Dubbo + Mesh 的部署方式,无论是 ThinSDK的mesh 方式还是 Proxyless的mesh 方式,都不再需要独立部署注册中心。而注册中心并不依赖于配置中心和元数据中心,如下图所示:该图中没有部署配置中心和元数据中中心,在 Dubbo 中会默认将注册中心的实例同时作为配置中心和元数据中心,这是 Dubbo 的默认行为,如果确实不需要配置中心或者元数据中心的能力,可在配置中关闭,在注册中心的配置中有两个配置分别为 use-as-config-center 和 use-as-metadata-center,将配置置为 false 即可。2、元数据中心元数据中心在2.7.x版本开始支持,随着应用级别的服务注册和服务发现在Dubbo中落地,元数据中心也变的越来越重要。在以下几种情况下会需要部署元数据中心:对于一个原先采用老版本Dubbo搭建的应用服务,在迁移到Dubbo 3时,Dubbo 3 会需要一个元数据中心来维护RPC服务与应用的映射关系(即接口与应用的映射关系),因为如果采用了应用级别的服务发现和服务注册,在注册中心中将采用“应用 ——  实例列表”结构的数据组织形式,不再是以往的“接口 —— 实例列表”结构的数据组织形式,而以往用接口级别的服务注册和服务发现的应用服务在迁移到应用级别时,得不到接口与应用之间的对应关系,从而无法从注册中心得到实例列表信息,所以Dubbo为了兼容这种场景,在Provider端启动时,会往元数据中心存储接口与应用的映射关系。为了让注册中心更加聚焦与地址的发现和推送能力,减轻注册中心的负担,元数据中心承载了所有的服务元数据、大量接口/方法级别配置信息等,无论是接口粒度还是应用粒度的服务发现和注册,元数据中心都起到了重要的作用。如果有以上两种需求,都可以选择部署元数据中心,并通过Dubbo的配置来集成该元数据中心。元数据中心并不依赖于注册中心和配置中心,用户可以自由选择是否集成和部署元数据中心,如下图所示:该图中不配备配置中心,意味着可以不需要全局管理配置的能力。该图中不配备注册中心,意味着可能采用了 Dubbo mesh 的方案,也可能不需要进行服务注册,仅仅接收直连模式的服务调用。3、配置中心配置中心与其他两大中心不同,它无关于接口级还是应用级,它与接口并没有对应关系,它仅仅与配置数据有关,即时没有部署注册中心和元数据中心,配置中心也能直接被接入到 Dubbo 应用服务中。在整个部署架构中,整个集群内的实例(无论是 Provider 还是 Consumer)都将会共享该配置中心集群中的配置,如下图所示:该图中不配备注册中心,意味着可能采用了 Dubbo mesh 的方案,也可能不需要进行服务注册,仅仅接收直连模式的服务调用。该图中不配备元数据中心,意味着 Consumer 可以从 Provider 暴露的 MetadataService 获取服务元数据,从而实现 RPC 调用。02 保护三大中心高可用的部署架构虽然三大中心已不再是 Dubbo 应用服务所必须的,但是在真实的生产环境中,一旦已经集成并且部署了该三大中心,三大中心还是会面临可用性问题,Dubbo 需要支持三大中心的高可用方案。在 Dubbo 中就支持多注册中心、多元数据中心、多配置中心,来满足同城多活、两地三中心、异地多活等部署架构模式的需求。Dubbo SDK 对三大中心都支持了 Multiple 模式。多注册中心:Dubbo 支持多注册中心,即一个接口或者一个应用可以被注册到多个注册中心中,比如可以注册到ZK集群和Nacos集群中,Consumer 也能够从多个注册中心中进行订阅相关服务的地址信息,从而进行服务发现。通过支持多注册中心的方式来保证其中一个注册中心集群出现不可用时能够切换到另一个注册中心集群,保证能够正常提供服务以及发起服务调用。这也能够满足注册中心在部署上适应各类高可用的部署架构模式。多配置中心:Dubbo 支持多配置中心,来保证其中一个配置中心集群出现不可用时能够切换到另一个配置中心集群,保证能够正常从配置中心获取全局的配置、路由规则等信息。这也能够满足配置中心在部署上适应各类高可用的部署架构模式。多元数据中心:Dubbo 支持多元数据中心:用于应对容灾等情况导致某个元数据中心集群不可用,此时可以切换到另一个元数据中心集群,保证元数据中心能够正常提供有关服务元数据的管理能力。拿注册中心举例,下面是一个多活场景的部署架构示意图:03 目前存在的问题元数据中心的配置可以绑定某个注册中心,通过 registry 配置,但是配置存在问题,待修复之前提到的只会采用一个元数据中心进行元数据的 Pub、Sub:作者简介:华钟明:Apache Dubbo Committer,《深入理解RPC原理与实现》书籍作者。该书更深入地介绍了 Dubbo 的核心架构及三大中心的重要性,感兴趣的读者可以阅读书籍了解更多内容。也欢迎积极参与到 Dubbo 开源社区中,与作者一起共建 Dubbo。

新晋 CNCF 沙箱项目 OpenClusterManagement 带来了它的最新特性

作者 | 左修OpenClusterManagement(OCM)项目在 11 月 9 日的 CNCF 委员会会议中正式批准为 CNCF 的沙箱项目,并且也吸引了微软 AKS 研发同学的加盟。同时 OCM 社区也即将在 KubeCon 2021 中国的主题演讲里展开介绍 KubeVela 社区和 OCM 社区正在共建的集成特性。分布式云正在成为云计算行业的趋势。从用户的角度认识所谓分布式云就是可以根据基础实施拓扑形式和功能需求选择合适的社区项目方案和集群管理模式获取流畅的用户体验,同时从云厂商的角度就需要在技术服务上主动适配开放的技术标准并且在一致性通过的前提下兼容其他厂商的技术方案。所以评价分布式云混合云技术方案的开放性的重要指标之一就是项目的厂商中立性和开放性,然而实践上中立性的目标是比较理想化的因为每个厂商都需要跟随本身的商业利益,所以回到混合云技术方案上我们需要重点建设的指标是在开放性,反过来绑定终端用户恰好是与分布式云的初衷背道而驰的。下面要展开介绍 OCM 项目是个开源开放的 Kubernetes 多集群管理平台项目,目前由阿里云,红帽以及微软等公司跨厂商联合推动。在宏观架构设计上 OpenClusterManagement 主要采用了自治管理架构,同时功能组件高度模块化可剪裁。这样而来终端用户可以根据实际的场景灵活安装拆卸自己所需要的部分模块,举个例子如果用户需要采用某个厂商的功能那么只需要在 OCM 上通过订阅插件快速安装厂商的服务,同时如果用户不再需要某模块了就可以干净地拆卸掉。换言之,一个最小的 OCM 安装模式下,OCM 只会提供精炼的集群元数据以证书管理等基础功能。01 新的子项目 Cluster-Gateway1、Endpoint-less 的多集群 API 网关框架 / Cluster-GatewayCluster-Gateway 由阿里云主要贡献的 OCM 新晋子项目,也即将引用在阿里云在云栖大会亮相的 ACK 敏捷版项目中。OCM 在自管理模式下不会再要求被托管集群提供任何形式的 API 访问入口及证书,但是实践上我们往往仍然迫切需要一个从中枢集群动态正向访问各个集群的工作链路,同时这个链路需要考虑分布式云 VPC 网络隔离的问题,甚至被托管集群有的情况下不具备开放网络出口的条件。在 OCM 里 Cluster-Proxy 这个神奇的特性可以帮助你在中枢集群和被托管集群之间没有任何正向网络连通性的情况下使得 API 请求能从中枢集群正确抵达被托管集群,甚至 Exec,Logs 等复杂请求也可以正常工作。这得益与 Kubernetes 社区在 Apiserver-Netwrok-Proxy(ANP)项目上积累的经验:https://github.com/kubernetes-sigs/apiserver-network-proxy通过上述 OCM 的插件开发框架(Addon-Framework),Cluster-Proxy 可以帮你托管维护滚动 ANP 的 Server 端和 Agent 端的 TLS 证书并同步两者之间的配置。在网络连通性稳定工作之后,再借助于下面 Kubernetes 社区的 Aggregated Apiserver 开发框架 Apiserver-Runtime,我们联合 KubeVela 社区为 OCM 开发了 Cluster-Gateway 项目以提供一个自定义资源及”/proxy”子资源,它就像 Kubernetes 原生的”pods/proxy”, ”services/proxy”一样工作:https://github.com/kubernetes-sigs/apiserver-runtime这样一来 Cluster-Proxy 提供了四层的网络链路,Cluster-Gateway 提供了七层的网络多集群路由,于是整体的 API Push 链路就可以完整工作了。详细信息可以参考下图:该特性本身借助于 OCM 的插件框架简化了 ANP 的部署及证书滚动等繁冗的事情,这些细碎平凡的工作恰恰是构建多集群平台最先需要解决的通用问题,也是多集群平台能简易敏捷工作的基础。一句话来说,我们可以把最枯燥的事情交给 OCM,然后再由你来定义 OCM 的功能上限。>> 更多关于 OCM 最新插件 cluster-proxy 的文档可以参考:https://open-cluster-management.io/getting-started/integration/cluster-proxy/022、更多新特性OpenClusterManagement 社区还有许多正在积极建设的特性模块等待你去体验发现,篇幅原因这里不能详细展开,可以参考的包括:ManifestWork 资源下发的“订阅式”回流特性多集群策略配置下发的 Kustomize 集成多集群 Workload 弹性能力参与社区了解更多02 OCM 能力回顾首页仓库:https://github.com/open-cluster-management-io/OCM主题站点:https://open-cluster-management.io/中文主题站点:https://open-cluster-management.io/zh/OpenClusterManagement 项目由 2020 年末开始走向公众,至今半年多来经过在蚂蚁金服大规模运维实践的打磨下逐渐走向稳定成熟。后续在吸引了阿里云,微软等厂商的登陆合作之后正式号召社区用户的使用和合作,并于最近正式被 CNCF 采纳为沙箱开源项目。以下为 OpenClusterManagement 项目的主要架构组成:011、集群生命周期核心控制器 / Registrationhttps://github.com/open-cluster-management-io/registration这是 OCM 里的最核心组件,用于控制管理集群的注册流程和元数据及其生命周期。显而易见集群的元数据本身是更上层能力的必需基础,其提供的集群元数据模型也是之上工作的各个模块的公共“协议”。值得一提的是 OCM 的集群元数据是极其简练的,甚至不包含任何被托管集群的证书密钥,这是得益于 Pull 模式天然排除证书管理的安全性和复杂性。此外 OCM 里的集群注册托管流程是基于“双向握手”认证的,并且在注册完成后在中枢 Hub 集群内会自动生成管理一个与被托管集群同名的命名空间作为工作空间。022、持续稳定的资源下发能力 / Workhttps://github.com/open-cluster-management-io/work在各个集群对应的命名空间中我们可以通过 ManifestWork API 将期望的资源打包下发给被托管集群,值得注意的是在被托管集群中会持久化一份备份的资源 AppliedManifestWork API 以保证在出现网络分区或者中枢离线的情况下被托管集群依然可以持续的维持期望的状态。通过 Kubernetes 社区多集群工作小组的决议 Work API 即将会被推为社区标准。033、动态集群拓扑路由能力 / Placementhttps://github.com/open-cluster-management-io/placement完全解耦模块化的多集群路由策略模块。在使用时通过对集群分组或者进一步筛选指定集群的标签之后,Placement 控制器就会动态计算出路由策略的计算结果即一份被匹配的集群列表。这份列表会根据集群的可用性以及其他卫星属性动态变化。用户可以基于 Placement 控制器自由开发属于自己的多集群高级特性例如多集群 Workload 下发等等。此外在 OCM 里集群的标签也分为普通的静态标签/Label,以及由被托管集群采集上报的动态标签/ClusterClaim,这些都可以作为多集群路由策略的信息输入。044、开放模块插件管理框架 / Addon-Frameworkhttps://github.com/open-cluster-management-io/addon-frameworkOCM 的插件框架提供了一系列好用的工具来辅助你开发属于自己的多集群功能特性,这样一以来你就不再需要重复处理繁杂的组件部署,中枢与被托管控制器的联动以及证书滚动等等劳动了,我们可以更专注在构建自己需要的定制功能特性本身。055、更多可选模块功能除了以上稳定工作的核心组件,OCM 还提供了多集群配置策略的下发,基于 Helm 的多集群的生命周期管理以及和 KubeVela 的集成等等进阶模块等你体验。03 如何参与社区随时欢迎参与我们的社区双周会,在这里关注会议及日程:https://github.com/open-cluster-management-io/community/projects我们的会议时间会动态调整因为横跨涉及中国欧洲美国东西部的协调,或者可以直接在我们的 slack 频道寻找伙伴:https://kubernetes.slack.com/archives/C01GE7YSUUF点击下方链接,快速浏览我们最新的 OpenClusterManagement 中文站点。https://open-cluster-management.io/zh/

四步轻松玩转微服务敏捷开发

作者 | 亦盏01 微服务敏捷开发不简单1、安得环境千万套,大庇开发小哥俱欢笑微服务给大家带来了敏捷开发的特性,基于敏捷开发带来的便利,让我们可以在同一个时间内多个迭代/feature 并行开发。但微服务架构本身也给开发环境带来了一定的复杂性:每个 feature 的修改点都可能会被分散在多个应用中,需要多个应用互相配合才能完成整体的逻辑。这些应用既需要互相配合好,又不能让他们互相影响,故敏捷开发有时候也不是那么容易。相信实践过微服务敏捷开发的同学曾经都遇到过以下情况:1、开发接口时,应用无法独立地联调测试,需要依赖于下游的返回,所以一般都需要一个完整的开发环境,这个环境需要包含所有的其他应用。2、A 同学辛辛苦苦,终于开发好了一个接口,但是部署到开发环境后,发现返回值一直是错的,就是不符合预期,百思不得其解。最终根据日志、arthas 层层跟踪下去,发现原来是另一个同事更新了下游应用的代码,导致原有逻辑发生了变更。3、A 同学准备开始联调测试了,这时候他要找到开发 B 和 C 吼一嗓子确认:“我要开始测试了哈兄弟们,你们都别动环境,不要重启和 debug 哈”。B 同学 和 C 同学一脸懵逼:“我自己这还有个逻辑没理清楚呢,刚改完代码准备测一发,你这一测试联调我就不能动环境了,我这功能得等到什么时候才能开发好”。4、排查问题好麻烦啊,要不直接 debug 一下吧,这 IDEA 远程 debug 刚连上去呢,立马就传来了同事的声音:“谁 XX 又在瞎动环境啊,怎么刚刚还能跑的接口现在就出错了”。以上这些问题显然会影响项目的进度,非常容易造成项目延期。对于此刻的开发小哥哥而言,拥有一套属于自己的独立环境,带来的幸福感也许比有一套属于自己的小房子还大。2、流量闭环是微服务敏捷开发的基础上文中提到的问题,其实都是因为没有在开发环境中,精准地控制流量在 feature 环境内流转。为什么精准地控制流量如此重要?举个最简单的微服务架构图来说明,这里假设应用的调用链路为 A ---> B ---> C ---> D ,现在同时开发两个 feature, feature1 和 feature2 。feature1 需要修改 A 和 C 的代码, feature2 需要修改 B、C 和 D 的代码。为了方便表述,我们用 A、B、C、D 来代指 A、B、C、D 的线上稳定版本,也叫做基线版本;A1、C1 来代指 feature1 环境中的 A 和 C ;B2、C2、D2 来来代指 feature2 环境中 B、C、D。那么开发测试 feature1 的同学会要求他的请求,准确地在 A1 ---> B ---> C1 ---> D 中流转。为什么一定要这样,我们来简单分析一下:1、如果流量走到 A 或者 C 的基线环境,因为他们都没有包含 feature1 相关的代码,所以肯定是无法正常测试和联调 feature1 对应的功能。2、如果流量走到 B2、D2 环境,大多数情况下是可以正常工作的,因为正常情况下 B2 和 D2 中的修改是不会影响 feature1 的。但是因为 feature1 和 feature2 可能是由不同的同学开发的,或者有不同的开发排期和节奏,他们有自己的开发、重启、debug 节奏,所以大概率还是会出现上文中提到的场景。综上所述,让流量在 feature 环境内流转非常重要,是微服务敏捷开发的基础。如何准确地让请求在 feature 环境内流转呢?最简单的办法是每个迭代/feature 的都享有一套独立的完整环境,这套独立的环境包含了整个微服务应用集所有的应用,包含注册中心和接入层,这样就能确保流量在 feature 环境里闭环,不用担心应用之间互相影响。这个解决方案虽然简单,但是问题也很显而易见,成本比较大。我们假设微服务应用有10 个,每个应用只部署一台,以 java 为例,部署一个 java 应用按  2C4G 的 共享标准型 ECS 进行计算,维护一套环境一年的成本是 10 × 140 × 12 = 16800 元,如果同时有 4 套环境,即只支持两个迭代并行开发,每个迭代只有 2 个 feature,这样一年的成本就是 67200 元,而且我们可以发现,这里面计算公式使用的是乘法,当应用增加和环境增加时,成本的增加是成倍的。注意,这里只是单纯地计算了应用使用的 ECS 的成本,其他周边的配套设施我们还没有计算,因为我们的开发、联调、测试是需要确保端到端的全流程都是足够顺利的,那这里就还会涉及到 域名/SLB/网关/注册中心这些资源,这些资源一般比较固定,不会需要进行大的修改,但是在多套环境的方案下这些资源也需要维护多套,成本还会进一步上升。那么,有没有一个比较优雅地方式,既能享受到微服务架构带来的敏捷开发的便利,又不会给日常开发环境的搭建带来很大的成本呢?基于 MSE(微服务引擎 MSE,以下简称 MSE)标签路由功能使用开发环境隔离方案是您的不二之选。03、如何低成本玩转敏捷开发什么是 MSE 开发环境隔离,简单地说就是将 feature 环境的隔离方式从简单的物理隔离转为逻辑隔离。借助于 MSE 提供的逻辑隔离,您只需要维护一套完整的基线环境,在增加 feature 环境时,只需要单独部署这个 feature 所涉及到改动的应用即可,而不需要在每个 feature 环境都部署整套的微服务应用及其配套设施。我们称这唯一的一套完整的环境为基线环境。基线环境包含了所有微服务应用,也包含了服务注册中心、域名、SLB、网关 等其他设施,而 feature 环境中只包含了这个 feature 中需要修改的应用。这样维护 n 套 feature 环境的成本,就变成了加法,而不是原来的乘法,由 n × m 变成了  n +  m。差不多相当于零成本增加 feature 环境,这样我们就可以放心地扩容出多套 feature 环境,每个开发小哥哥都可以轻松拥有属于自己的独立环境,尽情地享受微服务敏捷开发。从上图中我们可以看到,feature1 对应的流量,在发现 feature1 中存在 A1 应用时,一定会去往 A1 节点,A1在调用B的时候发现 feature1 环境中不存在 B1 ,则会将请求发到 基线版本的 B 中;B在调用C时,发现 feature1 环境存在 C1 应用,又会返回到 feature1 环境中,依次类推,确保了流量会在 feature1 环境中闭环。而且,在这个过程中,您不需要修改任何代码和配置,直接接入 MSE 微服务治理即可使用,不会给您增加任何开发成本。02 如何使用 MSE 开发环境隔离011、开通 MSE 微服务治理专业版登录 MSE治理中心控制台,如果您尚未开通 MSE 微服务治理,请根据提示开通专业版。如果您已经开通了MSE 微服务治理基础版,请根据概览页中右侧的提示,升级到 专业版。022、部署基线环境/基线环境接入首先需要将基线环境的所有应用接入到 MSE 中,接入方式与您开发环境中应用部署方式有关。这里我们拿两个典型的场景作为例子进行说明。更多接入场景请参考 MSE 帮助文档 MSE 微服务治理快速入门。阿里云容器服务 ACK若您的开发环境部署在 阿里云容器服务的 ACK 中,将基线环境接入 MSE 的流程如下:1、在 ACK 中安装 MSE 治理中心组件登录容器服务控制台。在左侧导航栏单击市场 > 应用目录。在应用目录页面搜索并单击 ack-mse-pilot。在 ack-mse-pilot 页面右侧集群列表中选择集群,然后单击创建。安装 MSE 微服务治理组件大约需要 2 分钟,请耐心等待。创建成功后,会自动跳转到目标集群的发布页面,检查安装结果。如果出现以下页面,展示相关资源,则说明安装成功。2、为 ACK 命名空间中的应用开启 MSE 微服务治理登录 MSE 治理中心控制台。在左侧导航栏选择微服务治理中心 > K8s 集群列表。在 K8s 集群列表页面搜索框列表中选择集群名称或集群 ID,然后输入相应的关键字,单击 🔍 图标。单击目标集群操作列的管理。在集群详情页面命名空间列表区域,单击目标命名空间操作列下的开启微服务治理。(如果您的基线环境部署在 default 这个 namespace 中,则目标命名空间为 default)在开启微服务治理对话框中单击确认3、完成上述步骤后,重启/部署基线版本的应用,您的基线环境就已经接入完成。ECS/虚拟机若您的应用是通过 ECS 或者 虚拟机的方式部署的,请您打开 MSE微服务治理控制台中的应用列表-接入方式-ECS 集群,根据指南里面的提示进行操作。1、通过Shell脚本方式下载Agent 复制以下命令行并在待治理应用所处的系统中运行。wget -O- http://mse-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/install.sh | sh # 此命令具体内容会随着您控制台中的选择的 Region 而变化,请注意在控制台中选择机器所在的 Region # 若您的机器不在阿里云环境中,请选择 杭州 Region。2、接入 MSE Agenta. 将MseAgent.zip中的所有文件解压到任意目录中。unzip MseAgent -d /{user.workspace}/ # 说明 “{user.workspace}”是示例路径,请根据具体环境替换为正确的路径。b. 在应用启动参数上添加AppName以及LicenseKey参数。java -javaagent:/{user.workspace}/MseAgent/mse-bootstrap-1.7.0-SNAPSHOT.jar -Dmse.licenseKey=<yourLicenseKey> -Dmse.appName=<yourAppName> -Dmse.enable=true -jar A.jar #系统将为您自动生成的 <yourLicenseKey> ,在上文中提到的 ECS接入指南 界面查看,请勿泄露。 #<yourAppName> 为应用名称,同一应用在后续的 feature 环境接入需要保持应用名称一致注意:各个 Region 的 LicenseKey 值可能不一致,请注意选择正确的 Region,若您的机器不在阿里云环境中,请选择 杭州 Region。验证环境接入成功完成上述步骤后,您的基线环境就已经部署好了。您可以在 MSE 控制台中找到对应的 Region 查看应用列表,以及应用详情页的节点情况。033、将应用接入 feature 环境将应用接入 feature 环境的方式和第二步中的方式基本相同,只不过这里需要额外给应用打上一个标签,将这个应用标记为属于 feature 环境。同样的,接入 feature 环境的方式也和应用的部署形态相关,这里同样分别以 K8s 和 ECS 方式举例,如何将 A 应用接入到 feature1 环境。K8s 部署方式如果您的应用是通过 K8s 方式部署,则应用在接入 feature1 环境时需要在 deployment 中的 spec > template > metadata 下的 annotations 增加如下配置:spec: template: metadata: annotations: alicloud.service.tag: feature1ECS/虚拟机如果您的应用是通过 ECS/虚拟机的方式部署,则应用在接入 feature1 环境时需要额外配置 JVM 系统属性(SystemProperty) ,增加的方式为在 Java 启动命令中增加 `-Dalicloud.service.tag=feature1`,完整的启动命令如下:java -javaagent:/{user.workspace}/MseAgent/mse-bootstrap-1.7.0-SNAPSHOT.jar -Dmse.licenseKey=<yourLicenseKey> -Dmse.appName=<yourAppName> -Dmse.enable=true -Dalicloud.service.tag=feature1 -jar A.jar验证环境接入成功完成上述操作后,登录 MSE 控制台,找到刚才启动的应用,在详情页面查看实例详情,可以确认节点的 ip 和标签是否符合预期。044、轻松开始联调和测试假设我们发往网关的请求是 http 请求,希望这个请求再 feature1 中完成闭环,只需要在请求的 header 中添加 x-mse-tag=feature1 即可,流量会自动在 feature1 环境内完成闭环。注意这里的 key 为 x-mse-tag 为固定值,feature1 则需要和环境的标签(即上文中配置的 alicloud.service.tag)保持一致。如果您的请求来源为 Dubbo,则需要在 RpcContext 中增加 Attachment ,内容也是 x-mse-tag=feature1。特别地,如果您的网关应用不属于 Java 体系,则需要在网关层配置一下规则,目前已经支持 MSE云原生网关,Nginx,K8s Ingress 等,详细的接入方式可以参考 MSE 全链路灰度配置 。03 更进一步 IDEA 接入 feature 环境上文中提到过,开发联调过程中,将应用部署到联调环境也是需要成本的,能不能直接在 IDEA 里面把正在开发的微服务跑起来呢?这样岂不是就可以直接愉快地快速部署和 debug 了?当然可以!而且操作起来还非常简单!将 IDEA 启动的应用直接接入到 feature 环境中也不复杂,只需要简单几步即可实现。注意:使用此特性的前提条件为,您本机的网络与开发环境其他应用能够正常通讯。011、 安装 CloudToolkit 插件安装最新版本的 Cloud Toolkit,安装详情请参考官网:https://www.aliyun.com/product/cloudtoolkit。2、配置 MSE 参数点击 IDEA 的 Tools 中找到 Preference ,找到 Alibaba Cloud Toolkit 中 Microservice 下的 MSE ,点击 开启微服务治理,并安装下图的方式进行配置即可。对以下几个参数做一下说明:LicenseKey您阿里云账号对应的 MSE 产品的 LicenseKey ,请在 https://mse.console.aliyun.com/#/msc/app/accessType 中的选择 ECS 集群,在 安装 MSE Agent 章节找到 LicenseKey 的值。注意:请您做好 LicenseKey 的保密工作。注意:各个 Region 的 LicenseKey 值可能不一致,请选择对应的 Region,并和基线环境接入的 Region 保持一致。App Name应用在接入 MSE 时所使用的应用名,请根据实际业务情况进行配置,注意这个值需要和本次所启动的应用保持一致。Tag此应用所属的环境 Tag,基线不用填,其他请根据实际业务情况进行填写。如果此应用属于 feature1 环境,请填写 feature1。Agent 地址选择自己应用所在的地域,需要和 LienseKey 所在的地域、以及基线环境接入的地域 都保持一致。开启 RPC 灰度  ✅支持对 Spring Cloud 和 Dubbo 近5年内的所有版本的流量进行精准控制。默认情况下请开启,除非您明确知道关闭此选项的使用场景,否则请勿关闭此选项。开启标签染色  ✅推荐开启,开启后经过此应用的流量就只会在对应的 Tag 环境中流转。开启消息灰度  ✅请根据业务实际情况选择是否开启,目前仅支持 RocketMQ 4.2 及以上版本。033、验证应用是否接入成功1、使用常见的 IDEA 启动应用的方式进行启动2、登录 MSE 控制台,选择对应 Region ,找到刚才填写的应用名,点击此应用名,如果在应用详情中发现了本地对应的 IP 和 Tag ,表明接入成功。注意,第一第二步只需要执行一次,若 AppName 和 Tag 发生了变更,则根据实际情况进行调整。044、接入成功现在,您可以在 IDEA 中尽情地享受本地开发部署和 debug 的快感。双 11 抢购倒计时 6 天,微服务引擎 MSE 注册&配置中心、MSE 云原生网关预付费低至 8 折,全年最低优惠!点击文末链接,移步详情页加购。https://www.aliyun.com/product/aliware/mse

成功报名须知 | Serverless 技术实践营广州站

如果您已经收到报名成功的短信通知,请了解本次活动的注意事项:1、活动时间和地址:12月2日(周四)、9:30,广州市海珠区鼎新路88号阿里中心10F-春秋书院;2、请搜索钉群群号:34120035,入群会审核,若您使用钉钉不频繁,也可以添加工作人员微信:zjjxg2018,我们会拉您进微信群;3、本次活动免费,采取报名审核制,中午含餐,完成下午的动手实操,颁发阿里云官方认证证书,请确保报名时的姓名是填写准确的,我们会提前制作好认证证书,现场颁发;4、我们将在会前1天发送访客码至您的报名手机号上,完成身份证实名认证,凭访客码入园,短信中实名认证链接;5、参与动手实操的客户,请带好笔记本电脑,无须提前安装相关程序,我们提供了工程化较好的体验沙箱,动手实操活动是免费的,无须在云上支出费用;6、建议您乘坐公共交通或者打车前往,低碳出行;自驾的同学可以停在华南桥底停车场(10元/小时,白天60元封顶),步行至阿里中心(约5分钟)7、请遵循当地疫情政策,入园出示健康码和行程码,佩戴口罩。任何疑问,您也可以钉群内或微信咨询工作人员。活动议程介绍:https://developer.aliyun.com/article/805658?groupCode=serverless

阿里云发布云原生加速器,携手生态企业拥抱数字时代

今天,千行百业都在拥抱云计算、拥抱云原生,进行数字化创新升级。作为国内最早实践云原生的企业,阿里巴巴在 2006 年就开始了在云原生领域的探索。为了更好地助力云原生领域生态伙伴的发展,继去年推出云原生合作伙伴计划之后,阿里云正式发布云原生加速器,携手生态企业拥抱数字时代。01 与成员企业能力融合,价值共塑阿里云此次发布云原生加速器,旨在挖掘云原生领域的优秀企业,通过阿里云强大的业务整合能力,助力伙伴在阿里云上形成百花齐放的云原生生态体系。第一期云原生加速器将面向云原生应用、云原生 PaaS、云原生基础技术三大方向开启招募,由知名投资人、阿里云顶级技术专家、业务专家、阿里战投等组成专业的评委团队,最终将有 30 家企业入围首期云原生加速器。招募方向包括,云原生应用:通用和垂直行业 SaaS、工具类 SaaS 等;云原生 PaaS:中间件、边缘计算、AI、物联网、低/无代码、行业 PaaS、iPaaS、低碳等;云原生基础技术:容器、微服务、可观测、DevOps、Serverless、容器存储、容器安全等。在一年期加速成长计划中,将通过 2 次集结 +N 次业务对接,开放阿里云生态和业务资源,提供技术和产品支持,打造阿里云云原生加速器 “朋友圈” ,帮助伙伴快速成长。在产品技术层面,阿里云云原生加速器将整合阿里云云原生技术产品线,与成员进行产品和解决方案共创,将为成员提供更高效、易用的平台和服务。入选成员还有机会成为阿里云云原生 MVP,助力成员获得更多资源与发展机会。在业务层面,阿里云云原生加速器将协同不同行业及区域业务线,基于成员实际需求提供多元的合作模式与商业机会,共同拓展云原生应用场景。在资本层面,阿里云云原生加速器将协同阿里体系投资机构为成员深度连接海量投资机构与专业的财务顾问,帮助成员快速、精准获得投资,全链条赋能企业融资。在“内功”方面,阿里云云原生加速器将为成员解读行业政策与产业趋势,扩大品牌势能与市场规模,从战略规划与实施、人才组织与团队管理等全方面帮助成员完成能力升级。02 庞大的创投导师阵容阿里云云原生加速器将协同强大的顶级投资机构资源,邀请红杉资本中国基金合伙人邹家佳,GGV 合伙人吴陈尧,深创投董事总经理伊恩江,启明创投合伙人叶冠泰,云锋基金合伙人朱艺恺,银杏谷创始人陈向明作为创投导师,基于云原生领域相关细分赛道,从投资角度剖析产业发展趋势,为成员梳理未来的机遇与挑战。同时,IDG、嘉御资本、蓝驰创投、北极光、元璟资本、线性资本、戈壁创投、金沙江创投、明势资本、英诺天使、真格基金、湖畔山南、元禾原点、九合创投、盈动资本等创投机构的合伙人与董事也将受邀作为嘉宾,剖析行业价值,深度链接更多合作机会。此外,阿里巴巴副总裁、阿里云智能基础产品事业部负责人蒋江伟,阿里巴巴副总裁、阿里云智能计算平台负责人贾扬清,阿里云智能副总裁、阿里巴巴达摩院秘书长刘湘雯,阿里巴巴研究员、阿里云智能云原生应用平台负责人丁宇等,也将与成员分享阿里云在生态构建与技术应用等方面的战略布局,与成员共商合作、共创行业未来。 点击下方链接,申请报名阿里云云原生加速器!https://yida.alibaba-inc.com/o/cna#/

我们如何实现“业务 100% 云原生化,让阿里中间件全面升级到公共云架构”?

作者 | 中间件支持集团上云技术小组2019 年,阿里巴巴核心系统 100% 运行在阿里云上。2021年,阿里巴巴业务 100% 云原生化。阿里巴巴已经成为全球首家,将所有业务都放在自家公共云上的大型科技公司。举全集团之力,将业务全部迁移至公共云,不仅是对云的笃定,也证明了阿里云有能力应对高难度、超复杂环境下的技术挑战,为客户享受云上技术红利提供了更坚实的实践保障。01 架构一致性,开源、自研、商业化三位一体在今年的天猫双 11 中,中间件支撑了 5403 亿的交易量,并全面升级到了公共云架构。此次的架构升级,是以开源为内核、以公共云为基础、以 OpenAPI 进行解偶扩展,在架构上,对开源、自研、商业化进行统一。通过采用和反哺开源、推动社区建设,通过阿里巴巴丰富的业务场景、打磨技术的性能和可用性,通过云上商业化服务更多企业、打造更好的用户体验,全方位锤炼云上产品的竞争力。这个过程中,阿里巴巴业务的研发效率提升了 20%,CPU 资源利用率提升了 30%,应用 100%云原生化,在线业务容器可达百万规模,计算效率大幅提升,双 11 计算成本下降 30%。接下去,我们将全方位揭秘业务 100%云化过程中,后端 BaaS 化,运行时 Mesh 化,业务侧 Serverless 化的全过程。02 中间件后端 BaaS 化,有状态应用也可分钟级交付以往的双 11 建站交付都是线性的。先交付 IaaS 资源,然后再交付中间件,最后再交付业务。今年,中间件升级到公共云架构后,IaaS 资源和中间件同步交付,节省了两者串行交付的时间。中间件公共云架构运维底座全部切到 K8s 上,让有状态的中间件也能做到极致弹性,使得中间件的交付效率从天级别,降低到了分钟级,极大地提升了交付效率,降低了资源保有时间和资源成本。后端的支撑系统也全面升级,如通过对接阿里云账号权限体系,来解决安全问题;通过对接计量计费体系,来解决 IT 资产数字化问题,为集团各个技术团队的经营者可以通过账单形式,可视化的进行成本优化。在用户界面上,也升级支持了 IPv6,为阿里巴巴生产网全面向 IPv6 架构演进做好了准备。03 海外业务 Mesh 化,异地多活可下沉 Sidecar阿里巴巴海外有 AE&Lazada 等多种业务形态,异地多活体系侵入性大,技术架构不统一,从而影响了全局高可用和研发协同效率。随着服务网格架构的演进和成熟,我们逐步将服务路由标准化,路由功能层次化,通过插件模式让业务进行扩展,让异地多活体系下沉到 Sidecar,和业务逻辑解偶,探索异地多活通用、无侵入、低成本的解决方案。今年,这套体系在海外业务得到了充分验证,为未来商业化积累了实践经验。随着 Mesh 化服务架构的深度应用,除了异地多活功能下沉 Sidecar,阿里巴巴还基于 Mesh 化架构,统一了流量调度技术与产品架构,降低了流量调度实施和治理成本,提升服务容灾能力和线上服务治理效率,实现了更加灵活和稳定的调度规则下发及单元间切流。04 业务侧 Serverless 化,实现研发提效 38%,弹性提升 200%Serverless 是阿里巴巴降本提效的首选技术方案。今年双 11,Serverless 不仅成功承载了 3 倍的峰值流量 ,支撑应用场景数量也提升了 2 倍,整体研发运维体系提升 38%,主要表现在以下两个关键点上。1、夯实三位一体技术体系,使用阿里云函数计算 FC 支撑大促全面 Serverless 化函数计算 FC 与阿里内部的运维体系,实现全面标准化对接,打通研发的最后一公里。首次实现了业务全链路“ FaaS + BaaS ”的 Serverless 全流程研发体系。在函数计算进入集团之前,云上的 Serverless 技术体系一直无法融入到开发者生态,虽然功能丰富、强大,但是无法被业务使用,甚至出现了使用 Serverless 技术后,研发成本反而增高的情况。所以,在 2021 年,我们发力 Serverless-Devs 工具链,基于标准的接口与集团内部的技术社区,共同打造了专属于 Serverless 的研发体系,把云上的技术巧妙的融入到了集团。通过双 11 大促场景作为“磨刀石”,把关键的核心技术进行进一步打磨,然后反哺给云上的商业化产品和工具链,夯实三位一体的技术体系,今年交出了满意的答卷,全面支撑 2021 天猫 双 11 各类业务场景,覆盖淘特、淘系、阿里妈妈、1688、高德和飞猪等多类业务场景,数量提升 2 倍,峰值流量总数同比增加 3 倍,实现了 50w QPS 的突破,整体研发提效达到 38%。022、加大 Serverless 硬核技术投入,阿里内部通过天猫双 11 场景打磨,外部通过公共云输出、服务千万家企业在 Serverless 的场景下,冷启动的速度是客户选型的关键,也是云上产品的核心竞争力,。今年,我们加大了硬核技术研发的投入,从“弹性策略”、“镜像分发”、“容器启动” 等全方位对冷启动进行了性能提升,冷启动时间进一步缩减 60%,刚性交付能力提升 200%。在年初,函数计算刚应用于集团内部时,Runtime 层的冷启动时间在秒级别,并且需要初始化中间件,整体的冷启动时间要大于 2s,这严重制约了 Serverless 的使用场景。所以,我们在镜像分发上,创新性发明了 Serverless Caching 。根据不同的存储服务特点,构建数据驱动、智能高效的缓存体系,实现软硬件协同优化;即便在 GB 级别镜像冷启动的场景下,函数计算也能提秒级别的交付能力。在调度上,相比去年,增加了定时/CPU 等更多指标的弹性策略,并且基于集团内资源统一调度的能力,支撑了天猫双 11 业务的 10w 级别的实例弹性。在容器层,使用了自研的安全容器池化技术,在容器启动上,时间进一步缩小到 50ms 以内。这些技术,都已经在双 11 场景下得到验证,也在公共云上全面输出,已经帮助我们的合作伙伴轻松应对业务高峰。05 从 Ops 到 Dev,云原生的技术改造正进入下半场第一时间让客户使用跟阿里巴巴一样的技术,是中间件开源、自研、商业化三位一体的初衷。这些源自三位一体的产品正帮助云上客户更好的提升 Ops 的效率。三位一体的商业化输出包括:微服务引擎 MSE:注册&配置中心全(原生支持 Nacos/ZooKeeper/Eureka)、网关(原生支持 Ingress/Envoy)和无侵入的开源增强服务治理(原生支持 Spring Cloud/Dubbo);消息队列 MQ:原生支持 Apache RocketMQ、Apache Kafka;应用实时监控服务 ARMS:原生支持 Prometheus,提供基于开源的 Tracing 能力;应用高可用服务 AHAS:原生支持 Sentinel、ChaosBlade;函数计算 FC:支持开发者工具开源 Serverless Devs、开源可观测工具等。云计算和云原生技术上半场更多的是解决的是 Ops 的问题,我们相信下半场更多是关注 Dev 的问题。围绕着开发者效率的提升,中间件已经完成了 Serverless、应用运行时、低代码、云边一体,在线 IDE 等关键领域的技术布局,通过服务网格和应用运行时等技术,将非业务逻辑下沉,并且通过插件模式,形成新的研发分工,让中间件研发屏蔽底层复杂技术,让安全研发在应用运行时这层建立可信的安全防线,让高可用研发在底层通用的构建熔断、限流、降级、异地多活等能力,让业务更轻量,更聚焦业务本身开发,更高效的构建业务竞争力。

如何通过任务调度实现百万规则报警

作者 | 黄晓萌01 问题背景报警是一个公司的日常需求,常见的形态除了满足运维过程中的基础设施监控报警(CPU/内存/磁盘等)之外,部分公司也会在应用指标(如 QPS、RT 等)及业务指标(如 GMV/日活 等)上有相应的报警需求。在业务发展初期,基础设施较少,且应用形态单一,所以处理这一类需求往往会比较粗暴直接,但是随着业务的增长,尤其发展到日活百万甚至上亿级的时候,监控指标也会呈指数级上涨,在这种情况下对于报警体系就提出了巨大的挑战,如何解决这种体量下报警的有效性和时效性就成为了 IT 治理的重中之重。本篇文章,我们将从监控指标的体量出发,详解各个阶段报警体系中遇到的各个挑战。02 一次常规的报警流程示意图如下图所示,一次常规意义上的报警流程,主要会包含并发检查、齐全度检查、数据追补、阈值判断等核心环节。同时,为了保证报警的时效性,基本上整个流程会是一个秒级触发的形态,具体如下:其中,报警后台任务处理系统是我们这次讨论的重点,几个核心流程的说明如下:并发检查:检查当前告警规则是不是在其他进程或者节点中执行中,避免有些告警规则检查耗时过长,被重复执行了或被其他的任务节点抢占执行。齐全度检查:获取当前告警规则对应的数据源的齐全度时间,即最新数据上报到什么时间了。因为数据源数据采集和上报一定会有延时的,如果数据不齐就进行检查,很容易漏报和误报。数据查询:从监控数据中获取该规则的数据,一般会从收集上来的日志服务(如:ElasticSearch 服务等)或者基础监控指标存储服务(如:Zabbix、Prometheus 等)中获取。数据追补:由某些报警任务设置的策略,没有数据点的情况下怎么处理。有补0,补满和不补三种。如在针对业务数据跌零报警的场景,我们会更倾向于补 0 ;但是针对 CPU 平均值超 80% 的场景,我们会倾向于不补。阈值判断:根据获取的数据和报警条件,判断是否需要触发报警。告警:将告警信息通过短信、钉钉、邮件等方式通知到配置的人,以便后续有人处理。03 进程内调度方案一开始的业务很少的时候,报警任务也趋于少数,这个时候一般的实现都会基于一个进程内的线程池执行相关的操作,架构图如下:把上图的“后台任务处理系统”放到一台机器上运行,能很快速的满足小规模的场景。但是等到业务量持续上涨的时候,一台机器就出现了资源瓶颈,这个时候一个下意识的反应就是扩容上面的任务处理系统,让不同的 Server 处理不同的报警规则。但是随着报警规则在不断增加,负载的持续上涨会引起 Server 也会重启或者突然挂掉。于是高可用、任务幂等执行、failover 等分布式问题又是面临的一个复杂的难题。04 分布式调度解决方案如果任务数达到万级别,寻求一个轻量的分布式的方案是我们的目标。分布式调度方案的基本思路都是通过单独的任务调度中心来调度任务,报警后台只管执行任务,即任务调度和任务执行隔离的思路,使得两层都能做很好的横向扩容来达到容量上涨的目的。业务实现上,每个报警规则会生成一个定时任务,这样可以保证每个报警规则负载均衡地执行。开源市场有挺多产品,比如:Quartz、xxl-job、elastic-job 等。以 quartz 为例,示意图如下:如上图所示,quartz 的每个 Server,会加载全量的所有任务,每次任务时间到了,所有 Server 会通过数据库抢锁,抢到锁的 Server 触发该任务给报警中心。这个架构解决了任务的分布式调度、幂等执行的问题,并且执行层可以水平扩展,在任务量低的情况下可以稳定运行。可是从上面的架构图可以看出,Quartz 的调度主要通过轮询 DB 和通过 DB 加锁的方式而实现,这个时候整个系统的吞吐基本上和 DB 的规格和性能息息相关。经测试,如果在任务量调度频率 1 分钟级别的触发达到1万,就会出现比较明显的调度延时。05 基于 SchedulerX 2.0 的超大规模任务调度方案SchedulerX 2.0 是阿里巴巴自研的一款商业化分布式任务调度平台,相对于开源任务调度系统,它有几大优势:支持海量任务自研轻量级分布式跑批模型可视化任务编排丰富的可视化权限隔离SchedulerX2.0 基础架构图与常见方案相比,SchedulerX2.0 会将任务分布式到不同的Server调度,每次任务调度也不需要抢锁触发,和数据库无任何交互,没有性能瓶颈。优势除了支持超大规模能力,SchedulerX2.0还有如下优势安全防护多层次安全防护:支持 HTTPS 和 VPC 访问,同时还有阿里云的多层安全防护,防止恶意攻击。多租户隔离机制:支持多地域、命名空间和应用级别的隔离。权限管控:支持控制台读写的权限管理,客户端接入的鉴权。高可用SchedulerX2.0采用高可用架构,任务多备份机制,经历阿里集团多年双十一、容灾演练,可以做到任意一个机房挂了,任务调度都不会收到影响。​商业级报警运维报警:支持邮件、钉钉、短信、电话、企业微信、飞书。支持任务失败、超时、无可用机器报警。报警内容可以直接看出任务失败的原因,以钉钉机器人为例 运维操作:原地重跑、重刷数据、标记成功、查看堆栈、停止任务、指定机器等丰富的可视化schedulerx拥有丰富的可视化能力,比如用户大盘查看任务历史执行记录查看任务运行日志查看任务运行堆栈查看任务操作记录兼容开源Schedulerx兼容开源XXL-JOB、ElasticJob、Quartz(规划中),业务不需要改一行代码,即可以将任务托管在SchedulerX调度平台,享有企业级可视化和报警的能力。分布式跑批SchedulerX提供了丰富的分布式模型,可以处理各种各样的分布式业务场景。包括单机、广播、分片、MapReduce等,架构如下:SchedulerX的MapReduce模型,简单几行代码,就可以将海量任务分布式到多台机器跑批,相对于大数据跑批来说,具有速度快、数据安全、成本低、简单易学等特点。任务编排SchedulerX通过工作流进行任务编排,并且提供了一个可视化的界面,操作简单,拖拖拽拽即可配置一个工作流。详细的任务状态图能一目了然看到下游任务为什么没跑,方便定位问题可抢占的任务优先级队列常见场景是夜间离线报表业务,比如很多报表任务是晚上1、2点开始跑,要控制应用最大并发的任务数量(否则业务扛不住),达到并发上限的任务会在队列中等待。同时要求早上9点前必须把KPI报表跑出来,可以设置KPI任务高优先级,会抢占低优先级任务优先调度。SchedulerX支持可抢占的任务优先级队列,可以在控制台动态配置:总结SchedulerX 2.0在阿里巴巴集团内支撑了所有事业群的业务,经历了多次双十一的考验,当前在公有云已接入1000+家企业,在海量任务和高可用方面有充分的经验,还有企业级的报警监控和可观测能力。显然,在超大规模任务调度领域,SchedulerX 2.0已经是目前最优解决方案之一。想了解更多分布式调度平台SchedulerX 2.0的特色,可前往:https://www.aliyun.com/aliware/schedulerx产品控制台:https://schedulerx2.console.aliyun.com

解决 Serverless 落地困难的关键,是给开发者足够的“安全感”

作者 | 不瞋刚刚过去的 2021 年天猫双 11,阿里云函数计算与阿里巴巴运维体系全面实现标准化对接,打通研发的最后一公里,首次实现了业务全链路“ FaaS + BaaS ”的 Serverless 体系化研发,覆盖淘特、淘系、阿里妈妈、1688、高德、飞猪等业务场景,支撑场景数量同比增加 2 倍,峰值流量总数同比增加 3 倍,实现了百万 QPS 的突破,人效提升 40%。前段时间,我与 InfoQ 大咖说合作了一期直播,跟开发者们聊了聊我眼中的 Serverless。大家对于 Serverless 热情很高,但是顾虑仍然存在,这也是我写作本文的原因。作为这一技术浪潮的见证者,我想跟大家一起思考 Serverless 诞生的原因,阿里云 Serverless 技术和产品的演进历程,以及我对 Serverless 未来趋势的判断。01 云产品体系的 Serverless 化推动技术演进虽然 Serverless 对很多人来说,仍然比较新鲜,但其实 Serverless 这种形态早已有之。2010 年我刚加入阿里云,参与飞天操作系统研发,飞天操作系统最初是通过管理数千台的机器来执行大数据处理的。用户的编程界面是 MapReduce 任务,通过 SQL 语句等来处理海量数据,这就是早期的 Serverless 形态。阿里云的第一个云服务对象存储 OSS,亚马逊云科技的第一个云服务 S3,它们其实也都是 Serverless 形态的存储服务。用户不需要关心数据如何被分片存储到不同的服务器上来实现负载均衡,也不需要考虑如何做到在服务器宕机或者交换机故障时,保证数据的高可靠性和高可用性,他们只需要用简单的 API 就可以实现海量数据的可靠存储。他们都屏蔽了 Server 的复杂度,让用户有一个非常简洁的 Serverless 体验,这些都是 Serverless 形态。2012 年,Serverless 概念被首次提出,到亚马逊云科技正式商用 Lambda,Serverless 开始流行并逐渐走红。近 10 年时间,这样的演进过程并不偶然、也非一蹴而就,反而是带着宿命般的必然性,其背后原因是云的产品体系一直都在向 Serverless 化演进。无论是阿里云、Azure,还是亚马逊云科技,绝大多数新产品都是全托管的 Serverless 形态。时至今日,公有云的用户越来越习惯使用全托管的服务,除了省力以外,对很多用户来说,最重要的是能更高效的解决业务问题。如果全托管的服务能带来更好的性能、更好的稳定性、更少的运维代价,为什么不用呢?按照这些逻辑,越来越多的云产品都会向全托管、Serverless 形态演进。当云的产品体系 Serverless 化达到一个临界值,通过函数计算这样的 Serverless 计算服务结合其他 Serverless 形态的云服务,能够完整的实现整个应用时,Serverless 就会变成了一个确定的技术趋势,并越来越流行。02 Serverless 走出幻想破灭的低谷2017 到 2018 年,我们都有体感 Serverless 热度达到了一个高峰,但和很多新兴技术一样,从概念大讨论到企业落地应用,都会经历幻想破灭的低谷。从 Serverless 这十年的发展来看,无论是学术界还是工业界,都认为这是一项颠覆式的技术,在提升研发效率、资源效率上有着巨大的潜力。但作为一个新概念和新的计算形态,Serverless 最主要的挑战是对开发者心智的改变,在工具链、编程模型、应用架构上,都需要开发者转换思路。今天,这些问题正在被快速的、持续的解决。Serverless 正处于稳步上升期,我们能看到业界最主要的云服务商在不断推出不同形态的 Serverless 计算服务,比如 Google Cloud Run,亚马逊云科技的 App Runner,阿里云的 Serverless 应用引擎 SAE。另外,阿里云的函数计算这类最经典的 Serverless 计算服务,也正变得越来越通用,对应用的侵入越来越少。无论在阿里巴巴上还是在阿里云上,开发者对 Serverless 的认识越来越客观、务实,并在越来越多的场景中引入 Serverless 技术和相关的工具链,驱动 Serverless 生态愈加成熟。03 给开发者安全感,是最重要的事我们经历了一个从 Serverless 非常受关注到落地困难,再到 Serverless 被广泛使用的全过程。这个过程中也确实遇到了不少挑战,解决 Serverless 落地困难的关键,在于给开发者安全感。对开发者来说,Serverless 把更多的技术层面的东西交给了云厂商去做,所以怎么给他们安全感,让他们无负担使用是非常关键的,也是他们做技术选型时最关注的点。开发者这种安全感的担忧主要来自于两方面:云厂商锁定问题:Serverless 让应用更深度的依赖于云服务商的能力,如何避免 vendor lock-in,从一个云迁移到另一个云,会有哪些障碍?控制黑盒问题:云厂商接管了应用的运行平台,怎么能提供给用户控制力?比如用户怎么能看到足够丰富的指标来优化应用或者掌控应用运行的情况?云平台出问题了怎么办?出现问题时,用户有什么手段能快速查明问题,恢复服务?对于供应商锁定的担忧。阿里云是以公有云、阿里集团、开源三位一体的方式打造 Serverless 产品,坚定的拥抱开源开放。阿里云函数计算的 Runtime 运行时采用无侵入的标准的 http-server 协议,用户使用 Golang 或者 PHP 写的 Web server 放上来就可以跟 Serverless 平台去交互。另外函数计算的可观测能力基于开源开放的 OpenTelemetry、OpenTracing 等标准。阿里云推出的 Serverless Devs 工具链也是开源开放的,提供了多个云厂商的 Serverless 应用部署的能力。承载阿里云事件生态的 EventBridge 也是采用 CNCF CloudEvents 开放标准。这些都是希望开发者能够通过开源开放的方式来使用产品,未来,我们会积极推进 Serverless 领域的标准。对于控制黑盒问题,最主要的是要做好产品设计的平衡,既能给开发者控制力,又能减小开发者的复杂度。阿里云函数计算把给开发者安全感看作最重要的事情,我们在可观测性上是业界首个,也是目前唯一一个透出了实例级别的指标,让用户能更容易调优 Serverless 应用。我们透出了非常细粒度的资源计量数据,让用户能更容易判断费用是否符合预期。在未来,我们会将系统事件和状态以合适的方式透出给开发者,让他们能更容易预期系统的行为。我们也会在问题诊断等方面开放更多的能力,去贴合开发者已有的开发习惯,让他们能更平滑的使用 Serverless。04 正在全面落地的 Serverless在应用场景上来看,Serverless 不再仅仅是小程序,还有电商大促、音视频转码、AI 算法服务、游戏应用包分发、文件实时处理、物联网数据处理、微服务等场景。Serverless 正持续与容器、微服务等生态融合,降低开发者使用 Serverless 技术的门槛,反过来也将促进传统应用的云原生化。在企业赋能方面,尤其是疫情之后,能够看到用户对 Serverless 的认知变深,在很多场景下,切换到 Serverless 架构确实能够为用户带来明显的收益,用户逐渐认可这项技术。011、Serverless 全链路、全场景覆盖天猫双 112020 年天猫双 11,阿里云实现了国内首例 Serverless 在核心业务场景下的大规模落地,扛住了全球最大规模的流量洪峰,创造了 Serverless 落地应用的里程碑。今年天猫双 11,阿里云 Serverless 支撑业务场景更多,范围更广,阿里云函数计算与集团内的运维体系全面实现标准化对接,打通研发的最后一公里,首次实现了业务全链路“ FaaS + BaaS ”的 Serverless 体系化研发,覆盖淘特、淘系、阿里妈妈、1688、高德、飞猪等业务场景,支撑场景数量同比增加 2 倍,峰值流量总数同比增加 3 倍,实现了百万 QPS 的突破,人效提升 40%。022、网易云音乐音视频算法的 Serverless 探索网易云音乐产品背后,实际有非常多的算法服务支撑,比如多种码率的音频转码、听歌识曲中应用的音频指纹生成和识别、副歌检测、小语种音译歌词等等。这些任务的资源需求和执行时间变化很大,需要使用 C++、Python 等多种语言实现,对算力的弹性要求非常大。原先网易是在自己的数据中心搭建这样一个算法服务平台,落地了 60+ 音视频算法,对接 100+ 的业务场景。但随着业务增长,基础设施管理的负担越来越大。虽然通过了很多方式去简化了内部业务场景、算法等的对接,但越来越多夹杂存量、增量处理的算法;不同流量的业务场景规模,以及不同业务场景可能会复用同一类算法的,导致在业务上的时间越来越少。比如上线一种新算法,首先要对超过 6000 万首存量歌曲进行处理,这要求平台在短时间内弹出大量算力,可靠的执行任务,同时提供完善的应用、实例等多维度的监控信息。这些需求是非常匹配函数计算的。网易在函数计算上高峰期一天处理超过 2000 万个任务,算法应用到业务 10 倍速的提升,稀疏调用的算法成本大幅缩减。网易这个案例最有意思的点,在于他们在应用层融合了自有机房和公有云上的服务。以往大家谈到 Serverless,觉得它很难在混合云的场景下应用。网易的案例证明了专有云和公有云融合不是只有资源纳管这一种方式,在应用层考虑融合方案,有时候效果会更好。网易云音乐音视频算法的 Serverless 探索之路3、南瓜电影 7 天全面 Serverless 化另一个比较有意思的案例是南瓜视频使用 SAE 实现传统微服务应用的零迁移改造,只用了一周就完整迁移到 SAE 平台。南瓜原有的微服务平台面临几个挑战:运维成本高。要管理基础设施,要规划网络,要升级系统等等,大量的时间花在这些低价值的工作上,而不是专注于业务的发展;机器难以规划容量。热点电影经常造成访问热点,临时扩容操作复杂、慢。南瓜经历了业务的爆发式增长,因为一部热映电影,1 小时新增 80 万注册用户,比正常流量高了 80 倍,系统很快就崩了。这次经历促使南瓜进行了技术升级。用户也对比了 K8s 和 SAE,最后认为要玩转 K8s ,需要组建好专业团队,代价不小。SAE 的产品形态非常有亲和力,南瓜只花了很短的时间就迁移到 SAE,现在所有的应用都运行在 SAE 上。南瓜电影 7 天内全面 Serverless 化实践05 Serverless 不是未来,是现在云的发展一定是往更高的抽象层面发展,让用户研发效率更高更敏捷,资源使用更高效。因此云的产品体系一定是 Serverless 化,也就是越来越多的云服务是全托管、Serverless 的形态。如果我们把云看作一台计算机,那么 IaaS 层是硬件,以 K8s 为代表的容器编排系统是操作系统,而 Serverless 计算则是应用的运行时。所以 Serverless 是云的未来,这实际上不算是对未来的预测,而是正在发生的事实。接下来,Serverless 的产品形态会变得多样,早些年大家都把 Lambda 这样形态的产品等同于 Serverless 计算,这几年我们看到 Google Cloud Run,亚马逊云科技 App Runner 等针对 Web 应用场景的 Serverless 服务,阿里云函数计算也在不断演进,比如支持容器镜像、更少的运行限制等等。而且针对传统微服务等存量市场,我们还推出了 SAE 这样形态的服务,让用户能够非常方便的把存量应用迁移上来,享受 Serverless 的红利。Serverless 底层技术发展上也有一些值得关注的趋势。包括在资源调度上更加智能,因为 Serverless 的计算模式给平台提供了更多的负载信息,使得平台有机会通过数据驱动的方式在资源调度、流量路由等方面做得更加精准。另外,Serverless 有望支持更多类型的硬件,包括 ARM 类型的 CPU、GPU 或者 FPGA 等异构硬件,给用户提供更有性价比的计算类型。谈未来,就不免说到对 Serverless 终点的判断,我想云就像一台计算机,在过去的 10 年,云主要是通过 Cloud Hosting 的模式,在兼容原有编程模式的同时,为开发者提供了海量的算力。但这种模式有点像使用汇编语言编程,开发者需要处理相当多的细节。微软预测未来 5 年将新增 5 亿个应用,超过过去 40 年的总和,这是传统的开发模式难以支撑的。所以我们看到现代应用、低代码等理念开始流行。下一个 10 年,云的编程模型将迎来巨大的创新。过去 PC、移动互联网,都从一开始的硬件创新,发展到形成自己的原生编程模型,形成完整的、繁荣的产业生态,云也正在经历这样的过程。最终,云会有属于自己的、原生的、高效的编程模型和应用研发模式。而 Serverless 在云的生态中,扮演应用运行时的角色,是承载应用运行的基础设施。作者简介:不瞋:阿里云 Serverless 产品研发负责人,致力于构建下一代弹性、高可用的无服务器计算平台。12.02 广州站 | Serverless 首个沉浸式技术实践营开放报名啦!点击下方链接,了解更多!https://developer.aliyun.com/article/805658?groupCode=serverless往期推荐今年双十一,阿里业务 100%上云,云原生有哪些技术亮点?首次!统一调度系统规模化落地,全面支撑阿里巴巴双 11 全业务全面升级 —— Apache RocketMQ 5.0 SDK 的新面貌

【体验有礼】Serverless 极速搭建 Hexo 博客

01 体验介绍Serverless 降本增效免运维的特性为开发者带来了实打实的好处,11 月 9 日至 11 月 23 日期间,阿里云函数计算上线了“Hexo 博客部署体验活动”,完成部署即可获得“TOMY 多美卡合金车模一辆”。活动时间:11月9日-11月23日参与方式:扫描下方二维码或浏览器打开网址快速体验 https://developer.aliyun.com/adc/scenario/a72a5fd7cec24405a0894d2361894dd1?02 活动详情搭建 Hexo 博客步骤:开通函数计算服务开通 CDN 服务创建资源安装 Serverless Devs 命令行工具配置阿里云账号信息搭建 Hexo 博客项目完成体验后,你将获得:Serverless Devs工具的使用搭建基于函数计算 Hexo 博客的流程精美礼品(活动详情见页面)入群还可与阿里云技术专家零距离交流11月9日-23日期间完成场景体验即有机会获得 TOMY 多美卡合金车模一辆!车模随机发放,工作日上午10:00刷新,数量有限先到先得若有相关问题钉钉搜索: 35791205 加入“体验实验室热心网友分群”咨询阿里云函数计算是事件驱动的全托管计算服务。开发者使用函数计算(FC)无需管理服务器,只需专注于函数代码便能快速搭建应用。权威咨询机构 Forrester 发布 2021 年第一季度 FaaS 平台评估报告,阿里云函数计算凭借在产品能力、安全性、战略愿景和市场规模等方面的优势脱颖而出,产品能力位列全球第一,这也是首次有中国云厂商进入 FaaS 领导者象限。在今年的可信云大会上,阿里云函数计算 FC 更是荣获《可信云 Serverless 平台技术能力》先进级认证(最高级、国内首批)。戳下方链接立即体验!https://developer.aliyun.com/adc/scenario/a72a5fd7cec24405a0894d2361894dd1?

干货分享:细说双 11 直播背后的压测保障技术

“今年 1 月到现在,淘宝直播的用户超过了 5 亿,到 8 月份流量也增长了 59%,在最核心的商家 GMV 上增长了 55%。双 11 是从 10 月 20 日晚开始的,我们希望淘宝直播作为主场去承接这件事情。”日前,淘宝事业群直播事业部负责人程道放在接受 21 世纪经济报道记者采访时透露,过去一年的直播可谓热闹,今年会更加专业化。  如此大的用户体量下,直播类应用给后端服务带来了一些什么不一样的挑战呢?我们今天来介绍一些直播的架构,以及针对这个架构,给我们的应用架构带来的挑战。 01直播的架构我们通常看到的有下面几种直播: 1. 单人直播,例如淘宝直播,通常伴随着秒杀,弹幕,送火箭等业务逻辑;2. 多人同时直播,例如连麦,会议;3. 录播,对于部分直播场景如培训、会议等,需要将现场直播视频保存以进行传播、留存等使用,有对直播进行录制的需求。这种往往对实时性要求不高。而当用户观看直播时,如果服务接入了 CDN,若接入 CDN,播放端选择就近的 CDN 节点进行拉流播放,此时拉流压力在 CDN;若未接入 CDN,播放端从直播源站进行拉流。下图是一个比较常见的视频流的架构和两条数据走向: 1. 视频流推拉逻辑,如蓝色线所示2. 常规的业务逻辑,如黄色线所示可以看到有四个主要模块:1. 推流端:主要的作用在于采集主播的音视频数据推送到流媒体服务端;2. 流媒体服务端:主要作用在于把推流端传递过来的数据转换成指定格式,同时推送到播放端方便不同播放端用户观看,当然目前云产商也流媒体服务端的一整套解决方案;3. 业务服务端:主要处理一些常见的业务逻辑,如秒杀,弹幕等等;4. 播放端:播放端简而言之就是拉取音视频进行播放,把相应的内容呈现给用户。四个关键的模块的协议其实就是流媒体传输协议。大部分直播的结构都采取上图的格式,较大的区别是是否引入 CDN。一般来说,我们建议客户引入 CDN 来减少直播流量对服务器的冲击。四个模块之间的协议并不着重强调一致性。接下来,我们沿着这个架构来讨论一下,在这其中比较脆弱的风险有哪些,以及我们如何提早通过压测来排查这些风险点。02 直播中的挑战01挑战一:视频流给流媒体服务端的压力在这个推拉的逻辑中,由于涉及视频的流量较大,经过的路线较长,对流媒体服务器都会造成冲击;通场的做法是引入 CDN,当用户开始收看视频的时候,会先就近去 CDN 拉取流,如果这个时候视频内容还没有缓存在 CDN 的时候,CDN 就回源到流媒体服务端。 但是,风险就存在在瞬间大量用户同时收看 CDN,CDN 大量回源的时候;这种脉冲流量,会给流服务端带来不可预计的效果。我们通常通过压测来提前验证链路的有效性,甚至可以通过压测,提前把视频在 CDN 预热。然而,传统的 HTTP 请求协议是无法支持这种场景的,因为:1. 即使开源软件 srs_bench,以及 JMeter 都提供了一些插件来使用。但是这些开源软件需要用户对视频协议有比较深入的理解,使用门槛会略微偏高;2. 视频压测本身对带宽的要求非常高,这就意味压测机器成本比较高;3. 视频压测需要考虑到地域对传输质量的影响。针对以上问题,PTS 加入了 RTMP/HLS 协议,并且结合压测场景做了抽象,让用户可以界面化的使用不同协议的压测。 除此以外,PTS 还提供丰富的编排模式,可以方便自如的对场景进行编排;更重要的是,还可以利用 PTS 全国定制的模式,模拟客户从不同的地方发起请求,更快捷的探测出问题。 02挑战二:低延时的互动协议和传统的大促不一样,直播往往追求和线下客户的互动。例如弹幕,评论,聊天,秒杀等等。主持人聊的 热火朝天,用户毫无反应,这就是一次失败的直播了。而普通的 HTTP 请求无法满足对时效的需求;因此,通常这些功能用WebSocket来实现的。因为 HTTP 是一种无状态的、无连接的协议,WebSocket 则通过服务端/客户端建立长链,来保证消息的实时性、以及降低性能开销。每建立一个 WebSocket 连接时,在握手阶段都会发起 HTTP 请求。通过 HTTP 协议协定好 WebSocket 支持的版本号、协议的字版本号、原始地址,主机地址等内容给服务端。报文的关键地方在于 Upgrade 的首部,用于告诉服务端把当前的 HTTP 请求升级到 WebSocket 协议,如果服务端支持,则返回的状态码必须是 101:HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept:xxxxxxxxxxxxxxxxxxxx有了上述返回,Websocket 连接才建立成功,接下来就是完全按照 Websocket 协议进行了数据传输了。针对 WebSocket 的通信过程,JMeter 提供了插件来模拟整个过程,但是它也需要用户理解协议的玩法,使用起来相对晦涩。PTS 通过抽象业务含义,用户通过场景配置和施压配置,仅需要配置压测 url 等基本配置、出参设置、检查点设置等几个简单参数,就能够把复杂协议玩起来。除了在直播中使用,Websocket 也广泛应用于在线游戏、股票基金、体育实况更新、聊天室、弹幕、在线教育等实时性要求非常高的场景。03挑战三: 高并发的脉冲流量不同于普通应用,直播类应用的使用时间段非常的集中,因此在这短短几小时之间,会涌入大量的用户,一次大 V 的直播通常就会造成百万级的用户登录,故直播系统对应脉冲流量的能力要求也变得很高。而且在抢货的时候,和传统的秒杀不同,往往是主播进行到某个时间突然发起秒杀的--这个时间往往无法非常精确--同时脉冲流量对系统的要求极高,很多平时不会出现的问题,例如懒加载,jit 预热,冷热数据切换等传统大流量不会出现的问题,都会出现。这两点特性,要求压测工具能够瞬间发起大流量。这除了需要较多的机器引擎,还需要对流量的有精准控制--满足流量快速攀升的诉求。而这两点,正是阿里云 PTS 的强项。阿里云 PTS 站在双 11 巨人的肩膀上,是阿里全链路压测的延伸。PTS 通过伸缩弹性,轻松发起用户百万级别的流量,免去机器、人力成本;PTS 对流量的控制,能够实时脉冲,精准控制; 是应对视频直播快速攀升的流量脉冲的优秀方案。03 最后PTS 针对视频、直播行业的变化,对 PTS 支持的协议做了全面升级。它不光支持传统的 HTTP 请求,更是引入了 HTTP 2、流媒体、MQTT 等多种协议,让用户可以 Test Anywhere!另外,PTS 推出了新的资源包售价,以及更低价格的 JMeter 专属资源包,现在正值双十一优惠中,全场 88 折起,最低可到 0.99 元,关于 PTS 的更多问题和产品建议,欢迎大家扫码进群沟通。相关链接阿里云PTS https://pts.console.aliyun.com/#/overviewpagePTS资源包购买 https://common-buy.aliyun.com/?commodityCode=ptsbag#/buy

首个沉浸式云原生 Serverless 技术实践营开启报名

阿里云云原生 Serverless 团队重磅推出“沉浸式”技术实践营,面向企业技术人员,分享 Serverless 的落地实践,多视角碰撞技术观点,实时互动答疑,共同探索 Serverless 企业落地更多的可能性。报名地址:https://survey.aliyun.com/apps/zhiliao/zOe4n4KM1温馨提示:参会免费,采取报名审核制,仅限 50 人,中午含餐,完成动手实操,颁发阿里云官方认证证书。12月2日(周四),广州—阿里中心,沉浸式参会体验:想听就听,企业生产业务 Serverless 化分享圆桌讨论,多视角剖析 Serverless想玩就玩,手把手体验万人打磨生产级场景想问就问,实时弹幕互动挑战答题,验证学习效果、赢大奖参与在左、纪念在右,颁发技术实践营结业证书

无处不在的 Kubernetes,难用的问题解决了吗?

作者:望宸、木环、溪洋 等容器本质是一项隔离技术,很好的解决了他的前任 - 虚拟化未解决的问题:运行环境启动速度慢、资源利用率低,而容器技术的两个核心概念,Namespace 和 Cgroup,恰到好处的解决了这两个难题。Namespace 作为看起来是隔离的技术,替代了 Hypervise 和 GuestOS,在原本在两个 OS 上的运行环境演进成一个,运行环境更加轻量化、启动快,Cgroup 则被作为用起来是隔离的技术,限制了一个进程只能消耗整台机器的部分 CPU 和内存。当然,容器技术之所以能流行,更因为他提供了标准化的软件开发交付物 - 容器镜像。基于容器镜像,持续交付这件事才能够真正落地。我们还能罗列出许多使用容器技术的理由,这里就不再一一赘述。同时,云计算解决了基础资源层的弹性伸缩,却没有解决 PaaS 层应用随基础资源层弹性伸缩而带来的批量、快速部署问题。于是,容器编排系统应运而生。从第三方的调研数据看,容器和 Kubernetes 已经成为云原生时代主流的选择,但实际落地的时候,却陷入了困境。我们尝试去总结了一些共通点,以及应对方案,也许能为正在落地容器技术的企业提供一些参考。01 难用在哪?容器和 Kubernetes 的先进性毋庸置疑,但当大量的企业在开始拥抱容器编排领域的事实标准 Kubernetes 时,却陷入了困境。“K8s 就像一把双刃剑,既是最佳的容器编排技术,同时也存在相当高的复杂性和应用的高门槛,这个过程中往往会导致一些常见性错误”。就连 Kubernetes 的创立者和核心推动者 Google 本身都承认这个问题。一次采访中,阿里巴巴高级技术专家张磊分析了 Kubernetes 的本质,他指出,“Kubernetes 本身是一个分布式系统而不是一个简单的 SDK 或者编程框架,这本身已经将其复杂度提升到了系统级分布式开源项目的位置。此外,Kubernetes 第一次将声明式 API 的思想在开源基础设施领域普及开来,并以此为基础提出了一系列诸如容器设计模式和控制器模型等使用范式,这些具有一定先进性和前瞻性的设计也使得 Kubernetes 项目被大众接受时会存在一定的学习周期。”我们大致总结了 Kubernetes 的 4 大复杂性。1、认知复杂:他和原有的后端研发体系不同,延伸出一套全新的理论,并提供了一系列全新的技术概念,并且这些概念,例如 Pod、sidecar、Service、资源管理、调度算法和 CRD 等等,主要是面向平台研发团队而非应用开发者设计,提供很多强大灵活的能力。但是,这不仅带来了陡峭的学习曲线,影响了应用开发者的使用体验,甚至在很多情况下理解不当还会引发错误操作,乃至生产故障。2、开发复杂:K8s 使用声明式方法来编排和管理容器。为了实现这一点,需要配置一个 YAML 文件,但再复杂的应用程序中,引入新环节影响了开发者的生产力和敏捷性。此外,缺乏内置的编程模型,开发者需要依赖第三方库来处理程序间的依赖关系,这些都会影响到开发效率,并增加不必要的 DevOps 开销。3、迁移复杂:将现有的应用程序迁移到 K8s 比较复杂,尤其是非微服务架构,在很多情况下,必须重构特定组件或整个架构,并且需要使用云原生原理重构应用程序,例如状态依赖,如写本地目录、有顺序,网络依赖,如写死 IP,数量依赖,如副本固定等等。4、运维复杂:K8s 的声明式 API 颠覆了传统的过程式运维模式,声明式 API 对应的是面向终态的运维模式。而随着 K8s 集群规模的增长,徒手基于开源K8s,运维难度也会呈线性增长,呈现在集群管理、应用发布、监控、日志等多个环节,集群稳定性将面临极高的挑战。02 是否还有别的解法?技术总有双面性,容器革新了云计算的基础设施,成为了新的计算界面。而 Kubernetes 则搭建了一个统一的基础设施抽象层,为平台团队屏蔽掉了“计算”、“网络”、“存储”等过去我们不得不关注的基础设施概念,使得我们能够基于 Kubernetes 方便地构建出任何我们想要的垂直业务系统而无需关心任何基础设施层的细节。这正是 Kubernetes 被称为云计算界的 Linux 以及 “Platform for Platforms” 的根本原因。但直接上手操作 Kubernetes 是否是我们应用容器技术的唯一选择呢?答案是否定的。在容器技术的演进过程中,我们也发现了不少能够降低容器编排门槛的开源项目和商业化产品,接下来,我们将从双手的解放程度由低到高,一一介绍。011、围绕 Kubernetes 生态的开源工具OAM/KubeVela 是托管在 CNCF 中的开源项目,旨在降低 K8s 在应用开发和运维上的复杂性,最初由阿里云和微软云联合发起。KubeVela 作为开放应用架构模型 OAM 的标准实现,与底层基础设施和无关、原生可扩展,而且最重要的是它完全以应用为中心。在 KubeVela 中,“应用”被设计为整个平台的「一等公民」。应用团队只需要围绕组件、运维特征、工作流等几个跨平台、跨环境的上层抽象来进行应用的交付与管理,无需关注任何基础设施细节和差异性;平台管理员则可以随时以 IaC 的方式配置平台支持的组件类型和运维能力集等特性,以便适配任何应用托管场景。KubeVela 是完全基于 K8s 构建的,具备天然的被集成能力和普适性,天然透出 K8s 及其生态的所有能力,而不是往上叠加抽象。因此 KubeVela 适用于那些具备一定的 K8s 平台开发和运维能力,同时希望能够使用到全套 K8s 能力,不断扩展平台能力的技术团队。容器已经从一项隔离技术演进成一个生态,KubeVela 这类可以极大降低 K8s 使用复杂度的开源工具,会逐步释放其生命力,使开发人员无需成为 K8s 专家即可享受到云原生带来的高效与便捷。sealer 是一款开源的分布式应用打包交付运行的方案,极大的简化了容器项目的交付复杂性和一致性问题。sealer 构建出来的产物可称之为"集群镜像",并内嵌了 K8s,该"集群镜像"可以 push 到 registry 中共享给其他用户使用,也可以在官方仓库中找到非常通用的分布式软件直接使用。交付是容器生态的另一个难题,面临着依赖复杂、一致性的问题,尤其是工业级的 Kubernetes 交付项目,交付周期变长、交付质量要求高,sealer 非常适合于软件开发商、ISV 等性质的企业,可将部署时间缩短至小时级别。2、开放、标准化的企业级 Kubernetes 服务大部分云厂商提供了 Kubernetes as a Service 的容器平台能力,比如 AWS EKS 和阿里云的 ACK,可以大幅简化 K8s 集群的部署、运维、网络存储、安全管理等能力,提供了通过 CNCF 标准化认证的 K8s服务,可以满足几乎全场景的工作负载需求,并提供了丰富的扩展和定制能力。此外,大部分云厂商会基于开源 Kubernetes 框架,在上层做不同程度的封装,来适配不同企业背景和不同场景下的需求,以提供发行版和 Pro 版,例如阿里云的 ACK Pro 就提供了托管 master 和全托管节点池的能力,全面整合IaaS能力,更加高效、安全、智能,将容器集群的各种细分场景最佳实践和全栈优化作为内置服务提供给企业。从现有用户规模来看,这是大部分互联网企业落地容器技术的主流选择。更多信息请移步至:《阿里云容器服务多项重磅发布:高效智能、安全无界的新一代平台》 。3、向 Serverless 演进的 Kubernetes 服务传统的 Kubernetes 采用以节点为中心的架构设计:节点是 Pod 的运行载体,Kubernetes 调度器在工作节点池中选择合适的 node 来运行 Pod。而对于 Serverless Kubernetes 而言,最重要的一个概念是将容器的运行时和具体的节点运行环境解耦。用户无需关注 node 运维和安全,降低运维成本;而且极大简化了容器弹性实现,无需按照容量规划,按需创建容器应用 Pod 即可;此外 Serverless 容器运行时可以被整个云弹性计算基础设施所支撑,保障整体弹性的成本和规模。众多云厂商也将容器和 Serverless 做进一步的融合:例如阿里云的 Serverless 容器服务 ASK、Google GKE 的 AutoPilot,以免运维的方式降低了客户在 K8s 节点和集群上的操作复杂度,无需购买服务器即可直接部署容器应用;同时,仍然可以通过 K8s 命令行和 API 来部署容器应用,充分利用了 K8s 的编排能力,并且根据应用配置的 CPU 和内存资源量进行按需付费。这类服务非常善于处理一些 Job 类的任务,例如 AI 领域的算法模型训练,同时拥有在 K8s 环境下比较一致的开发体验,是容器服务生态非常好的补充。更多信息可以移步至:《Serverless Kubernetes:理想,现实与未来》。044、容器和 Serverless 技术加持的新一代 PaaS 服务企业级市场的需求总是分层的、多样化的,这和技术人才的分布紧密相关,并不是每家企业都能建立一个技术实力足够强的团队,尤其是在非北上广深的城市,并且落地一项新技术时,总是分阶段规划的,这就给更多的产品形态孕育了市场空间。K8s 虽然提供了容器应用的全生命周期管理,但是太丰富、太复杂、太灵活,这既是一种优势,有时候也是一种劣势。尤其是对于习惯了在虚拟机时代,以应用为视角来管理应用的研发运维人员而言,即便像 AWS EKS、阿里云 ASK 等已经在一定程度上降低了 K8s 的操作复杂度,他们仍然希望通过某种方式,可以进一步降低容器技术的使用门槛。容器和 K8s 并非一定要捆绑使用,在一些新型的 PaaS 服务中,例如阿里云的 Serverless应用引擎(SAE),底层将虚拟化技术改造成容器技术,充分利用了容器的隔离技术,来提升启动时间和资源利用率,而在应用管理层,则保留了原有的微服务应用的管理范式,使用者不必学习庞大而复杂的 K8s 来管理应用。这类新型的 PaaS 服务通常还会内置全套微服务治理能力,客户无需考虑框架选型、更无需考虑数据隔离、分布式事务、熔断设计、限流降级等,也无需担心社区维护力度有限二次定制开发的问题。此外,底层计算资源池化后,其天然的 Serverless 属性使得用户不必再单独购买和持续保有服务器,而是按 CPU 和内存资源量来配置所需的计算资源,让容器 + Serverless + PaaS 得以合三为一,使得技术先进性、资源利用率优化、不变的开发运维体验可以融合在一起。因此,相比于本文中的其他方案,这类方案的特色是提供了PaaS 体验,让新技术落地更加平稳。大部分传统行业、一些技术能力偏向于业务层的互联网企业、和一些不希望因受制于后端而影响业务快递迭代的创业公司,大多都会倾向于 PaaS 形态的产品,抛开企业属性,PaaS 类的服务在处理以下场景更具交付优势:上线了一个新的项目,想快速验证,不要出故障,同时控制人力的投入成本;业务体量上升快,用户越来越多,业务稳定性有点 hold 不住,新版本发布、线上应用管理等环节开始有点畏手畏脚,但技术储备还无法及时应对当前变化;决定要把原有的单体架构升级成微服务架构,但由于团队缺少微服务专家,评估完项目发现升级风险比较高。更多信息可以移步至:《打破 Serverless 落地边界,阿里云 SAE 发布 5 大新特性》。5、更为极致的 Serverless 服务 -  FaaSFaaS 的出现,让具备弹性灵活诉求的业务场景,有了更好的选项。越来越多的大中型企业将传统后端领域对扩容有灵活需求的执行单元剥离出来,运行在 Serverless 架构上。这使得 FaaS(函数计算)成为容器和 K8s 外,另一种通用算力的选择。和 Google Cloud Run、App Runner 等 Serverless 服务一样,FaaS 的产品形态正变得越来越开放,运行上的限制越来越少,除了适合事件驱动的计算模型,也适合 Web 单体应用、Job 等场景,可以帮助用户把弹性发挥到极致,进一步提升计算资源的利用率。例如,游戏行业的莉莉丝将函数计算应用于战斗校验,来验证玩家客户端上传的战斗是否有作弊的情况。战斗校验一般需要逐帧计算,CPU 消耗会非常高,通常 1 队 v 1 队的战斗需要 n 毫秒,而 5 队 v 5 队的战斗则需要相应 5n 毫秒,对弹性要求很高。此外,容器架构下挂载的 SLB,会因为轮询机制导致无法感知 Pod 的实际负载,由此引起的负载不均,产生死循环和稳定性风险。函数计算的调度系统帮助莉莉丝合理安排每个请求,对于死循环问题,也贴心的提供了超时杀进程机制,并将调度系统的复杂性下沉到了基础设施。此外,函数计算深度优化后的冷启动时延大幅下降,从调度、到获取计算资源、再到服务启动,基本在 1 秒+左右。另外,FaaS 的出现,也极大的解放了创业公司全栈工程师在 DevOps 上花费的精力,来承载小程序、网站等 Web 单体应用,例如,函数计算降低了 Node.js 等前端语言的服务器维护门槛,只要会写 JS 代码就可以维护 Node 服务。更多信息可以移步至:《跨越行业绊脚石,阿里云函数计算发布 7 大技术突破》03 适合的才是最好的需求的越多,投入的也会越多,这是恒古不变的道理。在我们决定引入容器技术后,使用 K8s 之前,需要想清楚为什么需要 K8s。如果我们希望充分利用 K8s 的全套能力,并且团队具备一定的技术储备,那么 KubeVela 是理想的开源选型,sealer 还能帮助我们降低交付复杂度;如果希望将 K8s 上层不同程度的封装工作交给云厂商来处理,以更高效的适配不同业务场景下的需求,那么云厂商提供的商业化的容器服务是不错的选择;如果容器和 K8s 无法契合弹性业务类的诉求,则可以选择 FaaS。但又如果我们的应用并没有那么复杂,只是朴素的希望简化应用生命周期管理和底层基础设施,保障业务的高可用,并专注在业务开发上,那么可能就不需要使用 K8s 来编排容器应用了,毕竟 K8s 是源自 Google 的 Borg,他是用来管理 Google 海量的容器应用的。参考文章:《云计算的前世今生》,刘超《灵活、高效的云原生集群管理经验:用 K8s 管理 K8s》,淮右、临石《复杂性会成为 Kubernetes 的“致命伤”吗?》,赵钰莹《Simplifying Kubernetes ForDevelopers》,Rishidot Research《KubeVela 正式开源:一个高可扩展的云原生应用平台与核心引擎》,OAM项目维护者《KubeVela 1.0 :开启可编程式应用平台的未来》,OAM项目维护者相关链接:项目地址: https://github.com/oam-dev/kubevela项目地址: https://github.com/alibaba/sealer

首次!统一调度系统规模化落地,全面支撑阿里巴巴双 11 全业务

01 背景统一调度项目 1.0 成功支持 2021 年双 11 大促,统一调度方案实现了从容器调度到快上快下全流程的全面升级和优化。项目组 100 多位核心成员,成功走过了立项、POC、方案评审设计、封闭开发测试、大促冲刺各个阶段,历经考验成功上线。作为阿里巴巴的核心项目,阿里云(容器团队和大数据团队)联合阿里巴巴资源效能团队、蚂蚁容器编排团队,历时一年多研发和技术攻坚,实现了从“混部技术”到今天“统一调度技术”的全面升级。今天,统一调度已实现阿里巴巴电商、搜推广、MaxCompute 大数据和蚂蚁业务的调度全面统一,实现了 pod 调度和 task 高性能调度的统一,实现了完整的资源视图统一和调度协同,实现了多种复杂业务形态的混部和利用率提升,全面支撑了全球数十个数据中心、数百万容器、数千万核的大规模资源调度。云原生产品家族02 统一调度技术全面升级云计算的本质,就是把小的计算碎片变成更大的资源池,充分削峰填谷,提供极致的能效比。对数据中心低碳节能、绿色环保、科技发展、更高效运转的追求下,阿里巴巴对技术的探索永无止境。阿里的技术人有一个理想,让数据中心的算力成为水、电、气一样的基础设施,开箱即用。为了让业务间峰谷互补的优势发挥到最大,过去我们构建了混部技术,打破多资源池的割裂,不同计算领域的多调度大脑协同共用资源;老一代的混部技术带来了资源的统一和利用率的巨大提升,但多调度器的本质让我们的追求受限。阿里巴巴持续追求构建可支撑更多复杂任务无差别混部、极致弹性互补、领先的新一代调度技术,实现极致的全局最优调度,提供更高质量的算力。今年我们在技术上到达一个新的临界点,容器服务 ACK 牵头并协同众多团队,启动了基于 ACK 的新一代统一调度项目。容器产品家族今年双 11 首次规模化亮相的统一调度,通过一套调度协议、一套系统架构,统一管理底层的计算、存储、网络资源,超大规模、高效率、自动化的资源弹性,实现了业界新的突破。在离线混部、离在线混部、新的快上快下技术,减少数万台服务器采购,带来数亿计的资源成本优化和大促效率提升。今年首次引入大规模数据智能来进一步丰富调度能力,提供了包括实时的负载感知,自动规格推荐(VPA),差异化 SLO 工作负载编排,CPU 归一化,支持周期性预测的 HPA,分时复用等,提供了更多维度的成本优化技术和高可靠的容器运行时保障。围绕着新一代的统一调度,阿里巴巴电商、搜索、大数据等众多平台、不同类型的复杂计算资源都以一致的方式申请资源,统筹的额度管理和资源规划,数十万核资源借用秒级即可完成。基于统一调度,阿里云与蚂蚁也实现了调度技术融合,蚂蚁生态全面升级为统一调度。调度平台为未来带来更多想象空间,例如,我们可以通过众多手段,例如价格杠杆等经济因素,驱动阿里内部的业务更合理使用各个数据中心的资源,确保数据中心全局资源水位尽可能平衡,以改进数据中心的能效比。阿里云容器服务 ACK 对标准 Kubernetes 进一步增强,更高性能吞吐和更低的响应延迟构建稳定可靠的超大规模单集群能力,平稳支撑了 1.2 万节点超 100 万核的超大规模集群、为统一调度大资源池化的生产运行提供了坚实的基座。阿里巴巴众多类型的复杂资源也实现了基于容器服务底座 ACK 的全面融合升级。除电商、搜索、大数据等阿里经典场景外,统一调度也极大的赋能了新型的技术创新。以直播电商场景为例,决策对实时计算的需求很高,比如薇娅双 11 直播间 9 千多万在线观看人数的产生的浏览、交易等实时数据的秒级数据分析。今年阿里将实时计算引擎 Blink 升级为基于统一调度的新一代引擎,在成本、性能、稳定性以及用户体验上获得大幅提高,大规模作业拉起性能相比 Yarn 提速 40%,错误恢复效率提升 100%,通过统一调度技术在双 11 大促备战接节省数十万 CPU,在集群 CPU 水位超过 65% 时,实现全局零热点,保障了各直播推流的时效性。在 Serverless 方面,函数服务首次在集团内得到大规模落地,并应用于双 11 支撑了淘宝搜索推荐、数据处理、前端 SSR 等 10 多个业务场景。借助统一调度技术,函数计算可以和阿里资源池内实现大规模混跑,充分利用集群的碎片资源,彻底解决了 Serverless 场景在流量低峰期的资源闲置成本问题。基于 ACK 镜像按需加载和网络栈优化,函数实例的冷启动时间小于 150ms,并结合池化技术保证了函数计算容器的冷启动率小于 5%,这是保证双 11 大促成功的关键。03 未来展望未来,容器服务 ACK 将阿里巴巴统一调度的经验输出到整个行业,支撑更多新型计算负载生态、新型技术形态的架构演进,实现云计算无处不在,全面赋能更多的企业,释放更大的低碳价值红利。

技术人员的一点产品思维思考
作为一线的开发人员,大家是不是都经历过和产品吵得不可开交的经历,甚至最后谁也无法说服谁,只能将问题上升。最后由老板出面解决,而大多数情况下老板还真能够以某种方法去解决,并且是一个双方都能接受的方案。这个时候可能大部分同学会认为是老板的权威,地位导致了这一结果。 其实这很不准确(可能有一部分原因但绝对不是主要原因)其实更多的是各个老板们有比一线开发更强的产品力,能够听懂对方的诉求和抓住矛盾点并且给出解决方案。同时其中的表达方式更容易让彼此接受,才导致了最终你看到的老板出马,问题解决,好像自己的观点继续保持了,同时对方也留有余地。那这里这项重要的能力来源于什么呢?其实我认为更是一种产品思维的方式。
节省 58% IT 成本,调用函数计算超过 30 亿次,石墨文档的 Serverless 实践
借助函数计算毫秒级别的资源伸缩能力,石墨文档解决了高峰期负载突增的计算资源扩容问题,相比于自建机房维护服务器,节省了 58%的 IT 成本,目前石墨文档每月调用函数计算超过 30 亿次。 云原生时代,逐渐完善的 IT 基础设施,让企业能更高效地进行数字化创新。
第二届云原生编程挑战赛圆满落幕!
今天是 2022 年的第一个月中最特别的一天,因疫情影响而姗姗来迟的第二届云原生编程挑战赛终于在上海圆满落幕。跨越了重重阻碍,克服了各个难题的选手们交上了他们满意的答卷,也捧回了属于他们荣耀的奖杯。 再次感谢选手们的辛勤付出,也让我们祝贺他们未来在云原生技术领域中继续发光发热,越来越好!

40. 我们现在的CI/CD 都是用 Jenkins 做的,如何能跟SAE 结合起来?

如果仅需要打通 Jenkins,持续集成到部署应用到SAE,可以尝试调用SAE的部署应用OpenAPI。具体操作如下:使用 Jenkins,通过配置将 Jar 包或者镜像直接发布到 SAE 里面,将API打一个可执行的Jar包,并在CI流程里面上传Jar包到OSS,然后把URL作为参数,调用SAE的部署接口。OpenAPI 列表可在文档- API参考-API概览中查到。地址:https://help.aliyun.com/document_detail/125720.html

任何有关产品的使用疑问,欢迎加入我们的客户交流钉钉群:23198618。(1群100人已满,这是2群群号)

关于 Serverless 应用引擎(SAE): Serverless 应用引擎(Serverless App Engine,简称 SAE)是面向应用的 Serverless PaaS 平台,帮助 PaaS 层用户免运维 IaaS,按需使用,按量计费,实现低门槛微服务应用上云,有效解决成本及效率问题。支持 Spring Cloud、Dubbo 和 HSF 等流行的开发框架,真正实现了 Serverless 架构和微服务架构的完美融合。除了微服务应用外,您还能通过 Docker 镜像部署任何语言的应用。

产品官网:https://www.aliyun.com/product/sae

39. Serverless应用引擎(SAE)可以用于本地开发环境,开发微服务吗 ?

可以的,通过Cloud Toolkit插件,能打通本地和SAE,进行部署。部署方式可在文档--应用部署-插件部署中找到,现已支持Maven/ Idea/Eclipse 三类插件。

Cloud Toolkit下载地址:https://www.aliyun.com/product/cloudtoolkit

任何有关产品的使用疑问,欢迎加入我们的客户交流钉钉群:23198618。(1群100人已满,这是2群群号)

关于 Serverless 应用引擎(SAE): Serverless 应用引擎(Serverless App Engine,简称 SAE)是面向应用的 Serverless PaaS 平台,帮助 PaaS 层用户免运维 IaaS,按需使用,按量计费,实现低门槛微服务应用上云,有效解决成本及效率问题。支持 Spring Cloud、Dubbo 和 HSF 等流行的开发框架,真正实现了 Serverless 架构和微服务架构的完美融合。除了微服务应用外,您还能通过 Docker 镜像部署任何语言的应用。 产品官网:https://www.aliyun.com/product/sae

38. Serverless应用引擎(SAE)支持云效部署么?

通过云效可一键部署到SAE,欢迎加入Serverless 应用引擎客户交流钉群(群号:23198618),群内有云效大牛坐镇,提供在线支持。

任何有关产品的使用疑问,欢迎加入我们的客户交流钉钉群:23198618。(1群100人已满,这是2群群号)

关于 Serverless 应用引擎(SAE): Serverless 应用引擎(Serverless App Engine,简称 SAE)是面向应用的 Serverless PaaS 平台,帮助 PaaS 层用户免运维 IaaS,按需使用,按量计费,实现低门槛微服务应用上云,有效解决成本及效率问题。支持 Spring Cloud、Dubbo 和 HSF 等流行的开发框架,真正实现了 Serverless 架构和微服务架构的完美融合。除了微服务应用外,您还能通过 Docker 镜像部署任何语言的应用。 产品官网:https://www.aliyun.com/product/sae

37. 除 Java 外,Serverless应用引擎(SAE)是否支持多语言应用呢?

通过制作 Docker镜像,进行部署,您可以把任何语言的应用部署到SAE上。制作Docker镜像的方式可在文档-应用部署-高级设置-制作应用容器Docker镜像中找到,并提供了相关示例。详情:https://help.aliyun.com/document_detail/98492.html

任何有关产品的使用疑问,欢迎加入我们的客户交流钉钉群:23198618。(1群100人已满,这是2群群号)

关于 Serverless 应用引擎(SAE): Serverless 应用引擎(Serverless App Engine,简称 SAE)是面向应用的 Serverless PaaS 平台,帮助 PaaS 层用户免运维 IaaS,按需使用,按量计费,实现低门槛微服务应用上云,有效解决成本及效率问题。支持 Spring Cloud、Dubbo 和 HSF 等流行的开发框架,真正实现了 Serverless 架构和微服务架构的完美融合。除了微服务应用外,您还能通过 Docker 镜像部署任何语言的应用。 产品官网:https://www.aliyun.com/product/sae

29. Serverless应用引擎是否会考虑出一些小的规格给小站长这类的用户使用?

在2019-11-26发布的新版本中,SAE已经支持 0.5Core 1GiB 的小规格实例了,发布详情:https://help.aliyun.com/document_detail/120167.html

36. Serverless应用引擎(SAE)什么时候支持预付费资源包?

Serverless应用引擎(SAE)自商业化9月25日提供商业化服务以来,推出了按量付费6折的活动,并将持续至2020年3月31日。

我们将会在此期间,尽快推出预付费资源包,进一步降低您的使用成本,降本增效是SAE的产品主张。

任何有关产品的使用疑问,欢迎加入我们的客户交流钉钉群:23198618。(1群100人已满,这是2群群号)

关于 Serverless 应用引擎(SAE): Serverless 应用引擎(Serverless App Engine,简称 SAE)是面向应用的 Serverless PaaS 平台,帮助 PaaS 层用户免运维 IaaS,按需使用,按量计费,实现低门槛微服务应用上云,有效解决成本及效率问题。支持 Spring Cloud、Dubbo 和 HSF 等流行的开发框架,真正实现了 Serverless 架构和微服务架构的完美融合。除了微服务应用外,您还能通过 Docker 镜像部署任何语言的应用。 产品官网:https://www.aliyun.com/product/sae

1. Serverless应用引擎(SAE)怎么设置ARMS监控?

Serverless应用引擎(SAE)自带ARMS的基础应用监控功能,不需要单独设置,可以监控如 QPS、RT、接口调用量、错误数等指标,详情可在Serverless应用引擎(SAE)控制台查看。

2. 新建Serverless应用引擎(SAE)的应用会默认新建 ARMS 监控吗?

新建的Serverless应用会自带ARMS的基础应用监控指标能力(免费使用),如QPS、RT、接口调用量、错误数等,帮助快速定位出错接口和慢接口、发现系统瓶颈。 如果需要其他更高阶的监控指标,需要前往ARMS控制台单独开通ARMS的按量付费或应用/前端监控资源包。

9. 目前,Serverless应用引擎(SAE)支持华南Region吗?

更新:Serverless应用引擎(SAE)已经上线华南Region,截止目前,已经支持华北1(北京)、华东(杭州,上海)、华南1(深圳)4个Region。

35. 请问 Serverless应用引擎 什么时候支持香港地区?

答:暂时还不支持,如果您有在香港region部署的需求,请加入我们的用户钉钉群:23156632,并@SAE客服01,我们会进行登记。