如何将一个老旧的应用迁移到微服务架构

47次阅读
没有评论

问题描述

有一个长期使用的单体应用/代码库,他想知道是否还有机会将其迁移到微服务架构。他已经尝试了一些优化技巧,但在处理超过1亿行数据时没有显著的改进。现在他希望从智能的DevOps人员那里获得建议。他的当前应用是一个Rails应用,数据库、脚本、Redis和Sidekiq都在同一台服务器上运行。他希望将一些功能拆分到应用本身中,并通过API连接到这些功能。他希望这些功能能够在自己的服务器上运行,并且能够根据需要自动扩展。如果服务器受到限制或陷入链接黑洞,他希望能够在尽可能短的时间内启动一个新的服务器,并将脚本的所有内容迁移到新服务器上。他希望这些服务器的成本合理,因为这些是长时间运行的任务。脚本不需要数据库,只需通过API将重要数据返回给应用。总之,他希望每个脚本都在自己的服务器上,并且能够在短时间内轻松启动新的服务器。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

根据你的描述,我看到了一些可扩展性问题。我从Google App Engine(GAE)的角度来看,可通过将工作分解为小任务/工作项并严格限制任务执行的响应时间来实现可扩展性:
1. 你正在复制某些功能:两个脚本都需要解析相同的页面,这符合你的第一个要求。
2. 脚本A的任务执行时间基本上是不受限制的,它可能会因为需要检查已经爬取的链接的数量而有很大的变化。
我会以稍微不同的方式来解决这个问题,以避免这些问题。我甚至不认为这个特定的任务需要单独的服务:
1. 服务将单独的页面URL作为单独的任务/工作项拉取。
2. 它检查URL是否已经被爬取,如果是,则不执行任何操作,否则继续。
3. 获取页面内容并解析它以提取两种类型的信息:
– 需要爬取的其他URL列表,为每个URL创建并排队新的任务(这里不检查它们是否已经被爬取,这可能需要很长时间,具体取决于URL的数量)。
– 页面中需要的其他信息。
在这种方法中,每个任务执行的时间都被减少到最低限度:一个页面解析和仅一次检查URL是否已经被爬取。每个页面只解析一次。
待处理工作项的数量将驱动扩展 – 如果超过一定水平,可以启动新的实例;如果低于一定水平且有多个实例正在运行,则可以停止一些实例。如果将其实现为GAE应用程序,则GAE基础架构可以自动处理这些问题。
这个解决方案可以使用NoSQL数据库(如Google Datastore,在GAE环境中)来实现,它比SQL数据库更具扩展性。

方案2

使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。

示例:

以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:

#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b

在这个示例中,我们首先使用docker run命令启动容器A,并将其命名为container_a。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo命令来测试)。一旦容器A就绪,我们再使用docker run命令启动容器B,并将其命名为container_b

正文完