从 Lambda 到 EC2 服务器实例的触发命令



我想在 Amazon EC2 服务器上执行一个命令,这需要 30 多分钟。

我使用 node-ssh 在 EC2 实例上执行命令,但此模块会等到执行完成。Lambda 函数在超时之前最多运行 15 分钟。

我的问题是 Lambda 函数在执行完成之前超时。

在数据处理函数中,我有几个步骤:

  1. 建立连接 - 这正在工作
  2. 启动复制:将文件从 S3 复制到 EC2 实例
  3. 触发器实用程序:在 EC2 实例上执行文件

步骤 3 几乎需要 30-40 分钟,但 Lambda 的执行时间最长为 15 分钟,因此这会导致超时失败。

需要解决方案,我可以开火并忘记命令。

exports.handler = (event, context, callback) => {
if (event.Records && event.Records[0]) {
const awsBucket = event.Records[0].s3.bucket.name;
const fileKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/+/g, ' '));
dataProcess();
}
}
async function dataProcess() {
await sftpConnect();
await initiateCopy();
await triggerUtility();
await terminateConnection();
}
function sftpConnect() {
console.log('sftpConnect 1');
return new Promise((resolve, reject) => {
var password = process.env.PASSWORD || CONFIG.PASSWORD;
ssh.connect({
host: process.env.HOST ,
username: process.env.USER ,
password: password,
port: process.env.PORT,
readyTimeout: 40000,
tryKeyboard: true,
onKeyboardInteractive: (name, instructions, instructionsLang, prompts, finish) => {
if (prompts.length > 0 && prompts[0].prompt.toLowerCase().includes('password')) {
finish([password]);
}
}
}).then(function() {
console.log("Connected to Source");
resolve('success');
}, function(error) {
console.log("ERROR connecting to source:" + process.env.HOST || CONFIG.HOST + " - ", error);
reject(new Error(error));
});
});
}
function initiateCopy() {
return new Promise((resolve, reject) => {
var cmd = process.env.AWS_CP_CMD || CONFIG.AWS_CP_CMD;
cmd = cmd.replace('TODAY', TODAY).replace('TODAY', TODAY);
console.log('AWS Cmd ', cmd);
ssh.execCommand(cmd).then(function(output) {
resolve('resolved 1');
}, function(error) {
reject(new Error(error));
});
});
}
function triggerUtility() {
return new Promise((resolve, reject) => {
var cmd = process.env.JAVA_UTILITY_CMD || CONFIG.JAVA_UTILITY_CMD;
ssh.execCommand(cmd).then(function(output) {
resolve('resolved 1');
}, function(error) {
reject(new Error(error));
});
});
}

您应该尝试在后台在 EC2 服务器上执行该过程。有几种方法可以实现此目的,但最简单的方法是在 shell 命令的末尾添加一个&。这将在后台启动 Linux 进程,之后您应该能够退出 SSH 连接并结束 Lambda 函数执行。

考虑更改您的 EC2 端代码,以便 EC2 实例监视 SQS 队列并在收到消息时开始复制,而不是从 Lambda 执行复制和触发器。您的 Lambda 代码应在将消息发送到队列后立即退出。如果您需要在 Lambda 触发器后执行一些工作,则可以将消息从 EC2 实例发送到另一个队列,然后该队列将触发自己的新 Lambda 函数。

这具有非常可扩展的额外优势。

正如您所说,代码运行时间超过 15 分钟,因此不适合 Lambda。您可以尝试增加内存以查看它是否运行得更快,但它不太可能足够快。

因此,您应该设计一个不需要 AWS Lambda 函数的解决方案。这可以通过在 Amazon EC2 实例上完全运行来完成。

系统管理器的 run 命令应该适用于这种情况。

相关内容

最新更新