您的位置:首页 > 运维架构 > 反向代理

nginx做为反向代理实现负载均衡的例子 .

2012-09-26 15:21 796 查看
我们介绍了nginx这个轻量级的高性能server主要可以干的两件事情:

>直接作为http server(代替apache,对PHP需要FastCGI处理器支持,这个我们之后介绍);

>另外一个功能就是作为反向代理服务器实现负载均衡
(如下我们就来举例说明实际中如何使用nginx实现负载均衡)。因为nginx在处理并发方面的优势,现在这个应用非常常见。当然了Apache的mod_proxy和mod_cache结合使用也可以实现对多台app server的反向代理和负载均衡,但是在并发处理方面apache还是没有nginx擅长。



nginx作为反向代理实现负载均衡的例子:


转载请注明原文链接:http://blog.csdn.net/omohe/archive/2009/07/09/4335765.aspx

版本:v1.0 作者:OMO 最后修改时间:2009.07.09

1)环境:

a. 我们本地是Windows系统,然后使用VirutalBox安装一个虚拟的Linux系统。

在本地的Windows系统上分别安装nginx(侦听8080端口)和apache(侦听80端口)。在虚拟的Linux系统上安装apache(侦听80端口)。

这样我们相当于拥有了1台nginx在前端作为反向代理服务器;后面有2台apache作为应用程序服务器(可以看作是小型的server cluster。;-) );

b. nginx用来作为反向代理服务器,放置到两台apache之前,作为用户访问的入口;

nginx仅仅处理静态页面,动态的页面(php请求)统统都交付给后台的两台apache来处理。

也就是说,可以把我们网站的静态页面或者文件放置到nginx的目录下;动态的页面和数据库访问都保留到后台的apache服务器上。

c. 如下介绍两种方法实现server cluster的负载均衡。

我们假设前端nginx(为127.0.0.1:80)仅仅包含一个静态页面index.html;

后台的两个apache服务器(分别为localhost:80和158.37.70.143:80),一台根目录放置phpMyAdmin文件夹和test.php(里面测试代码为print "server1";),另一台根目录仅仅放置一个test.php(里面测试代码为print "server2";)。

2)针对不同请求 的负载均衡:

a. 在最简单地构建反向代理的时候 (nginx仅仅处理静态不处理动态内容,动态内容交给后台的apache server来处理),我们具体的设置为:在nginx.conf中修改:

location ~ /.php$ {

proxy_pass 158.37.70.143:80 ;

}

>这样当客户端访问localhost:8080/index.html的时候,前端的nginx会自动进行响应;

>当用户访问localhost:8080/test.php的时候(这个时候nginx目录下根本就没有该文件),但是通过上面的设置location ~ /.php$(表示正则表达式匹配以.php结尾的文件,详情参看location是如何定义和匹配的http://wiki.nginx.org/NginxHttpCoreModule) ,nginx服务器会自动pass给158.37.70.143的apache服务器了。该服务器下的test.php就会被自动解析,然后将html的结果页面返回给nginx,然后nginx进行显示(如果nginx使用memcached模块或者squid还可以支持缓存),输出结果为打印server2。

如上是最为简单的使用nginx做为反向代理服务器的例子;

b. 我们现在对如上例子进行扩展,使其支持如上的两台服务器。

我们设置nginx.conf的server模块部分,将对应部分修改为:

location ^~ /phpMyAdmin/ {

proxy_pass 127.0.0.1:80 ;

}

location ~ /.php$ {

proxy_pass 158.37.70.143:80 ;

}

上面第一个部分location ^~ /phpMyAdmin/,表示不使用正则表达式匹配(^~),而是直接匹配,也就是如果客户端访问的URL是以http://localhost:8080/phpMyAdmin/ 开头的话(本地的nginx目录下根本没有phpMyAdmin目录),nginx会自动pass到127.0.0.1:80
的Apache服务器,该服务器对phpMyAdmin目录下的页面进行解析,然后将结果发送给nginx,后者显示;

如果客户端访问URL是http://localhost/test.php 的话,则会被pass到158.37.70.143:80 的apache进行处理。

因此综上,我们实现了针对不同请求的负载均衡。

>如果用户访问静态页面index.html,最前端的nginx直接进行响应;

>如果用户访问test.php页面的话,158.37.70.143:80 的Apache进行响应;

>如果用户访问目录phpMyAdmin下的页面的话,127.0.0.1:80 的Apache进行响应;

3)访问同一页面 的负载均衡:

用户访问http://localhost:8080/test.php 这个同一页面的时候,我们实现两台服务器的负载均衡 (实际情况中,这两个服务器上的数据要求同步一致,这里我们分别定义了打印server1和server2是为了进行辨认区别)。

a. 现在我们的情况是在windows下nginx是localhost侦听8080端口;

两台apache,一台是127.0.0.1:80(包含test.php页面但是打印server1),另一台是虚拟机的158.37.70.143:80(包含test.php页面但是打印server2)。

b. 因此重新配置nginx.conf为:

>首先在nginx的配置文件nginx.conf的http模块中添加,服务器集群server cluster(我们这里是两台)的定义:

upstream myCluster {

server 127.0.0.1:80 ;

server 158.37.70.143:80 ;

}

表示这个server cluster包含2台服务器

>然后在server模块中定义,负载均衡:

location ~ /.php$ {

proxy_pass http://myCluster ; #这里的名字和上面的cluster的名字相同

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

这样的话,如果访问http://localhost:8080/test.php 页面的话,nginx目录下根本没有该文件,但是它会自动将其pass到myCluster定义的服务区机群中,分别由127.0.0.1:80;或者158.37.70.143:80;来做处理。

上面在定义upstream的时候每个server之后没有定义权重,表示两者均衡;如果希望某个更多响应的话例如:

upstream myCluster {

server 127.0.0.1:80 weight=5;

server 158.37.70.143:80 ;

}

这样表示5/6的几率访问第一个server,1/6访问第二个。另外还可以定义max_fails和fail_timeout等参数。

http://wiki.nginx.org/NginxHttpUpstreamModule

====================

综上,我们使用nginx的反向代理服务器reverse proxy server的功能,将其布置到多台apache server的前端。

nginx仅仅用来处理静态页面响应和动态请求的代理pass,后台的apache server作为app server来对前台pass过来的动态页面进行处理并返回给nginx。


通过以上的架构,我们可以实现nginx和多台apache构成的机群cluster的负载均衡。

两种均衡:

1)可以在nginx中定义访问不同的内容,代理到不同的后台server; 如上例子中的访问phpMyAdmin目录代理到第一台server上;访问test.php代理到第二台server上;

2)可以在nginx中定义访问同一页面,均衡 (当然如果服务器性能不同可以定义权重来均衡)地代理到不同的后台server上。 如上的例子访问test.php页面,会均衡地代理到server1或者server2上。

实际应用中,server1和server2上分别保留相同的app程序和数据,需要考虑两者的数据同步。


squid 不缓存任何文件

SQUID作为反向代理的服务器缓,目的不是要缓存只是要在访问不同域名时能转到下面对应的服务器,下面的动态网站更新后没有问题,每次更新后要重起清除一下SQUID的缓存才能看到更新的内容,一个字烦。今天网上找了找在squid.conf里的cache_dir ufs /home/cache 1024 16 256里加上一句 ,改成cache_dir ufs /home/cache 1024 16 256 read-only重起SQUID就OK了,完工后作个记录
http://hi.baidu.com/szythankyou?page=4

http://www.chinaz.com/server/2009/0507/74922.shtml

前端的lvs和squid,按照安装方法,把epoll打开,配置文件照搬,基本上问题不多。

这个架构和app_squid架构的区别,也是关键点就是:加入了一级中层代理,中层代理的好处实在太多了:

1、gzip压缩

压缩可以通过nginx做,这样,后台应用服务器不管是apache、resin、lighttpd甚至iis或其他古怪服务器,都不用考虑压缩的功能问题。

2、负载均衡和故障屏蔽

nginx可以作为负载均衡代理使用,并有故障屏蔽功能,这样,根据目录甚至一个正则表达式来制定负载均衡策略变成了小case。

3、方便的运维管理,在各种情况下可以灵活制订方案。

例如,如果有人用轻量级的ddos穿透squid进行攻击,可以在中层代理想办法处理掉;访问量和后台负载突变时,可以随时把一个域名或一个目录的请求扔入二级cache服务器;可以很容易地控制no-cache和expires等header。等等功能。。。

4、权限清晰

这台机器就是不写程序的维护人员负责,程序员一般不需要管理这台机器,这样假如出现故障,很容易能找到正确的人。

对于应用服务器和数据库服务器,最好是从维护人员的视线中消失,我的目标是,这些服务只要能跑得起来就可以了,其它的事情全部可以在外部处理掉。

一、squid及web缓存介绍

Squid是一种用来缓冲Internet数据的软件。它是这样实现其功能的,接受来自人们需要下载的目标(object的请求并适当地处理这些请求。也就是说,如果一个人想下载一web页面,他请求Squid为他取得这个页面。Squid随之连接到远程服务器(比如:http://squid.nlanr.net/)并向这个页面发出请求。然后,Squid将web端得到的数据转发给客户端机器,而且同时复制一份,当下一次有人需要同一页面时,Squid可以简单地从磁盘中读到它,那样数据迅即就会传输到客户机上。当前的Squid可以处理HTTP,FTP,GOPHER,SSL和WAIS等协议。但它不能处理如POP,NNTP,RealAudio以及其它类型的东西。

cache命中在squid每次从它的缓存里满足HTTP请求时发生。cache命中率,是所有HTTP请求中命中的比例。Web缓存典型的cache命中率在30%到60%之间。另一个相似的度量单位叫做字节命中率,描绘了cache提供服务的数据容量(字节数)。

cache丢失在squid不能从它的缓存里满足HTTP请求时发生。cache丢失的理由有很多种。最明显的,当squid第一次接受到对特殊资源的请求时,就是一个cache丢失。类似的情况是,squid会清除缓存以释放空间给新对象。另外的可能是资源不可到达。原始服务器会指示cache怎样处理响应。例如,它会提示数据不能被缓存,或在有限的时间内才被重复使用,等等。

cache确认保证squid不对用户返回过时数据。在重复使用缓存对象时,squid经常从原始服务器确认它。假如服务器指示squid的拷贝仍然有效,数据就发送出去。否则,squid升级它的缓存拷贝,并且转发给客户。

二、系统环境

两台web缓存服务器安装CentOS 5.8+squid+memcached,分别命名为squid_cache1和squid_cache2。Squid对于后端的web服务器没有要求,可以是IIS,也可以是apache或是其他的。缓存前端可以有一层负载均衡,如果是LVS的话,那么两台缓存服务器都需要绑定VIP。

Squid_cache1:

Ip:192.168.0.149

子网掩码:255.255.255.0

默认网关:192.168.0.1

Squid_cache2:

Ip:192.168.0.150

子网掩码:255.255.255.0

默认网关:192.168.0.1

三、安装前的准备工作

1、关闭SELinux

查看SELinux的状态

getenforce

如果是开启状态,则

vi /etc/selinux/config
SELINUX=disabled     #修改
#SELINUXTYPE=targeted  #注释掉


重启系统

reboot

2.优化内核参数

vi /etc/sysctl.conf # 编辑sysctl.conf文件添加以下内容
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 65536 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 786432 1048576 1572864
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 1024 65000


以上配置说明:

net.ipv4.tcp_rmem = 4096 87380 4194304:TCP读buffer,可参考的优化值: 32768 436600 873200

net.ipv4.tcp_wmem = 4096 65536 4194304:TCP写buffer,可参考的优化值: 8192 436600 873200

net.core.wmem_default:表示发送套接字缓冲区大小的缺省值(以字节为单位)

net.core.rmem_default:表示接收套接字缓冲区大小的缺省值(以字节为单位)

net.core.rmem_max :表示接收套接字缓冲区大小的最大值(以字节为单位)

net.core.wmem_max:表示发送套接字缓冲区大小的最大值(以字节为单位)

net.core.netdev_max_backlog = 262144:每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

net.core.somaxconn = 262144:web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。

net.ipv4.tcp_max_orphans = 3276800:系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。

net.ipv4.tcp_max_syn_backlog = 8192:表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。

net.ipv4.tcp_max_tw_buckets = 5000:表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。减少它的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。

net.ipv4.tcp_timestamps = 0:时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号,时间戳能够让内核接受这种“异常”的数据包,这里需要将其关掉。

net.ipv4.tcp_tw_recycle = 1:表示开启TCP连接中TIME-WAIT sockets的快速回收。

net.ipv4.tcp_tw_reuse = 1:表示开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接。

net.ipv4.tcp_mem = 786432 1048576 1572864:同样有3个值,net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力;net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段;net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket。可根据物理内存大小进行调整,如果内存足够大的话,可适当往上调。建议94500000 915000000 927000000。

net.ipv4.tcp_fin_timeout = 30:表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。

net.ipv4.tcp_keepalive_time = 1200:表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。

net.ipv4.ip_local_port_range = 1024 65000:表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。

使配置立即生效:

/sbin/sysctl -p

3.关闭系统无关的服务

接下来关掉一些不必要的系统服务

chkconfig bluetooth off

chkconfig firstboot off

chkconfig cups off

chkconfig ip6tables off

chkconfig isdn off

chkconfig kudzu off

chkconfig sendmail off

chkconfig smartd off

chkconfig autofs off

停止apache服务

service httpd stop

建议卸载掉apache

4.修改文件描述符限制

(1)修改用户级限制

ulimit -n #查看当前用户的文件描述符的限制数目

ulimit -HSn 4096 #修改当前shell环境文件描述符的限制数目

永久修改用户的文件描述符的限制

vi /etc/security/limits.conf #编辑limits.conf文件,添加以下两行
*                hard    nofile          4096
*                soft    nofile          4096


(2)修改系统级限制

vi /usr/include/bits/typesizes.h #编辑typesizes.h文件找到以下行将1024改为4096
#define __FD_SETSIZE            4096


vi /usr/include/linux/posix_types.h #编辑posix_types.h文件找到以下行将1024改为4096
#define __FD_SETSIZE    4096


注:刚才编辑的这两个文件是C/C++程序里面的头文件,编译squid的时候会被自动引用。只需要修改其数值,前面的#号不要去掉。

cat /proc/sys/fs/file-max #查看系统级的文件描述符的限制数目

如果小于4096,则执行下面语句,大于4096则跳过此步骤

echo 4096 > /proc/sys/fs/file-max

5.优化TCP/IP栈分配给出去连接的本地端口范围

netstat -n | grep TIME_WAIT #查看当前有多少个出去的连接

cat /proc/sys/net/ipv4/ip_local_port_range #查看分配的本地端口范围

echo "1024 65000" > /proc/sys/net/ipv4/ip_local_port_range #修改端口范围

vi /etc/rc.d/rc.local #编辑rc.local文件使其开机生效
echo "1024 65000" > /proc/sys/net/ipv4/ip_local_port_range


注:以上端口范围可根据自己网站的实际情况进行更改

6.配置时间同步

yum install ntp

crontab –e

在最后添加
1 5 * * * /usr/sbin/ntpdate time.nist.gov


7.开启防火墙80端口

vi /etc/sysconfig/iptables #添加一条规则
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT


service iptables restart #重启防火墙使配置生效

8.下载软件

cd /usr/local/src

wget http://cloud.github.com/downloads/libevent/libevent/libevent-2.0.19-stable.tar.gz
wget http://memcached.googlecode.com/files/memcached-1.4.13.tar.gz
wget http://www.squid-cache.org/Versions/v3/3.1/squid-3.1.20-20120610-r10455.tar.gz
9.安装编译工具

yum -y install gcc gcc-c++


Squid配置以缓存大量图片

配置文件如下

http_port 59.175.238.60:80 defaultsite=219.140.171.194 vhost vport=80

cache_mem 2048 MB

cache_swap_low 90

cache_swap_high 95

maximum_object_size 20 MB

maximum_object_size_in_memory 8 MB

cache_dir ufs /squid_cache 100000 128 512

cache_peer 219.140.171.194 parent 80 0 no-query originserver

cache_peer_domain 219.140.171.194 img.cnhubei.com

acl all src 0.0.0.0/0.0.0.0

acl Safe_ports port 80

acl Safe_ports port 443

acl AntiBaidu req_header User-Agent Baiduspider

acl cnhubei referer_regex -i cnhubei

acl nullref referer_regex -i ^$

http_access allow nullref

http_access deny !Safe_ports

http_access deny AntiBaidu

http_access deny !cnhubei

deny_info http://www.cnhubei.com/images/2007cnhubei04y002.jpg cnhubei

http_access allow all

visible_hostname www.w3cool.com

cache_mgr zhangweijie@gmail.com

#### Disable Logs

cache_store_log none

cache_vary on

logfile_rotate 0

refresh_pattern -i \.*$ 1440 90% 129600 reload-into-ims

参数设置的都很暴力,还设置了一个反盗链

其实主要就是refresh_pattern的一些理解和建议.

概念LM,LM就是页面Header里时间(Date)和Last-Modified时间的差。Date一般是Squid从后面取页面的时间,Last-Modified 一般是页面生成时间。

refresh_pattern 的语法是

refresh_pattern [-i] regexp min percent max [options]

min, max的单位是分钟,percent就是百分比。

refresh_pattern 的算法如下:(当前时间定义为CURRENT_DATE)

1) If ((CURRENT_DATE-DATE(就是LM里定义的时间)) < min),cache是新鲜的

2) else if ((CURRENT_DATE-DATE) < (min + (max-min)*percent),cache是新鲜的

3) else cache是过期的

cache过期就需要从后面server取新鲜内容。

常用的几个参数的意思

override-expire

该选项导致squid在检查Expires头部之前,先检查min值。这样,一个非零的min时间让squid返回一个未确认的cache命中,即使该响应准备过期。

override-lastmod

改选项导致squid在检查LM-factor百分比之前先检查min值。

reload-into-ims

该选项让squid在确认请求里,以no-cache指令传送一个请求。换句话说,squid在转发请求之前,对该请求增加一个If-Modified- Since头部。注意这点仅仅在目标有Last-Modified时间戳时才能工作。外面进来的请求保留no-cache指令,以便它到达原始服务器。

一般情况可以使用 reload-into-ims。它其实是强行控制对象的超时时间,这违反了http协议的精神,但是在带宽较窄的场合,可以提高明显系统相应时间。

举例:

refresh_pattern -i \.css$ 1440 50% 129600 reload-into-ims

refresh_pattern -i \.xml$ 1440 50% 129600 reload-into-ims

refresh_pattern -i \.html$ 1440 90% 129600 reload-into-ims-

refresh_pattern -i \.shtml$ 1440 90% 129600 reload-into-ims

refresh_pattern -i \.hml$ 1440 90% 129600 reload-into-ims

refresh_pattern -i \.jpg$ 1440 90% 129600 reload-into-ims

refresh_pattern -i \.png$ 1440 90% 129600 reload-into-ims

refresh_pattern -i \.gif$ 1440 90% 129600 ignore-reload

refresh_pattern -i \.bmp$ 1440 90% 129600 reload-into-ims

refresh_pattern -i \.js$ 1440 90% 129600 reload-into-ims

ignore-reload

该选项导致squid忽略请求里的任何no-cache指令。

所以。如果希望内容一进入cache就不删除,直到被主动purge掉为止,可以加上ignore-reload选项,这个我们常用在mp3,wma,wmv,gif之类。

Examples:

refresh_pattern -i \.mp3$ 1440 50% 2880 ignore-reload

refresh_pattern -i \.wmv$ 1440 50% 2880 ignore-reload

refresh_pattern -i \.rm$ 1440 50% 2880 ignore-reload

refresh_pattern -i \.swf$ 1440 50% 2880 ignore-reload

refresh_pattern -i \.mpeg$ 1440 50% 2880 ignore-reload

refresh_pattern -i \.wma$ 1440 50% 2880 ignore-reload

resource age =对象进入cache的时间-对象的last_modified

response age =当前时间-对象进入cache的时间

LM-factor=(response age)/(resource age)

举个例子,这里只考虑percent, 不考虑min 和max

例如:refresh_pattern 20%

假设源服务器上www.aaa.com/index.htm -----lastmodified 是 2007-04-10 02:00:00

squid上 proxy.aaa.com/index.htm index.htm进入cache的时间 2007-04-10 03:00:00

1)如果当前时间 2007-04-10 03:00:00

resource age =3点-2点=60分钟

response age =0分钟

index.htm还可以在cache停留的时间(resource age)*20%=12分钟

也就是说,index.htm进入cache后,可以停留12分钟,才被重新确认。

2)如果当前时间 2007-04-10 03:05:00

resource age =3点-2点=60分钟

response age =5分钟

index.htm还可以在cache停留的时间(resource age)*20%=12分钟-5=7

LM-factor=5/60=8.3%<20%

一直到2007-04-10 03:12:00 LM-factor=12/60=20% 之后,cache中的页面index.htm终于stale。

如果这时没有index.htm的请求,index.htm会一直在缓存中,如果有index.htm请求,squid收到该请求后,由于已经过期, squid会向源服务器发一个index.htm是否有改变的请求,源服务器收到后,如果index.htm没有更新,squid就不用更新缓存,直接把缓存的内容放回给客户端,同时,重置对象进入cache的时间为与源服务器确认的时间,比如2007-04-10 03:13:00,如果正好在这个后重新确认了页面。重置后,resource age变长,相应在cache中存活的时间也变长。

如果有改变则把最新的index.htm返回给squid,squid收到会更新缓存,然后把新的index.htm返回给客户端,同时根据新页面中的Last_Modified和取页面的时间,重新计算resource age,进一步计算出存活时间。

实际上,一个页面进入cache后,他的存活时间就确定了,即 (resource age) * 百分比,一直到被重新确认。

测试一个防盗链:

quid的缓存批量更新问题,因代理上有很多的域名,部分客户的网站如图片等会经常更新,要求又比较紧急,所以写了个自动清除缓存的脚本,后来网上也搜查了个,感觉还是别人的写的比较好,这里我把自己写的跟别人写的都记录下,方便以后查看。

我个人写的clear_squidcache.sh
#!/bin/bash
#clear_squidcache.sh
FILE="/tmp/123.txt"      #这里的123.txt中是存放更新文件的完整url路径。
cat $FILE |while read line
do
/usr/local/squid/bin/squidclient -l 127.0.0.1 -p 80 -m PURGE $line >/dev/null 2>&1
done
rm -f /tmp/123.txt


在网上找到高手写的:
#!/bin/sh

squidcache_path1="/data/cache1"  # Squid 的缓存目录
squidcache_path2="/data/cache2"
squidclient_path="/usr/local/squid/bin/squidclient"  # squidclient 的路径

grep -a -r $1 $squidcache_path1/* | strings | grep "http:" | awk -F'http:' '{print "http:"$2;}' > /tmp/cache_list.txt
grep -a -r $1 $squidcache_path2/* | strings | grep "http:" | awk -F'http:' '{print "http:"$2;}' >> /tmp/cache_list.txt

cat cache_list.txt |while read url; do
$squidclient_path -l 127.0.0.1 -m PURGE -p 80 $url   # 80 端口根据你squid的http 设置自行修改
done
rm -f /tmp/cache_list.txt


这个是我稍微修改过的,功能相对我个人写的要强大多了,可以拿来借鉴学习。用法也比较简单,保存脚本为clear_squid_cache.sh,赋予执行权限。

执行清除域名缓存:./clear_squid_cache.sh www.baidu.com

清除后缀缓存:./clear_squid_cache.sh jpg

清除特定文件缓存:./clear_squid_cache.sh 123.jpg

后续再研究研究,看看是否有更好的办法,或者再对脚本进行优化优化。

本文出自 “我的运维之路” 博客,请务必保留此出处/article/4470864.html

从我的独立博客中同步过来的,一起探讨

将近快一个月没写文章了,太懒散了,今天振作了一下,写了篇关于Squid的文章,Squid作为分布式代理缓存服务器真的非常的棒,希望本文对你有帮助。

版权声明:非商业自由转载,保留原文内容完整性,并署名作者王国峰原文链接

前言

上一篇我表明了自己对缓存的立场:缓存一切可以缓存的资源。并讨论了如何利用IIS自身的缓存功能来轻松满足中小规模的图片缓存需求。关于IIS的客户端缓存和服务器端缓存的介绍大家可以回顾这篇文章。自从上一篇文章发表后,有不少朋友向我反馈:用IIS自身的缓存功能负载有限,建议使用Varnish或Squid。是的,我非常同意,所以我今天就和大家来探讨一下分布式代理缓存服务器Squid在图片存储架构中的应用,文中的一些观点,如有错误,敬请指出,谢谢。

Squid简介

Squid是一款高性能分布式代理缓存服务器,它一般用来做前置Web Cache,加快用户访问Web的速度。为了说明其运行过程,我将仍旧沿用我前一篇的YD风格,再一次请出人见人爱、花见花开、车见爆胎的空空老师,请读者自觉送出掌声:

Squid君是时下最受欢迎的空空作品代理人,为了让所有空空迷能更快捷地欣赏到高质量的空空作品,Squid君天天加班加点,整理和保存空空的最新作品,并对其作进一步的优化处理,比如去码。

有一天,我无聊至极,便打电话给Squid君,向他要最新的空空写真图(向Squid发出下载请求);

Squid君仔细辨别了一下我的声音,发现是老朋友,于是便答应了我的请求(Squid中的ACL访问控制,只接受合法的请求);

Squid君对我说他手头刚好有一周前的空空写真,问我看过没有,我说发过来看看呗,于是他很快发给了我(Squid缓存命中,下载极快,哦耶!);

我收到写真图,发现是两天前已经看过了的,于是告诉Squid君要最新的,Squid君看了看库存,发现手头没有最新的了,于是就说让我等一会儿,他去问问其他的代理兄弟有没有,我说好的,谢谢(Squid支持分布式集群方式,各个父子节点、兄弟节点之间的缓存数据可以互相同步);

结果空欢喜一场,他回来和我说其他兄弟也没有,当我非常失落的时候,他突然说空空今天来杭州,他可以直接向空空要写真,我一开心就对他说,快去快去(当Squid缓存不命中时,只能从源服务器获取数据);

过了好久,Squid君回来了,他说见空空的人实在太多了,排了好久的队才拿到她最新的写真图呢,我谢过之后他就把写真很快地发给了我。之后他说他一定要把这个写真保存起来,以便提供给其他空空迷和其他兄弟代理(Squid会把从源服务器获取的数据保存到自己的缓存中,如果下一个用户提出同样的下载请求,Squid直接把缓存中的数据给用户,当然也可以把数据奉送给其他兄弟代理,独乐乐不如众乐乐)。

到这里,我相信你已经大概明白Squid的工作过程了吧,下面我就对Squid特点做一下简要概括:

开源,基于GNU通用公共许可证,意味着你可以在同等开源协议下使用和修改Squid。

支持多种协议,目前支持http、ftp、gopher、wais、ssl等网络协议。

支持分布式集群,Squid使用TCP(HTTP)和UDP(ICP/HTCP)通讯来确定邻居cache的状态。

支持访问控制,通过设置ACL和ARL来限制某些访问。

Squid官方网站:http://www.squid-cache.org/

你可以在官网上下载Squid以及阅读相关文档,当然接下来我也会用Chinese向大家介绍Squid的用法。

Squid配置详细说明

下面是一份详细的Squid的配置清单及其说明:



#http_port指令告诉squid在哪个端口侦听HTTP请求。默认端口是3128,除下面的形式外,也可以是http_port 192.168.63.50:3128
http_port 3128
icp_port 3130

#缓存目录的设置,可以设置多个缓存目录,语法为:<cache_dir> <aufs|ufs> <目录所在> <MBytes大小> <dir1> <dir2>
cache_dir ufs /var/spool/squid 1000 64 1024

#下面是关于日志文件的放置目录与文件名!
cache_access_log /var/log/squid/access.log
cache_log /var/log/squid/cache.log
cache_store_log /var/log/squid/store.log
pid_filename /var/run/squid.pid

#关闭认证机制,有些版本的 squid 会自动的加入代理认证机制,而普通情况下是不需要的,故找到包括auth_param的行,给它们加上注释
#auth_param basic children 5
#auth_param basic realm Squid proxy-caching web server
#auth_param basic credentialsttl 2 hours

#设置squid用户及用户组、管理员账号
cache_effective_user squid
cache_effective_group squid
cache_mgr youraccount@your.e.mail

# 与内存有关的配置:因为我的系统内存很小,所以只给 8 MB!如果您的物理内存很大的情况下,例如 512 MB,可以考虑加大到 64 或 128 MB。
cache_mem 128 MB

# 与磁盘容量有关的配置(注:下列的 90 与 95 是百分比 ),如果您的 cache_dir 所在磁盘很大时,可以考虑将 4096 改成 32768 KB
cache_swap_low 90
cache_swap_high 95
maximum_object_size 4096 KB

# 与内存保存资料有关的配置
maximum_object_size_in_memory 8 KB

#定义acl(访问控制列表), 语法为:acl<acl> <acl名称> <acl类型> <配置的内容>
#黑体为用户自定义部分

acl All src 0/0
acl Manager proto cache_object
acl Localhost src 127.0.0.1/32
acl Safe_ports port 80 21 443 563 70 210 280 488 591 777 1025-65535
acl SSL_ports 443 563
acl CONNECT method CONNECT
acl MyNetwork src 192.168.0.0/16

#利用前面定义的acl,定义访问控制规则
http_access allow Manager Localhost
http_access deny Manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow MyNetwork
http_access deny All

#定义与其它代理服务器的关系,语法: <cache_peer> <主机名称> <类别> <http_port> <icp_port> <其它参数>
cache_peer 192.168.60.6 parent 4480 7 no-query default

#设置与其它代理服务器的关系:
# <cache_peer_access> <上层 Proxy > <allow|deny> <acl名称>
#cache_peer_access 192.168.60.6 allow aclxxx
#cache_peer_access 192.168.60.6 deny !aclxxx

coredump_dir /var/spool/squid





注意:以上的配置说明来自这里

配置好以后,我们就可以启动squid了,启动的步骤如下:

1). 我们可以运行下面的命令来检查配置文件的正确性:

# squid -k parse

只有这一步正确你才可以进行下一步的操作

2). 初始化cache目录.即建立缓存目录的存储格式

只需在第一次启动squid服务之前执行(在初次运行squid之前,或者无论何时你增加了新的cache_dir,你必须初始化cache目录。)

# squid -z

cache目录初始化可能花费一些时间,依赖于cache目录的大小和数量,以及磁盘驱动器的速度。假如你想观察这个过程,请使用-X选项:

# squid -zX

3). 启动squid服务

# service squid start

假定squid安装在/usr/local/squid目录下,也可以

# /usr/local/squid/sbin/squid -sD

最后,我推荐你去看看Squid权威指南,并希望你可以利用Squid成功搭建一个分布式图片缓存系统,Squid真的很棒!

为了你和你家人的健康,转载请注明原文出处:http://www.itivy.com/ivy/archive/2012/3/10/squid-usage.html

另外,我觉得你可能还会对下面架构相关的文章感兴趣:

优酷网架构学习笔记

百万级访问量网站的技术准备工作

Facebook图片存储架构的学习

facebook图片存储架构技术全解析

转自:http://iyubo.blogbus.com/logs/37254471.html

其实本人实在是更喜欢

Varnish



些,而线上用来跑css/js等静态文件cache的Varnish也确实运行的非常好,缓存的命中率也很高,性能也很好。但是因为是内存式的

Cache,Varnish在缓存图片时当达到一定量的时候会出现无法分配内存导致重启子进程缓存丢失的情况。所以当图片数量级较大且访问量较大时,还是

老老实实用Squid吧。

安装环境

操作系统: CentOS release 5.2 (Final)

Kernel: 2.6.18-92.el5PAE

软件列表

squid-2.6.STABLE22.tar.gz

软件存放位置

/data/software

安装过程

#/usr/sbin/groupadd squid -g 610

#/usr/sbin/useradd -u 610 -g squid squid

#mkdir /srv/scache

#chmod +w /var/vcache

#chown -R squid.squid /srv/scache

#mkdir /var/log/squid

#chmod +w /var/log/squid

#chown -R squid.squid /var/log/squid

#cd /data/software/pkg

#tar zxvf ../squid-2.6.STABLE22.tar.gz

#cd squid-2.6.STABLE22

#./configure --prefix=/usr/local/squid

#make && make install

编辑Squid配置文件

#vi /usr/local/squid/etc/squid.conf

-------------------------华丽的分割线,以下都是配置文件内容----------------------------

#定义acl项名称

acl all src 0.0.0.0/0.0.0.0

acl manager proto cache_object

acl localhost src 127.0.0.1/255.255.255.255

acl to_localhost dst 127.0.0.0/8

acl SSL_ports port 443

acl Safe_ports port 80

acl safeprotocol protocol HTTP

acl test dstdomain .test.com

acl CONNECT method CONNECT

#定义acl规则

http_access allow manager localhost

http_access deny manager

http_access deny !Safe_ports

http_access deny CONNECT !SSL_ports

http_access deny to_localhost

http_access allow safeprotocol Safe_ports test

http_access deny all

icp_access allow all

#squid监听端口

http_port 80 accel defaultsite=59.151.32.58 vhost

always_direct allow all

#后端服务器

cache_peer 10.10.10.8 parent 80 0 no-query originserver

hierarchy_stoplist cgi-bin ?

#内存cache大小

cache_mem 2048 MB

#内存cache中最大的object大小(超过这个值则不进入内存cache)

maximum_object_size_in_memory 8 KB

#内存cache的替换规则

memory_replacement_policy lru

#硬盘cache的替换规则

cache_replacement_policy lru

#磁盘cache目录(文件类型 cache目录路径 cache目录大小 二级目录个数 每个二级目录下的三级目录个数)

cache_dir ufs /srv/scache 40000 16 256

#磁盘cache中最小的object的大小(低于这个值则不缓存)

minimum_object_size 0 KB

#磁盘cache中最大的object的大小(超过这个值则不缓存)

maximum_object_size 2048 KB

cache_swap_low 90

cache_swap_high 95

#定义日志格式

logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %Hs %h" "%{User-Agent}>h" %Ss:%Sh

#记录相关日志

access_log /var/log/squid/access.log squid

cache_log /var/log/squid/cache.log

cache_store_log /var/log/squid/store.log

#日志rotate(24则后缀从.0到.23)

logfile_rotate 24

emulate_httpd_log on

#如果你的URL里面带有?,这两行一定要注销掉

#acl QUERY urlpath_regex cgi-bin \?

#cache deny QUERY

#配置自动更新(关于后面的三个值请参考Squid配置手册)

refresh_pattern -i \.jpg$ 60 80% 1440

refresh_pattern -i \.png$ 60 80% 1440

refresh_pattern -i \.gif$ 60 80% 1440

quick_abort_min 16 KB

quick_abort_max 16 KB

quick_abort_pct 95

request_header_max_size 10 KB

reply_header_max_size 10 KB

acl apache rep_header Server ^Apache

broken_vary_encoding allow apache

#相关timeout设置

forward_timeout 4 minutes

connect_timeout 3 minutes

peer_connect_timeout 30 seconds

read_timeout 15 minutes

request_timeout 1 minute

persistent_request_timeout 3 minutes

half_closed_clients off

pconn_timeout 1 minute

#cache管理员邮箱

cache_mgr webmaster@test.com

cache_effective_user squid

cache_effective_group squid

#squid服务器的visible_hostname,此处指定的值显示在Squid响应的Header里面的X-Cache项中

visible_hostname squidserver

coredump_dir /var/log/squid/cache

------------------------华丽的分割线,以上都是配置文件内容-----------------------------

初始化squid缓存目录

#/usr/local/squid/sbin/squid -z

启动squid

#/usr/local/squid/sbin/squid -sD

配置完成以后,最重要最重要的一点,修改Squid服务器的hosts文件,将需要Cache的域名指向到后端的服务器IP上

相关命令

停止squid

/usr/local/squid/sbin/squid -k shutdown

启用新配置

/usr/local/squid/sbin/squid -k reconfig

通过crontab每小时截断/轮循日志

59 * * * * /usr/local/squid/sbin/squid -k rotate

查看squid运行状况

/usr/local/squid/bin/squidclient -p 80 mgr:info

/usr/local/squid/bin/squidclient -p 80 mgr:5min

查看squid内存使用情况

/usr/local/squid/bin/squidclient -p 80 mgr:mem

查看squid磁盘使用情况

/usr/local/squid/bin/squidclient -p 80 mgr:diskd

查看squid已缓存列表(小心使用,可能会导致crash)

/usr/local/squid/bin/squidclient -p 80 mgrbjects

强制更新某个url

/usr/local/squid/bin/squidclient -p 80 -m PURGE http://img.test.com/h/a.jpg
查看squid缓存到内存cache中并返回给访问用户的项

#cat /var/log/squid/access.log | grep TCP_MEM_HIT

查看squid缓存到磁盘cache中并返回给访问用户的项

#cat /usr/local/squid/var/logs/access.log | grep TCP_HIT

查看没被squid缓存住,直接从原始服务器获取并返回给访问用户的项

#cat /usr/local/squid/var/logs/access.log | grep TCP_MISS

关于 TCP_XXXX 等参数及代表的信息,请参考《squid中文权威指南》13.2.1 章节。

更多参数

/usr/local/squid/bin/squidclient -h

/usr/local/squid/bin/squidclient -p 80 mgr:menu


学习CDN不得不读之-Squid
高级优化指南

由 Neters.CN 发表于 10:58 下午

首先要明确一下,squid 能够用来作什么。很多人没有搞明白 squid 的工作原理,只是听说 squid 性能不错可以用来给网站提速,就直接在自己的 website 前面套了一个 squid ,这基本没有任何用处,即使你都是静态页面,后面apache上面没有开 mod_expires,一样缓存不了,squid只能起到一个连接管理的用处。

一般说来,网站用 squid 加速,目的有二种

1: squid 本身具有缓存功能,可以将webserver输出的内容缓存起来,在缓存没有过期之前来的访问,都直接用缓存里面的内容,这样可以有效减少 webserver 机器上面的请求数量。这是 squid 的主要功用。

2: 网络慢的用户会长时间占用 webserver 的 TCP 连接,webserver 对每个连接占用的资源比较大,如果长时间不能释放出来服务其他请求,性能会有比较大的影响。前面放一个 squid, webserver 就可以迅速处理完逻辑以后,把数据快速发送给 squid, 然后去处理别的逻辑,而 squid 每个 TCP 连接占用的资源很少,不用担心占用太多资源。这个用途也叫做连接管理,有一些网络设备也可以做这个事情,价格都很贵。

下面针对 squid 的两种功用,来讲述如何调整业务逻辑和 squid 参数

预操作

在搞 squid 之前,不管你用什么编译配置,需要什么特殊选项,都请 –enable-snmp ,并配置好 mrtg 之类,可以图形化的显示 squid 状态,例如 Request Hit Ratio(RHR), Byte Hit Ratio(BHR), 等等,反馈是做一切事情的基础,优化也不例外。

缓存

A: 使用 Expires header 来控制缓存

squid在缓存webserver内容的时候,需要后端webserver输出一些控制信息告诉他页面是不是可以被缓存,以及可以缓存多久。否则 squid 是不会自作主张给你缓存内容的。一个页面到底能不能缓存,只有开发网站的人才知道,因此开发人员有责任在动态页面里面输出 Expires 和 Cache-Control header。简单举一个 php 的例子以说明这两个 header 的值是什么含义,其中$expiretime 的单位是秒。

header(”Expires: ” . gmt_date_format(time()+$expiretime));

header(”Cache-Control: max-age=” . “$expiretime”);

对于静态文件,有两种方式来让 squid 自动给静态文件缓存,一种是使用 apache 的 mod_expires ,可以针对路径或者针对文件类型/扩展名来自动输出 cache 头。详细的请参考 mod_expires 的说明 。另一种是用 squid 的 refresh_pattern 来指定。详细的还是请参考 squid 的配置文件。一般来说,如果后端不是配置很麻烦,建议还是在后端做,前端的配置修改大多数都是违背http协议的,如果出现问题,也比较难排查。

B 根据 squid 访问的模式,进行业务拆分

进行了 Expires Header 的处理以后,squid 就真正可以起到加速的作用了,你可能也能感觉到,网站的访问速度明显加快。但是不要满足于这点成绩,查看 squid 的 snmp 统计图,通常 hit ratio 并不会太高,有 50% 就了不起了。这就是我们需要进一步优化的,我们的目标是让大部分 squid 都达到 9X% 的命中率。

为什么 squid 命中这么低呢,这大概有两种原因。大多数的网站都是有一些页面不能够被缓存的,例如登录页面。这些页面请求也从 squid 走,成为分母的一部分,直接就降低了命中率,我们首先可以做的事情是,把这些不能够缓存的页面请求,拆分到单独一个 squid 上面,或者访问量不大的话,干脆把 apache 暴露出来。这样能够缓存的那个 squid 命中率马上上升一截。

有人可能会说,把不能缓存的页面分拆开去,就光为了让能缓存的那个数字好看,这不是掩耳盗铃么?其实这么做是有意义的,首先就是去掉了不能缓存页面 的干 扰,使得我们进一步优化 squid 的依据更加准确。其次是不可缓存请求和可缓存请求之间的重要性通常是有差距的,分拆了以后,它们之间不容易互相抢占资源,不会因为下载图片的连接太多把 squid 占满,影响更重要的登录请求。第三就是可缓存内容通常是图片等页面元素, 浏览器在 load 它们的时候,对每个站点的并发连接会有控制,如果分开成不同的IP,可以多一些请求同时执行。提高少许显示速度。

其实观察 sohu, sina 之类的页面,你会发现它们的页面也是分拆的,可以看到页面里面的图片都是指向 images.sohu.com 之类的地址,虽然它们可能和其他页面一样后台都指向同一个 apache。

这样做完,缓存命中率大概能上升到 70%-80% 了,运气好的时候完全可以上 90%。

另一种导致 squid 命中低的原因和这个比较类似,同样都是可缓存的内容,有的可能是软件下载站上面的大文件,有的是新闻站点上面的小图片,如果同一个 squid 对这样差别巨大的文件加速的话,会严重干扰 squid 的缓存策略,两者不能兼顾,要不就是大文件占据了 cache ,把小文件都挤出了 cache, 要不就是小文件特别多,大文件无法进入 cache, 导致大文件经常 miss 。这个比不能缓存的页面还要恶心,因此即使在服务器资源有限的情况下,也要优先拆分这两类型访问。一般来说,文件大小分界线定在 1M
左右就可以了,如果是有软件下载这样特别大的文件,可以在 4M – 10M 左右再拆分一次。对于不同访问类型的 squid, 其系统优化参数也会有所不同,这个我们后面还会讲到。

只要悉心按照访问模式来拆分业务,大部分起缓存作用的 squid 都可以达到很高的命中率,至少都可以到达 9X%。

C 根据不同的需求,调整参数优化缓存

完成 A 和 B 两步优化以后, squid 的命中率经常可以达到 9x%, 可以说我们已经给 squid 创造了非常优秀的外部环境,下面我们就要从 squid 本身入手,通过调整它的缓存参数和缓存策略,甚至系统的参数,来让 squid 发挥出更好的性能。

在 B 步骤中,我们把 squid 划分成了三种用途,缓存大文件,缓存小文件,不缓存文件,这其中最后一种用途情况下面 squid 不起到缓存效果,只用来做连接管理,因此我们把它放到后面的连接管理里面叙述,这里只讨论和缓存相关的 squid 参数。

squid 有内存缓存和磁盘缓存两级缓存, 通常来说, 只要是专门给 squid 用的机器, 内存缓存都建议开得比较大, 大内存缓存总是有好处的嘛, 但是注意不要使得系统开始吃 swap ,像Linux这样一开始吃 swap 性能就下降比较严重的系统尤其要注意. 这个程度需要自己试验确定.

通常 1G 内存的Linux机器用来跑 squid ,内存缓存可以开到 512M.

有些libc比较差的平台, 例如比较老的 freebsd 系统, 其 malloc 函数的质量不高,可能会造成比较多的内存碎片,导致 squid 运行一段时间以后分配不出来内存挂掉. 这时候推荐在编译时候使用 dlmalloc package. 即使如此, 仍然要再缩小 squid 的内存缓存,以防不幸发生.

磁盘缓存的情况比较复杂, squid 有 ufs, aufs, coss, diskd, null 五种存储后端, 其中 ufs, aufs, diskd 都是在文件系统上面保存很多小文件, coss 是 squid 自己实现了一个简单的文件系统,可以使用一个大文件或者一个磁盘设备来存储. null 则是给不想要磁盘缓存的情况准备的. coss 看起来好像比较拽, 但是以前试验并不足够稳定,因此并不推荐使用. 剩下的三种存储方式,具体选择哪种需要根据操作系统的特性来进行.

ufs 是最传统的存储方式, 我们知道, squid 是一个单进程的程序, 它使用 ufs 存储后端时, 直接在进程里面读写文件. 这是一种很简单的方式, 缺点是当读写磁盘被阻塞的时候, squid 不能够处理请求, 会造成服务质量波动比较大. 因此出现了 aufs 和 diskd 两种存储后端, 原理都是 squid 主服务循环不负责读写文件, 而是通过消息队列或者tcp/pipe连接将数据传送给其他的线程(aufs)/进程(diskd), 然后其他线程/进程进行读写. 很显然,这两种存储方式有一定的通信开销,
因此不一定就比 ufs 好, 需要具体问题具体分析

前面说到, ufs/aufs/diskd都是在文件系统上面存储很多小文件,因此文件系统本身的特性严重影响了squid缓存的性能,对于 Linux ,强烈推荐用 reiserfs 等适合处理小文件的文件系统, bsd 则至少要打开 softupdate, 以及 dirhash 等一切对很多小文件有好处的选项. 在比较新的系统上面, reiserfs 等文件系统的性能已经足够优越, 通常 ufs 就已经可以应付需要. 对于一些老系统,使用 aufs 或者 diskd 是比较好的选择,如果系统的线程库比较好(如Linux,Solaris),那么使用
aufs, 否则 diskd.

也有一些例外情况, 比如多 cpu 的 Linux 2.6 系统, 线程库很优秀, 虽然 ufs 本身已经比较快了,但是 squid 单进程无法利用另外的 cpu , 不如使用 aufs , 让另外的 cpu 也可以起到一些作用, aufs 在编译的时候可以选择使用几个读写线程. 这个个人觉得稍微超过 cpu 个数就可以了.但是并没有实际测试过.

磁盘缓存开多大? 这个问题没有固定答案. 需要经过试验来确定, 一般来说开大一些没有太大问题. 只要你的硬盘足够
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: