Agentic AI、具身智能、强化学习框架、端侧大模型……来QCon上海站,感受AI的未来! 了解详情
写点什么

沈剑聊微服务:先做好你的服务拆分

  • 2017-09-12
  • 本文字数:3820 字

    阅读完需:约 13 分钟

随着自动化运维等相关技术的发展,微服务变得更容易管理,这给了微服务架构良好的发展机会;同时,Docker 等容器技术的发展,使微服务架构的落地变得更加方便,这更是为其成为主流技术铺好了道路。目前各家对微服务架构都有自己的理解与落地实践。

本次 InfoQ 采访到 58 到家技术委员会主席沈剑老师,请他讲讲他对微服务架构的一些思考。沈剑老师之前任职于 58 到家,目前在 58 速运,本次分享涉及到 58 到家与 58 速运的相关内容。本文即由采访整理而成。

本次分享主要从服务化的角度来看待微服务,主要是梳理一下微服务这个概念,不做深入地讲解。

从服务化的角度看微服务

互联网架构发展的过程中,当业务复杂度剧增,数据量剧增,吞吐量剧增的时候,就会出现一些技术痛点,下边几个都是最常见的:

痛点一:代码到处拷贝

举一个最常见的业务的例子:用户数据的访问。

绝大部分公司都有一个数据库用来存储用户数据,而各个业务都有访问用户数据的需求。

各个业务线都是自己通过 DAO(Data Access Object)写 SQL 访问 user 库来存取用户数据,这无形中就导致了代码的拷贝。

抽象出一个服务层之后,有统一的一份代码,那么就解决了代码复用的问题。同时业务方通过 RPC 访问用户数据,就像调用一个本地函数一样,比如使用

复制代码
User = UserService::GetUserById(uid);

传入一个 uid,得到一个 User 实体,就像调用本地函数一样,不需要关心序列化、后端执行、网络传输、反序列化等复杂性,方便高效。

痛点二:复杂性扩散

这个内容主要讲一下下边两个点:

1、缓存导致的复杂性

随着访问量越来越高,数据库成了瓶颈,需要加入缓存来降低数据库的读写压力,于是架构中引入了缓存,由于没有统一的服务层,各个业务线都需要关注缓存的引入导致的复杂性:

  • 对于用户数据的写请求,所有业务线都要升级代码:
  1. 先淘汰 cache
  2. 再写数据
  • 对于用户数据的读请求,所有业务线也都要升级代码:
  1. 先读 cache,命中则返回
  2. 没命中则读数据库
  3. 再把数据放入 cache

这个复杂性是典型的“业务无关”的复杂性,业务方需要被迫升级。

2、分库分表导致的复杂性

数据量越来越大,数据库需要进行水平拆分,于是架构中又引入了分库分表,这时又是由于没有统一的服务层,各个业务线都需要关注分库分表的引入导致的复杂性。

这个复杂性也是典型的“业务无关”的复杂性,业务方需要被迫升级。

有了服务层之后,只有服务层需要专注关注底层的复杂性了,向上游屏蔽了细节。

痛点三:库的复用与耦合

服务化并不是唯一解决上述两个痛点的方法,另一种方法是抽象出统一的“库”。比如抽象出一个 user.so,负责整个用户数据的存取,从而避免代码的拷贝。至于复杂性,现在也只剩下 user.so 这一个地方需要关注了。

但是这时候会引入新的问题:库的版本维护与业务线之间代码的耦合

比如业务线 A 将 user.so 由版本 1 升级至版本 2,如果不兼容业务线 B 的代码,那就会导致 B 业务出现问题;
业务线 A 如果通知了业务线 B 升级,这时的业务线 B 就会去升级,但这是与它“自身业务无关”的升级。

痛点四:SQL 质量得不到保障,业务相互影响

本质上 SQL 语句还是各个业务线拼装的,资深的工程师写出高质量的 SQL 没啥问题,经验没有这么丰富的工程师可能会写出一些低效的 SQL。业务线通过 DAO 访问数据库,假如业务线 A 写了一个全表扫描的 SQL,导致数据库的 CPU100%,影响的不只是这一个业务线,而是所有的业务线

有了服务层之后,所有的 SQL 都是服务层提供的,业务线不能再为所欲为了。底层服务对于稳定性的要求更好的话,可以由更资深的工程师维护,而不是像原来 SQL 难以收口,难以控制。

痛点五:疯狂的 DB 耦合

业务线不只访问 user 数据库,还会结合自己的业务访问自己的数据库。

典型的情况是,通过 join 数据表来实现各自业务线的一些业务逻辑。这样的话,业务线 A 的 table-user 与 table-A 耦合在了一起,业务线 B 的 table-user 与 table-B 耦合在了一起,业务线 C 的 table-user 与 table-C 耦合在了一起,最后的结果就是:table-user,table-A,table-B,table-C 都耦合在了一起

服务化之后,底层的数据库被隔离开了,可以很方便的拆分出来,进行扩容。

像上边说的,服务层就是在这样的情况下被抽象出来的。概括起来,它就是用来统一完成一部分数据访问或者子业务逻辑。这就是指服务化

而从这个角度来看,微服务本质上就是指粒度比较细的服务化的实施

具体到 58 到家 /58 速运

就像上边说的,随着业务越来越复杂,数据量越来越大,并发量越来越大,58 到家因为经历了这些阶段,所以系统架构走上了微服务之路。

具体来说,15 年的时候,58 到家的架构碰到了类似的种种问题:

  • 垂直业务扩展,家政、丽人、速运、平台,一些相似的业务代码拷贝越来越严重
  • 数据量、并发量提升,底层架构复杂性不断向上游扩散,所有调用方都需要关注缓存、分库、存储引擎等,效率逐步降低
  • jar 包耦合,多个系统依赖一个公用的 jar 包,一个业务升级导致兼容性问题,影响其他业务
  • 数据库耦合,多个业务公用一个数据库,相互耦合,相互影响
  • SQL 质量低,业务相互耦合,一个业务撰写了一个低质量的 SQL,导致其他业务受影响

其实我们也不是一开始就直接采用微服务架构,这个也是经过了不同阶段而演进出来的。

简单地说,58 到家刚开始的时候,我们先找到通用痛点,抽象出通用数据访问与子业务,然后将它们下沉成微服务

更具体地,早期 58 到家是抽象出用户中心,订单中心,支付中心等来构建微服务的。

我们从 58 速运的角度来讲,刚开始 58 到家是大一统阶段,就是系统没有进行业务拆分的时候,因为刚开始业务量也小,所以它还是可行的。

后来整个系统拆分成了站点、数据库、缓存这三个部分。

接着我们进行了垂直拆分,将平台、家政、丽人、速运这些业务拆分开来。

然后就具体到速运这一块进行服务化架构。

而最近我们还在演进这样一个架构,我们知道速运这一块其实它本身也有多个业务形态,有对小 C 的,有对小 B 的。小 C 是搬家服务,小 B 是货的服务,大 B 是优配服务。原来这三块它们都是耦合在一起的,现在也在进行拆分。

这其实也就是架构演进过程中必然会出现的,而具体再讨论下去,其实就是在做一些微服务架构上的事情了。

上边这些说的都是业务的垂直拆分,下边看一下我们的系统分层情况是怎么样的。

我们现在的系统分成了四层,如下:

  • 第一层:站点平台
  • 第二层:业务服务层。把基础数据通用的东西往上抽,就像上边说的,比如它解决代码拷备的痛点,不能让代码拷来拷去,所以把这份代码抽象成一个服务。解决库的耦合,如果之前没有服务化,可能用代码库,用 jar 包、DLL、SO 库来解决代码拷备这个问题,一个库,多个服务依赖,那库的版本升级,影响范围很大,可能多个服务因为一个库的原因耦合在一起。上边说的这些就是发生在这个层上,它解决的是底层复杂性屏蔽的问题。如果没有服务层,那么牵一发而动全身
  • 第三层:基础数据服务层。不包含复杂的业务逻辑,只是数据访问的代理,对数据库层的 CRUD。原来设计为相对简单的“DAO 层”。
  • 第四层:数据层。数据层包括缓存和 DB。

最开始的时候是没有业务服务层的,业务应用分别直接访问数据库,导致大量耦合;架构演进到第二个阶段的时候,我们抽象出一些通用的业务无关的基础服务,例如地理位置服务、经纬度服务、短网址服务、短信服务等;到了第三个阶段,我们抽象出一些通用业务的服务,例如 passport 服务、订单中心服务、支付中心服务等;未来,我们会进一步去抽象更多的通用业务服务。总之,整个微服务架构演进的思路就是:“共性 + 通用痛点”抽象下沉

需要关注的问题

很多架构师只看到微服务的好处,但其实微服务会导致增加系统运维的复杂性,增加配置文件的复杂性,加大追查问题与监控系统的难度。为了解决这些问题,需要有配套的技术体系支撑,例如:引入自动化上线平台解决运维复杂性问题,引入配置中心解决配置耦合的问题,引入监控平台与调用链平台解决监控与问题追查的问题。微服务体系,需要有一系列技术基础设施配套,而不只是引入一个简单的服务框架,而这些配套的技术基础设施,往往比服务框架本身复杂得多

微服务体系配套基础设施包括但是不限于以下这些东西:

  • 配置中心,解除系统之间因为配置文件导致的耦合,做逻辑上解耦(但物理上仍然保持上下游连接)
  • 消息中心,解除系统之间调用关系导致的耦合,做逻辑上与物理上的双重解耦(物理上不再相互连接)
  • 监控中心,立体化监控,实施机器、进程、接口、日志、用户层面多维度监控,及早发现问题
  • 调用链跟踪系统,图形化,量化展现请求在系统中的调用路径,及早定位问题

一个重要的原则

像上边提到的,在微服务架构的实施过程中,抓住“共性”与“通用痛点”下沉,是一个最常见的原则。这里简单地再以 58 到家为例做一下总结。家政、丽人、速运各个业务都有自己的账户体系、订单体系、支付体系,这样成本显然是较高的,复杂性成本也是会不断增加的。对于这样的一些通用业务,就应该抽象出 passport 服务统一解决 SSO(Single Sign-On)问题;抽象出订单中心服务解决订单的集中存储与展现问题;抽象出支付中心服务来统一解决微信与支付宝的对接,统一解决对账等问题。

寄语

关注业务比研究架构更重要,任何脱离业务的架构设计都是耍流氓。找痛点、解决痛点比高瞻远瞩重要,架构是演进而来的,而不是设计而来的。几点个人浅见,共勉。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-09-12 19:007787

评论 1 条评论

发布
用户头像
很好,点个赞
2019-10-11 17:58
回复
没有更多了
发现更多内容

实时防护,清洗服务可用性达99.95%,江苏杰邦芜湖DC安全基地正式上线

江湖老铁

IT服务台的5个基本参与度指标

ServiceDesk_Plus

IT服务管理 IT服务台 IT服务台指标

【FAQ】HarmonyOS SDK 闭源开放能力 —Vision Kit

HarmonyOS SDK

HarmonyOS

万界星空科技汽车零部件MES解决方案

万界星空科技

mes 万界星空科技mes 汽车行业数字化转型 汽车零部件 汽车零部件mes

打造理想开发环境!双十一硬核装备与云资源全攻略【必备收藏清单】💻🌐

申公豹

程序员

探讨京东商品 API 接口:运用及收益

科普小能手

API 接口 API 测试 京东API接口 京东API 京东商品API

TDengine 签约蘑菇物联,改造通用设备工业互联网平台

TDengine

数据库 tdengine 时序数据库

从热数据到冷数据:TDengine 多级存储如何助力智能数据管理

TDengine

数据库 tdengine 时序数据库

达摩院发布八观气象大模型:精度达1小时1公里,率先落地国网山东省调

新消费日报

怎么在国内运营tiktok账号?

Ogcloud

云手机 tiktok云手机 tiktok运营 TikTok矩阵运营 tiktok运营干货

TikTok封号原因有哪些?怎么解决?

Ogcloud

TikTok 云手机 海外云手机 tiktok运营 tiktok封号原因

度量数据是人工凭感觉录入的,产生的偏差如何解决?

思码逸研发效能

DevOps 研发效能 效能度量 研发效能管理

MySQL 8.0 执行COUNT()很慢原因分析

GreatSQL

如何确保度量过程中收集到的数据是有实际意义的?

思码逸研发效能

研发效能 数据研发 研发效能度量 研发效能管理

团子东子开奖了,这泼天的富贵!

王磊

大语言模型鼻祖Transformer的模型架构和底层原理

Zilliz

nlp Transformer 大模型 Zilliz LLM

怎么对ppt进行批注?2个PPT制作干货分享!

职场工具箱

效率工具 PPT 办公软件 高效办公 AI生成PPT

低代码,而不是低能力,低代码能成为企业降本增效的神器吗?

积木链小链

低代码 低代码开发

如何预测市场趋势和潜在价格变动?请收好这份「加密货币蜡烛图」解读指南

TechubNews

Premiere Pro 2025 for mac(adobe pr 2025) 特别版

你的猪会飞吗

mac破解软件下载 pr2025下载

豆包MarsCode 助力:Canvas 上的素描变色魔法✨

TRAE.ai

程序员 AI 开发 代码 可画

Playwright:掌握Web自动化测试的新利器

霍格沃兹测试开发学社

沈剑聊微服务:先做好你的服务拆分_语言 & 开发_沈剑_InfoQ精选文章