From 1bc2e22833e55d9a00ee6c19916b6f8ac60d7fbc Mon Sep 17 00:00:00 2001 From: zhangwenjian Date: Fri, 28 Aug 2026 19:42:38 +0800 Subject: [PATCH] =?UTF-8?q?fix=F0=9F=90=9B:=20give=20the=20config=20templa?= =?UTF-8?q?tes=20the=20defaults=20a=20deployment=20actually=20needs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two settings that decide whether a deployment survives load, neither of which appeared in any template. The connection pool. Left unset, Go's defaults apply, and MaxIdleConns is 2: under load almost every request opens a TCP connection and closes it again, local ports run out, and the process answers "can't assign requested address" to everything. Not slower - unavailable. A sweep against MySQL collapsed to zero successful responses at 64 concurrent requests without these, and served 13,846 req/s with no errors once they were set. The queue buffer. poolSize is the point at which messages start being dropped, not a tuning knob: a full queue discards the message and returns an error rather than blocking, and each stream has one consumer goroutine writing to the database. At the previous default of 100 a load test lost over 60% of them; at 1000, none. Login and operation logs travel this queue, so what gets lost is audit data - though only when logger.enableddb is on. Both carry the reasoning in the file, because the failure mode of each is invisible until it happens in production. --- config/settings.full.yml | 21 ++++++++++++++++++++- config/settings.yml | 21 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/config/settings.full.yml b/config/settings.full.yml index c3067364..29754928 100644 --- a/config/settings.full.yml +++ b/config/settings.full.yml @@ -42,6 +42,17 @@ settings: source: user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local&timeout=1000ms # source: sqlite3.db # source: host=myhost port=myport user=gorm dbname=gorm password=mypassword + # 连接池。不配置这几项时走 Go 的默认值,其中 MaxIdleConns 默认只有 2: + # 高并发下几乎每个请求都要新建 TCP 连接、用完立刻关闭,本机端口很快耗尽, + # 表现为 "can't assign requested address" 且请求全部失败——不是变慢,是不可用。 + # + # maxOpenConns 是单个实例的连接上限,多实例部署时总连接数是它乘以实例数, + # 需要小于数据库的 max_connections(MySQL 默认 151)。 + # connMaxLifeTime 单位为秒,应小于数据库的 wait_timeout(MySQL 默认 28800), + # 否则会复用到已被服务端关闭的连接。 + maxIdleConns: 20 + maxOpenConns: 100 + connMaxLifeTime: 3600 registers: - sources: - user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local&timeout=1000ms @@ -52,7 +63,15 @@ settings: frontpath: ../go-admin-ui/src queue: memory: - poolSize: 100 + # poolSize 是队列的缓冲长度,不是并发度。队列满时 Append 会丢弃该消息并 + # 返回错误,而不是阻塞等待,所以这个值实际是「开始丢消息的临界点」。 + # + # 每个 stream 只有一个消费 goroutine,而登录日志、操作日志的消费要写数据库, + # 吞吐受限于单条写入耗时。突发流量高于消费速度时,缓冲区是唯一的缓解手段。 + # 压测中默认的 100 丢弃率超过 60%,1000 为 0。 + # + # 仅在 logger.enableddb 为 true 时才会真正入队。 + poolSize: 1000 extend: # 扩展项使用说明 demo: name: data diff --git a/config/settings.yml b/config/settings.yml index 058aabc0..15af8c19 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -32,6 +32,17 @@ settings: driver: mysql # 数据库连接字符串 mysql 缺省信息 charset=utf8&parseTime=True&loc=Local&timeout=1000ms source: user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local&timeout=1000ms + # 连接池。不配置这几项时走 Go 的默认值,其中 MaxIdleConns 默认只有 2: + # 高并发下几乎每个请求都要新建 TCP 连接、用完立刻关闭,本机端口很快耗尽, + # 表现为 "can't assign requested address" 且请求全部失败——不是变慢,是不可用。 + # + # maxOpenConns 是单个实例的连接上限,多实例部署时总连接数是它乘以实例数, + # 需要小于数据库的 max_connections(MySQL 默认 151)。 + # connMaxLifeTime 单位为秒,应小于数据库的 wait_timeout(MySQL 默认 28800), + # 否则会复用到已被服务端关闭的连接。 + maxIdleConns: 20 + maxOpenConns: 100 + connMaxLifeTime: 3600 # databases: # 'locaohost:8000': # driver: mysql @@ -64,7 +75,15 @@ settings: memory: '' queue: memory: - poolSize: 100 + # poolSize 是队列的缓冲长度,不是并发度。队列满时 Append 会丢弃该消息并 + # 返回错误,而不是阻塞等待,所以这个值实际是「开始丢消息的临界点」。 + # + # 每个 stream 只有一个消费 goroutine,而登录日志、操作日志的消费要写数据库, + # 吞吐受限于单条写入耗时。突发流量高于消费速度时,缓冲区是唯一的缓解手段。 + # 压测中默认的 100 丢弃率超过 60%,1000 为 0。 + # + # 仅在 logger.enableddb 为 true 时才会真正入队。 + poolSize: 1000 # redis: # addr: 127.0.0.1:6379 # password: xxxxxx