V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
heishao
V2EX  ›  推广

微服务化的道与术

  •  
  •   heishao · 2018-11-16 16:35:23 +08:00 · 1734 次点击
    这是一个创建于 2206 天前的主题,其中的信息可能已经有所发展或是发生改变。
    微服务的目标是提高响应能力,降低复杂度,让一切去中心化是微服务的最高宗旨。
    

    背景

    随着研发团队的项目工程的增加、代码量的膨胀、团队人员的增长,传统的单体架构的弊端越来越凸显,严重影响了业务的快速创新和敏捷交付。随行付在 2015 年底为了解决传统单体架构面临的挑战,先后经历了单体架构、系统模块拆分以及到现在的微服务化。

    微服务架构并非银弹,它的实施过程中会面临很多的陷阱和挑战、几乎影响到整个软件开发的生命周期,稍有不慎,会导致整个微服务改造的效果大打折扣,甚至失败。

    本公众号接下来的一段时间会协同随行付架构部、随行付技术委员会等技术团队,结合随行付的一些实际经验,论证微服务架构实施的道与术。

    微服务原因

    为什么要做微服务化?可以从以下三个方面看为什么搞微服务。

    • 分而治之:减低复杂性
    • 分而用之:提高可重用性
    • 分而做之:提高开发效率

    可以用变化的成本来衡量架构的好坏。而架构的目的是管理复杂性、易变性和不确定性,以确保系统在进化过程中,架构的变化不会对应用产生不必要的负面影响。保证业务和研发效率的敏捷、保证易变应用频繁响应市场需求而中台部分的影响尽可能的小。

    10 几年前,一提到架构,大多数人都会认为,架构=性能+高可用。随着现在的技术不断更新(Docker、人工智能、区块链等技术)、各类开源软件异军突起、DevOps 理念深得人心、敏捷开发成为主流开发模式等等,性能和高可用已经不再是那么棘手的问题。应用如何可持续发展?产品如何能快速上线 /快速迭代?可维护性、可扩展性、成本,开始慢慢成为很多架构师的关注点。而微服务架构的根本目的就是降低复杂性。

    微服务前提

    业务拆分

    采纳微服务架构首当其冲的问题就是根本没有一个确定的、良好定义的算法可以完成服务的拆分工作。像软件开发本身,服务的拆分和定义更像是一门艺术。更糟糕的是,如果你对系统的服务拆分出现了偏差,你很有可能会构建出一个「分布式的单体应用」,一个包含了紧耦合服务的必须部署在一起的系统。这将会把单体架构和微服务架构两者的弊端集于一身。

    自动测试

    微服务一个明显的表象就是随着服务的增多,如果继续沿用传统的测试模式就会遇到瓶颈,为了保证高效的迭代,尽量做到测试自动化。通过自动化让测试也可以「一处编写,处处运行」、让回归测试日常化。

    自动运维

    当互联网发展到今天,业务要保持对市场变化的一个高效响应,自动化运维就是提升交付速度的一个重要环节。微服务拆分之后,每个服务都可以独立部署,不再是固定的时间段去升级,人肉运维已经成了阻碍进步的绊脚石了。

    多维度监控

    硬件环境、服务状态、系统健康度、服务调用情况、异常的实时告警以及生产事故的事先预警等等。监控在实施微服务过程中至关重要。

    微服务架构原则

    技术栈统一

    一定要使用成熟技术,充分考虑新技术带来的性价比。所谓成熟不仅仅是指有良好的社区活跃度、稳定性、节约开发成本、提高开发效率。更多的是指在随行付的技术普适度,说白了就是有多少人会,出了问题有多少人能 hold 住。

    数据最终一致性

    权衡好哪些服务是最终一致、哪些必须是强一致。而强一致的保障机制是什么?框架层和应用层相互互补来共同保障数据一致性。

    服务无状态

    对于无状态服务,首先说一下什么是状态。如果一个数据需要被多个服务共享,才能完成一笔交易,那么这个数据被称为状态。进而依赖这个「状态」数据的服务被称为有状态服务,反之称为无状态服务。那么这个无状态服务原则并不是说在微服务架构里就不允许存在状态,表达的真实意思是要把有状态的业务服务改变为无状态的计算类服务,那么状态数据也就相应的迁移到对应的「有状态数据服务」中。

    场景说明:例如我们以前在本地内存中建立的数据缓存、Session 缓存,到现在的微服务架构中就应该把这些数据迁移到分布式缓存中存储,让业务服务变成一个无状态的节点。迁移后,就可以做到按需动态伸缩,微服务应用在运行时动态增删节点,就不再需要考虑缓存数据如何同步的问题。

    无状态通信,我们推荐使用 Restful 通信风格,因为他有很多好处:

    • 无状态协议 HTTP,具备先天优势,扩展能力很强。
    • JSON 报文序列化,轻量简单,人与机器均可读,学习成本低,搜索引擎友好。
    • 语言无关,各大热门语言都提供成熟的 Restful API 框架,相对其他的一些 RPC 框架生态更完善。

    AKF 拆分原则

    AKF 扩展立方体,《架构即未来》一书中提出的可扩展模型。理论上按照这三个扩展模式,可以将一个单体系统,进行无限扩展。

    X 轴 :是水平复制。比如讲单体系统多运行几个实例,做个集群加负载均衡的模式。

    Z 轴 :是数据分区,比如按照用户请求的地区进行数据分区,北京、上海、四川等多建几个集群。

    Y 轴 :是微服务的拆分模式,就是基于不同的业务进行拆分。

    举例:比如打车 APP,一个集群撑不住时,分了多个集群,后来用户激增还是不够用。分析后发现打车 APP 上主要用户是乘客和车主,就将打车应用拆成了三个乘客服务、车主服务、支付服务。三个服务的业务特点各不相同,独立维护,各自都可以再次按需扩展。

    服务拆分原则

    单一职责

    根据业务能力拆分。了解过面向对象的人应该都听说过「单一职责原则」,即每一个类都拥有一个职责。比如一个搬砖类,它既可以盖房子,也可以用来拍人,这时搬砖就拥有了两个职责,所以我们应该把类拆分为两个。微服务也是一个道理,我们应该做到一个服务是用来做一件事情的。

    松耦合、高内聚

    紧密关联的事物应该放在一起,每个服务是针对一个单一职责的业务能力的封装,专注做好一件事情。(每次只有一个更改它的理由)。

    DDD

    领域驱动设计。我们怎么按领域来划分服务呢?对,我们可以按业务进行拆分,比如财务、订单、仓库等等。这样我们的团队也可以拆分开来分别负责不同的服务,这样不仅项目清晰了,就连公司内部的组织结构权责分配也变得清晰了。

    刚才从横向来看我们可以按业务领域拆分,纵向的呢?我们可以按层次进行拆分,比如最底层的数据层、基础设施层以及与业务无关的推送、邮件、短信等等。我们还可以按安全性、性能等需要特别关照的以及通用的功能进行抽离沉淀。

    掌握了领域驱动设计不仅遵守了高内聚、松耦合还符合了单一职责原则,那还不赶紧拆起来?

    演进式拆分

    避免过早拆分。过早的划分服务,可能发展一段时间之后,服务的边界会和之前有所不同,导致很多跨服务的修改,代价越来越高,最终又变成了单块系统。所以一开始我们应该按照较粗的粒度进行划分,而是否拆分为更小的服务,应该由团队组织结构决定,如果团队对拆分后服务的维护成本更大了,那就应该放弃拆分更小的粒度。

    服务开发原则

    微服务的开发会面临依赖滞后的问题。在单体架构时,大家需要什么,往往喜欢自己写什么,这其实是没有太严重的依赖问题。但是到了微服务时代,微服务是一个团队或者一个小组提供的,这个时候一定没有办法在某一个时刻同时把所有的服务都提供出来,「需求实现滞后」是必然存在的。

    例如:A 要做一个商户黑名单校验,依赖服务提供者 B。而 B 有其他更重要的任务,导致该服务的开发优先级排的比较低,无法满足 A 的交付时间点。A 会面临要么等待,要么自己实现一个服务。

    一个好的实践策略就是接口先行,基于契约,语言中立。服务提供者和消费者解耦,并行开发,提升产能。无论有多少个服务,首先需要把接口识别和定义出来,然后双方基于接口进行契约驱动开发,利用 Mock 服务提供者和消费者,互相解耦,并行开发,实现依赖解耦。

    采用契约驱动开发,如果需求不稳定或者经常变化,就会面临一个接口契约频繁变更的问题。对于服务提供者,不能因为担心接口变更而迟迟不对外提供接口,对于消费者要拥抱变更,而不是抱怨和抵触。要解决这个问题,一种比较好的实践就是管理 + 技术双管齐下:

    • 代码通过 Sonar 扫描(随行付 Sonar 中定制 208 条规则)

    • 有 80%以上的单元测试复杂度

    • 允许接口变更,但是对变更的频度要做严格管控

    • 提供全在线的 API 文档服务(例如 Swagger UI ),将离线的 API 文档转成全在线、互动式的 API 文档服务

    • API 变更的主动通知机制,要让所有消费该 API 的消费者能够及时感知到 API 的变更

    • 契约驱动测试,用于对兼容性做回归测试

    随行付微服务平台是以 DevOps 为理念,基于 Spring Boot、Spring Cloud、React、React Native、容器技术、人工智能等,面向微服务应用的 PaaS 平台。实现基础设施云化、应用架构现代化和开发流程敏捷化。

    平台核心及功能介绍

    Spring Cloud 生态时序图

    如图上所示,我们围绕 Spring Boot、Spring Cloud 做了很多功能的扩展,让 Spring 生态在随行付能生长出更多的解决实际问题的「果实」,同样并没有盲目的造轮子。因文章篇幅,技术篇更多内容会在系列文章中着重介绍,会从各个中间件入手介绍随行付金融科技技术生态。

    ———————————————————————分割线—————————————————————————

    我是黑少,专注微服务技术分享,喜欢分享、爱交友人、崇尚“实践出真知”的理念,以折腾鼓捣代码为乐

    我的微信:weiweiweiblack

    微信公号:黑少微服务,非技术不八卦,欢迎关注

    Livid
        1
    Livid  
    MOD
       2018-11-16 16:35:58 +08:00
    这样的文章请只发送到 /go/promotions

    这个主题已经被移动。
    Livid
        2
    Livid  
    MOD
       2018-11-16 16:37:36 +08:00
    你之前发布的其他主题也已经被移动到 /go/promotions

    请重视此规则,如果忽略,会导致你的账号及注册手机号被永久 ban。
    heishao
        3
    heishao  
    OP
       2018-11-16 16:50:03 +08:00
    @Livid 站长好,关于已发布的文章只是纯粹分享技术,并无意做推广,只是在文末附加了个人微信号和公号,纯属个人行为,如果不符合发帖规范,后续发文会多加注意
    Livid
        4
    Livid  
    MOD
       2018-11-16 17:02:49 +08:00
    @heishao 需要滚屏、看到最后出现一个公众号的文章,在这里只能发布到 /go/promotions
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2592 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:40 · PVG 18:40 · LAX 02:40 · JFK 05:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.