中国式微服务技术栈2.0

2018/6/5 posted in  Microservice

原文地址

**本文转载自公众号: 波波微课**

| 前言

近年,Spring Cloud 俨然已经成为微服务开发的主流技术栈,在国内开发者社区非常火爆。

我近年一直在一线互联网公司(携程,拍拍贷等)开展微服务架构实践,根据我个人的实践经验和我平时对 Spring Cloud 的调研,我认为 Spring Cloud 技术栈中的有些组件离生产级开发尚有一定距离。比方说 Spring Cloud Config 和 Spring Cloud Sleuth 都是 Pivotal 自研产品,尚未得到大规模企业级生产应用,很多企业级特性缺失(具体见我后文描述)。另外 Spring Cloud 体系还缺失一些关键的微服务基础组件,比如 Metrics 监控,健康检查和告警等。

所以在参考 Spring Cloud 微服务技术栈的基础上,结合自身的实战落地经验,也结合国内外一线互联网公司(例如 Netflix,点评,携程,Zalando 等)的开源实践,我综合提出更贴近国内技术文化特色的轻量级的微服务参考技术栈。希望这个参考技术栈对一线的架构师(或者是初创公司)有一个好的指导,能够少走弯路,快速落地微服务架构。

这个参考技术栈和总体架构如下图所示:

1、中国式微服务技术栈 2.0

主要包含 11 大核心组件,分别是:

  • 核心支撑组件:
  1. 服务网关 Zuul

  2. 服务注册发现 Eureka+Ribbon

  3. 服务配置中心 Apollo

  4. 认证授权中心 Spring Security OAuth2

  5. 服务框架 Spring MVC/Boot

  • 监控反馈组件:
  1. 数据总线 Kafka

  2. 日志监控 ELK

  3. 调用链监控 CAT

  4. Metrics 监控 KairosDB

  5. 健康检查和告警 ZMon

  6. 限流熔断和流聚合 Hystrix/Turbine

2、核心支撑组件

2.1 服务网关 Zuul

2013 年左右,InfoQ 曾经对前 Netflix 架构总监 Adrian Cockcroft 有过一次专访 [附录 1],其中有问 Adrian:“Netflix 开源这么多项目,你认为哪一个是最不可或缺的 (MOST Indispensable)”,Adrian 回答说:“在 NetflixOSS 开源项目中,有一个容易被忽略,但是 Netflix 最强大的基础服务之一,它就是 Zuul 网关服务。Zuul 网关主要用于智能路由,同时也支持认证,区域和内容感知路由,将多个底层服务聚合成统一的对外 API。Zuul 网关的一大亮点是动态可编程,配置可以秒级生效。

从 Adrian 的回答中,我们可以感受到 Zuul 网关对微服务基础架构的重要性。

Zuul 在英文中是一种怪兽,星际争霸中虫族里头也有 Zuul,Netflix 为网关起名 Zuul,寓意看门神兽。

Zuul 网关在 Netflix 经过生产级验证,在纳入 Spring Cloud 体系之后,在社区中也有众多成功的应用。Zuul 网关在携程(日流量超 50 亿),拍拍贷等公司也有成功的落地实践,是微服务基础架构中网关一块的首选。其它开源产品像 Kong 或者 Nginx 等也可以改造支持网关功能,但是较复杂门槛高一点。

Zuul 网关虽然不完全支持异步,但是同步模型反而使它简单轻量,易于编程和扩展,当然同步模型需要做好限流熔断(和限流熔断组件 Hystrix 配合),否则可能造成资源耗尽甚至雪崩效应(cascading failure)。

2.2 服务注册发现 Eureka + Ribbon

针对微服务注册发现场景,社区里头的开源产品当中,经过生产级大流量验证的,目前只有 Netflix Eureka 一个,它也已经纳入 Spring Cloud 体系,在社区中有众多成功应用,例如携程 Apollo 配置中心也是使用 Eureka 做软负载。

其它产品如 Zookeeper/Etcd/Consul 等,都是比较通用的产品,还需要进一步封装定制才可生产级使用。Eureka 支持跨数据中心高可用,但它是 AP 最终一致系统,不是强一致性系统。

Eureka 是阿基米德洗澡时发现浮力原理时发出的惊叹声,在微服务中寓意发现。

Ribbon 是可以和 Eureka 配套对接的客户端软负载库,在 Eureka 的配合下能够支持多种灵活的动态路由和负载均衡策略。内部微服务直连可以直接走 Ribbon 客户端软负载,网关上也可以部署 Ribbon,这时网关相当于一个具有路由和软负载能力的超级客户端。

Ribbon 是蝴蝶结的意思

2.3 服务配置中心 Apollo

Spring Cloud 体系里头有个 Spring Cloud Config 产品,但是功能远远达不到生产级,只能小规模场景下用,中大规模企业级场景不建议采用。携程框架研发部开源的 Apollo 是一款在携程和其它众多互联网公司生产落地下来的产品,开源两年多,目前在 github 上有超过 4k 星,非常成功,文档齐全也是它的一大亮点,推荐作为企业级的配置中心产品。

Apollo 支持完善的管理界面,支持多环境,配置变更实时生效,权限和配置审计等多种生产级功能。Apollo 既可以用于连接字符串等常规配置场景,也可用于发布开关(Feature Flag)和业务配置等高级场景。在《2018 波波的微服务基础架构和实践》课程中,第二个模块就配置中心相关主题,会深度剖析携程 Apollo 的架构和实践,预计 6 月份推出,欢迎大家关注学习。

阿波罗是希腊神话中太阳神的意思

2.4 认证授权中心 Spring Security OAuth2

目前开源社区还没有特别成熟的微服务安全认证中心产品,之前我工作过的一些中大型互联网公司,比如携程,唯品会等,在这一块基本都是定制自研的,但是对一般企业来说,定制自研还是有门槛的。OAuth2 是一种基于令牌 Token 的授权框架,已经得到众多大厂(Google, Facebook, Twitter, Microsoft 等)的支持,可以认为是事实上的微服务安全协议标准,适用于开放平台联合登录,现代微服务安全(包括单页浏览器 App / 无线原生 App / 服务器端 WebApp 接入微服务,以及微服务之间调用等场景),和企业内部应用认证授权 (IAM/SSO) 等多种场景。

Spring Security OAuth2 是 Spring Security 基础上的一个扩展,支持四种主要的 OAuth2 Flows,基本可以作为微服务认证授权中心的推荐产品。

但是 Spring Security OAuth2 还只是一个框架,不是一个端到端的开箱即用的产品,企业级应用仍需在其上进行定制,例如提供 Web 端管理界面,对接企业内部的用户认证登录系统,使用 Cache 缓存令牌,和微服务网关对接等,才能作为生产级使用。

在波波在极客时间的《微服务架构实践 160 讲》课程中,第一个模块就是微服务安全架构和实践相关主题,会深度剖析 OAuth2 原理和 Spring Security OAuth2 实践,欢迎大家关注学习。

Spring Security OAuth2 是 Spring Security 框架的一个扩展

2.5 服务框架 Spring Boot

Spring 可以说是史上最成功的 Web App/API 开发框架之一,它融入了 Java 社区中多年来沉淀下来的最佳实践,虽然有将近 15 年历史,但目前的社区活跃度仍呈上升趋势。Spring Boot 在 Spring 的基础上进一步打包封装,提供更贴心的 Starter 工程,自启动能力,自动依赖管理,基于代码的配置等特性进一步降低接入门槛。

另外 Spring Boot 也提供 actuator 这样的生产级监控特性,支持 DevOps 研发模式,它是微服务开发框架的推荐首选。

REST 契约规范 Swagger 和 Spring 有比较好的集成,使得 Spring 也支持契约驱动开发 (Contract Driven Development) 模型。对于一些中大规模的企业,如果业务复杂团队较多,考虑到互操作性和集成成本,建议采用契约驱动开发模型,也就是开发时先定义 Swagger 契约,然后再通过契约生成服务端接口和客户端,再实现服务端业务逻辑,这种开发模型能够标准化接口,降低系统间集成成本,对于多团队协同并行开发非常重要。

Spring Boot Logo

三、监控反馈组件

3.1 数据总线 Kafka

最初由 Linkedin 研发并在其内部大规模成功应用,然后在 Apache 上开源的 Kafka,是业内数据总线 (Databus) 一块的标配,几乎每一家互联网公司都可以看到 Kafka 的身影。

Kafka 堪称开源项目的一个经典成功案例,其创始人团队从 Linkedin 离职后还专门成立了一家叫 confluent 的企业软件服务公司,围绕 Kafka 周边提供配套和增值服务。在监控一块,日志和 Metrics 等数据可以通过 Kafka 做收集、存储和转发,相当于中间增加了一个大容量缓冲,能够应对海量日志数据的场景。除了日志监控数据收集,Kafka 在业务大数据分析,IoT 等场景都有广泛应用。如果对 Kafka 进行适当定制增强,还可以用于传统消息中间件场景。

Kafka 的特性是大容量,高吞吐,高可用,数据可重复消费,可水平扩展,支持消费者组等。Kafka 尤其适用于不严格要求实时和不丢数据的大数据日志场景。

Kafka 创始人三人组,离开 Linkedin 后,创立了基于 Kafka 的创业公司 Confluent

3.2 日志监控 ELK

ELK(ElasticSearch/Logstash/Kibana)是日志监控一块的标配技术栈,几乎每一家互联网公司都可以看到 ELK 的身影,据称携程是国内 ELK 的最大用户,每日增量日志数据量达到 80~90TB。ELK 已经非常成熟,基本上是开箱即用,后续主要的工作在运维、治理和调优。

ELK 一般和 Kafka 配套使用,因为日志分词操作还是比较耗时的,Kafka 主要作为前置缓冲,起到流量消峰作用,抵消日志流量高峰和消费(分词建索引)的不匹配问题。一旦反向索引建立,日志检索是非常快的,所以日志检索快和灵活是 ElasticSearch 的最大亮点。另外 ELK 还有大容量,高吞吐,高可用,可水平扩容等企业级特性。

创业公司起步期,考虑到资源时间限制,调用链监控和 Metrics 监控可以不是第一优先级,但是 ELK 是必须搭一套的,应用日志数据一定要收集并建立索引,基本能够覆盖大部分 Trouble Shooting 场景(业务,性能,程序 bug 等)。另外用好 ELK 的关键是治理,需要制定一些规则(比如只收集 Warn 级别以上日志),对应用的日志数据量做好监控,否则开发人员会滥用,什么垃圾数据都往 ELK 里头丢,造成大量空间被浪费,严重的还可能造成性能可用性问题。

ELK + Kafka 参考部署架构

3.3 调用链监控 CAT

Spring Cloud 支持基于 Zipkin 的调用链监控,我个人基于实践经验认为 Zipkin 还不能算一款企业级调用链监控产品,充其量只能算是一个半成品,很多重要的企业级特性缺失。Zipkin 最早是由 Twitter 在消化 Google Dapper 论文的基础上研发,在 Twitter 内部有较成功应用,但是在开源出来的时候把不少重要的统计报表功能给阉割了(因为依赖于一些比较重的大数据分析平台),只是开源了一个半成品,能简单查询和呈现可视化调用链,但是细粒度的调用性能数据报表没有开源。

Google 大致在 2007 年左右开始研发称为 Dapper 的调用链监控系统,但在远远早于这个时间(大致在 2002 左右),eBay 就已经有了自己的调用链监控系统 CAL(Centralized Application Logging),Google 和 eBay 的设计思路大致相同,但是也有一些差别。CAL 在 eBay 有大规模成功应用,被称为是 eBay 的四大神器之一(另外三个是 DAL,Messaging 和 SOA)。

开源调用链监控系统 CAT 的作者吴其敏(我曾经和他同事,习惯叫他老吴),曾经在 eBay 工作近十年,期间深入消化吸收了 CAL 的设计。2011 年后老吴离开 eBay 去了点评,用三年时间在点评再造了一款调用链监控产品 CAT(Centralized Application Tracking),CAT 具有 CAL 的基因和影子,同时也融入了老吴在点评的探索实践和创新。

CAT 是一款更完整的企业级调用链监控产品,甚至已经接近一个 APM(Application Performance Management)产品的范畴,它不仅支持调用链的查询和可视化,还支持细粒度的调用性能数据统计报表。这块是 CAT 和市面上其它开源调用链监控产品最本质的差异点,实际上开发人员大部分时间用 CAT 是看性能统计报表(主要是 CAT 的 Transaction 和 Problem 报表),这些报表相当于给了开发人员一把尺子,可以自助测量并持续改进应用性能。另外 CAT 还支持应用报错大盘,自助告警等功能,也是企业级监控非常实用的功能。

CAT 在点评,携程,陆金所,拍拍贷等公司有成功落地案例,因为是国产调用链监控产品,界面展示和功能等更契合国内文化,更易于在国内公司落地。个人推荐 CAT 作为微服务调用链监控的首选。至于社区里头有人提到 CAT 的侵入性问题,我觉得是要一分为二看,有利有弊,有耦合性但是性能更好,一般企业中基础架构团队会使用 CAT 统一为基础组件埋点,开发人员一般不用自己埋点;另外企业用了一款调用链监控产品以后,一般是不会换的,开发人员用习惯就好了,侵入不是大问题。

CAT 的 Transaction 报表

3.4 Metrics 监控 KairosDB

除了日志和调用链,Metrics 也是应用监控的重要关注点。互联网应用提倡度量驱动开发(Metrics Driven Development),也就是说开发人员不仅要关注功能实现,做好单元测试(TDD),还要做好业务层(例如注册,登录和下单数等)和应用层(例如调用数,调用延迟等)的监控埋点,这个也是 DevOps(开发即运维)理念的体现,DevOps 要求开发人员必须关注运维需求,监控埋点是一种生产级运维需求。

Metrics 监控产品底层依赖于时间序列数据库(TSDB),最近比较热的开源产品有 Prometheus 和 InfluxDB,社区用户数量和反馈都不错,可以采纳。但是这些产品分布式能力比较弱,定制扩展门槛比较高,一般建议刚起步量不大的公司采用。如果企业业务和团队规模发展到一定阶段,建议考虑支持分布式能力的时间序列监控产品,例如 KairosDB 或者 OpenTSDB,我本人对这两款产品都有一些实践经验,KariosDB 基于 Cassandra,相对更轻量一点,建议中大规模公司采用,如果你们公司已经采用 Hadoop/HBase,则 OpenTSDB 也是不错选择。

KairosDB 一般也和 Kafka 配套使用,Kafka 作为前置缓冲。另外注意使用 KariosDB 打点的话 tag 的值不能太离散,否则会有查询性能问题,这个和 KariosDB 底层存储结构有关系。Grafana 是 Metrics 展示标配,可以和 KariosDB 无缝集成。

Grafana 是 Metrics 展示标配,和主流时间序列数据库都可以集成

3.5 健康检查和告警 ZMon

除了上述监控手段,我们仍需要健康检查和告警系统作为配套的监控手段。

ZMon 是德国电商公司 Zalando 开源的一款健康检查和告警平台,具备强大灵活的监控告警能力。ZMon 本质上可以认为是一套分布式监控任务调度平台,它提供众多的 Check 脚本(也可以自己再定制扩展),能够对各种硬件资源或者目标服务(例如 HTTP 端口,Spring 的 Actuator 端点,KariosDB 中的 Metrics,ELK 中的错误日志等等)进行定期的健康检查和告警,它的告警逻辑和策略采用 Python 脚本实现,开发人员可以实现自助式告警。ZMon 同时适用于系统,应用,业务,甚至端用户体验层的监控和告警。

ZMon 分布式监控告警系统架构,底层基于 KairosDB 时间序列数据库

3.6 限流熔断和流聚合 Hystrix+Turbine

2010 年左右,Netflix 也饱受分布式微服务系统中雪崩效应(Cascading Failure)的困扰,于是专门启动了一个叫做弹性工程的项目来解决这个问题,Hystrix 就是弹性工程最终落地下来的一个产品。Hystrix 在 Netflix 微服务系统中大规模推广应用后,雪崩效应问题基本得到解决,整个体统更具弹性。之后 Netflix 把 Hystrix 开源贡献给了社区,短期获得社区的大量正面反馈。

目前 Hystrix 在 github 上有超过 1.3 万颗星,据说支持奥巴马总统选举的系统也曾使用 Hystrix 进行限流熔断保护 [参考附录 2],可见限流熔断是分布式系统稳定性的强需求,Netflix 很好的抓住了这个需求并给出了经过生产级验证的解决方案。Hystrix 已经被纳入 Spring Cloud 体系,它是 Java 社区中限流熔断组件的首选(目前还看不到第二个更好的产品)。

Turbine 是和 Hystrix 配套的一个流聚合服务,能够对 Hystrix 监控数据流进行聚合,聚合以后可以在 Hystrix Dashboard 上看到集群的流量和性能情况。

Hystrix 在英文中是豪猪兽的意思,豪猪兽通过身上的刺保护自己,Netflix 为限流熔断组件起名 Hystrix,寓意 Hystrix 能够保护微服务调用。

4、结论

  • 技术栈没有好坏之分,只有适合一说。

    本文推荐的技术栈主要基于我个人的实践和总结,但是未必适合所有场景,毕竟每个企业的上下文各不相同。作为架构师你可以参考我推荐的技术栈,但不可拘泥照搬,你必须在深入理解分布系统原理的基础上,再结合企业实际场景灵活应用。

  • 本文推荐的技术栈主要面向微服务基础架构,也是波波在极客时间上的《微服务架构实践 160 讲》课程要深度剖析的主题。

    在整个互联网基础技术平台体系中,还有消息,任务,数据访问层,发布系统,容器云平台,分布式事务,分布式一致性,测试,CI/CD 等其它重要主题,这些是波波在 2019 第三季和 2020 第四季在极客时间上要陆续推出的内容,请大家持续关注。

  • 2018 年波波在极客时间上的课程《微服务架构实践 160 讲》约有 8 个模块化课程组成,每个模块专注剖析微服务基础架构的一个核心组件,技术人员可以在碎片化时间自由学习,快速掌握微服务核心组件的问题域、架构原理和开发运维实践。对开发人员和架构师的个人能力提升和职业发展收益主要包括:

  1. 对主流微服务技术栈的组件及其架构有较全面深入的理解,

  2. 对微服务基础架构有体系化认识,

  3. 能够根据企业场景设计和搭建微服务基础架构,

  4. 中高级程序员可以向架构师行列迈进,

  5. 现有架构师可以充实和拓展基础架构知识和技能体系。

5、附录