有时候 mysql 服务所在服务器打开了防火墙,只允许某些指定的 IP 地址访问,而客户端又不停地在变换 IP 地址,这导致了客户端无法直接访问 mysql 服务器端。要解决这个问题,通常有几个办法:一是找一个 IP 地址不会变的中间设备,在最终客户端上登录操作这个中间设备,在中间设备上连接 mysql 服务器;典型操作就是在客户端使用 ssh 连接中间设备,在中间设备上的 ssh 环境内运行 mysql 连接 mysql 服务器。二是找一个 IP 地址不会变的中间设备,在中间设备上架设代理服务器将 TCP/UDP 流量反向代理到背后真正的 mysql 服务器上,在最终客户端上直接连接访问中间设备上架设的 mysql 服务。
mysql 客户端不支持使用正向代理服务器,只能直接连接目标服务器。在这种场景下,可以在中间设备上架设一个反向代理服务器,将流量转发到背后真正的 mysql 服务器上。
nginx 是一个非常强大的代理服务器,它可以轻松实现 TCP/UDP 代理;前提是 nginx 编译支持了 stream。运行以下命令可以查看 nginx 的编译参数来确认 nginx 是否支持 stream。
如果 nginx 不在 PATH 或工作目录中,要把 nginx 所在目录的路径带上。
nginx 官方提供的 windows 预编译版会显示下面这样的结果。- nginx version: nginx/1.29.4
- built by cl 19.44.35211 for x86
- built with OpenSSL 3.5.4 30 Sep 2025
- TLS SNI support enabled
- configure arguments: --with-cc=cl --builddir=objs.msvc8 --with-debug --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --http-scgi-temp-path=temp/scgi_temp --http-uwsgi-temp-path=temp/uwsgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs.msvc8/lib/pcre2-10.46 --with-zlib=objs.msvc8/lib/zlib-1.3.1 --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_stub_status_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_slice_module --with-mail --with-stream --with-stream_realip_module --with-stream_ssl_preread_module --with-openssl=objs.msvc8/lib/openssl-3.5.4 --with-openssl-opt='no-asm no-tests no-makedepend -D_WIN32_WINNT=0x0501' --with-http_ssl_module --with-mail_ssl_module --with-stream_ssl_module
复制代码 如果有下面这个参数,则代表 nginx 支持 stream。
确认 nginx 支持 stream 后,如下配置 nginx stream。- stream {
- log_format stream "$remote_addr [$time_local] $protocol $status $bytes_sent/$bytes_received $session_time $upstream_addr";
- access_log /wuxiancheng.cn/nginx/logs/stream.log stream;
- upstream mysql {
- server qsez.org:33066 max_fails=5 fail_timeout=5s;
- }
- server {
- listen 0.0.0.0:3306;
- listen [::]:3306;
- proxy_pass mysql;
- proxy_connect_timeout 10s;
- proxy_timeout 3600s;
- proxy_buffer_size 32k;
- resolver 225.6.6.6 119.29.29.29;
- }
- }
复制代码 stream 配置块和 http 配置块同级,需要放在 main 层,也就是最顶层。
qsez.org 是背后真正的 mysql 服务器的连接地址,33066 是这个这个 mysql 服务器使用的服务端口号。
保存好配置,在中间设备上重新启动 nginx 后,代理服务器就开始工作了。
在客户端设备上连接时,使用中间设备的 IP 地址或域名作服务器的连接地址,使用 3306 作服务端口号。
如果中间设备打开了防火墙,需要将入栈方向 3306 端口上的流量放行。
这个方法不只适用于 mysql,也同样适用于其他服务。 |
|