子进程部分可能相关或不相关,它可能只是并发/并行连接/请求的数量,但它甚至没有那么高(最大 50)。
我的架构是我的主应用程序按照 CRON 计划启动子进程。产生的每个进程都会通过一个独特的体育赛事来关注。 CRON 作业基于此事件的开始时间。如果事件时间相同,则每个子进程的生成间隔 1.2 秒。子进程的数量各不相同,但每次运行的数量不得超过 50。每个子进程都会创建与内部 API 的新连接。内部 API 只有 1 个进程正在运行,据我了解,无法与其他机器一起扩展或 fork 子进程(正如建议的 here & here ),作为内部 API,依次调用外部 API,该 API 最初在多次请求后返回 ECONNRESET 。由于我不知道外部 API 的性质,因此我将自己的 API 放在它前面,以确保对外部的所有请求都通过单个连接进行。但是,现在我可以从内部 API 取回 ECONNRESET,即使只有 10 个子进程已启动。
与我的内部 API 的连接保持事件状态,以减少响应时间,并且使用 Axios 的最大套接字数为 1。架构图如下:
子进程按计划轮询内部 API,因此可能(可能)向其发出并行请求。但是,因为这些生成间隔至少为 1.2 秒,所以我认为这会降低并行请求的可能性。 Express的处理能力有什么区别parallel请求与处理能力 concurrent要求?据我所知,Express 可以毫无失败地处理 1000 个并发请求。
axios.js(工作人员)
module.exports = axios.create({
baseURL: process.env.INTERNAL_API_ENDPOINT,
httpAgent: new http.Agent({
keepAlive: true,
maxSockets: 1
}),
httpsAgent: new https.Agent({
keepAlive: true,
maxSockets: 1
}),
timeout: 60000, // 1 min timeout
auth: {
username: process.env.INTERNAL_API_USERNAME || 'user',
password: process.env.INTERNAL_API_PASSWORD || 'pass'
},
headers: {
Connection: 'keep-alive',
'Content-Type': 'application/json',
Accept: 'application/json'
}
})
request.js
const API = require('./axios')
module.exports = async function(params) {
try {
return API.get('/api/events', { params })
} catch(err) {
throw err
}
}
event.js(内部 API)
const { Router } = require('express')
const external = require('../client/betting')
const router = Router()
/**
* GET /api/events
*/
router.get('/events', async (req, res, next) => {
const { query } = req
try {
// Call to External API
const response = await external.GetEvents(query)
res.send(response.data)
} catch (err) {
next(err)
}
})
module.exports = router
这个answer表明我的内部 API 可能因请求而过载,因此导致连接丢失。
这里的问题是什么?是我的并行请求导致了 ECONNRESET 吗?在这种情况下,我可以想到 3 种可能的补救措施(真正寻找最佳选择):
- 我可以按照建议在内部 API 端对请求进行排队 here
- 我可以重构我的代码以不启动子进程,因此只有 1 个进程以及随后 1 个与 API 的连接。这不是可取的,因为这是一个很大的架构变化,但如果这是最好的建议,那就可以了
- 有没有办法扩展我的内部 API,让子进程可以共享主进程的 TCP 连接,这样,与外部的连接就只有 1 个?类似于 cluster-client &那里提到的领导者/追随者模式
如果这些都不清楚,那么我可以在需要时提供更清晰的信息:)谢谢!
最佳答案
如果我正确地阅读你的问题,问题是对“外部 API”的严格限制,这是你的应用程序的瓶颈。
这很粗糙,因为您创建的事件可能超出外部 API 可以处理的数量!在某些时候,可以想象外部 api 无法跟上您的负载。
对于初始实现,我将探索您的第一种方法:
I could queue the requests on my internal API side as is suggested here
我会尽可能让内部 API 响应式,以便它从队列或事件流中读取。
在此架构中,您的工作人员将事件排入队列,然后继续。内部 API 监听队列上的事件,它可以一个接一个地拉取单个事件,并且每个事件都会向外部 API 发出请求,或者如果您开始压垮外部 API,您可以开始批量事件(即拉取 100 个事件或某个时间间隔)。
希望外部 API 有足够的能力来处理您的负载,并且您能够批量处理事件。但在某些时候,您的负载可能会超出外部 API 实际能够处理的负载。
关于node.js - 从子进程到 API 的请求导致 ECONNRESET,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60154601/