胡荣良

胡荣良

工程架构 | 算法

© 2019

QCon上海2016参会笔记

前言

一整天 一个会议厅 一个主题:微服务架构,我们该如何实践

《微服务:模式与实践》

QCon联合主席Wesley Reisz的演讲主题是《微服务:模式与实践》,从宏观角度介绍微服务的重要概念和实践原则。

第一部分介绍微服务的一些理论性知识。侧重介绍微服务架构领域的核心概念。

Adrian Cockcroft对微服务的表述:loosely couped service oriented architecture with bounded context。这里涉及两个微服务的概念:

  • loosely couped,松耦合。松耦合可以引申出其他概念,如各自独立,微服务应该是各自独立的,可以独立开发,独立测试,独立部署,独立运维,如果每个服务都需要同时被更新,那就不是送耦合。服务自理,高度内聚,对外界应该是没有依赖的。
  • bounded context,有界上下文。业务有界,每个微服务有着明确的业务功能,业务场景。数据有界,每个微服务自身数据不对外界暴露,外界只能通过微服务暴露的接口访问内部数据。

微服务领域常设计一个模型即scale cube(伸缩魔方)

扩展一个应用有三个方向:

  • X轴:通过复制扩展。常用于业务功能的扩展。运行应用的多个实例,配合负载均衡策略。缺点是多个应用对同一份数据进行访问增大了内存资源消耗,并没有解决系统复杂度问题。
  • Y轴:通过相似事务分区。常用于数据分区,如数据库分区。优点是每个分区只处理数据的子集,提升缓存效率,降低IO(操作部分数据而非全部),提升容错能力(只在部分数据上出错)。缺点是增加了复杂度,需要提供一个分区方案,并且方案确定后很难调整,缺乏灵活性。
  • Z轴:分解事务内部不同部分。就是我们说的微服务概念。讲应用拆分成多个微服务,每个微服务处理逻辑相关的功能集合。拆分方案可以基于动词或名词。

CAP理论:分布式系统不可能同时满足一致性(consistency)、可用性(availability)、分区容错性(partition tolerance)。最多只能满足两个。

  • C:分布式系统所有服务在同一时刻提供同样的业务形态。
  • A:每个服务都必须能在限定时间内响应请求。
  • P:即使服务之间丢失数据,服务仍然响应请求。

拿订单同步会员举例:

  • C:用户下完单,订单必须在保证同步到会员后才能提示用户下单结果,才能保证用户在同一时刻在下单页面和会员的订单列表页面得到同样的dangdang状态。
  • A:下单和会员页面必须能访问。
  • P:订单同步会员失败,仍能下单,仍能查看会员的订单列表。

CAP理论是分布式系统的设计一个重要准则。

一些对CAP的质疑:

  • 每个节点只能知道自己的状态,无法得知其他系统的状态。
  • P的可能性小,有解决方案。
  • 可以通过构建不可变模型来避免CAP。数据是客观存在的,不存在变更删除。任何变更对时对数据施加了一个操作(事件)。每次操作都是对全局数据的一次计算。

这里有一篇对CAP的归纳总结文章:http://blog.csdn.net/chen77716/article/details/30635543

第二部分介绍相关技术

  • 事件溯源(event sourcing):与CRUD不同的另一种对象管理机制。一个对象从创建到消亡会经历多个事件。CRUD的模式是每次对象参与完一个事件后讲对象的最新状态更新到数据库。 ES的模式是将对象经历的每个引起对象变动都封装为一个事件对象并将其按事件的发生顺序保存到数据库。因为事件是客观存在的,不可改变,事件只会增加,这就构造了一个不可变系统,使得CAP成为可能。
  • CQRS(Command Query Responsibility Segregation):命令查询职责分离模式:分别提供查询和操作的接口来分离对象的读写操作。这就意味着读写使用的对象模型可以不一样。可以分别对读写做优化。

CQRS和Event Sourcing是DDD(领域驱动设计)概念。更多停留在理论和概念阶段,没有大范围的实践场景。

CIRCUIT BREAKER:断路器模式。是分布式系统的一种容错机制。

分布式系统容错一般有两种机制:

  • 重复尝试:适用于能预知到的短期故障。
  • 断路器模式:适用于无法预知的突发性故障,无法预估恢复耗时的场景。

RETRY(重试):上层超时实践必须大于(下层超时实践×超时重试次数)

SPINE模型:http://spinemodel.info/explanation/introduction/

第三部分介绍一些实践操作。

介绍了日志的设计原则,需要保持一致性,需要结构化日志。日志不能代替人。推荐ELK。

比较了协议和传输领域的各技术优劣:RPC VS HTTP, JSON VS BINARY

介绍了分布式系统追踪的相关工具:Zipkin, Prometheus

第四部分:文化

介绍了康威定律(CONWAY’S LAW):在复杂的系统都没有人复杂。人的组织方式决定了系统设计。 康威定律是微服务架构的理论基础。

《构建微服务体系下的全链路监控系统》

唯品会高级架构师姚捷介绍了唯品会对其微服务体系实施的全链路监控体系

介绍了微服务相对于单体应用的优势,如:

  • 技术异构:各个微服务内部可以有不同的技术实现,相互使用统一的协议通讯。
  • 弹性:单个微服务故障不会影响整个微服务体系。
  • 可扩展性:单个微服务可以独自扩展。
  • 简化部署:单个微服务可以独立部署。
  • 可复用性:可以提取可复用组件以微服务形式为其他微服务提供公共服务。
  • 可替代性:服务越简单重构或重写的风险越小。

介绍了微服务的一些特性:

  • 基础组件多:rpc,服务治理,注册发现,异步消息系统
  • 部署灵活:服务,容器,机房灵活组合
  • 治理功能强大:路由,负载均衡,熔断,降级

链路监控的内容是服务画像,包括:服务状态指标,服务性能指标,服务拓扑关系,服务调用链

介绍了服务监控日志数据模型,日志采集方式分两种:

  • 业务模块主动埋点,提供标准API上报日志。
  • 动态植入埋点,减少对业务功能的入侵。

他们的数据采集架构

介绍了日志序列化协力的差异 JSON VS BINARY

提出了设计监控系统的一些最佳实践:

  • 规范日志格式
  • 减少冗余日志
  • 日志采集率可调,减少逢时日志量
  • 日志采集粒度可调
  • 异常日志收敛
  • 异步线程收集日志,避免影响业务主线程
  • 合理设置日志队列大小,允许日志丢失并监控日志丢失率
  • 单线程批量消费日志队列
  • 网络传输使用BINARY协议提高吞吐量

日志监控链路

《滴滴代驾微服务架构演进》

滴滴代驾事业部架构师赵伟介绍了滴滴代驾微服务的架构设计

提出选择微服务的理由

  • 简化业务复杂度
  • 提升服务可复用性
  • 品比业务复杂度
  • 提升可扩展性
  • 提升发布效率
  • 方便技术改造

提出微服务实践的架构规范

  • 单服务单进程
  • 服务无状态
  • 保持服务职责单一,通过API提供服务
  • 核心服务存储独立,外部服务智能通过API访问数据
  • 数据库只做单表查询
  • 服务间调用关系为树状关系,下层服务异步反馈

滴滴代驾微服务架构图:

介绍了微服务降级措施

流量控制降级策略

  • 未登录:IP + API
  • 已登录:USER ID + API
  • APP级别流控
  • 黑白名单
  • 通用模式匹配流控(如不同ip,相同请求参数)

故障降级

  • 设计专门的降级策略服务,微服务实时同步策略,业务代码埋点,if else 判断降级并做降级处理

  • 客户端降级,关键服务允许降级来保证可用性

异步请求:适用于耗时长的服务

《电商 CRM 的微服务重构实践》

阿里巴巴高级技术专家介绍微服务系统改造的实践

介绍了单体应用CRM带来的痛苦,决定使用微服务。

观点:微服务不是万能的,微服务实施的前提是系统复杂,在业务发展初期可以用单体应用优先满足业务需求。

介绍了M Flower对微服务的定义:

The microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

提到了康威法则:组织内的沟通结构决定系统设计结构,并延伸出其他概念:

  • 沟通成本随人力增加呈指数增加
  • 你不能把事情做的完美,但是可以把事情完成,构建有生命力的系统,而不是完美的系统,持续集成。问题太复杂就忽略细节,资源不够就减少功能。瀑布式开发。
  • 人的沟通协调能力有上限。
  • 组织决定架构。

微服务的目的是有效的拆分应用,实现敏捷开发和部署。

服务间协作:两种方式,

  • 请求响应模式,REST RPC
  • 异步消息模式:MQ KAFKA

服务治理:去中心化治理,

  • ZOOKEPPER
  • HSF(client)
  • AWS Elastic Load Balancer(server)

微服务的优点:

  • 开发简单
  • 技术栈灵活
  • 服务独立无依赖
  • 扩展性强
  • 可用性高
  • 微服务的缺点:
  • 多服务运维难度
  • 部署依赖
  • 通信成本
  • 数据一致性
  • 集成测试
  • 重复工作
  • 性能监控

容错方案 怀疑第三方:

  • 降级方案
  • 快速失败
  • 熔断和重试
  • 故障模拟 防备使用方:
  • 规范API,提供文档,避免吴用
  • 流量控制降级 做好自己:
  • 单一职责原则(SRP)

微服务决策推导

持续集成交付和容错

允许分布式系统存在缺项,通过不断增强系统能力来提升系统可靠性,而不是在设计之初就避免系统缺陷。

按业务划分服务,组织研发资源

数据闭环

《服务框架 Pigeon 的设计与实现》

大众点评吴湘介绍了他们开源的服务框架Pigeon以及一些微服务实践

Pigeon包含了比较完善的微服务框架必须的元素如:

  • 注册发现:依赖zookepper,服务提供方自动注册,也提供后台管理端手动注册,调用方通过服务名发现服务,调用方和提供方通过心跳保持服务有效性,同时提供独立的心跳服务于服务提供方建立心跳,在zookepper适时摘除无效服务。
  • 序列化:两种基于rpc的二进制序列化方案:hessian和thrift。
  • 调用模式:支持多种主流的调用模式:同步,异步,多并发Future,oneway(无需返回)
  • 心跳机制:客户端定期发起,多次不成功则摘除服务方并下次重连。
  • 负载均衡:支持可扩展的客户端负载均衡策略。记录在途请求数,新请求选择发往在途请求数最少的服务节点。对刚启动服务节点采用预热控制,从慢到快的频率逐步发往服务节点,防止刚启动的服务节点收到大量请求而响应超时。
  • 服务限流:目前实现了服务端限流,限制每个接口的请求占用的线程数。防止单个接口占用过多线程。
  • 服务隔离:服务端监控每个接口健康度(如超时情况),将不健康的服务排入慢线程池直到恢复。为关键服务提供单独线程池。
  • 服务降级:提供多种降级策略,降级结果可以是直接返回默认值,抛异常,返回mock对象。

  • 多IDC支持。优先选择本地IDC服务,或者设置比例。
  • 内置http服务:查看服务状态。提供服务测试能力。
  • 链路监控:使用CAT
  • 告警分析:依赖CAT
  • 服务治理:定时运营报告。服务指标统计。

分享了一些实践经验:

  • 基础设施应该能标准化
  • 使用docker提供标准化运行环境
  • 标准化运行容器如tomcat
  • 标准化环境标示
  • 标准化应用命名规范
  • 统一开发语言
  • 标准化发布
  • 统一服务通讯框架
  • 统一配置中心
  • 统一数据库,KV存储访问层
  • 统一mq
  • 统一监控系统
  • 底层存储尽量保证只有一个服务访问,应用只能访问自己的存储。
  • 按产品线规划应用,理解业务,面向业务领域定义服务,根据业务发展方向拆分、重构。
  • 服务应该高内聚,减少外界依赖。
  • 微服务需组织结构支持。

《携程多机房微服务灰度发布》

携程王潇俊介绍了他们的微服务发布系统的一些实践经验

理想的发布要点:

  • 每次代码改动构建新镜像
  • 每次发布使用新实例替换旧实例
  • 独立部署,互补干涉
  • 系统运行中不修改镜像

现实有困境:

  • 多服务共享进程
  • 需要修改运行中的实例
  • 流控不能到机器级别
  • 跨平台部署
  • 建模不完整

提出Docker不是万能的,如何迁移到Docker是难题。

提出降级处理机制:

  • 本地缓存
  • 减少外部强依赖
  • 服务端历史版本缓存

发布需要确保幂等性:

  • 同版本跳过
  • 分组发布,每个组不能并行发布
  • 按组扩容

环境配置有两种:本地文件和配置中心

不可以在部署时改变pacakge内容

《大型企业云平台架构和关键技术实践》

华为苗彩霞介绍了大型企业应用的微服务实践各个环节及关键技术,满满的干货

介绍了企业应用相对于消费应用的区别,庞大负责的应用需要微服务提升敏捷度、自动化及弹性,解决思路:

  • 大系统小左,快速创新
  • 自动部署、弹性伸缩
  • 敏捷运维、自动运维

介绍了系统服务架构演进

介绍了华为微服务架构视图

中间的微服务框架是一个完整微服务体系需要具备的模块

微服务的设计

拆分原则:围绕业务功能进行垂直和水平拆分,大小粒度是难点。

  • 围绕业务模型设计微服务
  • 微服务应该有层次性,需要合理的聚合
  • 进行数据建模,保证整个分布式系统的数据完整性 拆分原则:围绕业务模型做垂直和水平拆分。大小粒度需要兼顾微服务特性和实施成本
  • 迭代开发、持续开发
  • API和兼容性考虑,考虑部署

微服务开发测试

开发构建原则:接口先行,语言中立,并行开发,提升产能;自动测试,持续构建,持续集成联调

  • 接口先定义,确保能并行开发
  • 持续构建,开速发现问题
  • 允许API调整,考虑兼容性

部署

部署原则:独立交付件,独立生命周期管理,基础设施自动化,部署自动化并行化

  • 微服务应该能独立部署发布,生命周期独立
  • 隔离核心服务和非核心服务
  • 基于docker部署

微服务治理和运维

服务自治,精益化管理,在线治理,实时生效

分布式事务一般采用最终一致性

性能和延迟考虑。

技术优化上:

  • P2P通讯,长链接
  • 二进制协议(rpc)
  • 码流压缩
  • 本地短路策略,本地-本地通讯优先
  • 同时支持同步/异步

业务策略上:

  • 并行请求,减少等待
  • 服务分层,接口内聚,减少调用
  • 利用缓存,减少反复调用
  • 长调用建议使用异步消息机制

一些新的关注点:

从微服务到serverless的演进

API + 网关

CI/CD

最后的建议

  • 微服务是系统工程,需要技术,管理协同并进,技术框架,组织结构,业务流程要配套
  • 微服务的构建部署运维能力要备齐,否则系统复杂度倍增
  • 微服务有适用范围,以数据处理为中心的逻辑不适合微服务化

学习收获

  • 熟悉了微服务本身的理论支撑,架构特征,优缺点,设计原则,适用场景,技术组成,落地方案,对微服务有了较全面的理解。
  • 熟悉了微服务在IT系统架构演进中的地位,了解围绕微服务形成的技术生态。
  • 了解目前主流的微服务应用方案,指导以后的微服务架构实践。