我正在构建应用程序(Java、Spring),它从单个数据库读取“服务”列表,然后监听单个 REST 端点并在单个工作线程中运行指定的服务(取决于请求参数)。我可能还想在更多实例上运行某些“服务”,有些仅在几个实例上运行,因为有些服务可能会被大量使用,而有些则不会。我的目标是通过 Docker 复制使该应用程序可扩展。
典型用例 - 服务:
- 1x 服务 A
- 1x 服务 B
- 2x 服务 C
- 2x 服务 D
- 5x 服务 E
如何构建这样的系统,能够平衡节点之间的服务?
最佳答案
这是一个非常普遍的问题,根据您的应用程序有多种方法。我将尝试用一些关于复制和云基础设施的一般想法来回答这个问题。
您更喜欢哪种基础设施?
- 商业云(AWS、Google...)为您提供一切(负载平衡、复制)
- 在您自己的硬件上使用 kubernetes 让您有机会定义不同节点(服务器)上应运行多少服务,以及在不同节点上共享数据存储的可能性
- 您可以实现您的自定义解决方案
是否必须复制存储?
虽然运行“无状态”应用程序服务的多个实例非常容易,但跨多个节点共享数据库却更加困难。您可以分割数据存储(例如,a 组的用户位于节点 a...),或者必须将数据库中的每个更改复制到所有节点(如果您有很多写入操作,这会降低您的性能)
负载均衡
如果您有多个节点,则应该使用负载均衡器(例如 nginx 实例),它是没有应用程序逻辑但将请求路由到正确服务的每个请求的入口点。对于实例化服务,负载均衡器可以均匀地路由请求,例如使用随机函数或了解每个节点的工作负载(因此每个节点都必须提供其工作负载)。如果您想动态处理它,每个服务都应该有一个检测工作负载的路径(例如/status),或者您需要像 cadvisor 这样的工具来检测节点的使用情况。也许 kubernetes 是更好的解决方案。
Docker
通过对基础设施的每个元素进行 Docker 化,您通常可以很好地获得可扩展性。每项服务例如你的java后端、数据库、负载均衡器......应该是docker化的。关键问题还是您可能需要复制的存储。
微服务
一种非常流行的模式是微服务。每个服务都遵循关注点分离的模式。您不会拥有大型数据库,因为每个服务都有自己的相当小的数据库。越位的是通信开销,如果它需要来自另一个服务的数据,它将通过服务间请求来请求(因此您必须实现严格的安全策略,例如 jwts)
摘要
从我的角度来看,如果您想避免 aws&co,我会首先在同一节点上启动具有同一数据库的所有服务。例如。在与其应用程序服务相同的节点上运行 sql 或 nosql 数据库。使用 nginx 等负载均衡器将所有请求路由到您的节点。将所有内容 Docker 化并使用 docker 卷挂载数据。如果您达到了限制,请升级您的硬件。如果这不适合使用 kubernetes。
关于java - 如何构建可扩展的多应用程序并能够扩展某些应用程序组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49161091/