【编者的话】微服务是一个软件架构模式,对微服务的讨论大多集中在容器或其余技术是否能很好的实施微服务,而本文将从如下几个角度来和你们分享在微服务架构下进行数据设计须要关注的地方,旨在帮助你们在构建微服务架构时,提供一个从数据方面的视角:
- 微服务定义
- 微服务的优点及架构特色
- 微服务架构下的数据设计
- 选择一个合适的数据库
什么是微服务?
按照 Martin Fowler 的定义,微服务是一个软件架构模式,经过开发一系列的小型服务的方式来实现一个应用。每个这样的小服务一般都是运行在本身的进程里面,而且经过轻量级的 HTTP API 方式进行通信。这些服务一般会以业务模块为界限,可以被单独开发部署,每每都会用自动化的部署工具来进行产品的发布。经过使用微服务方法,大公司能够更快推出新产品和服务,使得开发团队与业务目标保持一致。
微服务的优点
微服务方法体现出许多优点,包括更快的上线时间、灵活性、弹性、一致性以及相对更低的成本。
更快的上线时间
实施微服务架构可使组织更快地将其应用程序推向市场。对总体应用程序的更改(即便很小)须要从新部署整个应用程序堆栈,从而引入风险和复杂性。相反,服务的更新能够当即提交、测试和部署,对个别服务的更改不会影响系统的其余部分。
更好的灵活性和可扩展性
微服务方法在扩展应用程序时也提供了灵活性。单片应用程序要求整个系统(及其全部功能)同时扩展。使用微服务,只须要缩放须要额外性能的组件或功能。能够经过部署更多微服务实例来扩展服务范围,从而实现更有效的容量规划并下降软件许可成本,从而下降整体拥有成本。
弹性
使用单体应用程序时,组件的故障可能会危及整个应用程序。在微服务中,每项服务都是隔离的,以防止级联失败致使整个系统崩溃。若是单个微服务的全部实例均失败,则总体服务可能会降级,但其余组件仍可提供有价值的服务。
更容易的规模化
微服务使技术团队可以与组织需求保持一致,而且能够调整团队的大小以匹配所需的任务。一般,微服务团队规模较小可是跨部门(如通常涵盖 Ops、Dev、QA),并专一于整个应用程序的单个组件。经过提供对我的服务的全部权,而不是功能区域,微服务还能够打破团队之间的孤岛,并改善协做。这种方法对于分布式和远程团队尤为强大。 (例如,不一样地点的团队能够独立发布和部署功能。)
微服务的技术特色
让咱们来经过一个例子来了解微服务架构的技术特色。
联邦银行的架构师 Jonnathan 很是不喜欢他的产品经理 Mandy,由于他以为 Mandy 永远有无穷无尽的想法要实现,搞得他整天就在不断地修改代码。可是 Mandy 是老板的红人,并且用户对产品的反响也不错,因此不少时候他只能默默的服从。
这一天 Mandy 又成功的说服了老板要在他们的客户体验提高项目中增长舆情分析和 AI 客户服务模块,但愿经过对社交媒体上有关联邦银行的全部评论进行实时的监控和分析来及时发现联邦银行的产品反馈或者用户体验问题。Jonnathan 已经预感到了这样史无前例的应用场景,会有太多的未知和太多的改变,因而此次决定尝试使用 Microservices 来构建这个应用。
这个是 Jonnathan 设计的架构,系统要求对客户的社交帐号如 Facebook、Twitter、Google+ 及 Snapchat 公开的信息及评论进行收集,并在某些合适的时候使用 AI 技术直接和用户在经过社交工具进行互动。
在上图这个架构里面,Jonnathan 把 4 个不一样社交媒体的数据采集和交互用 4 个独立的模块进行实现,并用一个 Feed Merge 服务,一个 Aggregate Service 把 4 个相似功能的微服务模块的数据和功能进行整合,提供给分析平台使用。这里面每个服务按照微服务的架构,每个都是单独部署,在一个独立的容器内执行,并使用本身的一个数据库。
果不其然,系统上线一段时间,Mandy 说 Google+ 上面几乎没有什么活动,不值得继续维护这样的一套系统。Jonnathan 此次毫无抱怨,直接把负责 Google+ 的容器停了,没有须要任何代码改动,甚至彻底没有须要对整个系统进行停机。
刚下线 Google+,Mandy 又来提需求说最近合并了另外一家银行,客户不少使用 Whatsapp。二话不说,Jonnathan 直接上了一个新的模块来处理 Whatsapp:
又过了一段时间,这一次是 Jonnathan 本身要对系统作调整了,原来 Snapchat 最近大火,他部署的系统频受压力,性能降低。为了解决这个问题,Jonnathan 果断增长了额外 2 台容器来同时支撑 Snapchat 信息的采集和处理。
感谢微服务架构,Jonnathan 在一系列的产品需求变化以及系统扩容需求下,能够从容应付。要实现微服务架构,须要你铭记如下几个微服务架构的应用设计原则:
文章中涉及到的技术点我都分享在群 697579751 里,录制成视频供你们免费下载,但愿能够帮助在这个行业发展的朋友和童鞋们,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,因此我把这些资料,分享出来。相信对于已经工做和遇到技术瓶颈或者写博客码友,在这份资料中必定都有你须要的内容。数据库
Decouple 解耦
在微服务架构中,应用程序被分解为小型的独立服务。服务一般专一于特定的离散目标或功能,并沿着业务边界解耦。按业务界限分离服务可以让团队专一于正确的目标,并确保服务之间的自主性。每项服务都是独立开发,测试和部署的,服务一般是做为独立的进程或软件容器分开的,经过网络和商定的 API 进行通讯,尽管在某些状况下,网络可能在本地。一般部署相同微服务的多个实例,从而提供冗余和可扩展性。
Dump Pipes 轻量级 API
微服务之间的通讯要使用轻量级 API,如 HTTP RESTful API。这样可使得服务对 API 通讯方案的依赖减到最小。复杂的通讯处理要在服务端进行,而不是像 ESB 或者 Data Pipeline 处理总线那样在数据传输过程当中引入很是多的逻辑,致使微服务模块牢牢的绑定在这个数据管道上。
DevOps 持续集成
微服务架构带来的一个很是显著的负面性就是众多实例的测试发布及管理。传统应用虽然开发复杂,可是部署和运维相对比较集中,一台数据库,2-4 个应用服务器就差很少了。可是微服务架构下单独服务的数量轻则 10-20,多则上百个,因此微服务架构通常须要配套的 CI/CD 方法来支撑。
Decentralized 去中心数据治理
数据的管理在微服务架构下也是和传统单体有很大的不一样考量。大部分时候咱们但愿数据就和服务同样,要有充分的独立性,能够和某个服务一块儿部署,一块儿扩展,或者一块儿重构。这一般意味着咱们可能要在一个微服务架构应用内使用多个数据库实例。可是一样须要考虑到数据分布在多实例之间之后,每每还须要一些冗余,以及如何保持这些数据在这些系统中的一致性等问题。下面一章,咱们就着重来讨论微服务架构下的数据设计的一些考量因素。
微服务的数据设计考量
历来没有一个 one-size-fits-all 的架构,因此在微服务架构下面,咱们须要了解的,同样是几个关键的架构考量点。而后针对本身的实际应用,选择哪些考量点是更加剧要。这篇文章的目的,主要就是跟你们来讨论从哪几个角度着手来设计一个符合微服务架构原则的数据架构。好比说,咱们能够从一系列的问题来开始这个讨论:
- 这么多微服务之间,我是否能够用一个数据库,仍是多个数据库来支持多个微服务?
- 若是是多个数据库,我是否为每个微服务挑选一个最合适的数据库,仍是选择同一种类型的数据库?
- 我如何在微服务架构下扩展个人数据库?
- 当一个我依赖的服务须要修改数据库 Schema 的时候,是否会影响到我?
- 当微服务应用不断衍变的时候,个人数据库是否能够快速的响应应用需求变化?
这些就是咱们在微服务数据架构时候要关注的地方。
一库一服仍是一库多服
不管是单体应用,仍是微服务应用,有一点是确定的:应用的各个模块之间都须要进行较为频繁的通讯,经过一块儿协同合做,来实现应用的总体价值。在单体应用中,这种通讯是经过方法调用来完成的。在微服务中,则经过 API 调用来完成。这些模块或者服务间调用,大部分时候是为了共享数据。 共享数据最贱的方式固然就是采用一种共享数据库的模式,也就是单体应用经常使用的方式 - 应用能够有多个系统模块,但通常都是只有一个数据库。以下图左边,3 个微服务模块,后面共享一个数据库,简称一库多服务:
这种架构模式一般会被认为是微服务架构下的反范式,它的问题在于:
- 单点故障:一个数据库倒下,整批服务所有中止。何来的服务独立性?
- 数据在同一个地方,会给贪图方便的开发或者 DBA 工程师编写不少数据间高度依赖的程序或者工具;
- 没法针对某一个服务进行精准优化或扩展,如上文所讲的 Snapchat 的例子。
因此通常推荐的作法,是为每个微服务准备一个单独的数据库,也即一库一服(database per service)模式。如上图右侧所示。这种模式更加适合微服务架构 - 它知足每个服务是独立开发、独立部署、独立扩展的特性。当须要对一个服务进行升级或者数据架构改动的时候,无须影响到其余的服务。须要对某个服务进行扩展的时候,也能够手术式的对某一个服务进行局部扩容。另外,若是某些服务对数据库有特殊的需求,这种模式也为下文所讲的混合持久化(Polyglot Persistence)提供了可能性。
混合持久化 vs. 多模数据库
混合持久化在大型互联网公司是一个比较风行的模式。它秉承的原则就是为特别的任务提供最好的工具。好比说,若是我但愿提供一个高并发低延迟的共享用户会话方案(shared session storage), Redis 多是一个很是理想的选择。若是我是在实现一个产品目录,涉及到大量不定结构的商品数据及属性的建模管理,我可能会采用模式灵活,动态 schema 的 MongoDB 来做为个人数据库解决方案。若是我但愿支持很是强大的全文搜索,ElasticSearch 则是行业中的佼佼者。微服务的功能分块独立部署为这种架构模式提供了很是好的基础,以下图左侧所示就是个典型的混合持久化的案例:
- 混合持久化 - Polyglot Persistence
- 多模数据库 - Multi-model Database
固然,有句话说的是架构师的工做就是天天作不断的取舍 (trade off),由于选择每每是让人很纠结。混合持久化的优点很明显,可让每一个单独的服务使用到最佳的工具和技术。可是它的弊端也是不容忽视。部署、监控、备份、升级等数据库管理工做历来都是一件困难可是重要的任务。引入多个不一样的数据库,也意味着对系统管理维护的复杂度和成本提升了不少。这种状况下可能须要比较有资源的公司或者团队才可使用。这也解释了这个模式在大型互联网公司获得较多的采用与推广。针对于其余小型规模的用户,或者是缺少足够掌握各类新型技术人才的公司来讲,另外一种更为可行的模式多是多模数据库(Multi-model)。如上图右侧所示。
多模数据库的特征是:
- 依然是一库一服务(为一个服务部署一个单独的数据库);
- 可是使用的是同一种类型,支持多种场景的数据库,如 NoSQL 中间为功能最全面的 MongoDB;
- 虽然是多实例,可是只需维护一种类型的数据库,管理上和人员配备上都较为简单。
若是你在开发的应用是一款企业级产品,会交付到客户环境部署安装,则运维管理的简单性将在技术选型中占据很是重要的一个比重,无疑这种状况下多模数据库更加适用。
微服务扩展你的数据
微服务架构的一大裨益是其灵活的扩展性。以上面的 Snapchat 为例,若是须要采集或处理的数据量快速增加,在咱们增长应用服务实例的同时,支撑数据存储的模块也要相应扩充。AFK Partners 在他们的 Scale Cube 一文里对性能扩展提出了这样的观点:要设计一个真正意义上的可扩展系统,咱们必须考虑 3 个维度,以下所示:
- X-轴, 系统复制(横向扩展)
- Y-轴, 非重叠功能的拆分(微服务)
- Z-轴, 数据的分区 (Sharding)
一个好的数据架构,在微服务体系内,应该具备一样的可扩展、易扩展性质,从而不给微服务架构拖后腿。关于数据分区扩展有两种作法:
应用数据分区,顾名思义,就是在应用端对数据的存储进行分区管理。好比说,一个社交应用能够按国家或地区为界把用户的数据分发到不一样数据库实例里面。这样的话每一个数据库实例只须要存储一部分数据,从而实现海量的数据管理能力。数据库分区,就是由数据库的路由节点来完成数据分区的任务。数据库分区的优点是显然的 - 对应用透明、扩展快速、无须下线等。 若是你的应用有潜在扩充的需求,选择一个可以自动扩展的分布式数据库是一个比较明智的选择。
动态模式支持及快速开发能力
这是一个不少架构师可能会忽略,可是很是重要的关注点。咱们在迭代式开发 DevOps 微服务上的不少努力,都是为了快速开发,快速上线,以及快速响应变化的需求。从数据架构师的角度来看,如何不成为在这个快速开发方法模式中的一个瓶颈,有一个很重要的环节就是是否有一个可以及时响应变化的数据模型。传统的数据库都是强模式,须要对 schema 进行清晰定义, 在需求修改致使模型修改的时候须要对数据库进行模式升级,是一个须要下线、耗时而且是高成本的运维操做。
在新一代的 NoSQL 数据库产生以前,咱们并不须要考虑这个问题,可是以 MongoDB、Cassandra 等为表明的 NoSQL 表明的是灵活建模,动态支持模式变化的特征使得它们成为敏捷开发和微服务体系内一个有力的竞争者,在选型的时候也是一个重要的考量因素之一。咱们说一库一服的架构使得对一个服务的数据库模式修改不会影响到其余服务。可是若是使用一个动态模式(有时候有人会说无模式)的数据库,则在该服务自己模式修改时候也能够最小化其最小化的维运成本。
一个适合微服务架构的数据库
红杉资本的合伙人 Matt Miller 是公认的微服务技术领域专家。他的广被传播的“微服务生态图”详尽的列出了微服务架构的相关技术栈。在这里他推荐了 MongoDB 做为主要的数据管理方案。
MongoDB 是一个分布式文档型数据库,它有如下一些特性使它很是适合于微服务架构:
- 多模数据库(Multi-model)
- 原生 JSON 数据结构 - API
- 动态模式、无模式(Dynamic schema / Schemaless)
- 数据变化流(Change Stream)
- 横向扩展能力(Sharding)
多模数据库
MongoDB 从 3.4 版本起在多模数据库场景上提供了很多功能模块,好比说,使用聚合框架(Aggregation Framework)如今开发者可使用:
- $graphLookup 来实现相似于图数据库的查询
- $facet 来实现分面搜索。
- 内存引擎功能,用于支持相似于 Redis 的高速缓存
- 全文检索,用于实现搜索类型场景
JSON 数据结构
因为 MongoDB 原生就是 JSON 数据模型,正好是微服务架构中用于模块间通讯的 HTTP RESTful API 调用的主要数模型。事实上,你可使用一些开源中间件,快速的来构建起微服务之间的 API 服务。
动态模式
这一点一直是 MongoDB 得到开发者青睐的主要缘由之一。MongoDB 无须显式的定义数据模式便可让你开始往数据库写入。当数据模型有变化时候,好比说在迭代式开发中很是常见的就是增长一些字段,MongoDB 数据库不须要对其进行修改 schema 操做,而是能够直接在同一个集合(表)里直接写入新版本的文档。这个对于须要实现快速迭代,快速交付的微服务应用开发是一个很是重要的特性。
数据更改流
微服务架构中因为其分布特性,传统的强事务机制再也不适用。数据的一致性通常须要经过一些基于 Event Sourcing 或者事件驱动模型的解决方案。MongoDB 3.6 版本推出的数据更改流,能够用来实现一个相似于 Kafak 同样的 Message Queue,为各个微服务间的数据协调提供一个简单易用的线程方案。
横向扩展能力
MongoDB 一贯以其强大的横向扩展能力著称。很多 MongoDB 用户迁移的主要缘由就是使用 MongoDB 的 sharding 技术能够突破关系型数据库在数据量和性能上的瓶颈。MongoDB 的 sharding 有几个特征使得其很是适合微服务架构考虑使用:
- 弹性扩展:能够扩容也能够缩容;
- 无缝扩展:无须停机,就可在线扩容;
- 自动均衡:无须应用参与便可实现数据的自动均衡,彻底透明。
一个基于 MongoDB 的微服务参考架构图:
文章中涉及到的技术点我都分享在群 697579751 里,录制成视频供你们免费下载,但愿能够帮助在这个行业发展的朋友和童鞋们,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,因此我把这些资料,分享出来。相信对于已经工做和遇到技术瓶颈或者写博客码友,在这份资料中必定都有你须要的内容。缓存