在运行SQL查询时,我的一个项目在生产环境中出现了几个PROTOCOL_CONNECTION_LOST错误代码。在Fastify中处理此问题的最佳方法是什么?
我已经搜索了Stackoverflow,但似乎没有明确的答案。我已经改变了MySQL的配置,允许更高的连接限制,但它没有解决这个问题。
对于这个项目来说,目前的交通量真的不是很高,我担心的是,当交通量增加时,这个问题会变得更加突出。
该项目使用Cloud Run托管在GCP上,并使用GCP Cloud SQL。不确定是否与GCP相关,我可能必须更改,但生产数据库正在高内存机器上运行(4vCPU,26GB内存,100GB SSD,启用高可用性)。
Cloud Run容器有4个CPU,2GB内存,3600个请求超时,1000个并发请求,启动CPU boost启用,最小示例数设置为1,最大设置为100。
MySQL插件:
import fp from 'fastify-plugin'
import mysql from '@fastify/mysql'
const plugin = async (fastify, options, done) => {
const { config } = fastify;
fastify.register(mysql, {
host: config.DB_HOST,
socketPath: config.DB_SOCKET,
port: config.DB_PORT,
user: config.DB_USERNAME,
password: config.DB_PASSWORD,
database: config.DB_NAME,
namedPlaceholders: true,
promise: true,
connectionLimit: 100,
waitForConnections: true
})
done()
}
export default fp(plugin)
错误信息:
Error: Connection lost: The server closed the connection.
at PromisePoolConnection.query (/app/node_modules/mysql2/promise.js:93:22)
at Object.getErrorSyncedTransactions (file:///app/models/cron.js:33:41)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Object.<anonymous> (file:///app/routes/v1/cron.js:89:39) {
code: 'PROTOCOL_CONNECTION_LOST',
errno: undefined,
sql: undefined,
sqlState: undefined,
sqlMessage: undefined
}
查询示例:
import fp from 'fastify-plugin'
const model = (fastify, options, done) => {
const getPendingPayments = async () => {
const connection = await fastify.mysql.getConnection()
const [rows] = await connection.query(
`SELECT
t.id,
t.uuid,
t.status_code,
y.consent_token AS consent_token,
y.payment_payload->>'$.data.id' AS payment_id,
m.id AS merchant_id,
m.uuid AS merchant_uuid,
m.webhook_url,
m.webhook_status
FROM transactions t
JOIN transactions_yapily y
ON t.id = y.transaction_id
JOIN merchants m
ON m.id = t.merchant_id
WHERE y.payment_payload IS NOT NULL
AND t.status_code IN ('ACCP', 'ACSP', 'ACTC', 'ACWC', 'ACWP', 'ACFC', 'RCVD', 'PDNG')
AND t.created_at >= DATE_SUB(NOW(), INTERVAL 3 HOUR)`
)
connection.release()
return rows
}
fastify.decorate('cron', {
getPendingPayments,
})
done()
}
export default fp(model)
1条答案
按热度按时间du7egjpx1#
代码显示了异步和同步代码风格的混合。
在异步插件函数中,不要使用
done
回调。这会导致意想不到的行为。否则,可以通过删除
async
关键字来使用done
回调。另一件重要的事情是,由于您正在使用
promise: true
参数,因此始终释放处理程序中的连接:connection.release()