【问题标题】:Spring Boot application can handle tons of requestsSpring Boot 应用程序可以处理大量请求
【发布时间】:2019-08-01 12:35:53
【问题描述】:

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

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

但我不确定我的做法是否正确,谁能来帮我检查一下我目前的做法是否合理,或在我的做法中引发任何潜在风险。

我正在做的是:

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

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

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

【问题讨论】:

  • 只要你 a) 使用 Spring Boot,并且 b) 想要可扩展性......然后想想“微服务”。将您的应用程序划分为可以部署在container(如 Docker)中的微服务,并让 Kubernetes(或等效的)处理“可扩展性”。只是一个想法......

标签: spring performance spring-boot rocketmq


【解决方案1】:

你说你想要

make the system can handle more incoming requests.

这不取决于机器吗?

我认为在您的情况下,您应该考虑使您的应用程序与所有服务都可扩展。

在云端或您自己构建。

像 Kubernetes。 https://kubernetes.io/

或基于 Kubernetes 构建的 KNative https://cloud.google.com/knative/

Amazon Web Services 还提供可扩展性。

【讨论】:

  • 感谢您的回复,不过在这里我想多谈谈系统架构层面的问题。我们使用 F5 硬件进行负载平衡。并且服务将部署在 docker 中,并且可以自动扩展。
【解决方案2】:

Hi 缩放与您要处理的负载非常相关:

但您可以使用此事件总线模式处理多个请求:

1) 服务 A:将消息发布到事件总线(主题/交换)
2) Broker(ActiveMq/RabbitMq/etc..):将这些消息转发到队列中。
3) 服务 B:从队列中监听并更新 MySQL 中的记录。

下游服务的多个实例(服务 B)将按需提供可扩展性(如果负载更多,则部署更多实例,如果负载更少,则部署更少实例)。

【讨论】:

    【解决方案3】:

    我可以简单地将您的问题分为两个子主题。

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

    为了使您的应用程序对传入的请求更敏感,您需要

    • 减少请求处理时间
    • 垂直或水平扩展您的系统

    如果您考虑第一种方法,您可以简单地引入更强大的硬件,优化传输级别协议的使用或简单地删除不必要的处理步骤(例如:而不是使用步骤 B 和 C,您可以简单地引入 Kafka 之类的消息代理并可靠地持久化消息。然后你可以删除 Redis 依赖)

    为了优化您系统中的网络控制和协议使用,请参阅High Performance Browser Networking 书。

    考虑到负载,只需使用 Docker swarm 或 Kubernetes 进行扩展。最重要的是,您可以简化应用程序中的依赖关系,以获得更好的性能和易于处理。

    【讨论】:

    • 感谢您的详细回复。你关于使用 Kafka 的想法及其持续存在的信息真的让我大开眼界。
    【解决方案4】:

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

    事实

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

    建议

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

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

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

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

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

    【讨论】:

    • 非常感谢您的友好解释。我使用基于 Redis 的分布式锁进行缓存存储和刷新,因此一次只有一个进程可以访问 Redis 缓存。我还按照您的建议将 mirco-service B 和 C 合并为一个服务。
    猜你喜欢
    • 2018-04-04
    • 2019-11-01
    • 2018-02-28
    • 2019-06-20
    • 1970-01-01
    • 2020-06-05
    • 2016-12-27
    • 2019-02-28
    • 1970-01-01
    相关资源
    最近更新 更多