前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >异步架构,避免相互依赖的系统耦合

异步架构,避免相互依赖的系统耦合

作者头像
小马哥学JAVA
发布2023-02-27 14:57:01
6490
发布2023-02-27 14:57:01
举报
文章被收录于专栏:JAVA开发专栏
前言:

使用缓存架构可以减少不必要的计算,快速响应用户请求,但是缓存只能改善系统的读操作性能,也就是在读取数据的时候,可以不从数据源中读取,而是通过缓存读取,以加速数据的读取速度。

但是对于写操作,缓存是无能为力的,虽然缓存的写入速度也很快,但是通常情况下,不能把用户提交的数据直接写入到缓存当中,因为缓存通常被称为一种不可靠的存储,缓存通常无法保证数据的持久性和一致性等这些数据存储的基本要求,因此数据写入操作还是需要写入到RDBMS或者NoSql数据库中,但是数据库操作通常都比较慢。

两个应用系统之间需要远程传递数据,常规的做法就是直接进行远程的调用,用HTTP或者其他RMI方式进行远程的调用,但是这种方式其实是把两个应用耦合起来了,被调用应用产生了故障或者升级,都可能会引起调用者故障,或者也不能不升级处理。

事件驱动架构:

使用消息队列实现异步架构:

消息队列实现异步架构是目前互联网应用系统中一种典型的架构模式,所谓异步架构是和同步架构相对应的,同步架构是说,当应用程序调用服务的时候,当前程序需要阻塞等待服务完成,返回服务结果后才能继续向下执行。

应用程序代码ClientCode需要发送邮件,调用接口服务EmailService,实现了EmailService接口的SmtpEmailAdapter通过SMTP协议与远程服务器进行通信,远程邮件服务器可能有很多的邮件在等待发送,当前邮件可能要等待较长时间才能发送成功,发送成功后再通过远程通信返回结果给应用程序。

在这个过程中,当远程服务器发送邮件的时候,应用程序必须阻塞等待,准确的说,是执行应用程序代码的线程被阻塞,这种阻塞,一方面导致线程不能释放被占用的系统资源,导致系统资源不足,影响系统性能。另一方面也导致线程不能无法快速给用户返回响应结果,用户体验较差,此外,如果远程服务器出现异常,这个异常会传递给应用程序ClientCode,如果应用程序没有妥善处理好这个异常,就会导致整个请求处理失败。

事实上,在大部分应用场景下,发送邮件是不用得到发送结果的,比如用户笧的时候,发送账户的激活邮件,无论邮件是否发送成功了,都可以给用户返回,“激活邮件已经发送,请接收邮件并且进行激活处理”。如果发送失败,只需要提示用户“点击重新发送邮件”。

应用程序ClientCode调用EmailService的时候,EmailService将请求封装成一个邮件发送消息个消息队列,然后就直接返回了,应用程序收到返回以后就可以继续执行,快速完成用户响应,释放系统的资源

而发送消息队列的邮件发送消息,则会被一个专门的消息队列消费者程序,QueueConsumer消费掉,这个消费者通过SmtpEmailAdapter调用远程服务器,完成邮件的发送。如果远程服务处理异常,这个异常只会被传递给消费者程序QueueConsumer,而不会影响到应用程序。

消息队列异步架构的主要角色包括消息生产者,消息队列和消息消费者。消息生产者通常就是主应用程序,生产者将请求封装成消息发送个消息队列。此外还需要开发一个专门的消息消费者程序,用来从消息队列中获取、消费消息,由消息消费者完成业务逻辑的处理。

消息队列的作用就是缓冲消息,等待消费者消费,根据消息消费的方式分为点对点模式和发布订阅模式两种。

点对点模式:

在点对点模式中,多个消息生产者向消息队列发送消息,多个消息消费者消费消息,每个消息只会被一个消息消费者消费。

发布订阅模式:

开发者可以在消息队列中设置主题,消息生产者的消息按照主题进行发送,多个消息消费者可以订阅同一个主题,每个消费者都可以收到这个主题的消息拷贝,然后按照自己的业务逻辑分别进行处理计算。

消息生产者向消息队列某个主题发布消息m,多个消息消费者订阅主题,就会分别收到这个消息。典型场景就是新用户注册,新用户注册的时候一方面需要发送激活邮件,另一个方面可能还需要发送欢迎短信,还可能需要将用户信息同步给关联用户,当然还需要将用户信息保存到数据库中。

这种场景也可以用点对点的模式,由应用程序,也就是消息生产者构造发送邮件的消息,发送到邮件消息队列,以及构造短信消息,构造新用户消息,构造数据库消息分别发送到相关消息队列中,然后由对应的消息消费者程序分别获取消息进行处理。

但是处理的方式使用订阅模式。在消息队列中创建“新用户注册”主题,应用程序只需要发布包含新用户注册数据的消息到该主题中,相关消费者再订阅该主题即可,不同消费者都订阅该主题,得到新用户注册消息,然后根据自己的业务逻辑从消息中获取相关的数据,进行处理。

发布订阅模式下,一个主题可以被重复订阅,所以如果需要扩展功能,可以在当前的生产者和消费者都没有影响的前提下,增加新的消费者订阅同一个主题即可。

消息队列异步架构的优点:
降低耦合性:

使用消息队列实现异步架构可以解决系统耦合的问题,实现更高的写操作性能以及更低的耦合性。

改善写操作请求的响应时间:

使用消息队列,生产者应用程序只需要将消息发送到消息队列之后,就可以继续向下执行了,无需等待耗时的消息消费处理,也就是说,可以更快速的完成请求处理操作,快速响应用户。

更容易的伸缩:

应用程序可以通过负载均衡进行集群的伸缩,以整个应用服务器为单位,如果只是其中某些功能有负载压力,比如说当用户上传图片,需要对图片进行识别、分析、压缩等一些比较耗时的计算操作,需要伸缩整个应用服务器集群。

削峰填谷:

互联网应用的访问压力随时都在变化,系统的访问高峰和低谷的并发压力可能也有非常大的差距。如果按照压力最大的情况部署服务器集群,那么服务器在绝大部分时间内都处于闲置状态,但是利用消息队列,可以将需要处理的消息放入消息队列中,而消费者可以控制消费的速度,因此能够降低系统访问的高峰压力,而在访问低谷的时候,可以继续消费消息队列中未处理的消息,保持系统的资源利用率。

隔离失败:

使用消息队列,生产者发送消息到消息队列后就可以继续自己后面的计算,消费者如果在处理消息的过程中失败了,不会传递给生产者,应用程序具有更高的可用性。

小结:

消息队列实现异步架构是改善互联网应用写操作性能的重要手段,也是一种低耦合,易扩展的分布式应用架构模式,但是使用这种架构也要注意些事项。

比如说:消费者程序可能没有完成用户请求的操作,上面发送邮件的例子,消费者程序发送邮件的时候可能遇到各种问题,从而导致未完成邮件的发送。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小马哥学JAVA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言:
  • 事件驱动架构:
  • 点对点模式:
  • 发布订阅模式:
  • 消息队列异步架构的优点:
    • 降低耦合性:
      • 改善写操作请求的响应时间:
        • 更容易的伸缩:
          • 削峰填谷:
            • 隔离失败:
            • 小结:
            相关产品与服务
            消息队列 CMQ 版
            消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档