一、背景:我们为什么需要端口转发?
想象一下,你是一个小区的物业经理(服务器管理员)。小区里有很多住户(各种应用程序),比如住101的Web服务、住102的数据库、住103的邮件服务。通常情况下,访客(客户端请求)想找101住户,就得直接去101敲门。但这里有几个麻烦:
**1.安全隐患:**直接暴露住户的门牌号(端口),容易被坏人盯上。
2.搬家麻烦:如果101住户搬到201,你得通知所有访客去新地址。
**3.交通堵塞:**如果101访客太多,一个人忙不过来,而102却闲着。
这时候,你需要在小区门口设立一个传达室。所有访客都先到传达室,告诉门卫想找谁,然后由门卫帮你把话带到(或者引导你过去)。这个传达室,就是我们的反向代理或端口转发服务器。
而HAProxy,就是这个传达室里最敬业、最高效的"门卫"或"智能交通警察"。
二、HAProxy是什么?
HAProxy是一款免费、开源、高性能的软件,它主要干两件事:
**1.端口转发:**把从A端口来的流量,原封不动或经过处理,转给B端口(可以是本机或其他机器)。
**2.负载均衡:**如果后面有多台服务器干活,它能决定把任务分给谁,避免有人累死,有人闲死。均衡服务器流量的同时,也避免一台服务器罢工,整个线路都出问题
简单来说,它是一个"流量中转站"。
三、核心功能:不仅仅是"转发"那么简单
HAProxy之所以强大,是因为它在转发时能做很多精细化的操作:
转发类型:可以进行UDP、TCP和HTTP等多重协议的转发
四层转发:只看网络层的IP和端口,速度极快,像快递员只看包裹上的地址标签 。
七层转发:能看懂应用层的内容(比如HTTP头、URL、Cookie),可以根据不同的域名、不同的路径转发到不同的后端,像个分拣员会根据包裹里的东西分类处理 。
**健康检查:**定期检查后端的服务器是否还活着,如果死了,就不再往那里转发流量 。
会话保持:确保一个用户连续的操作始终由同一台后端服务器处理
四、动手实战:配置你的第一个端口转发
下面,我们通过一个场景来学习配置。
场景:用户访问我们服务器的 8080 端口,我们希望HAProxy将流量转发到本机的 80 端口(假设跑着一个网站)
第一步:安装HAProxy
在Linux(如CentOS或Ubuntu)上,安装非常简单:
bash
# CentOS / RHEL
sudo yum install haproxy -y
# Ubuntu / Debian
sudo apt update
sudo apt install haproxy -y
第二步:认识配置文件
HAProxy的配置文件通常位于 /etc/haproxy/haproxy.cfg。它的结构很清晰,主要分为以下几个部分 :
global:全局配置,如进程权限、日志等。
defaults:默认配置,如果后面没特别指定,就套用这里的设置。
frontend:"传达室门口",定义在哪里等客人(监听哪个IP和端口)。
backend:"住户地址本",定义把客人带到哪里去(后端服务器的列表)。
listen:把frontend和backend合在一起写(适用于简单配置)。
第三步:编写转发配置
我们用vim编辑配置文件:
bash
sudo vim /etc/haproxy/haproxy.cfg
一个最简单的端口转发配置(四层TCP模式)如下:
bash
# 全局设置
global
daemon # 以后台进程运行
maxconn 256 # 最大连接数
# 默认设置
defaults
mode tcp # 默认模式为TCP(四层转发)
timeout connect 5000ms # 连接后端超时
timeout client 50000ms # 客户端超时
timeout server 50000ms # 服务器端超时
# 前端:定义入口
frontend web-in
bind *:8080 # 监听服务器的所有IP地址的8080端口
default_backend web-servers # 默认转发到叫做 web-servers 的后端
# 后端:定义出口
backend web-servers
mode tcp # 使用TCP模式
server web1 127.0.0.1:80 maxconn 1024 # 定义一台服务器,就是本机的80端口, 端口转发服务名称为web1
这样,当用户访问 http://你的服务器IP:8080 时,HAProxy就会把这个请求转发给本机的 80 端口。
第四步:启动与验证
保存配置文件后,启动HAProxy服务:
bash
# 启动HAProxy
sudo systemctl start haproxy
# 设置开机自启
sudo systemctl enable haproxy
# 查看状态
sudo systemctl status haproxy
如果状态是活跃的,你可以通过访问服务器的 8080 端口,看看是否成功显示了你 80 端口的网站内容。
五、进阶技巧:让"交通警察"更智能
掌握了基础转发,我们来看看几个常用技巧。
技巧1:基于域名的转发(七层)
假设你有多个域名都指向同一台服务器,你想让 http://blog.example.com 转发到博客服务(端口8001),让 http://shop.example.com 转发到商城服务(端口8002)。这时需要开启HTTP模式 。
bash frontend http-in
bash
bind *:80 # 监听80端口
mode http # 模式改为http,这样才能看懂域名
# 定义访问控制列表(ACL)
acl is_blog hdr(host) -i blog.example.com # 如果host是blog.example.com
acl is_shop hdr(host) -i shop.example.com # 如果host是shop.example.com
# 根据ACL执行转发
use_backend blog-servers if is_blog
use_backend shop-servers if is_shop
# 默认情况
default_backend web-servers
backend blog-servers
bash
mode http
server blog1 127.0.0.1:8001
backend shop-servers
bash
mode http
server shop1 127.0.0.1:8002
技巧2:修改Host头
有时后端服务依赖于客户端请求的域名。当你用HAProxy转发时,后端收到请求的Host可能是HAProxy的IP而非真实域名。可以通过配置修改 :
bash frontend http-in
bash
bind *:8080
mode http
# 从请求中移除端口号,或者重写Host头
http-request replace-value Host (.*):.* \1
default_backend servers
这条命令会将Host头从 http://example.com:8080 重写为 http://example.com。
技巧3:TCP与HTTP模式的选择
用TCP模式:转发数据库(MySQL 3306)、Redis、SSH、MongoDB等非HTTP服务 。它只管数据包,不管内容,性能损耗小。
用HTTP模式:转发网站、RESTful API等。它能解析URL、Cookies,做更智能的负载均衡和路由 。
六、注意事项
别让"传达室"变成"麻烦室" 端口冲突 在配置 bind 的端口时,要确保该端口没有被其他程序(如Nginx、Apache本身)占用。否则HAProxy会启动失败。
6.1 检查端口是否被占用
sudo netstat -tulnp | grep 8080 防火墙设置 配置完HAProxy后,别忘记在系统防火墙中放行HAProxy监听的端口(如上面的8080),否则外部无法访问 。例如 firewalld
bash
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent sudo firewall-cmd --reload
6.2 日志查看
如果转发不成功,第一步是去看日志。
bash
sudo tail -f /var/log/haproxy.log # 或查看系统日志
6.3 配置语法检查
重启HAProxy前,养成检查语法的好习惯,避免手误导致服务中断。
bash
sudo haproxy -f /etc/haproxy/haproxy.cfg -c
6.4 资源限制
在 global 中设置的 maxconn 受限于系统最大网络连接数。如果并发极高,需要同步调整系统参数 ulimit -n。
6.5 转发链中的IP地址
当使用TCP转发时,后端服务器看到的客户端IP是HAProxy的IP,而不是真实用户IP。对于HTTP模式,可以使用 option forwardfor 选项添加 X-Forwarded-For 头来传递真实IP 。
七、总结
HAProxy是一个非常可靠的工具,掌握了它,你就拥有了对服务器流量进行灵活调度的能力。从最简单的端口转发入手,逐渐尝试七层转发和负载均衡,你会发现它在架构中的作用远不止一个"传达室"那么简单。