You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多次数据库请求后Heroku应用崩溃(H10错误)问题排查与解决

解决Heroku上React+Node(TypeScript)应用连接ClearDB MySQL崩溃的问题

问题回顾

你在Heroku上部署React+Node(TypeScript)应用,搭配免费版ClearDB MySQL附加组件时遇到了这类问题:

  • 数据库请求次数较少时应用运行完全正常
  • 当请求达到约10次(服务器未休眠状态)后,后续请求会直接导致应用崩溃
  • 页面刷新后无法正常加载,仅显示“Application Error”,错误日志中能观察到H10错误

进一步排查后确认核心问题是数据库连接丢失,Heroku会在连续出现多个错误时自动关闭应用,对应的错误日志如下:

2021-08-30T11:25:45.178960+00:00 app[web.1]: > api@1.0.0 start
2021-08-30T11:25:45.178960+00:00 app[web.1]: > ts-node server.ts
2021-08-30T11:25:45.178961+00:00 app[web.1]: 
2021-08-30T11:25:49.764096+00:00 heroku[web.1]: State changed from starting to up
2021-08-30T11:25:49.701827+00:00 app[web.1]: APP running on port 26858
2021-08-30T11:26:01.705662+00:00 heroku[router]: at=info method=GET path="/api/message" host=random-messenger.herokuapp.com request_id=1fac5c60-c66c-425a-acb4-17f173b72870 fwd="188.167.229.146" dyno=web.1 connect=0ms service=81ms status=200 bytes=309 protocol=https
2021-08-30T11:26:02.705066+00:00 heroku[router]: at=info method=GET path="/api/message" host=random-messenger.herokuapp.com request_id=56879ea0-382d-42ca-b757-ed1d6e4d5137 fwd="188.167.229.146" dyno=web.1 connect=0ms service=9ms status=200 bytes=361 protocol=https
2021-08-30T11:26:03.599888+00:00 heroku[router]: at=info method=GET path="/api/message" host=random-messenger.herokuapp.com request_id=8f8fa4ef-0535-4cdd-abbd-6f93eeae0941 fwd="188.167.229.146" dyno=web.1 connect=0ms service=11ms status=200 bytes=312 protocol=https
2021-08-30T11:27:01.162648+00:00 app[web.1]: /app/api/node_modules/mysql/lib/protocol/Protocol.js:112
2021-08-30T11:27:01.162660+00:00 app[web.1]: var err = new Error('Connection lost: The server closed the connection.');
2021-08-30T11:27:01.162661+00:00 app[web.1]: ^
2021-08-30T11:27:01.164283+00:00 app[web.1]: Error: Connection lost: The server closed the connection.
2021-08-30T11:27:01.164284+00:00 app[web.1]: at Protocol.end (/app/api/node_modules/mysql/lib/protocol/Protocol.js:112:13)
2021-08-30T11:27:01.164284+00:00 app[web.1]: at Socket.<anonymous> (/app/api/node_modules/mysql/lib/Connection.js:94:28)
2021-08-30T11:27:01.164285+00:00 app[web.1]: at Socket.<anonymous> (/app/api/node_modules/mysql/lib/Connection.js:526:10)
2021-08-30T11:27:01.164286+00:00 app[web.1]: at Socket.emit (node:events:406:35)
2021-08-30T11:27:01.164286+00:00 app[web.1]: at Socket.emit (node:domain:475:12)
2021-08-30T11:27:01.164286+00:00 app[web.1]: at endReadableNT (node:internal/streams/readable:1331:12)
2021-08-30T11:27:01.164286+00:00 app[web.1]: at processTicksAndRejections (node:internal/process/task_queues:83:21) {
2021-08-30T11:27:01.164287+00:00 app[web.1]: fatal: true,
2021-08-30T11:27:01.164287+00:00 app[web.1]: code: 'PROTOCOL_CONNECTION_LOST'
2021-08-30T11:27:01.164287+00:00 app[web.1]: }
2021-08-30T11:27:01.316331+00:00 heroku[web.1]: State changed from up to crashed
2021-08-30T11:27:01.228791+00:00 heroku[web.1]: Process exited with status 1
2021-08-30T11:28:17.001351+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/receive" host=random-messenger.herokuapp.com request_id=a5d2639a-b804-4706-bc75-ed236fbbaa25 fwd="188.167.229.146" dyno= connect= service= status=503 bytes= protocol=https
2021-08-30T11:28:17.461640+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=random-messenger.herokuapp.com request_id=78e7a216-d0c3-4c7f-928b-b10ae7dff3ae fwd="188.167.229.146" dyno= connect= service= status=503 bytes= protocol=https

问题根源

免费版ClearDB MySQL附加组件有个容易被忽略的限制:仅允许同时存在10个数据库连接。你的应用当前的实现是每次请求都新建一个数据库连接,没有做连接复用,当请求次数达到10次后,连接配额被完全耗尽,新的请求无法获取可用连接,最终触发连接丢失错误,导致Heroku强制关闭应用,出现H10报错。

解决方案

修改你的数据库连接逻辑,改为复用连接(使用连接池),而不是每次请求都创建新连接:

  • 如果你使用的是mysql包,用createPool方法创建连接池,替代createConnection
  • 请求处理完成后,不要直接关闭连接,而是让连接自动归还到池中
  • 配置合理的连接池参数,比如connectionLimit设置为8-9,给ClearDB留少量余量避免触发限制

这里给一个简单的TypeScript示例:

import mysql from 'mysql';

// 创建数据库连接池
const pool = mysql.createPool({
  host: process.env.CLEARDB_HOST,
  user: process.env.CLEARDB_USER,
  password: process.env.CLEARDB_PASSWORD,
  database: process.env.CLEARDB_DATABASE,
  connectionLimit: 8, // 不超过ClearDB免费版的10连接限制
});

// 在接口中使用连接池处理请求
app.get('/api/message', (req, res) => {
  pool.query('SELECT * FROM messages', (error, results) => {
    if (error) throw error;
    res.json(results);
  });
});

修改后,连接会被循环复用,不会快速耗尽ClearDB的连接配额,应用就能稳定运行了。


内容的提问来源于stack exchange,提问作者Matej Peluha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 08:29:06