您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 1浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

争取短暂的同步通信

寒冰屋 发布时间:2022-03-15 21:23:36 ,浏览量:1

目录

介绍

服务之间的通信

将长时间运行的任务提取到单独的作业中

水平扩展解决方案

减少HTTP请求持续时间

结论

介绍

与服务交互时,异步通信通常是首选方式。“企业集成模式”一书就是这么说的(这也可能是TL;DR;对于本文的其余部分)。

引用:

使用同步通信,调用者必须等待接收者完成处理调用,然后调用者才能接收结果并继续。这样,调用者只能以接收者执行调用的速度进行调用。另一方面,异步通信允许发送方以自己的节奏对接收方的请求进行批处理,并让接收方以自己不同的节奏消费请求。这允许两个应用程序以最大吞吐量运行,并且不会浪费时间等待对方(至少在接收器用完要处理的消息之前)。

但是,在某些情况下,同步通信是不可避免的。让我们看一下这个例子。

服务之间的通信

假设我们有一个上传和处理文件的系统。它由一个我们无法控制的遗留模块组成。该模块从文件系统中获取一个文件,通过HTTP将其上传到给定的端点,如果上传成功,它会上传一个补充元数据文件。

由于我们无法控制遗留模块,我们别无选择,只能坚持同步通信。文件上传到我们的系统后,我们会执行大量处理活动,这些活动会消耗大量时间。

我们可以用下图来概括当前的事态:

将长时间运行的任务提取到单独的作业中

与往常一样,除非您对其应用一些比例,否则此设计没有任何问题。但是一旦需要上传大量文件,瓶颈显然是遗留模块每次都等待,直到我们的代码完成保存和处理文件,然后才能上传附加文件。因此,为了满足要求,我们需要减少交互时间。然后,您开始注意到等待每个HTTP请求完成处理是多么浪费。补救方法是尽早返回响应,在后台进行处理。

这里,异步通信用虚线箭头表示。一旦我们持久化文件,我们就会发送一条消息,表明文件已保存到处理器模块。为了实现这一点,我们可能会采用我们喜欢的AMQP实现。由于消息是异步的,我们不必等待处理器响应,并且能够更早地将响应返回给我们的旧上传器组件。

请注意,两个组件在单个进程内进行通信。这是我将在下一节中介绍的原因。

水平扩展解决方案

到目前为止,一些读者可能会提出一个问题:“既然可以将两个组件分开,为什么还要将它们留在一个服务中?”

虽然微服务在几年前是一个热门话题,但现在越来越多的组织开始意识到正确地做微服务是很困难的。它需要一定的工程能力(分布式日志记录、故障恢复)以及组织能力(代码所有权分离、维护服务之间的最新合约、稳健的部署策略)。对于那些仅将微服务用作将代码库拆分为更易于管理的部分的工具的人,所有这些都应该作为一种预防措施。这就是为什么我决定坚持使用进程间通信作为默认的架构风格。

尽管如此,在某些情况下,由于高负载,您必须扩展解决方案以承受更大的负载。所以自然的解决方案是并行处理文件上传。但是,单个服务器实例上的并行化过程有其自身的限制,因此最终,您将提出在多个服务上部署服务(水平扩展)。在这种情况下,将文件持久化到数据库的IO密集型部分可能会受益于水平扩展,而处理器部分可能会受益于垂直扩展(例如,添加更强大的处理器来执行计算密集型逻辑)。

独立扩展部分系统的能力是使用微服务架构风格的关键原因之一。(另一种是逆康威机动,但超出了本文的范围)。

在这种情况下,系统的两个部分都是独立部署的,并通过消息队列进行通信,如下图所示。

减少HTTP请求持续时间

另一个感兴趣的领域是面向客户的UI应用程序。大量研究揭示了页面加载时间的增加如何导致客户不满意。由于HTTP调用持续时间是页面加载时间不可分割的一部分,我们自然也希望减少它。

让我们看一下以下负责在应用程序中注册用户的假设代码。

public async Task FlushTemporary(CancellationToken token)
{
    if (validator.IsValid(user))
    {
        await _repository.SaveUser(user, token);
        await _mailingService.SendConfirmationEmail(user, token);
    }
    return Ok();
}

虽然从调用者的角度来看,上面的代码实际上利用了一个名为异步编程模型的特性,但它是同步的,因为调用者需要等到用户被持久保存在数据库中并发送确认电子邮件!

不用说,这会导致在注册步骤中额外等待客户。同样,如上面的示例一样,我们应该将确认电子邮件提取到将在注册步骤之后执行的后台作业中。

结论

同步通信引入了等待时间,这在系统间通信或面向客户的应用程序中可能是多余的。了解同步通信的哪些部分是不可避免的以及稍后可能完成的部分至关重要。对于后一部分,后台处理器是处理该问题的巧妙技巧。

https://www.codeproject.com/Tips/5316581/Strive-for-Short-Lived-Synchronous-Communication

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0448s