目录
一、知识回顾
正向代理和反向代理在我前面的博客《Nginx实现反向代理》中有提到,有兴趣的朋友可以去看看。
1.1 正向代理
举个例子:客户端(Client)想访问某个后端服务器,但无法正常访问,这时就需要找到一个可以访问该后端服务器的代理服务器,然后将我们的请求发送给代理服务器,代理服务器再去访问后端服务器,最后将请求的结果返回给客户端。实际上这就是属于正向代理,代理的过程隐藏了真实的请求客户端,即后端服务器不知道真实的客户端是谁,因为客户端请求的服务都被代理服务器代替请求了。代理的对象是客户端(Client),而且请求的客户端(Client)和代理服务器(Proxy)处于同一个LAN内。如下图所示:
1.2 反向代理
举个例子:当我们访问某购物网站时,尤其是在某些特殊节日期间,单个服务器会处于一个供不应求的状态。这时需要我们对服务器进行分布式部署,即通过部署多台服务器来解决高访问量人数限制的问题。实际上大多数的购物平台都是通过Nginx进行的反向代理而实现的分布式部署。与正向代理相反,反向代理的过程隐藏了提供服务的真实服务器,即客户端不知道是那一台服务器提供的服务,客户端请求的服务都被代理服务器处理。反向代理的是响应方(即server服务端),而且代理服务器(Proxy)和提供真实服务的服务端(server)处于同一个LAN内。如下图所示:
常用的正向代理服务有:
squid,varnish(几乎绝迹),nginx,ats。
二、Web缓存
2.1 cache命中
cache命中是在cache server 每次从它的缓存里满足客户端HTTP请求时发生。cache命中率,是所有客户端HTTP请求中命中的比例。Web缓存典型的cache命中率在30%到60%之间。另一个相似的度量单位叫做字节命中率,描绘了cache提供服务的数据容量(字节数),如何提升cache命中率?
- apache nginx 可以expries(可设置客户端缓存时间),cache-control缓存头;
- 动静分离,静态化,对静态走CDN;
- mysql cache让缓存靠前;
- 4XX、5XX之类错误页面以及死链不缓存。
2.2 cache丢失
cache丢失在cache server不能从它的缓存里满足客户端HTTP请求时发生。cache丢失的原因有很多种:
(1)当cache server第一次接收到对第一个新资源的请求时,就会产生一个cache丢失。如何解决第一次命中?
-
预热或者预取;
-
内部先请求访问。可以通过脚本实现(这是个思路但不靠谱);
-
后端生成数据之后,统一推到前端cache server。即预取,预热。
(2)存储空间满或者对象自身过期,cache server会清除这些缓存对象以释放空间给新对象。
- 加大内存或者磁盘;
- 过期时间设置的长一些;
- 参数设置,缓存的参数设置大一些。最大缓存对象2M(热点缓存);
- 分资源缓存,1M,10M,100M(分拆服务器,acl 正则匹配抛给不同的pools)
(3)还有可能是客户访问的资源不可到达。
2.3 cache确认
- 对于缓存来讲,数据的一致性是一个特别头疼的问题,特别是memcached。
- cache确认保证cache server不对访问的用户返回过期的数据。在重复使用缓存对象时,cache server需要经常从原始服务器确认它。假如服务器指示squid的拷贝仍然有效,数据就发送出去。否则,squid更新它的缓存拷贝,并且转发给客户。
- 当用户更新了数据到数据库或者存储服务器的时候,可以从业务角度主动调用接口清除该对象缓存的指令。CDN 5-15分钟。
- 图片放到CDN了需要更新吗?不需要更新。图片修改算更新,这样的业务就要推送。
- 网站改版:再CDN上推送JS,css(改名)
三、Squid代理服务器部署
主机 | 功能 |
---|---|
192.168.137.128(10.20.151.143) | 正向代理服务器 |
192.168.137.129 | Linux客户端 |
说明:192.168.137.128(10.20.151.143)
主机在实验中设置了两块网卡,用来模拟我们的代理服务器,192.168.137.129
主机用来模拟我们客户端(这里该主机不能上网),因此我们的目的就是让我们的代理服务器作为代理,使我们的Linux客户端能实现上网的功能。
3.1 配置Squid代理端
1、安装squid
[root@web ~]# yum install -y squid
2、编辑squid配置文件
-
修改如下:
[root@web ~]# vim /etc/squid/squid.conf acl local src 10.20.151.0/24 # 允许10.20.151.0/24网段内所有客户机访问代理服务器 http_access allow localnet # 该记录一定要添在deny all之前 http_port 3128 # squid端口号(默认不改)
-
配置文件名词解释:
acl # 控制类型 src # 源地址 dst # 目标地址 port # 目标地址 dstdomain # 目标域 time # 访问时间 maxconn # 最大并发连接 url_regex # 目标URL地址:可以定义大的范围比如http://www.baidu.com urlpath_regex # 整个目标URL路径:可以定位到每个网站的具体目标的url,比如百度音乐的一首歌的url
3、启动squid服务
[root@web ~]# systemctl start squid
[root@web ~]# systemctl enable squid
3.2 配置linux客户端
1、开启路由转发
[root@database ~]# echo 1 > /proc/sys/net/ipv4/ip_forward # 临时开启
2、linux客户端配置正向代理
[root@database ~]# export http_proxy=http://192.168.137.128:3128
[root@database ~]# export https_proxy=http://192.168.137.128:3128
或:
[root@database ~]# echo "export http_proxy=http://192.168.0.109:3128" >>/etc/profile
[root@database ~]# echo "export https_proxy=http://192.168.0.109:3128" >>/etc/profile
3、测试http
[root@database ~]# curl www.baidu.com
[root@database ~]# wget http://www.baidu.com/index.php
[root@database ~]# ls
index.php
四、Squid拒绝访问
4.1 修改Squid配置文件
4.2 Linux客户端测试
[root@database ~]# curl www.baidu.com
下图返回了一个错误页面,说明客户端的请求被squid服务器拒绝了。
如果请求的是其他网站,则返回正确结果,如下所示:
[root@database ~]# curl www.xiaomi.com
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr/>Powered by MiWeb</body>
</html>
五、设置黑名单
[root@database ~]# vim /etc/squid/ip.list
182.37.29.100
182.22.40.0/24
[root@database ~]# vim /etc/squid/domain.list
.baidu.com
[root@database ~]# vim /etc/squid.conf # 修改配置文件
acl IP dst "/etc/squid/ip.list"
acl DOMAIN dstdomain "/etc/squid/domain.list"
http_access deny IP
http_access deny DOMAIN
[root@database ~]# systemctl restart squid # 重启服务
六、缓存配置
cache_mem 2048 MB
maximum_object_size 20 MB
maximum_object_size_in_memory 8 MB
cache_dir ufs /squid_cache 100000 128 512
cache_peer 1.1.1.1 parent 80 0 no-query originserver
cache_peer_domain 1.1.1.1 image.baidu.com
七、工作时间上网
[root@database ~]# vim /etc/squid.conf
acl all src 0.0.0.0/0.0.0.0
acl ipaddr src 10.20.151.0/24 10.20.160.0/24
acl worktime time MTWHF 08:30-17:30
http_access allow ipaddr worktime
http_access deny all
[root@database ~]# systemctl restart squid
注意:要先写http_access allow ipaddr worktime再写http_access deny all,因为先执行前面的,后面的就不执行了。