用Kong突破单一数据库

译文
数据库
如果您的微服务设计导致非常大的 API 或多个服务访问单个数据库,请查看为什么 Kong Gateway 应该成为您项目的一部分。

[[441661]]

【51CTO.com快译】您一定对RESTful API并不陌生吧。它为客户端应用提供了一种能够满足业务需求的、访问数据资源的简单方式。事实上,Angular、React和Vue等都是依赖RESTful API的Javascript框架,它们引领着Web应用的市场。

从效果上说,此类RESTful服务类型的API和前端Javascript框架模式的配合,激发了许多组织从单一(monolithic)或过时的应用程序,迁移到新项目中的愿望。当然,凡事都有利与弊,RESTful API在助推敏捷迭代式开发的同时,也带来了一个问题:在传统的应用设计中,我们虽然可以使用多个RESTful API和Javascript框架的组件化客户端,但是也使用着单一的数据库。这种设计的结果往往会导致数据所有权的冲突、高于预期的数据库连接数、以及对大型数据库过高的支持与维护成本。

下图展示了多个服务竞争来自单个数据库资源的情况:

而且,此类现象在开发领域十分常见。大家会倾向于将单个数据库作用并服务于整个微服务的集合。

微服务应该从数据库开始

在大多数编程语言中,我们通常可以使用单个的文件,去创建功能齐全的应用程序。例如在Java中,一切都可以被放置在同一个类的文件中,并且由简单的main()方法实现统领和调用:

  1. Java 
  2. public class SingleClassApplication { 
  3.     public static void main(String[] args) { 
  4.         // Start doing something really cool here 
  5.     } 

但是,这种方法并不利于多个开发人员通过协作的方式贡献代码。就应用程序的各个方面而言,我们需要关注“所有权”(或系统记录)的概念。如果不止一项服务或功能对账户等组件存在着交叉所有权的话,那么我们的业务规则可能会在不同的场景下出现混乱的局面。例如,在RESTful API声明对于某个给定对象的所有权时,就可能发生类似的情况。而且,当我们采取RESTful API的设计模式时,这些概念都需要被转化到数据库的层面上。对此,我们需要遵从如下规则:

将单个RESTful API视为某个应用在给定方面的记录系统(system of record),以便相应的数据层仅专注和使用应用在该方面的数据存储。

下图展示了遵循该规则的微服务设计:

据此,那些为了满足客户需求,而对给定服务采取的扩展,不会对任何其他的服务产生影响。这便是优秀的、针对微服务的数据库设计实践。

数据库的各种约束

在开发过程中,我力推将给定的微服务与专用数据库相隔离。这能够保证相关组件的数量和大小,能够与用户需求相匹配,同时避免具有不同需求水平的元素产生额外的成本。

数据库管理员往往会发现,当应用程序的所有元素都驻留在单个数据库中时,各种约束和关系能够很好地在单个数据库的设计模式中发挥作用。例如,如果有与客户相关联的订单在排队等待删除的话,那么单一数据库的设计就会阻止删除某个客户的请求,毕竟该用户的订单尚未“结清”。

虽然这绝对是拥有单个数据库的好处,但在选择为所有微服务使用单个数据库之前,您需要考虑如下几点:

  • 将使用单个数据库可能获得的长期价值,与扩展单个大型数据库的相关成本进行比较,以了解未来扩展和支持单一数据库设计的预期成本。
  • 在API层强制实施各类约束的利与弊。请记住,由于单个微服务将被视为给定数据库的所有者,因此在业务逻辑上可能会出现上述提到的,不允许删除带有活跃订单的客户的情况。
  • 对于事件驱动(或基于消息)的设计而言,某个微服务如何处理请求,取决于来自另一个微服务的响应情况。虽然这与单个应用程序+单个数据库的设计有着相似之处,但需要在隔离和控制时,具有一定的扩展和分配专用处理算力的能力。

当然,做为一种良好的开发习惯,即使是数据库仅支持某个专用的服务实例,我们也应该实施和强制执行对应的约束关系。

公共元素应该被抽象出来

如果规划不当,采用真正的微服务设计也可能会产生副作用。例如在微服务中,包括认证、缓存、日志记录、监控、以及安全在内的各个公共组件元素,可能会与服务层相重复。

如上图所示,在软件开发的生命周期中,人们往往会用不同的语言,去重复相同的软件模式。对此,我们需要通过在应用程序栈的公共级别、或不同级别,抽象和处理某些元素,来尽可能地避免DRY(不要重复自己)。在此,我推荐使用Kong的情况,进而提供分布式的微服务抽象层。

将Kong置于理想的设计中心

Kong Gateway(允许开发者将服务层API的复杂性,降低到专注于满足业务需求和功能集合的各个端点(或 URI)处。由网关处理的诸如:身份验证、日志记录和安全性等重复性组件,可以被Kong Gateway从服务层的设计中移出。

如下图所示,每个RESTful微服务都维护着一个专用的数据库实例,并且抽象出了各个重复的组件。这里所展示的便是一组以目的为驱动(purpose-driven)的微服务:

开发人员可以通过使用各种常见的企业集成模式(enterprise integration patterns)的消息传递层来,去处理服务间的通信,其中包括:

这样的设计会给我们的应用开发带来如下好处:

  • 如果Node.js服务的使用率高于预期的话,则可以通过扩展,来低成本地实现服务与专用数据库的相互隔离。
  • 如果任何服务发现了数据存储模式从SQL更改为NoSQL,则可以在不更改RESTful API的URI的前提下,部署新的设计,而不会对任何其他服务产生影响。
  • 任何抽象层组件的更改(例如,使用新的日志记录方法)都可以在Kong Gateway层进行,而不会影响到底层服务。

小结

开发人员往往利用包和类,来对他们的程序代码进行分组,以实现可支持性和可维护性。在这些类中,定义方法和函数的规则是,每个代码块应当小且易于理解。这也正是“微服务”的“微”字的体现。其实不只是微服务,程序员也需要让数据库持续以微小、高效、以及目标驱动的方式进行扩展。

通过上述讨论可知,Kong真正为微服务的设计提供了可扩展、且易于采用的核心方式。而Kong Gateway则允许开发人员引入通用组件,并驻留在分布式微服务的抽象层,以实现DRY。

原文标题:Breaking Up a Monolithic Database with Kong,作者:John Vester

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

 

责任编辑:华轩 来源: 51CTO
相关推荐

2011-04-07 17:07:35

MySQL数据

2016-11-03 13:22:57

云产品购买攻略双十一

2009-03-11 17:04:53

2017-05-18 12:16:03

LinuxPythonNoSql

2011-04-26 10:24:27

C++MySQL

2021-05-14 10:45:21

PythonNoSQL数据库

2024-02-21 12:17:00

2018-11-07 15:30:19

数据库NewSQLNoSQL

2010-05-20 14:52:42

MySQL数据库

2023-06-09 00:09:46

MySQL分库分表

2009-05-20 13:48:55

限制MySQLthe table i

2020-11-24 17:22:15

数据库MySQL技术

2019-08-13 08:32:14

MySQL数据库性能调优

2019-07-05 11:20:31

PythonMySQL数据库

2009-07-16 11:11:39

PowerDesign

2015-10-23 14:37:56

DelphiDBExpress连接

2010-05-05 11:17:55

Oracle数据库

2011-03-04 11:08:46

ADO.NET数据库

2009-06-10 22:11:28

javascript连

2010-05-31 09:44:38

点赞
收藏

51CTO技术栈公众号