![限制 Apache 服务器(镜像)传出带宽的最佳方法](https://linux22.com/image/694223/%E9%99%90%E5%88%B6%20Apache%20%E6%9C%8D%E5%8A%A1%E5%99%A8%EF%BC%88%E9%95%9C%E5%83%8F%EF%BC%89%E4%BC%A0%E5%87%BA%E5%B8%A6%E5%AE%BD%E7%9A%84%E6%9C%80%E4%BD%B3%E6%96%B9%E6%B3%95.png)
我将设置一个 Apache Foundation 下载镜像,并向公共和私人访问开放。我想将外部访问限制在 650Mbps 左右,但不限制(最好优先考虑)内部访问。我还想在有足够容量时尽快为客户端提供服务,但在连接许多客户端时分配带宽(希望是均匀的,但不是必须的)。另一方面,该服务器还将用于 Ubuntu 和 Debian 软件包镜像。Web 服务器将仅提供静态内容,并且必须使用 Apache。
当前配置:
Apache 版本:Apache 2.4.18
操作系统:Ubuntu 16.04 LTS
CPU 和 RAM:目前最好是 2 核 4GB,但如果需要可以扩展到 4 核 32GB Apache 模块:默认
可用选项按访问难易程度排序:
- Apache 模块
- 对运行 Apache 服务器的服务器的根访问权限(开放软件流量整形/速率限制)
- 功能非常强大且空闲率达 99% Juniper EX4xxx 系列交换机
答案1
这是基于 tc 和 iptables 的工作示例。
步骤1:
用 PRIO 队列替换默认的 pfifo_fast 队列。PRIO
队列是分类队列,允许我们稍后附加过滤器来对不同类型的流量进行分类。
检查现有队列
tc -s qdisc ls dev eth0
用 PRIO 替换。这将创建 3 个默认频段。
tc qdisc add dev eth0 root handle 1: prio
如下图所示
1: root qdisc
/ | \
/ | \
/ | \
1:1 1:2 1:3 classes
现在让我们添加分类队列。我们将把它们附加到 1:1、1:2 和 1:3 频段
tc qdisc add dev eth0 parent 1:1 handle 10: sfq
tc qdisc add dev eth0 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000
tc qdisc add dev eth0 parent 1:3 handle 30: sfq
如下图所示
1: root qdisc
/ | \
/ | \
/ | \
1:1 1:2 1:3 classes
| | |
10: 20: 30: qdiscs qdiscs
sfq tbf sfq
0 1 2 bands
根据数据包 TOS 流量将转到
- 1:10 – 互动交通
- 1:20 – 互动交通
- 1:30 – 流量大
但考虑到一些应用程序实际上会设置 TOS 值,这并不是我们想要的。
我们希望将从端口 80(sport=80)发起的流量分类为 1:2(我们对其进行整形和限制速率),其余流量分类为 1:1。
这样,其余流量就不必等待 http 流量,并且将具有优先级。否则,缓慢的 http 流量将阻止其他非交互式流量。
那么如何做到这一点呢?
我们将通过 iptables 将从源端口 80 发起的数据包标记为 2,非 http 流量标记为 1
iptables -t mangle -A OUTPUT -m tcp -p tcp --sport 80 -j MARK --set-mark 2
iptables -t mangle -A OUTPUT -m tcp -p tcp ! --sport 80 -j MARK --set-mark 1
我们将使用 tc 过滤器,它将标有标签的数据包路由到特定频段
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 2 fw flowid 1:2 ### Send traffic from source port 80 to tbf queue
tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 1 fw flowid 1:1 ### Send all other traffic to sfq queue 1:1
现在我们准备测试了。我将从 http 服务器启动 CentOS iso 下载,同时我将从同一服务器启动同一映像的 sftp 传输。在下图中我们可以看到,虽然 sftp 传输速度约为 13MB/s,但 http 传输速度限制为 20kbit/s。
在这个例子中,1:3 频段甚至没有使用。
所以也许最好在 1:3 频段上使用 tbf,并使用 sfq 和默认优先级设置 1:1 和 1:2。然而,这只是一个快速测试,应该足以澄清一些更复杂的 tc 文档。
所用资源:
- http://lartc.org/howto/lartc.qdisc.classful.html
- http://www.lartc.org/howto/lartc.qdisc.filters.html
- http://www.lartc.org/howto/lartc.adv-filter.html
- man iptables(在 CentOS6、CentOS 7 上,iptables 的 man 已经大大减少,因为它不再是控制防火墙的默认方法)
答案2
一种简单的方法是启动多个物理接口,每个接口可能为 1 Gbps。将一个接口放在面向外部的子网上,将另一个接口放在面向内部的子网上。mirror.example.com 可供公众访问,但 mirror.corp.example.com 仅在 LAN 上。
但是,在虚拟机上,受接口限制的技巧是不够的,因为虚拟机的 vNIC 速度比它所模拟的设备更快。
而且控制的精细程度也远低于您的要求。如果超过 650 Mbps 的目标不安全,您可能需要更复杂的措施。
答案3
因为 apache 的架构将负载分散到许多不同的进程/线程中,所以我认为在 apache 级别进行限制/优先排序不会有帮助。
我认为最好的方法是使用 Linux 内核中的流量限制/优先级支持。
不幸的是我自己没有这样做过,但我知道关于这个主题的参考文档是 Linux 高级路由和流量控制指南。
我相信http://lartc.org/howto/lartc.qdisc.html是相关章节。
如果您让它工作了,请回来写一个答案,详细说明您是如何让它工作的。