到目前为止,在本书中,我们已经了解了如何开发企业级应用,以及如何使我们的流程成熟,从而使我们交付的应用符合我们的质量标准,并为其用户提供强健而有弹性的体验。在本章中,我们将研究开发应用的新范例,其中应用不是单个产品,而是多个相互交互的产品的组合,以提供统一的体验。
近年来,发展情景发生了迅速变化。应用开发已经从开发大型整体过渡到开发较小的服务,所有这些服务都相互作用,为用户提供所需的结果。这一变化是为了满足快速交付项目的需求,以提高添加新功能和改进应用可伸缩性的能力。
在本章的过程中,我们将了解这种新的应用开发模式,其中团队变得越来越小,以不断降低的成本在应用中发布新功能的能力已成为新的标准。这种被称为微服务开发方法的范式从根本上改变了应用开发周期的工作方式,也导致了与 DevOps、持续集成和部署相关的技术的当前趋势。
随着本章的学习,您将了解以下内容:
- 走向微服务开发方法
- API 驱动的服务间通信
- 构建健壮的微服务
- 在微服务中处理用户-服务器交互
- 微服务之间的异步通信
可以通过运行以下命令克隆代码示例:
git clone https://github.com/PacktPublishing/Hands-On-Enterprise-Application-Development-with-Python设置和运行代码的步骤已包含在目录中的README.md文件中,以提供有关代码示例的更深入上下文。
在过去几年中,开发人员一直在尝试开发应用的新方法。这样做的目的是缩短开发生命周期的时间,提高将项目更快地投入生产的能力,增加组件之间的解耦,以便它们可以独立开发,并提高开发应用的团队的并行性。
随之而来的是使用微服务的开发技术,这有助于解决上述用例。在这种方法中,应用不是一个大型代码库,所有组件都放在一起,对任何组件进行一次更改都需要重新部署整个应用。首先,让我们看看微服务模型与单一模型的区别,然后看看遵循微服务方法有哪些优势。
我们都习惯于构建一个应用,其中一个代码库由一个应用的所有功能组件组成,紧密地联系在一起以实现特定的预期结果。这些应用遵循严格的开发方法,在最初的需求收集和设计阶段首先考虑应用的功能和体系结构,然后开始严格的应用开发。
只有在开发了所有组件并进行了彻底测试之后,应用才进入生产阶段,在生产阶段,应用被部署到基础架构上以供正常使用。该模型如下图所示:
这个过程。。。
微服务体系结构为我们解决了很多问题,主要是因为我们开发和部署微服务的方式发生了变化。让我们来看一下微服务体系结构给我们的开发过程带来的一些优势,如下表所示:
- **小型团队:**由于特定的微服务通常专注于做一件事并把它做好,因此负责构建该微服务的团队通常可以是小型的。一个团队可以拥有多个端到端的微服务,他们不仅负责开发,还负责部署和管理,从而形成良好的 DevOps 文化。
- **独立性增强:**在微服务体系结构中,负责开发一个微服务的团队不需要完全了解另一个微服务的内部工作方式。为了与微服务进行交互,团队只需要处理微服务公开的 API 端点。这避免了团队在执行开发活动时相互依赖。
- **增强了故障恢复能力:**在微服务体系结构中,故障恢复能力相当高,因为一个微服务中的故障不会影响整个应用,而是会导致服务的逐渐降级。在此期间,可能会启动失败服务的新实例,或者可以轻松隔离失败服务进行调试,以减少影响。
- **增加了可伸缩性:**微服务架构在应用的可伸缩性方面提供了很大的自由度。现在,随着负载的增加,单个微服务可以独立扩展,而不是扩展整个应用。这种扩展可以作为水平扩展发生,其中根据应用所经历的负载,可以启动一组选定微服务的更多实例,或者可以使用垂直扩展单独扩展这些服务,将更多资源专用于特定服务,以便更好地处理不断增加的负载。
- **易集成:**通过微服务,不同服务之间的集成很容易,因为不需要了解其他微服务的内部结构。所有的集成都是在假定其他微服务是黑盒的情况下进行的。
- **提高了可重用性:**一旦开发,微服务可以用于不同的应用。例如,负责处理用户身份验证的微服务可以在多个应用中重用,这可能需要用户身份验证而无需复制代码。
- **轻松推出****新功能的自由:**借助微服务架构,可以轻松推出新功能。在大多数情况下,一个特定的特性被转换成它自己的微服务,然后在适当的测试之后,该服务被部署到生产环境中。一旦该服务投入生产,其功能就可以使用。这与单片方法不同,在单片方法中,当需要将新功能或改进部署到生产环境时,需要重新部署整个应用。
从这个列表中,我们可以看到微服务体系结构的发展为我们提供了许多好处。从工具的选择到推出新功能的方便,微服务体系结构使开发人员能够迅速开始推出新的微服务。
但所有这些优势并不是免费的。尽管有很多优点,但在使用微服务体系结构时也有可能造成基础设施混乱,这不仅会增加成本。然而,这也可能会影响团队的整体生产力,最终可能会更加关注由于体系结构的缺陷实现而可能出现的问题,而不是关注对应用用户来说至关重要的功能的改进和开发。
这没什么好担心的。我们可以遵循一些简单的建议,这些建议在我们使用微服务架构的过程中会有很大帮助。所以,让我们花一些时间来理解这些简单的提示,它们可以大大帮助我们使我们的微服务之旅顺利进行。
微服务的开发是具有挑战性的,要正确使用它们是相当困难的。我们能做些什么来简化这个过程吗?事实证明,有两条指导原则,如果遵循这些指导原则,将大大有助于获得正确的微服务。那么,让我们看看下面的指南,如下表所示:
- 开发前设计:当微服务开发发生时,它们通常被认为是对特定责任领域建模。但这也是最大错误发生的地方。通常,不定义服务的边界。在后期阶段,随着领域的发展,微服务也变得复杂,以便处理不断增加的。。。
在传统的应用开发模型中,与特定应用相关的服务通常以静态方式部署,其网络位置不会自动更改。如果是这种情况,那么维护一个偶尔更新以反映服务的更改网络位置的配置文件是绝对正确的。
但在现代基于微服务的应用中,服务的数量可能会根据多种因素而上下波动,例如负载平衡、升级、新功能的推出等等,维护配置文件有点困难。此外,目前大多数云环境都不为这些服务提供静态网络部署,这意味着这些服务的网络位置可能会不断变化,给配置文件的维护带来更多麻烦。
为了应对这类情况,我们需要有更具动态性、能够适应不断变化的环境的东西。进入服务发现的概念。服务发现允许动态解析所需服务的网络端点,并且不需要手动更新配置文件。
服务发现通常有以下两种类型:
- 客户端服务发现
- 服务器端服务发现
但在介绍这两种方法之前,我们需要了解服务发现系统的另一个重要组件。让我们来看看这个重要组件是什么,以及它如何促进服务发现过程。
使用客户端服务发现方法,单个服务需要知道服务注册表。例如,在此模型中,如果服务实例 A想要向服务实例 C发出请求,则发出该请求的过程如下图所示:
请求的流程解释如下:
- 服务实例 A向服务注册中心查询服务实例 C的网络地址。
- 服务注册表检查其数据库中服务实例 C的网络地址,并将其返回给服务实例 A。如果服务实例 C是负载平衡服务。。。
使用服务器端服务发现模式,解析服务的网络地址的能力不存在于单个客户端中,而是将此逻辑移动到负载平衡器中。在服务器端服务发现模式中,请求流如下图所示:
此图显示了以下过程:
- 客户端请求 API 端点
- 负载平衡器截获请求并查询服务注册表以解析相应服务的网络地址
- 然后负载平衡器将请求发送到相应的网络服务以处理该请求
这种模式的优点在于,通过从客户机中删除服务发现逻辑,减少了代码重复,并且由于服务注册表不占用负载平衡算法的负载,因此可以实现更好的负载平衡。
既然我们已经了解了微服务体系结构中的服务发现是如何发生的,那么让我们集中精力了解微服务中另一个有趣的概念。
假设您正在构建一个应用,该应用应该处理多个设备,并且每个设备提供的功能根据某些方面而有所不同,例如移动设备将不具有允许向其他用户发送直接消息的功能。在这种情况下,每个设备都需要一个不同的 API 端点,它可以调用该端点来访问其特定的服务集。但是,在应用的维护阶段,或者当某些 API 发生更改时,让客户机知道每个 API 端点可能会成为一个问题。为了处理这类场景,我们需要一些东西作为我们交流的中间层。
幸运的是,在微服务体系结构中,我们有一些东西可以帮助我们解决这个问题。让我们来看看我们有什么办法。
在基于微服务体系结构的任何生产级应用的开发过程中,服务可能在很大程度上取决于生产中部署的其他服务的可用性。例如,为应用的管理面板提供功能的服务可能需要用户身份验证服务的可用性,以允许管理员登录和权限管理。如果用户管理服务宕机,应用提供的操作稳定性可能会受到严重影响。
为了保证这些类型的需求,我们需要 SLA 作为提供特定微服务的团队之间的合同。这些
我们现在已经准备好使用微服务体系结构构建我们的第一个应用。在开发此应用的过程中,我们将看到如何利用我们迄今为止获得的知识来推出一个工作应用。
现在,关于我们的例子,为了保持这个应用简单,并提供一个简单的理解如何使用微服务架构,我们将构建一个简单的待办事项列表创建应用:让我们来看看这个应用的外观,如以下列表中所规定的:
- 该应用将由两个微服务组成,即待办事务管理器服务和用户身份验证服务
- 这些服务将用 Python 开发
- 出于本练习的目的,这些服务将使用它们自己的 SQLite 数据库
- to-do 服务将依赖于用户服务来收集与用户操作相关的任何类型的信息,包括用户身份验证、配置文件获取等
- 这些服务将通过使用 RESTful API 进行通信,每个 API 都提供一个 JSON 编码的响应
指定了基本需求之后,现在是我们开始编写微服务的时候了。
用户微服务负责处理与用户配置文件管理相关的任何事情。该服务有助于实现以下功能:
- 新用户的注册
- 用户配置文件的管理
- 现有用户的身份验证
- 生成用户登录时使用的唯一身份验证令牌
- 向其他服务提供用户身份验证功能
要使此服务正常运行,我们需要以下两种数据库模型:
- **用户数据库模型:**用户数据库模型负责管理用户记录,如用户名、哈希密码等。
- **令牌数据库模型:**令牌数据库模型负责存储已生成令牌的相关信息。。。
待办事务管理器服务是帮助我们的用户管理他们的todo项目的服务。此服务为用户提供创建新列表和向列表中添加项目的功能。为此,唯一的要求是应该对用户进行身份验证。
要正常工作,该服务将需要一个列表数据库模型,该模型将用于存储有关用户创建的todo列表的信息,以及一个项目模型,该模型将包含特定todo列表的项目列表。
以下代码片段实现了这些模型:
'''
File: models.py
Description: The models for the todo service.
'''
from todo_service.todo_service import db
import datetime
class List(db.Model):
"""The list database model.
The list database model is used to create a new todo list
based on the input provided by the user.
"""
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, nullable=False)
list_name = db.Column(db.String(25), nullable=False)
db.UniqueConstraint('user_id', 'list_name', name='list_name_uiq')
def __repr__(self):
"""Provide a representation of model."""
return "<List {}>".format(self.list_name)
class Item(db.Model):
"""The item database model.
The model is used to store the information about the items
in a particular list maintained by the user.
"""
id = db.Column(db.Integer, primary_key=True)
list_id = db.Column(db.Integer, db.ForeignKey(List.id))
item_name = db.Column(db.String(50), nullable=False)
db.UniqueConstraint('list_id', 'item_name', name='item_list_uiq')
def __repr__(self):
"""Provide a representation of model."""
return "<Item {}>".format(self.item_name)一旦开发了这些模型,接下来我们要做的就是实现 API。
对于待办事务管理器服务,将提供以下 API,为服务提供交互端点:
/list/new:此 API 端点接受要创建的列表的名称并创建一个新列表。/list/add_item:此 API 端点接收需要添加到列表中的项目列表以及应该添加项目的列表名称。验证后,项目将添加到列表中。/list/view:此 API 端点采用需要显示其内容的列表的名称,并显示列表的内容。
以下代码片段显示了服务的端点实现:
def check_required_fields(req_fields, input_list):
"""Check if the required fields are present or not in a given list.
Keyword arguments:
req_fields -- The list of fields required
input_list -- The input list to check for
Returns:
Boolean
"""
if all(field in req_fields for field in input_list):
return True
return False
def validate_user(auth_token):
"""Validates a user and returns it user id.
Keyword arguments:
auth_token -- The authentication token to be used
Returns:
Integer
"""
endpoint = user_service + '/auth/validate'
resp = requests.post(endpoint, json={"auth_token": auth_token})
if resp.status_code == 200:
user = resp.json()
user_id = user['user_id']
return user_id
else:
return None
@app.route('/list/new', methods=['POST'])
def new_list():
"""Handle the creation of new list."""
required_fields = ['auth_token', 'list_name']
response = {}
list_data = request.get_json()
if not check_required_fields(required_fields, list_data.keys()):
response['message'] = 'The required parameters are not provided'
return jsonify(response), 400
auth_token = list_data['auth_token']
# Get the user id for the auth token provided
user_id = validate_user(auth_token)
# If the user is not valid, return an error
if user_id is None:
response['message'] = "Unable to login user. Please check the auth token"
return jsonify(response), 400
# User token is valid, let's create the list
list_name = list_data['list_name']
new_list = List(user_id=user_id, list_name=list_name)
db.session.add(new_list)
try:
db.session.commit()
except Exception:
response['message'] = "Unable to create a new todo-list"
return jsonify(response), 500
response['message'] = "List created"
return jsonify(response), 200
@app.route('/list/add_item', methods=['POST'])
def add_item():
"""Handle the addition of new items to the list."""
...
# The complete code for the service can be found inside the assisting code repository for the book有了前面的代码,我们现在就可以使用我们的待办事项管理器服务了,它将帮助我们通过使用 RESTful API 创建和管理待办事项列表。
但是,在执行待办经理服务之前,我们需要记住一件重要的事情。该服务依赖于用户服务来执行任何类型的用户身份验证和获取有关用户配置文件的信息。为了实现这一点,我们的待办经理需要知道用户服务在哪里运行,以便它能够与用户服务交互。对于本例,我们通过在 to-do 管理器服务配置文件中为用户服务端点设置配置密钥来实现这一点。以下代码段显示了待办事项管理器服务配置文件的内容:
DEBUG = False
SECRET_KEY = 'du373r3uie3yf3@U#^$*EU9373^#'
BCRYPT_LOG_ROUNDS = 5
SQLALCHEMY_DATABASE_URI = 'sqlite:///todo_service.db'
SQLALCHEMY_ECHO = False
USER_SERVICE_ENDPOINT = 'http://localhost:5000'要运行 To-do manager 服务,需要从存储库中的todo_service目录中执行以下命令:
python3 run.py一旦命令成功执行,待办事务管理器服务将在http://localhost:5001/可用。
一旦服务启动并运行,我们就可以利用它的 API 来管理我们的库存。例如,如果我们想要创建一个新的待办事项列表,我们所需要做的就是向http://localhost:5001/list/newAPI 端点发送一个 HTTP POST 请求,将以下键作为 JSON 格式的输入传递:
auth_token这是用户使用http://localhost:5000/auth/loginAPI 端点成功登录用户服务后收到的认证令牌 ***list_name这是要创建的新列表的名称**
****API 端点调用完成后,待办事务管理器服务首先尝试通过与用户服务交互来验证 API 调用中提供的auth令牌。如果验证了auth令牌,则待办事务管理器服务将接收用于标识用户的用户 ID。完成此操作后,待办事项管理器服务将根据检索到的用户 ID 在其数据库中为新的待办事项列表创建一个条目。
这是待办事务管理器服务的一个简单工作流。
现在我们了解了如何构建一个简单的微服务,现在我们可以关注一些关于微服务体系结构的有趣话题。您是否注意到我们是如何通知待办经理服务存在用户服务的?我们使用了一个配置密钥来实现这一点。当您只有两个或三个服务时,使用配置键决不是一个坏选项,无论发生什么情况,这些服务都将始终在相同的端点上运行。然而,当微服务数量甚至略多于两个或三个服务时,这种方法就会出现严重故障,这些服务可能在基础设施的任何位置运行。
除了这些问题之外,如果新服务频繁投入生产以向应用添加新功能,问题会进一步加剧。在这一点上,我们将需要更好的东西,它不仅可以提供一种简单的方法来识别新服务,还可以自动解析它们的端点。
假设有一场魔术表演将在礼堂内举行。这个节目对每个人开放,任何人都可以到礼堂来参加。在礼堂门口,有一个登记台,你需要在那里登记才能进入礼堂。观众一开始来,他们就先到登记台,提供姓名、地址等信息,然后拿到入场券。
服务注册中心是这样的。它是一种特殊的数据库,用于记录基础设施上运行的服务以及它们的位置。每当新服务出现时,它都会注册。。。
在构建微服务体系结构时,我们有很多选择,我们可以自由选择最适合实现微服务的技术堆栈。除此之外,我们还可以通过推出特定于不同设备的不同微服务,为不同设备呈现不同的功能。但是当我们这样做的时候,我们也增加了客户机的复杂性,它现在必须处理所有这些不同的场景。
因此,让我们首先看看我们在客户端可能面临的挑战,如下图所示:
上图显示了我们面临的挑战,如下表所示:
- **处理不同的 API:**当每个设备都有一个特定的微服务来提供其所需的一组功能时,该设备的客户端需要了解与该特定服务相关的 API 端点。这增加了复杂性,因为现在负责处理客户机开发的团队需要了解可能会减慢客户机开发过程的特定于微服务的端点。
- **更改 API 端点:**在一段时间内,我们可能会修改微服务中特定 API 端点的工作方式。这将要求我们更新使用 microservice 提供的服务的所有客户端,以反映这些更改。这是一个繁琐的过程,还可能引入 bug 或破坏现有功能。
- **协议支持差:**通过微服务架构,我们有能力控制用于构建微服务的技术堆栈。有时,微服务可能由其他平台通常不支持的协议提供动力,或者在其他平台上实现较差。例如,客户机运行的大多数平台可能不支持 AMQP 之类的东西,这将使客户机的开发成为一项艰巨的工作,因为现在开发人员必须在每个客户机内部构建处理 AMQP 协议的逻辑。这种需求不仅具有挑战性,而且如果平台不支持处理所需处理的额外负载,也可能无法完成。
- **安全性:**如果我们需要嵌入为每个客户端供电的微服务的各个网络位置的详细信息,我们也可能会在我们的基础设施中打开安全漏洞,即使其中一个微服务的安全配置不正确。
这些只是我们在开发微服务应用过程中可能面临的一些挑战。但我们能做些什么来克服它们吗?
这个问题的答案在于 API 网关的使用。
API 网关可以被视为客户端和应用通信之间的中介,处理客户端请求的路由以及这些请求从客户端支持的协议到后端微服务支持的协议的转换。它可以做到这一切,而不会让客户端担心微服务可能在哪里运行。
在利用 API 网关的基于微服务体系结构的应用中,从客户端到应用的请求流可描述如下:
- 客户机有一组公共端点,它知道要访问某一组功能。
- 客户端向 API 端点发送请求,以及完成请求所需传递的任何数据。
- API 网关拦截客户端向 API 端点发出的请求。
- API 网关确定客户端类型和客户端支持的功能。
- 然后,API 网关确定完成请求所需调用的各个微服务。
- API 网关然后将请求转发到后端运行的特定微服务。如果微服务接受的协议与客户端发出请求的协议不同,API 网关会将客户端协议的请求转换为微服务支持的协议,然后转发请求。
- 一旦微服务完成了响应的生成,API 网关将收集响应并将一个集体响应发送回请求客户端。
这种方法有几个优点;让我们来看看其中的几个:
- **简单客户端:**有了 API 网关,客户端就不需要知道他们可能需要调用的单个微服务。这里的客户端为特定功能调用公共端点,然后 API 网关负责确定需要调用哪个服务来完成请求。这大大降低了正在开发的客户端的复杂性,并使它们的维护变得容易。
- **更改 API 端点的方便性:**当后端微服务中特定 API 的实现发生更改时,API 网关可以处理未更新的旧客户端的兼容性。这可以通过使 API 网关返回降级响应或自动将其收到的请求更新到较新的 API 兼容层(如果可能)来实现。
- **更简单的协议支持:**有了 API 网关,可以处理微服务可能需要的任何类型的协议转换,客户端不需要担心如何处理它无法支持的协议,通过引入对平台不支持的协议的支持,大大降低了复杂性和可能出现的问题。
- **提高了安全性:**通过 API 网关,客户端不需要知道特定微服务运行的各个网络位置。他们所需要知道的就是 API 网关在哪里侦听请求以进行成功的 API 调用。调用完成后,API 网关将负责确定服务于该 API 的各个微服务的运行位置,然后将请求转发给它们。
- **改进的故障处理:**如果某个特定后端服务出现故障,API 网关也可以提供帮助。在这种情况下,如果后端微服务是非基本微服务,API 网关可以将降级响应返回给客户端,而如果基本后端服务出现故障,API 网关可以立即返回错误响应,而不会让请求排队,从而增加服务器上的负载。
正如我们所看到的,使用 API 网关的好处是巨大的,并且大大简化了微服务应用中客户端的开发。此外,通过利用 API 网关,可以轻松地建立服务间通信。
为了让服务相互通信,它们所要做的就是调用 API 网关知道的适当端点,API 网关负责从那里确定适当的微服务及其网络地址,以完成向其发出的请求。
前面的方法确实不错,但有一个缺点:这里的所有内容本质上都是序列化和同步的。发出一个调用,然后调用的客户机/服务等待,直到返回响应。如果服务上的负载很高,这些响应可能需要很长时间才能到达,这可能会导致大量请求在基础结构上排队,从而进一步增加基础结构上的负载,或者可能会导致大量请求超时。这会大大降低应用的吞吐量,如果排队请求的数量变得非常大,甚至可能会导致整个基础结构的崩溃。
这些服务之间是否有一种异步通信方法,通过这种方法它们可以相互交互,而无需一次又一次地进行 API 调用?让我们来看一个这样的方法。
在 microservices 体系结构中,每个服务都做一项工作,而且做得很好。为了实现业务应用的任何有意义的响应,这些服务需要相互通信。所有这些通信都是通过网络进行的。
这里,一个服务向另一个服务发出请求,然后等待响应返回。但有一个陷阱。如果另一个服务需要很长时间来处理请求,或者该服务已关闭,该怎么办?然后呢?
大多数情况下,请求将超时。但是,如果这个服务是一个关键服务,那么到达它的请求数量可能会很大,并且可能会继续排队。如果服务速度慢,这将。。。
消息队列是一种相当古老的机制,用于在应用中的许多不同组件之间建立通信。这种旧方法甚至适用于我们当前的微服务体系结构用例。但在我们深入探讨如何使用消息队列使 microservice 通信异步之前,让我们先看看处理这种通信方法时使用的一些术语:
- **消息:**消息是特定服务生成的一种包,用于向另一个服务传达其想要实现的目标。
- **队列:**队列是一种主题,特定消息可能会出现在该主题下。对于任何实际应用,都可能有许多队列,每个队列代表一个特定的通信主题。
- **Producer:**Producer 是生成消息并将其发送到特定主题的服务。
- **消费者:**消费者是一种服务,它收听特定主题并处理可能出现的任何消息。
- **路由器:**路由器是消息队列中的一个组件,负责将特定主题的消息路由到适当的队列。
现在我们知道了这些术语,我们可以继续了解消息队列如何帮助我们在微服务之间建立通信。
当微服务使用消息队列之类的东西时,它们通过异步协议进行交互。例如,AMQP 是异步通信中比较著名的协议之一。
通过异步通信,微服务之间的通信将按如下方式进行:
-
设置了一个 MessageBroker,它将提供管理消息队列和将消息路由到适当队列的功能。
-
一个新的服务出现并注册它想要收听或发送消息的主题。MessageBroker 为主题创建适当的队列,并将请求服务添加为该队列的使用者或生产者。对于其他服务,此过程也将继续。
-
现在,希望实现特定目标的服务向主题发送消息,比如说主题验证。
-
收听主题认证的消费者收到新消息的通知并使用该消息。
-
消费者处理其已消费的消息,并将响应放回另一主题主题验证响应。
-
原始消息的生产者是主题验证响应的消费者,并收到关于新消息的通知。
-
然后,原始请求客户端读取此消息并完成请求-响应循环。
现在,我们知道了由异步消息队列驱动的微服务体系结构中的通信是什么样子的。但是除了异步通信之外,这种方法还有其他好处吗?
事实证明,我们可以从这种通信模式中看到许多好处。以下列表显示了我们可能体验到的一些好处:
- **更好地分配请求:**由于可能有许多消费者正在收听特定主题,因此可以并行处理消息,并且可以通过在消费者之间平均分配消息来自动处理负载平衡。
- **更好的错误恢复能力:**在特定微服务宕机的情况下,需要该微服务处理的消息可以在消息队列中排队一段时间,一旦出现,就可以由该服务处理,减少可能的数据丢失。
- **重复响应的减少:**由于一条消息只向单个消费者发送一次,并且在消息被消费后立即退出队列,因此对于单个请求,出现重复响应的可能性非常小。
- **增加了容差:**当基础设施内的不同微服务承受高负载时,消息队列系统提供了异步请求-响应周期,从而减少了请求排队的机会。
有了这一点,我们现在知道了如何在微服务之间建立异步通信,并使我们的基础设施随着时间的推移而不断发展,而不必担心如何处理为服务间通信添加新的 API 端点。
在本章中,我们将介绍如何使用微服务体系结构,以及它与开发企业应用的传统单一方式的区别。然后,我们看了一下微服务开发方法带来的优势,并了解了我们可以遵循的指导原则,以使我们的微服务开发之旅更加顺利。
一旦我们了解了微服务的基础知识,我们就开始了解 SLA 如何保证服务之间的特定功能集,以及它们如何作为契约来支持应用的平滑服务。然后,我们通过编写一个简单的待办事项列表管理应用,利用。。。
- 面向服务的体系结构与微服务体系结构有何不同?
- 我们如何确保基于微服务的应用的高正常运行时间?
- SLA 提供了什么样的保证?
- 我们可以让 API 网关直接与服务注册中心通信吗?
- 我们可以使用哪些工具来实现微服务之间的异步通信?
想了解更多有关微服务的信息吗?请看Packt Publishing的Umesh Ram Sharma的实用微服务。****


