在 Fastify 中处理 MySQL PROTOCOL_CONNECTION_LOST 的最佳方式 - GCP 托管

问题描述 投票:0回答:1

在运行 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 提升,最小实例数设置为 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
}
node.js google-cloud-sql google-cloud-run node-mysql fastify
1个回答
0
投票

代码显示混合了异步和同步代码风格。

在异步插件函数中,不要使用

done
回调。 这会导致意想不到的行为。

否则,可以通过删除

done
关键字来使用
async
回调。

import fp from 'fastify-plugin'
import mysql from '@fastify/mysql'

const plugin = async (fastify, options) => {
    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() in an async function do not use the `done` callback
}

export default fp(plugin)

另一件重要的事情,因为你正在使用

promise: true
参数,所以总是释放处理程序中的连接:
connection.release()

© www.soinside.com 2019 - 2024. All rights reserved.