java - 多线程中的 MQ 与 REST 性能
问题描述
目前我有一个每秒处理数千个请求的消息传递引擎,性能很差,因为当前的实现正在使用一个阻塞操作的 REST 服务,所以它最终耗尽了线程池中的线程,因为使用了一个 REST服务在 HTTP 之上运行我的理解是,我无法触发“即发即弃”请求,至少我需要等待 HTTP 响应,即使使用了 Future 这将在其中运行一个不同的线程,所以即使主线程没有被阻塞,它最终还是会饿死线程池,所以我的问题是,如果我有这么高的并发数,将它发送到 MQ 不是更好吗?这样,这将不再是阻塞操作,对吗?该应用程序当前在 Akka 框架上运行。
解决方案
所以初始数据如下:
- 您的程序每秒向 REST 服务发出数千个请求,
- POST 请求耗时超过 1 秒,
- 它最终耗尽了线程池中的线程。
您应该检查的第一件事:REST 服务能够承受多少并发请求?会不会每秒处理不了上千个请求,单次请求的大时序是服务超载的结果?然后你必须设置一个机制来限制你的请求速率。实际上,设置这样的限制在任何情况下都是一个好主意。
其次,您应该决定是否可以通过同步或异步 I/O 实现这样的访问速率。同步 I/O 更简单、更快,但需要更多的线程消耗内存。粗略估计如下:
- 少于 100 个同时请求:使用同步
- 超过 10000 个并发请求:使用异步
- 介于两者之间:无论哪种方式
如果您决定使用同步 I/O,那么设置请求速率限制的最简单和自然的方法是使用信号量:想要发出下一个请求的线程获取信号量对象,并在收到回复后释放它。保持线程池中的线程数等于请求限制。
如果您决定使用异步 I/O,则没有通用机制来设置这样的限制,因为异步信号量通常对开发人员不可用。如果您的异步 I/O 库具有响应式接口,请使用它(异步信号量是背压机制的一部分)。如果没有,您可以使用以下组件创建这样的机制:
- 异步请求的阻塞队列
- 限制信号量
- 一个线程,它在一个循环中执行以下操作:获取信号量,从队列中获取下一个请求,然后发出它。当请求完成时(无论成功与否),信号量由请求的回调释放。
这种机制对所有异步请求使用单线程,因此消耗的内存不多,并且运行速度足够快。但是,如果您需要它更快地工作,只需增加线程数。
推荐阅读
- javascript - OnClick Javascript函数在reactjs中不起作用
- javascript - 从 Google App Script 发送 twilio whatsapp 消息
- android - FAILURE:构建失败,在模拟器 nexus5 api27 上运行异常
- linux - 遍历函数名数组并在 bash 脚本中执行所有这些函数名
- c# - 如何启动 jsonResult 异步任务?
- node.js - AdminBro 与 postgres 和 sequelize
- javascript - 尽管有键,为什么我的所有子组件都重新渲染?
- python - 使用python从doc文件中获取大写/小写的特定单词?
- azure-logic-apps - 逻辑应用视频索引器连接器
- logging - 如何在 UP 板上记录功耗?