我确实意识到这个问题大约 6 年前就被问过了将 nginx 绑定到 tcp 和 http 的同一端口上
但是,有什么变化吗?我是否可以做类似的事情:
stream {
listen 80;
location / {
protocol http;
}
location /mysql {
protocol tcp;
}
}
或者tcp
和http
模块仍然必须是分开的吗?
答案1
这不仅仅是 Nginx 缺少的一个功能,将来可以以某种方式进行改进,而且协议级别的不兼容性使得这完全不可能。
在您的示例中,位置路径/mysql
仅存在于 HTTP 协议中。在 HTTP 中,客户端通过请求开始通信:
GET /mysql HTTP/1.1
Hostname: example.com
这MySQL 客户端/服务器协议是一个完全不同的协议,它甚至以相反的方式开始:服务器发送一个初始握手数据包例如
36 00 00 00 0a 35 2e 35 2e 32 2d 6d 32 00 0b 00 6....5.5.2-m2... 00 00 64 76 48 40 49 2d 43 4a 00 ff f7 08 02 00. ..dvH@I-CJ...... 00 00 00 00 00 00 00 00 00 00 00 00 00 2a 34 64. .............* 4d 7c 63 5a 77 6b 34 5e 5d 3a 00 |cZwk4^]:.
理论上,TLS 可以根据以下方式区分同一 TCP 端口上的不同服务:服务器名称指示(SNI)并将流量转发到不同的上游服务器,即使使用不同的底层协议。然而,
- 据我所知,Nginx 中还没有实现类似功能。
- 您选择的示例 MySQL 客户端/服务器协议不会启动与 TLS 的通信,但 TLS 的功能是宣布在初始握手包中,如果服务器和客户端都支持 TLS,则连接升级到 TLS。
- 每种标准协议都有自己的 TLS 端口(或带有 的纯文本
STARTTLS
),而且我们的 TCP 端口也不会用完。因此,对此功能的需求并不大。
答案2
它们仍然需要分开。否则 nginx 需要能够代理 mysql 调用,但它做不到。