背景与思路
某网站的附件服务器采用 Lighttpd,希望实现客户端根据服务器当前的连接数进行分流。
最初考虑基于 SNMP 获取 IP 连接数,但 SNMP 查询时常出现超时问题。因此,我们换一种思路:实现一个简单的 API,返回 JSON 格式数据供客户端调用。
整体方案如下:
- 在 Lighttpd 服务器上配置一个虚拟主机,绑定特定端口,用于提供 JSON 文件。
- 编写一个 Shell 脚本,通过 crontab 定时任务(例如每 5 分钟)收集服务器的 TCP 连接信息。
- 脚本将收集到的数据写入虚拟主机目录下的 JSON 文件。
- 客户端需要分流时,请求该 JSON 文件地址,获取数据并处理,从而实现分流。
一、配置 Lighttpd 虚拟主机
1. 创建目录
首先,创建一个目录用于存放 JSON 文件。
mkdir -p /srv/www/vhosts/ipcount
2. 修改 Lighttpd 主配置文件
在进行修改前,建议先备份配置文件。
cd /etc/lighttpd/
cp -a lighttpd.conf lighttpd.conf.backup
编辑配置文件:
vi /etc/lighttpd/lighttpd.conf
在文件末尾(在非插入模式下按 Shift+G 可跳转到末尾)添加以下配置:
# 请将 static.xxx.com:666 替换为实际的域名(或IP)和端口
$SERVER["socket"] == "static.xxx.com:666" {
server.document-root = "/srv/www/vhosts/ipcount/"
}
此配置表示,当 Lighttpd 收到对该端口(666)的 TCP 请求时,将使用指定的目录作为根目录来响应请求。
补充说明:Lighttpd 绑定多个端口的通用方法如下,可供参考:
server.port = 80 $SERVER["socket"] == "0.0.0.0:82" { server.document-root = "/path/to/webroot1/" } $SERVER["socket"] == "0.0.0.0:83" { server.document-root = "/path/to/webroot2/" }
3. 验证配置并重启服务
重要:在重启 Lighttpd 前,务必验证配置文件语法是否正确,以避免影响线上服务。
lighttpd -t -f /etc/lighttpd/lighttpd.conf
如果验证通过,重启 Lighttpd 服务:
systemctl restart lighttpd
4. 配置防火墙
如果系统防火墙(如 firewalld)已启用,需要开放对应端口。
firewall-cmd --permanent --add-port=666/tcp
firewall-cmd --reload
5. 测试虚拟主机
创建一个简单的测试文件,验证虚拟主机是否正常工作。
echo "Test Page" > /srv/www/vhosts/ipcount/index.html
通过浏览器访问 http://static.xxx.com:666/index.html,应能看到 "Test Page" 字样。如果需要启用 SSL,请参考 Lighttpd 官方文档进行配置。
至此,API 接口的服务器端基础环境已准备就绪。
二、编写数据收集 Shell 脚本
创建一个 Shell 脚本,用于定时收集服务器状态数据并生成 JSON 文件。
#!/bin/bash
# 脚本名称:ServerIPcount.sh
# 功能:统计当前服务器的 ESTABLISHED 连接数和实时带宽
# 1. 统计 80 端口的 ESTABLISHED 连接数
establishedIP=$(netstat -na | grep -i ":80" | grep ESTABLISHED | wc -l)
# 2. 计算 eth0 网卡近 1 秒的出口带宽(字节/秒)
TXpre=$(cat /proc/net/dev | grep "eth0" | tr : " " | awk '{print $10}')
sleep 1
TXnext=$(cat /proc/net/dev | grep "eth0" | tr : " " | awk '{print $10}')
bandwidth=$((TXnext - TXpre))
# 3. 将数据写入 JSON 文件
JSON_DATA='{"establishedIP":"'$establishedIP'","bandwidth":"'$bandwidth'"}'
echo $JSON_DATA > /srv/www/vhosts/ipcount/index.json
将脚本保存到系统目录,例如 /tools/,并赋予执行权限:
touch /tools/ServerIPcount.sh
vi /tools/ServerIPcount.sh # 将上述脚本内容粘贴进去
chmod +x /tools/ServerIPcount.sh
配置定时任务
使用 crontab 设置脚本每 5 分钟执行一次:
crontab -e
在打开的编辑器中添加以下行:
*/5 * * * * /tools/ServerIPcount.sh
脚本执行后,/srv/www/vhosts/ipcount/index.json 文件内容将类似:
{"establishedIP":"42","bandwidth":"1250000"}
三、PHP 客户端调用示例
客户端(如 PHP 应用)可以通过 HTTP 请求获取 JSON 数据并进行处理。
100) {
// 连接数过高,切换到备用服务器
$download_server = 'backup-server.example.com';
} else {
// 使用主服务器
$download_server = 'main-server.example.com';
}
echo "当前使用的下载服务器:" . $download_server;
?>
四、进阶:结合时间段的判断逻辑
在实际分流策略中,可能还需要结合时间段。以下是一个 PHP 函数示例,用于判断当前时间是否在指定的每日时间区间内(例如 9:00 至 18:00)。
= $start_hour && $current_hour < $end_hour);
}
// 使用示例
if (is_within_time_section()) {
echo "当前处于业务高峰时段 (9:00-18:00)。";
// 可以在此处应用更严格的分流策略
} else {
echo "当前处于非高峰时段。";
}
?>
你可以将时间段判断与连接数判断结合,形成更复杂、灵活的分流规则。
总结
本文介绍了一种轻量级的服务器状态监控与分流方案。通过 Lighttpd 提供静态 JSON 文件,配合定时 Shell 脚本更新数据,客户端可以便捷地获取服务器当前的连接数和带宽信息。此方案避免了 SNMP 的复杂性和超时问题,实现简单,易于集成到现有的 PHP 或其他客户端应用中,实现基于服务器负载的智能分流。