MySQL负载均衡需专用方案:nginx/lvs因不解析MySQL协议易致连接失败或主从混发;ProxySQL工作在第7层,支持SQL解析、读写分离、健康检查与连接池,是更务实的选择。

MySQL 本身不支持直接对外暴露负载均衡能力,nginx 和 lvs 也无法原生理解 MySQL 协议(TCP 层转发会破坏连接状态、认证 handshake、包分片等),强行用它们做 MySQL 负载均衡大概率导致连接失败、认证卡死、查询中断——这不是配置问题,是协议层不兼容。
为什么 nginx -s reload 后 MySQL 连接全断?
因为 nginx 默认只支持 HTTP/HTTPS/SMTP 等应用层协议;对 MySQL 这类二进制长连接协议,必须启用 stream 模块并单独编译。CentOS/RHEL 自带的 yum 安装版 nginx 默认不含该模块,直接配 upstream + proxy_pass 到 3306 端口,实际走的是 HTTP parser,MySQL 客户端发来的第一个握手包(0x85 0x00 0x00 0x00...)会被当成非法 HTTP 请求丢弃。
- 验证方式:抓包看客户端是否收到
0x0A(MySQL OK packet);若只看到 TCP RST 或空响应,就是协议解析失败 - 正确做法:确认
nginx -V 2>&1 | grep -o with-stream输出含with-stream;否则需重装或自行编译 -
stream块不能写在http块内,必须平级,且监听端口不能与 http 冲突
lvs + keepalived 能否直接转发 MySQL 流量?
可以,但仅限于 DR(Direct Routing)或 TUN 模式下的纯 TCP 转发,且后端 MySQL 实例必须绑定 VIP(否则回包绕过 LVS)。但这种方案完全无状态、无健康检查、无连接池、不识别 SQL 类型——select 和 update 都被一视同仁轮询,主从混发必然导致从库写入失败或主库读压力过大。
- LVS 不解析 MySQL 协议,无法做读写分离,也不能剔除半同步延迟超阈值的从库
- keepalived 的
tcp_check只能判断端口通不通,无法检测SELECT 1是否返回、复制延迟是否 > 30s - 真实故障时(如从库 SQL thread stopped),LVS 仍持续转发读请求,业务报错“Table doesn't exist”或脏读
ProxySQL 是更务实的选择
它专为 MySQL 设计,工作在 OSI 第7层,能解析 SQL、维护连接池、自动发现节点状态、按规则路由(比如 ^SELECT.*FOR UPDATE 强制走主库),且配置通过标准 MySQL 协议管理,无需改应用代码。
- 部署位置:独立服务器或与应用同机(内存占用约 100MB,CPU 开销低)
- 关键配置项:
mysql_servers表定义 hostgroup(如 10=write, 20=read),mysql_query_rules定义正则匹配规则 - 健康检查默认每 3000ms 执行一次
SELECT 1,失败三次即下线节点;也可自定义脚本检查Seconds_Behind_Master - 连接复用:应用连 ProxySQL 的 6033 端口,ProxySQL 复用后端连接,避免频繁建连开销
如果非要用 nginx stream 做最简入口统一
仅适用于「所有流量都打向单点主库」或「已用程序层读写分离、只需统一 VIP 入口」的极简场景。配置核心就三行,但必须严格满足前提:
stream {
upstream mysql_backend {
server 192.168.1.101:3306 max_fails=3 fail_timeout=10s;
server 192.168.1.102:3306 max_fails=3 fail_timeout=10s;
}
server {
listen 3306;
proxy_pass mysql_backend;
proxy_timeout 1h;
proxy_responses 1;
}
}
- 后端 MySQL 必须关闭
skip-name-resolve,否则反向 DNS 查询会拖慢认证 -
proxy_responses 1是关键,否则 nginx 无法识别 MySQL 协议中的多包响应(如大结果集) - 无法感知主从角色,不能防脑裂;主库宕机时,nginx 会把写请求继续转给从库,触发
ERROR 1290 (HY000): The MySQL server is running with the --read-only option
真正需要读写分离和故障转移时,别省这一步:用 proxysql 或 maxscale,而不是硬套 nginx/lvs 的通用转发逻辑。


















