写点什么

云原生时代消息中间件的演进路线

  • 2020 年 5 月 19 日
  • 本文字数:7702 字

    阅读完需:约 25 分钟

云原生时代消息中间件的演进路线

引言

本文以一张云进化历史图开场,来谈谈云原生时代消息中间件的演进路线,但本文绝对不是“开局一张图,内容全靠编”。



从虚拟化技术诞生以来,IaaS/PaaS/SaaS 概念陆续被提了出来,各种容器技术层出不穷。到 2015 年, Cloud Native 概念应运而生,一时间,各种云厂商,云服务以及云应用都加上了“云原生”前缀。


我们也一直在思考,传统的消息中间件需要做些什么才能加上云原生这个修饰词,这也是本文探讨的主题:传统的消息中间件如何持续进化为云原生的消息服务。


云原生消息服务

什么是云原生


首先来谈谈什么是云原生,云原生是一个天然适用于云计算的架构理念,实践云原生技术理念的应用可以最大化享受云计算的技术红利,包括弹性伸缩、按量付费、无厂商绑定、高 SLA 等。


应用在实践云原生技术理念时一般会遵循四个要素:


  • 采取 DevOps 领域的最佳实践来管理研发和运维流程。

  • 通过 CICD 工具链做到应用的快速迭代和持续交付。

  • 采取微服务架构。

  • 采取容器及相关技术进行应用的托管。


消息服务作为应用的通信基础设施,是微服务架构应用的核心依赖,也是实践云原生的核心设计理念的关键技术,通过消息服务能够让用户很容易架构出分布式的、高性能的、弹性的、鲁棒的应用程序。消息服务在云原生的重要性也导致其极可能成为应用实践云原生的阻塞点,所以消息服务的云原生化是至关重要的。


什么是云原生消息服务


先说结论,我们认为云原生消息服务是云原生的通信基础设施。2015 年成立的 CNCF 基金会大范围推广了云原生的技术理念,并提供了一套完整的实践技术工具集,帮助开发者落地云原生理念。这套工具集收录于 CNCF 云原生全景图,其中消息中间件处于应用定义和开发层的 Streaming 和 Messaging 类目。


消息中间件在云原生的应用场景,主要是为微服务和 EDA 架构提供核心的解耦、异步和削峰的能力,在云原生全景图定义的其它层次领域,消息服务还发挥着数据通道、事件驱动、集成与被集成等重要作用。


另外云原生倡导面向性能设计,基于消息队列的异步调用能够显著降低前端业务的响应时间,提高吞吐量;基于消息队列还能实现削峰填谷,把慢服务分离到后置链路,提升整个业务链路的性能。


云原生消息服务演进方向


云原生时代对云服务有着更高的要求,传统的消息服务在云原生这个大背景下如何持续进化为云原生的消息服务,我们认为方向有这么几个:


高 SLA


云原生应用将对消息这种云原生 BaaS 服务有更高的 SLA 要求,应用将假设其依赖的云原生服务具备跟云一样的可用性,从而不需要去建设备份链路来提高应用的可用性,降低架构的复杂度。只有做到与云一样的可用性,云在服务就在,才能称为真正的云原生服务。


低成本


在过去,每家公司自建消息中间件集群,或是自研的、或是开源的,需要投入巨大的研发、运维成本。云原生时代的消息服务借助 Serverless 等弹性技术,无需预先 Book 服务器资源,无需容量规划,采取按量付费这种更经济的模式将大幅度降低成本。


易用性


在云原生时代,消息服务第一步将进化成为一种所见即所得、开箱即用的服务,易用性极大的提高。接下来,消息服务将以网格的形式触达更复杂的部署环境,小到 IoT 设备,大到自建 IDC ,都能以跟公有云同样易用的方式接入消息服务,且能轻易地满足云边端一体化、跨 IDC 、跨云等互通需求,真正成为应用层的通信基础设施。


多样性


云原生消息服务将致力于建设大而全的消息生态,来涵盖丰富的业务场景,提供各式各样的解决方案,从而满足不同用户的多样性需求。阿里云消息队列目前建设了多个子产品线来支撑丰富的业务需求,比如消息队列 RocketMQ ,Kafka ,微消息队列等。


标准化


容器镜像这项云原生的核心技术轻易地实现了不可变基础设施,不可变的镜像消除了 IaaS 层的差异,让云原生应用可以在不同的云厂商之间随意迁移。但实际上,很多云服务提供的接入形式并不是标准的,所以依赖这些非标准化云服务的应用形成了事实上的厂商锁定,这些应用在运行时是无法完成真正的按需迁移,所以只能称为某朵云上的原生应用,无法称为真正的云原生应用。因此,消息服务需要做到标准化,消除用户关于厂商锁定的担忧,目前阿里云消息队列采纳了很多社区标准,支持了多种开源的 API 协议,同时也在打造自己标准化接口。


总结一下,传统的消息队列将从高 SLA 、低成本、易用性、多样性和标准化几个方向持续进化为云原生的消息服务。


云原生消息三化

谈到云原生,离不开 Kubernetes、Serverless 以及 Service Mesh ,接下来为大家分享下我们如何利用 K8s 社区的生态红利,如何实践 Serverless 和 Service Mesh 技术理念。


云原生消息 Kubernetes 化

Kubernetes 项目当下绝对是大红大紫,在容器编排和应用托管领域绝对的事实标准,整个社区也是生机盎然。所以,必须将我们的消息服务升级为 K8s 环境开箱即用的服务。



云原生消息 Kubernetes 化是指通过自定义 CRD 资源将有状态的消息集群托管至 Kubernetes 集群中,充分利用。


K8s 提供的部署、升级、自愈等能力提高运维效率,同时尽可能享受 K8s 的社区生态红利。


我们在 RocketMQ 开源社区也提供了 CRD 描述文件以及相应的 Operator 实现,通过这套实现,可以快速部署 RocketMQ 集群至 K8s 环境;利用 K8s 的能力低成本运维 RocketMQ 集群;也可以使用云原生的 Prometheus 观察集群指标。


RocketMQ 完成 Kubernetes 化后,就变成了 Kubernetes 环境原生可访问的一个消息服务,将给开发者带来极大的便利性。


同时,在商业化环境,我们也正在依赖 Kubeone 将消息队列系列产品完成 Kubernetes 化。


云原生消息 Serverless 化

Serverless 最核心的理念是“按需”,云原生消息 Serverless 化主要是从两个维度落地按需的概念。一方面根据业务规模自动化扩缩容实例规格、队列数等逻辑资源;另一方面,根据服务端负载自动化扩缩容计算、存储等物理资源。



逻辑资源按需扩缩容:


在用户侧,更关心的是消息实例提供的逻辑资源是否充足,比如购买的实例 TPS 规格是否足够,队列数量是否能满足扩展性需求。比如一个商业化的 MQ 实例中,可以根据用户的流量对实例规格进行自动的升降配,从 2W TPS 至 10W TPS 按需调整;也可以根据用户分布式消费者的数量规模,对逻辑队列数量进行动态调整;用户完全不需要进行容量评估。


物理资源按需扩缩容:


在云服务开发者侧,我们更关心的是如何通过 Serverless 降低运维成本,避免手动的机器购买、VIP 申请、磁盘申请以及集群扩缩容等。在 Kubernetes 化完成后,可以很轻易地根据集群 Load 等指标自动扩容 MQ 物理资源;在集群缩容的处理上,会比较麻烦,因为每个 MQ 节点其实是有状态的,图中的某个 PV 代表了一个 CommitLog ,我们在内部通过在 ASI 上支持 PV 漂移,在 RocketMQ 存储层支持多 CommitLog 挂载来完成自动化缩容。


云原生消息 Mesh 化


Service Mesh 出发点是解决微服务架构的网络问题,将服务之间的通信问题从业务进程中进行剥离,让业务方更加专注于自身的业务逻辑。云原生消息 Mesh 化将消息的富客户端能力下沉至 Sidecar ,将消息的服务发现、负载均衡、流量监控等职责与业务逻辑隔离,在运行时完成透明组装,同时提供细粒度的消息灰度和治理能力。


目前阿里云消息队列 RocketMQ 是国内第二个成功进入 Service Mesh 官方社区的中间件产品,在进行 Envoy 适配的过程中推动了 Envoy 社区加速对 on-demand CDS 的支持,创新性地使用 Pop 消费模式来适配 Mesh 的无状态网络模型。


云原生消息生态

在云原生消息服务演进方向小节中提到,云原生消息服务需要大而全的消息生态来覆盖业务方丰富的业务场景,本小节介绍我们在生态建设方面做的一些努力。


云原生消息产品矩阵


阿里云消息产品矩阵包含消息队列 RocketMQ、Kafka、AMQP、微消息队列 MQTT、消息通知服务 MNS 以及即将发布的 EventBridge ,涵盖互联网、大数据、移动互联网、物联网等领域的业务场景,为云原生客户提供一站式消息解决方案。


  • 消息队列 RocketMQ :阿里巴巴自主研发及双 11 交易核心链路消息产品,阿里云主打品牌,主要面向业务消息处理,打造金融级高可靠消息服务。

  • 消息队列 Kafka :聚焦大数据生态链,100% 融合 Kafka 开源社区,大数据应用领域中不可或缺的消息产品。

  • 微消息队列 MQTT :基于 MQTT 标准协议自研,拓展消息产品的领域与边界,延伸到移动互联网以及物联网,实现端与云的连接。

  • 消息队列 AMQP :100% 兼容 AMQP 事实标准协议,全面融合 RabbitMQ 开源社区生态。

  • 消息服务 MNS :聚焦云产品生态集成 & 消息通知服务(HTTP Endpoint、Function Compute、事件通知、移动推送等)。

  • 事件总线 EventBridge :作为我们下一代的消息产品形态,原生支持 CloudEvents 标准,提供中心化事件服务能力,加速云原生生态集成,EDA 首选。


云原生消息生态


在生态建设方面,我们在商业化和开源两个生态都取得了不错得成功。


在阿里云消息商业化生态中,消息队列产品线已经支持 11 BU,30+云产品或者解决方案,有些对用户是可见的,有些是不可见的,真正做到了云原生通信基础设施的定位。


在开源方面,开源 RocketMQ 已经完成了云原生技术栈的集成,包括 Knative 中的事件源,Prometheus 的 Exporter,K8s 的 Operator 等;也支持了微服务框架 Dubbo、SpringCloud 以及函数计算框架 OpenWhisk ;同时开发了很多 Connector 作为 Sink 或者 Source 去连接了 ELK、Flume、Flink、Hadoop 等大数据和数据分析领域的优秀开源产品。


云原生消息标准

最开始我们就提到标准化是云原生消息中间件的进化方向之一,我们从两个维度打磨产品的标准化建设。



社区标准


在消息领域,无论是接口还是协议,社区一直有很多事实上的“标准”,比如 Kafka 提供的 API 和协议,JMS API,CloudEvents 规范,MQTT 中的协议和模型,AMQP 的协议和模型等,阿里云消息队列产品线对这些事实标准都提供了相应的接入方式,用户可以低成本完成迁移上云。


自建标准


事实上的“标准”如果太多,其实就没有标准,开源方面一直在推动自建标准 OpenMessaging,OMS 将提供六大核心特性:多领域、流、平台无关、标准的 Benchmark ,面向云,线路层可插拔。目前,国内有很多云提供商都接入了 OMS 标准。


OpenMessaging:


https://github.com/openmessaging


云原生消息核心竞争力

作为云原生的消息,核心竞争力在哪,特别是开源生态愈发蓬勃,用户可选的解决方案非常多,如何让用户选择我们云原生的消息服务,我们认为核心竞争力主要有这么几个。


领先的消息服务能力


阿里云的消息服务,在多个方面都具备绝对领先的服务能力。


接入 &迁移


整个产品线支撑了多协议、多 API、多语言、多终端以及多生态的接入,做到了“0”接入成本,开源或自建用户都可以无缝上云;同时全球消息路由也支持跨地域的消息同步,异构的消息迁移同步等。


多租户


阿里云消息服务支持命名空间隔离、标准的访问控制;支持实例限流、资源隔离、多租户的海量堆积。


消息类型


在业务消息领域,阿里云消息有多年的业务沉淀,消息类型上支持:普通消息、事务消息、定时消息、顺序消息、重试消息以及死信消息等。


消费 &治理


在消费和治理领域,云消息服务支持 Pub/Sub 模式,广播/集群消费模式,消费过程中支持 Tag 过滤、 SQL 过滤。在运维时,提供了消息轨迹、消息查询以及消息回放等治理能力。


服务能力


阿里云消息的服务能力是经过多年锤炼的:


  • 高可用:核心交易链路 12 年,双十一 10 年历程,在云上承诺的可用性 SLA 为 99.95% ,可靠性 8 个 9 。

  • 高性能:双 11 消息收发 TPS 峰值过亿,日消息收发总量 3 万亿;拥有全球最大的业务消息集群之一。

  • 低延迟:在双 11 万亿级数据洪峰下,消息发送 99.996% 在毫秒级响应;消息发布平均响应时间不超过 3 毫秒。


统一的消息内核

阿里云消息队列的另一核心竞争力为统一的消息内核,整个消息云产品簇都建设在统一的 RocketMQ 内核之上,所有的云产品提供一致的底层能力。



RocketMQ 内核主要包含以下几个模块:


富客户端


RocketMQ 提供一个轻量级的富客户端,暴露 Push、Pull 以及 Pop 三种消费模式,同时内置了重试、熔断等高可用功能,产品簇的众多客户端都是通过对内核的富客户端进行二次开发的。


注册中心


也就是 RocketMQ 开发者熟知的 NameServer ,以简单可靠的方式提供集群管理、元数据管理、Topic 路由和发现等功能,节点无状态,最终一致的语义确保 NameServer 具有超高的可用性。


计算节点


Broker 中的计算部分包含一个高性能的传输层,以及一个可扩展的 RPC 框架,以支持各个产品的丰富的业务需求。


存储引擎


Broker 中的核心为存储引擎,经过多年锤炼的存储引擎包含几个核心特点:


  • 低延迟读写互斥:通过在 PageCache 层完成消息的读写互斥,来大幅度保障写链路的低延迟。

  • 日志与索引分离:整个存储层将消息以 Append-Only 的方式集中式存储在 CommitLog 中,同时以索引派发这种可扩展的方法来支持事务、定时、查询以及百万队列等高级特性。

  • 一致性多副本:提供多套一致性多副本实现来满足不同的部署场景和需求,比如 Master-Slave 架构、基于 Raft 的 Dleger 和正在自研的秒级 RTO 多副本协议。

  • 多模存储:在未来存储的方式肯定是多样化的,存储引擎抽象来统一的存储接口,并提供了本地块设备、云存储以及盘古原生存储等实现。

  • 多级存储:越来越的用户对消息生命周期有了更高的要求,在过去,消息作为应用开发的中间状态,往往只会被存储数天,通过 Deep Storage ,将以低成本的方式大幅延长消息的生命周期,将消息转化为用户的数据资产,以挖掘更多的诸如消息分析、消息计算需求。


全方面的稳定性建设

稳定性永远是前面的 1,业务发展和创新是后面的 0。–叔同


稳定性的重要性是不言而喻的,稳定性是用户做技术和产品选型的时候考察第一要素,阿里云消息队列在稳定性方面做了全面的建设。



阿里云消息队列主要从以下几个维度进行稳定性建设:


架构开发


整个系统是面向失败设计的,除了最核心的组件,所有的外部依赖都是弱依赖;在产品迭代阶段,建立了完善的 Code Review 、单元测试、集成测试、性能测试以及容灾测试流程。


变更管理


风险往往来自于变更,我们对变更的要求是可灰度、可监控、可回滚以及可降级的。


稳定性防护


限流、降级、容量评估、应急方案、大促保障、故障演练、预案演练、定期风险梳理等都是我们的稳定性防护手段。


体系化巡检


分为黑盒巡检和白盒巡检,黑盒巡检会站在用户视角对产品功能进行全方面扫描,包含了 50+ 检测项;白盒巡检会自动化检测 JVM 运行时指标、内核系统指标、集群统计指标等,并在指标异常时及时预警。


故障应急


我们建设了一套完整的故障应急流程,从监控报警->故障发生->快速止血->排查根因->故障复盘,整个链路都是顺畅的。


云原生消息展望

在消息产品矩阵小节中提到, EventBridge 是作为我们下一代的消息产品形态,该产品也即将迎来公测,本章节主要介绍 EventBridge 的产品定位。


消息与事件


消息和事件是两种不同形态的抽象,也意味着满足不同的场景:


消息:消息是比事件更通用的抽象,常用于微服务调用之间的异步解耦,微服务调用之间往往需要等到服务能力不对等时才会去通过消息对服务调用进行异步化改造;消息的内容往往绑定了较强的业务属性,消息的发送方对消息处理逻辑是有明确的预期的。


事件:事件相对于消息更加具像化,代表了事情的发送、条件和状态的变化;事件源来自不同的组织和环境,所以事件总线天然需要跨组织;事件源对事件将被如何响应没有任何预期的,所以采用事件的应用架构是更彻底的解耦,采用事件的应用架构将更加具备可扩展性和灵活性。


EventBridge:中心化事件总线

EventBridge 作为我们即将发布的新产品,其核心能力之一便是提供中心化的事件总线能力。



EventBridge 将提供云产品之间、云应用之间、云产品与云应用之间,以及它们与 SaaS 提供商之间的集成与被集成能力。


在中心化事件总线中有几个重要的概念:


事件源:事件源可以是阿里云服务,比如对象存储、ECS、数据库等,也可以是用户的应用程序或者第三方 SaaS ,这些事件源将提供丰富的业务事件、云产品运维事件、事件流等。


资源管理:EventBridge 内部将提供总线管理、规则管理以及 Schema 管理,提供全托管的事件服务。


事件处理:EventBridge 将提供事件传输、事件过滤、事件路由、事件查询、回放、重试、追踪等核心的事件处理能力。


事件目标:事件最终投递的目标服务包罗万象,既可以触发一个 Serverless 的 Function ,也可以投递至消息队列其它产品,运维事件还可以通过短信、邮件以及日志服务触达运维人员。


EventBridge:EDA 服务框架


EventBridge 另一个核心能力是 EDA 服务框架。微服务有两种驱动方式:请求驱动和事件驱动。在请求驱动模式下,服务之间调用是同步调用,这种模式优点是延迟低,但是服务之间的耦合是比较重的,相比之下事件驱动有几个优点:


  • 异步化,所有的调用通过事件异步化驱动,服务之间没有显示的依赖关系。

  • 松耦合,通过事件总线解除所有服务之间的耦合关系。

  • 可扩展,可扩展能力非常强,基于总线和事件 Schema 完成业务的扩展非常简单。

  • 零改造,请求驱动的微服务,在遇到服务之间能力不对等时,往往需要进行基于消息异步化改造,避免慢调用、超时等异常情况在整个分布式集群触发雪崩效应。基于事件驱动的微服务天然具备力异步、削峰等能力,所以在业务规模扩大时不会带来额外的改造成本。


上图是设想的一个采用 EDA 的应用架构图:


  • 基于 EventBridge 可以实践流行的 CQRS 和 Event Souring 范式。

  • 可以从 IoT 端设备上接入 Event Streaming 。

  • 基于事件驱动的微服务程序也可以通过 API 网关暴露传统的 Request 请求方式,供前端访问。

  • EventBridge 还可以连接第三方 SaaS 提供商,云提供商,不同组织的观察者,与分布式的事件微服务集成。

  • 事件驱动和请求驱动是相辅相成的关系,通过统一 Event APIs 和 REST APIs 打通事件驱动的微服务与请求驱动的微服务,来进行架构上的融合与统一。


EDA 成熟度模型


我们通过 Gartner 报告总结的 EDA 成熟度模型,展望以下 EDA 架构的未来:


  • Incidental:偶发性地使用事件通知机制来进行一些状态的捕获,没有明确的事件处理策略。

  • Brokered:提供托管的事件代理服务,组织中部分应用开始采用基于消息或者事件的异步化架构。

  • Centralized:以战略的形式提出中心化的 EDA 解决方案,有专门的组织团队提供 EDA 实现, EDA 架构开始广泛被采用。

  • Advanced:EDA 架构开始触达更多的业务领域,比如流计算,数据分析,AI,以及 API 市场等,跨组织的事件生态开始形成并进行扩张。

  • Pervasive:事件变得无处不在,庞大的事件生态形成,组织间的隔离被事件彻底打通,企业的关键业务都将采取 EDA 架构;事件驱动与请求驱动两个生态完成融合。


总结

阿里云消息团队在 EDA 领域的探索目前是处于第三个阶段,未来还有很长的路要走。


作者介绍


周新宇(花名:尘央),阿里云技术专家,Apache RocketMQ PMC Member/Committer,在消息和云原生领域有多年的研发经验,目前在阿里云消息中间件团队从事 RocketMQ 产品的研发工作。


本文转载自公众号阿里巴巴中间件(ID:Aliware_2018)。


原文链接


https://mp.weixin.qq.com/s?__biz=MzU4NzU0MDIzOQ==&mid=2247489465&idx=1&sn=631b812a9b8fd175939f804538a33bc2&chksm=fdeb25d9ca9caccf3467893e16f3a687e566574f7fd6c26ec0e1ebcb5730092c6f93703b6e93&scene=27#wechat_redirect


2020 年 5 月 19 日 10:043303

评论 1 条评论

发布
用户头像
CQRS 和 Event Sourcing
2020 年 05 月 22 日 17:37
回复
没有更多了
发现更多内容

我肝了3个月终于整理出了这份超全面的《Android面试题及解析》(1)

android 程序员 移动开发

手写一款Android-手绘风格组件----这是你从未见过的组件库

android 程序员 移动开发

抖音四面被拒,再战头条终获offer!凭什么我可以做到,2021最新Android笔试题及答案

android 程序员 移动开发

我的2020年终总结:疫情之下裸辞后的一些感悟和面试心得(上篇

android 程序员 移动开发

手把手带你剖析ReentrantLock的底层实现AQS,android插件开发过时

android 程序员 移动开发

插件化框架解读之四大组件调用原理-Activity(三)上篇

android 程序员 移动开发

揭秘!大厂招聘内幕!如何才能进大厂,Android技术类校招面试题汇总

android 程序员 移动开发

我肝了3个月终于整理出了这份超全面的《Android面试题及解析》

android 程序员 移动开发

手把手教你打通车载蓝牙与手机app的音频信息传输&车载反向控制手机app

android 程序员 移动开发

掌握了这些Android高级工程师必备知识后,他拿到了 BAT Offer

android 程序员 移动开发

我敢打赌!你从未见过如此简单的Dagger-导航---基于-Android-Studio-4-1

android 程序员 移动开发

扒一扒:2020台湾Android-Kotlin-&-Java-面試題庫,竟如此--

android 程序员 移动开发

拖不得了,Android11真的要来了,最全适配实践指南奉上

android 程序员 移动开发

我,Android开发,40岁熬到中层月薪15K,百度Android岗一面+二面内容

android 程序员 移动开发

接地气的面试记录:记一次Android面试心得(1),详细的Android学习指南

android 程序员 移动开发

接地气的面试记录:记一次Android面试心得,retrofit教程

android 程序员 移动开发

搞Android开发为什么这么难?想哭了!,vue双向绑定

android 程序员 移动开发

我是如何做到在-5-分钟之内将应用大小减少-60%-的?,零基础学android编程

android 程序员 移动开发

战战兢兢面试了一个35岁Android开发程序员,就这水平开发了8年?

android 程序员 移动开发

战战兢兢面试了一个35岁Android开发程序员,就这水平开发了8年?难怪没有一个公司愿意要你

android 程序员 移动开发

插件化框架解读之Class文件与Dex文件的结构(一),android软件开发教程第二版电子版

android 程序员 移动开发

支付宝 App 构建优化解析:Android 包大小极致压缩(1),阿里P8亲自讲解

android 程序员 移动开发

揭秘:如何化身BAT面试offer收割机?,androidapp内存优化

android 程序员 移动开发

我来告诉你:零基础如何成为高级Android开发,入职字节跳动

android 程序员 移动开发

手动实现Android热修复,给2021的移动开发一些建议

android 程序员 移动开发

打造一个完整的Flutter-APP项目!,安卓高级开发面试题

android 程序员 移动开发

换个姿势,带着问题深入学习Handler,手撕吊打面试官,kotlin单例firbase

android 程序员 移动开发

换肤、全局字体替换、无需编写shape,Android程序员月薪20k的涨薪秘籍

android 程序员 移动开发

手把手讲解-一个复杂动效的自定义绘制,2021Android开发社招面试总结

android 程序员 移动开发

把Flutter扩展到微信小程序端的探索,安卓面试题库

android 程序员 移动开发

拿不到想要的offer,只缘身在CV中,关于一些面试小知识,Android开发人员不得不收集的代码

android 程序员 移动开发

云原生时代消息中间件的演进路线_云原生_尘央_InfoQ精选文章