如何确定我的node-js应用程序在启动时是否在AWS EC2上运行



最终,如果应用程序在AWS EC2上运行,我希望在我的应用程序中有一个额外的功能。

如何检查和设置变量以指示它是否在AWS上?我找到了这个线程来进行检查,但在启动时,我如何在应用程序中设置一个像布尔值一样的变量?类似于:

let checkAWS;
metadata.isEC2().then(function (onEC2) {
checkAWS = true;
console.log("EC2: "  + onEC2);
});
let app = express();
app.locals.isAWS = checkAWS;
console.log(checkAWS);

每次,我总是得到相同的输出:

undefined
EC2: true

我使用.ejs文件中的isAWS变量来决定该功能。

metadata.isEC2()是异步的,因此它的值在稍后.then()处理程序运行时可用。同时,您正在尝试在.then()处理程序运行之前使用checkAWS的值。

由于您希望在启动Express服务器之前访问该值,因此只能在.then()处理程序中启动它,如下所示:

let isAWS;
metadata.isEC2().then(function (onEC2) {
console.log("EC2: "  + onEC2);
isAWS = true;
}).catch(err => {
isAWS = false;
}).finally(err => {
const app = express();
app.locals.isAWS = isAWS;
// do the rest of your app initialization here
app.listen(...);
});
// do not use app here (it won't be defined here)

如果您试图导出app以供其他模块使用,则必须采取稍微不同的方法。我们必须查看您更广泛的代码上下文,才能知道该推荐什么。但是,基本上这里的想法是,在异步检索到isAWS结果之前,不应该启动服务器。

此外,您应该知道,使用您正在使用的metadata.isEC2()调用,它会在EC2实例中查找一个已知的端点来检测EC2。如果该端点不存在,则需要500毫秒才能超时并命中上面的.catch()分支。如果它是EC2实例,它会很快。


注意,只检查AWS环境自动设置的一些环境变量(如AWS_REGIONAWS_EXECUTION_ENV(的存在可能更简单。这些可以同步检查。

let app = express();
app.locals.isAWS = !!process.env.AWS_REGION;;

为了将来参考,以防其他人正在寻找,这对我来说很有效,以便能够判断您是否在AWS上运行。

let isAwsSet = false; //has the app checked whether it is running on AWS by setting app.locals.isAWS
app.locals.isAWS = false;
app.get('/home', function(request, response) {
if (!isAwsSet){
urlExists().then(function (onAWS){
app.locals.isAWS = true;
isAwsSet = true;
response.render('home');
}).catch(function(error){
app.locals.isAWS = false;
isAwsSet = true;
response.render('home');
})
} else {
response.render('home');
}
});
function urlExists() {
return new Promise((resolve, reject) => {
//https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html
const options = {
method: 'HEAD',
host: '169.254.169.254',
path: '/latest/meta-data/',
port: 80,
timeout: 1500
};
const req = http.request(options, (res) => {
// reject on bad status
if (res.statusCode !== 200) {
return reject(new Error('statusCode=' + res.statusCode));
}
resolve(res.statusCode = 200);
});
req.on('timeout', () => {
req.destroy();
});
req.on('error', function(err) {
reject(err);
});
req.end();
});
}

最新更新