简介:
squid是很老的代理软件,功能齐全可以做正向和反向代理。目前反向代理市场已经被nginx和varnish占据了主导地位,不过依然是正向代理的霸主。本文介绍如何利用squid的子节点和父节点配置组成一个代理矩阵。代理矩阵在普通场景很少使用。应用的场景主要是需要大量缓存的地方,如运营商为了减少网间结算费用设置了很多代理来缓存用户访问的网页静态页面、视频、下载的文件等。然而一台服务器从性能和存储空间来看都无法支撑起那么庞大的用户访问,所以就有了代理集群的概念。本文将介绍如何配置一个代理矩阵的集群和工作原理。
原理:
Squid正向代理矩阵_第1张图片
上图分为三个组成部分。公网、第一层代理、第二层代理。
公网就是下面第一层代理可以直接访问到公网的链路,第一层代理的服务器每台都有自己的公网链路访问公网资源。第二层代理只能通过第一层代理才能访问到公网资源。
第二层代理的下方就是正常的普通用户群。
当用户上网的时候会通过第二层代理获取资源,比如访问百度。用户访问的数据包将经过网关,网关会把80端口做重定向处理数据包将给到代理上去做响应。这个称为透明代理配置,用户无感知,用户也不需要做任何的配置。代理二层服务器接受到请求以后会检索本机的缓存内容:
1、发现缓存内容,直接取出内容返回给用户。
2、没有缓存内容,查询兄弟节点同级代理。(这里二级代理一般是区县市的服务器,所以基本是没有内网互联的,这种不会配置兄弟节点。二级代理中间的黑线一般不存在,squid2-1到squid2-4之间互相不知道对方的存在。图画出来只是告诉大家可以这么配置)
3、没有缓存内容,查询父节点上层代理。(这个地方一般是配置所有上级代理,查询的方式是轮训,也可以通过配置使用域名等方式指定访问上级代理)
4、一级代理检查本机缓存,如果有内容直接返回给二级代理。二级代理根据策略决定是否缓存结果,然后返回给用户。
5、一级代理没有缓存内容,将查询同级的子节点,如果有直接返回二级代理。
6、一级代理子节点没有内容,服务器会去公网获取内容根据策略决定是否缓存,然后返回给二级代理。
整个流程大概就是这样,其中访问的路径和策略全部可以通过squid的配置进行设置。
配置案例:
这是一个整体解决方案,其中配置比较繁杂所以拆开来讲比较容易一些。
透明代理配置:
如果是linux作为路由,其它所有的主机默认路由都指向了这个linux主机。squid代理在本机安装,那么可以通过iptables进行配置。iptables -t nat -A PREROUTING -p tcp -s 192.168.2.0/27 -d 0.0.0.0/0 --dport 80 -i ens192 -j REDIRECT --to-ports 3128。本机需要开启数据包转发功能。
eth0为链接用户端的网卡 -s为本地用户子网,REDIRECT squid的监听端口。这样用户就能无感知的情况下使用代理了。
如果squid代理不是在本机,那么无法使用REDIRECT。 iptables -A PREROUTING -t nat -s 192.168.4.11/32 -p tcp --dport 80 -j DNAT --to 192.168.4.10:3128
如果是其它网关,请根据数据包重定向的原理进行配置。
透明代理应用场景是靠近用户端的网页加速,可以起到提高网速访问的目的。网页打开的速度会比平时快很多,因为大部分的静态内容都缓存到了离用户最近的主机上,只有一些动态内容需要回源访问。
代理矩阵配置:
代理与代理之间有两种关系,1、兄弟代理,2、父代理。关键字对应sibling、parent。
兄弟代理的作用是和同级代理之间组成缓存阵列来分摊请求和缓存内容。根据策略就能把相关内容分配到不同的主机上保存。
父代理的作用是为下级代理提供快速响应。
如上图所示的结构,二级代理没有直接出口公网的地址。它们只是复杂网络中更加靠近用户的代理,比如通过一级代理来获得网络资源。
父代理的配置实例:cache_peer 172.21.5.57 parent 3128 0 round-robin IP地址为上层代理的地址,parent为代理类型,3128上层代理端口 0 icp_port端口,如果没有配置为0 round-robin相对于其他代理而言轮训的类型。
兄弟代理的配置实例:cache_peer 172.21.5.57 sibling 3128 3129 round-robin 基本和parent节点一样。
更多更加详细的配置请参阅网站内容:http://www.phpfans.net/manu/Squid/ squid中文权威指南
爬虫代理实例:
首先在下面的节点安装好squid代理。实例中没有用到兄弟代理的相关配置,下面节点的squid只做了简单的允许访问的配置。
中心节点做为二级代理存在,访问节点的父级代理,主要配置大概如下。
#cache_peer 172.21.5.241 parent 3128 0 round-robin
#cache_peer 172.21.5.29 parent 3128 0 round-robin
#cache_peer 172.21.5.65 parent 3128 0 round-robin
cache_peer 172.21.5.57 parent 3128 0 round-robin
#cache_peer 172.21.7.73 parent 3128 0 round-robin
cache_peer 172.21.5.21 parent 3128 0 round-robin
这里配置了一批节点作为父级代理,通过这个代理访问的请求都将按照squid内部策略把访问转发到某个父级代理上。
因为每个父级代理可能不是非常稳定,所以需要有一个检测脚本来负责对父级代理进行检测。开启和关闭父级代理配置。
#!/bin/bash
. /etc/profile
cd dirname $0
for ip in cat proxy_ip
do
curl -x $ip:3128 --max-time 20 www.baidu.com > /dev/null
if [ $? -gt 0 ];then
[ -f /etc/squid/squid.conf ] && sed "s/^cache_peer $ip parent 3128 0 round-robin/#&/" -i /etc/squid/squid.conf
else
[ -f /etc/squid/squid.conf ] && sed "s/^#(cache_peer $ip parent 3128 0 round-robin)/\1/" -i /etc/squid/squid.conf
fi
done
service squid reload
文件proxy_ip内容
172.21.5.241
172.21.5.29
172.21.5.65
172.21.5.57
172.21.7.73
172.21.7.121
172.21.5.21
然后运行这个脚本,添加到计划任务以后就能通过脚本定期检测车站代理的可用性,是否能访问到百度的网页。如果无法访问时将会自动剔除掉,当下次又能访问时再次开启。脚本每次运行完都会重载配置文件使其生效。
如果有新的节点加入,只需要在节点上安装好squid,然后把相应的IP地址添加进去就行了。