#node.js #express #concurrency #axios #aws-fargate
Вопрос:
Привет, у меня есть сервер expressjs, работающий на AWS Fargate, который обрабатывает множество вызовов API к различным сервисам и объединяет их в единый ответ клиенту.
Моя проблема в том, что я обнаружил, что, когда у меня есть запросы к одной и той же конечной точке, поступающие примерно в одно и то же время, по крайней мере один из этих запросов завершится неудачей. Поведение было очень странным, и поэтому я хотел бы немного помочь объяснить, что происходит, и, надеюсь, как это исправить.
Для начала это псевдокод того, как настраивается мой маршрут:
router.post( '/endpoint', async function (req, res, next) {
try {
let uId = req.body.uId
let logId = req.body.logId
let user = await axios(uId) //call to database to retrieve user information (appsync)
console.log(logId, user)
let data = []
for (i = 0, i<user.accounts.length, i ) {
if (user.accounts[i].provider === 'google') {
let googleInfo = await axios(user.accounts[i]) // calls google API
console.log(logId, user.accounts[i], i , googleInfo)
data.push(googleInfo)
} else if (user.accounts[i].provider === 'microsoft') {
let microsoftInfo = await axios(user.accounts[i]) // calls microsoft graph API
console.log(logId, user.accounts[i], i , microsoftInfo)
data.push(microsoftInfo)
}
}
let response = processDataFunction(data) // some function that processes the data
res.json(response)
} catch (e) {
next(e)
}
})
Все это нормально работает, когда есть только один запрос. Однако, когда 2 или более одновременно отправляются в нашу конечную точку, сервер отвечает ошибкой сервера 500, и это то, что я вижу в своих журналах cloudwatch.
dateTime1: request1, user: {}
dateTime2: request1, user.accounts[0], 0, googleInfo: {user.accounts[0]}
dateTime3: request1, user.accounts[1], 1, microsoftInfo: {user.accounts[1]}
dateTime4: request1, user.accounts[2], 2, googleInfo: {user.accounts[3]}
dateTime5: error ......
dateTime6: request2, user.accounts[0], 0, googleInfo: {user.accounts[0]}
dateTime7: request2, user.accounts[1], 1, microsoftInfo: {user.accounts[1]}
dateTime8: request2, user.accounts[2], 2, googleInfo: {user.accounts[2]}
dateTime9: request2, user.accounts[3], 3, googleInfo: {user.accounts[3]}
Ошибка вызвана тем , что сервер microsoft/google выдает ошибку, потому что я запрашиваю ресурсы user.accounts[3]
, когда цикл и маркер доступа все еще находятся user.accounts[2]
(см. dateTime4)
Мне удалось частично исправить это, увеличив количество выполняемых задач в ECS. В итоге я смог одновременно получать больше одновременных запросов. Однако в определенный момент все равно будут возникать те же ошибки.
Любое объяснение, почему это происходит, и является ли мое единственное решение увеличить количество задач ECS?
Ответ №1:
Для всех, кто сталкивается с такой же проблемой. Я все еще не знаю, что происходит, но я смог это исправить, превратив все мои циклы for в:
Promise.all(arr.map( async(item) => {
return await axios( // request )
}))