微服务架构设计

一、微服务概述

1、什么是微服务?

微服务就是一些可独立运行、可协同工作的小的服务。

从概念中我们可以提取三个关键词:可独立运行、可协同工作、小。这三个词高度概括了微服务的核心特性。下面我们就对这三个词作详细解释。

  • 可独立运行
    微服务是一个个可以独立开发、独立部署、独立运行的系统或者进程。

  • 可协同工作
    采用了微服务架构后,整个系统被拆分成多个微服务,这些服务之间往往不是完全独立的,在业务上存在一定的耦合,即一个服务可能需要使用另一个服务所提供的功能。这就是所谓的“可协同工作”。与单服务应用不同的是,多个微服务之间的调用时通过RPC通信来实现,而非单服务的本地调用,所以通信的成本相对要高一些,但带来的好处也是可观的。

  • 小而美
    微服务的思想是,将一个拥有复杂功能的庞大系统,按照业务功能,拆分成多个相互独立的子系统,这些子系统则被称为“微服务”。每个微服务只承担某一项职责,从而相对于单服务应用来说,微服务的体积是“小”的。小也就意味着每个服务承担的职责变少,根据单一职责原则,我们在系统设计时,要尽量使得每一项服务只承担一项职责,从而实现系统的“高内聚”。

2、微服务的优点

  • 易于扩展
    在单服务应用中,如果目前性能到达瓶颈,无法支撑目前的业务量,此时一般采用集群模式,即增加服务器集群的节点,并将这个单服务应用“复制”到所有的节点上,从而提升整体性能。然而这种扩展的粒度是比较粗糙的。如果只是系统中某一小部分存在性能问题,在单服务应用中,也要将整个应用进行扩展,这种方式简单粗暴,无法对症下药。而当我们使用了微服务架构后,如果某一项服务的性能到达瓶颈,那么我们只需要增加该服务的节点数即可,其他服务无需变化。这种扩展更加具有针对性,能够充分利用计算机硬件/软件资源。而且只扩展单个服务影响的范围较小,从而系统出错的概率也就越低。

  • 部署简单
    对于单服务应用而言,所有代码均在一个项目中,从而导致任何微小的改变都需要将整个项目打包、发布、部署,而这一系列操作的代价是高昂的。长此以往,团队为了降低发布的频率,会使得每次发布都伴随着大量的修改,修改越多也就意味着出错的概率也越大。
    当我们采用微服务架构以后,每个服务只承担少数职责,从而每次只需要发布发生修改的系统,其他系统依然能够正常运行,波及范围较小。此外,相对于单服务应用而言,每个微服务系统修改的代码相对较少,从而部署后出现错误的概率也相对较低。

  • 技术异构性
    对于单服务应用而言,一个系统的所有模块均整合在一个项目中,所以这些模块只能选择相同的技术。但有些时候,单一技术没办法满足不同的业务需求。如对于项目的算法团队而言,函数试编程语言可能更适合算法的开发,而对于业务开发团队而言,类似于Java的强类型语言具有更高的稳定性。然而在单服务应用中只能互相权衡,选择同一种语言,而当我们使用微服务结构后,这个问题就能够引刃而解。我们将一个完整的系统拆分成了多个独立的服务,从而每个服务都可以根据各自不同的特点,选择最为合适的技术体系。
    当然,并不是所有的微服务系统都具备技术异构性,要实现技术异构性,必须保证所有服务都提供通用接口。我们知道,在微服务系统中,服务之间采用RPC接口通信,而实现RPC通信的方式有很多。有一些RPC通信方式与语言强耦合,如Java的RMI技术,它就要求通信的双方都必须采用Java语言开发。当然,也有一些RPC通信方式与语言无关,如基于HTTP协议的REST。这种通信方式对通信双方所采用的语言没有做任何限制,只要通信过程中传输的数据遵循REST规范即可。当然,与语言无关也就意味着通信双方没有类型检查,从而会提高出错的概率。所以,究竟选择与语言无关的RPC通信方式,还是选择与语言强耦合的RPC通信方式,需要我们根据实际的业务场景合理地分析。

二、数据库的服务化切分

1、什么是“分库分表”?

随着大数据时代的到来,业务系统的数据量日益增大,数据存储能力逐渐成为影响系统性能的瓶颈。目前主流的关系型数据库单表存储上限为1000万条记录,而这一存储能力显然已经无法满足大数据背景下的业务系统存储要求了。随着微服务架构、分布式存储等概念的出现,数据存储问题也渐渐迎来了转机。而数据分片是目前解决海量数据持久化存储与高效查询的一种重要手段。数据分库分表的过程在系统设计阶段完成,要求系统设计人员根据系统预期的业务量,将未来可能出现瓶颈的数据库、数据表按照一定规则拆分成多个库、多张表。这些数据库和数据表需要部署在不同的服务器上,从而将数据读写压力分摊至集群中的各个节点,提升数据库整体处理能力,避免出现读写瓶颈的现象。

目前数据分片的方式一共有两种:离散分片和连续分片。

离散分片是按照数据的某一字段哈希取模后进行分片存储。只要哈希算法选择得当,数据就会均匀地分布在不同的分片中,从而将读写压力平均分配给所有分片,整体上提升数据的读写能力。然而,离散存储要求数据之间有较强的独立性,但实际业务系统并非如此,不同分片之间的数据往往存在一定的关联性,因此在某些场景下需要跨分片连接查询。由于目前所有的关系型数据库出于安全性考虑,均不支持跨库连接。因此,跨库操作需要由数据分库分表中间件来完成,这极大影响数据的查询效率。此外,当数据存储能力出现瓶颈需要扩容时,离散分片规则需要将所有数据重新进行哈希取模运算,这无疑成为限制系统可扩展性的一个重要因素。虽然,一致性哈希能在一定程度上减少系统扩容时的数据迁移,但数据迁移问题仍然不可避免。对于一个已经上线运行的系统而言,系统停止对外服务进行数据迁移的代价太大。
连续分片,它能解决系统扩容时产生的数据迁移问题。这种方式要求数据按照时间或连续自增主键连续存储。从而一段时间内的数据或相邻主键的数据会被存储在同一个分片中。当需要增加分片时,不会影响现有的分片。因此,连续分片能解决扩容所带来的数据迁移问题。但是,数据的存储时间和读写频率往往呈正比,也就是大量的读写往往都集中在最新存储的那一部分数据,这就会导致热点问题,并不能起到分摊读写压力的初衷。

2、数据库扩展的几种方式

数据库扩展一共有四种分配方式,分别是:垂直分库、垂直分表、水平分表、水平数据分片。每一种策略都有各自的适用场景。

  • 垂直分库
    垂直分库即是将一个完整的数据库根据业务功能拆分成多个独立的数据库,这些数据库可以运行在不同的服务器上,从而提升数据库整体的数据读写性能。这种方式在微服务架构中非常常用。微服务架构的核心思想是将一个完整的应用按照业务功能拆分成多个可独立运行的子系统,这些子系统称为“微服务”,各个服务之间通过RPC接口通信,这样的结构使得系统耦合度更低、更易于扩展。垂直分库的理念与微服务的理念不谋而合,可以将原本完整的数据按照微服务拆分系统的方式,拆分成多个独立的数据库,使得每个微服务系统都有各自独立的数据库,从而可以避免单个数据库节点压力过大,影响系统的整体性能,如下图所示。
    这里写图片描述

  • 垂直分表
    垂直分表如果一张表的字段非常多,那么很有可能会引起数据的跨页存储,这会造成数据库额外的性能开销,而垂直分表可以解决这个问题。垂直分表就是将一张表中不常用的字段拆分到另一张表中,从而保证第一章表中的字段较少,避免出现数据库跨页存储的问题,从而提升查询效率。而另一张表中的数据通过外键与第一张表进行关联,如下图所示。
    这里写图片描述

  • 水平分表
    如果一张表中的记录数过多(超过1000万条记录),那么会对数据库的读写性能产生较大的影响,虽然此时仍然能够正确地读写,但读写的速度已经到了业务无法忍受的地步,此时就需要使用水平分表来解决这个问题。水平分表是将一张含有很多记录数的表水平切分,拆分成几张结构相同的表。举个例子,假设一张订单表目前存储了2000万条订单的数据,导致数据读写效率极低。此时可以采用水平分表的方式,将订单表拆分成100张结构相同的订单表,分别叫做order_1、order_2……、order_100。然后可以根据订单所属用户的id进行哈希取模后均匀地存储在这100张表中,从而每张表中只存储了20万条订单记录,极大提升了订单的读写效率,如下图所示。当然,如果拆分出来的表都存储在同一个数据库节点上,那么当请求量过大的时候,毕竟单台服务器的处理能力是有限的,数据库仍然会成为系统的瓶颈,所以为了解决这个问题,就出现了水平数据分片的解决方案。
    这里写图片描述

  • 水平分库分表
    水平数据分片与数据分片区别在于:水平数据分片首先将数据表进行水平拆分,然后按照某一分片规则存储在多台数据库服务器上。从而将单库的压力分摊到了多库上,从而避免因为数据库硬件资源有限导致的数据库性能瓶颈,如下图所示。
    这里写图片描述

3、分库分表的几种方式

目前常用的数据分片策略有两种,分别是连续分片和离散分片。

  • 离散分片
    离散分片是指将数据打散之后均匀地存储在逻辑表的各个分片中,从而使的对同一张逻辑表的数据读取操作均匀地落在不同库的不同表上,从而提高读写速度。离散分片一般以哈希取模的方式实现。比如:一张逻辑表有4个分片,那么在读写数据的时候,中间件首先会取得分片字段的哈希值,然后再模以4,从而计算出该条记录所在的分片。在这种方法中,只要哈希算法选的好,那么数据分片将会比较均匀,从而数据读写就会比较均匀地落在各个分片上,从而就有较高的读写效率。但是,这种方式也存在一个最大的缺陷——数据库扩容成本较高。采用这种方式,如果需要再增加分片,原先的分片算法将失效,并且所有记录都需要重新计算所在分片的位置。对于一个已经上线的系统来说,行级别的数据迁移成本相当高,而且由于数据迁移期间系统仍在运行,仍有新数据产生,从而无法保证迁移过程数据的一致性。如果为了避免这个问题而停机迁移,那必然会对业务造成巨大影响。当然,如果为了避免数据迁移,在一开始的时候就分片较多的分片,那需要承担较高的费用,这对于中小公司来说是无法承受的。

  • 连续分片
    连续分片指的是按照某一种分片规则,将某一个区间内的数据存储在同一个分片上。比如按照时间分片,每个月生成一张物理表。那么在读写数据时,直接根据当前时间就可以找到数据所在的分片。再比如可以按照记录ID分片,这种分片方式要求ID需要连续递增。由于Mysql数据库单表支持最大的记录数约为1000万,因此我们可以根据记录的ID,使得每个分片存储1000万条记录,当目前的记录数即将到达存储上限时,我们只需增加分片即可,原有的数据无需迁移。连续分片的一个最大好处就是方便扩容,因为它不需要任何的数据迁移。但是,连续分片有个最大的缺点就是热点问题。连续分片使得新插入的数据集中在同一个分片上,而往往新插入的数据读写频率较高,因此,读写操作都会集中在最新的分片上,从而无法体现数据分片的优势。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值