Spring Boot 应用程序可以处理大量请求

Xma*_*gic 4 performance spring spring-boot rocketmq

我正在使用 Spring-boot 或 Spring-Cloud Framework 来开发 Web 应用程序。系统主要处理来自客户端的HTTP Restful请求,然后将其保存到MySQL数据库中。

但我计划让它更具可扩展性。它应该能够启动每个服务的更多实例,并使系统可以处理更多传入请求。

但我不确定我这样做是否正确,有谁能来帮我检查一下我目前的做法是否合理,或者提出我的做法是否存在潜在的风险。

我正在做的是:

  1. 服务A在其控制器中接收请求,然后将其异步写入RocketMQ。RocketMQ用于削峰。

  2. 然后服务B订阅服务A写入的RocketMQ主题,并将消息以列表的形式缓存到Redis中。

  3. 服务 C 启动一个守护线程检查 Redis 中的消息编号。如果缓存列表大小达到一定值,它将拉取所有消息并将它们保存到MySQL中,然后刷新Redis中的缓存。

CAP*_*OCK 6

与往常一样,单个问题可以有多种解决方案。以下建议基于我作为软件架构师的日常工作和经验。

事实

您的系统由三个(微)服务(A、B 和 C)、消息代理 (RocketMQ)、缓存 (Redis) 和数据库 (MySQL) 组成。在评论中,您还提到您计划在 F5 硬件和 Docker 上运行它。

建议

服务A暴露在前端来处理HTTP请求。使用异步处理来管理负载,但是效率仍然受到服务 A 性能的限制。因此,服务 A 应该是可扩展的以实现更高的吞吐量。必须评估单个单元的性能(查看性能测试、压力测试......)以确定扩展。

要实现 Docker 容器的自动扩展,您将需要编排工具(例如 Kubernetes),该工具将根据配置的指标扩展您的系统。还要考虑扩展系统可以使用的系统资源。

服务 B 和 C 也可以轻松扩展。评估服务 B 和服务 C 的功能是否可以合并到一个服务中。B 不仅可以将新数据存储在 Redis 中,还可以将其存储在 MySQL 中。这取决于您需要多少碎片以及您将如何管理碎片带来的额外复杂性。B 已经对发布的内容做出反应,而服务 C 似乎不断地汇集 Redis 缓存以获取条目数量(这可以通过键空间通知来解决)。

从 Redis 读取数据、将其存储到 MySQL 并刷新时要小心。当您对写入其中的所有服务实例使用一个 Redis 密钥时,您很容易会错过或刷新一些未存储在 MySQL 中的数据。

在处理异步处理时,您经常会处理最终一致性,这意味着服务 A 处理的数据将无法立即供其他可能想要从 MySQL 读取数据的服务使用(只是考虑更广泛的情况,重要性因情况而异) )。