分享

反向代理

 敬而远 2011-12-03

目录:

1:什么是反向代理

2:prixy_cache用于架构中的优势

3:常用的反向代理有哪些?

4:反向代理的设置

 

1:什么是反向代理-----------------------------------------------

反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。 

    通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务 器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。由于外部网络上的主机并不会配置并使用这个代理服务器,普通代理服务器也被设 计为在Internet上搜寻多个不确定的服务器,而不是针对Internet上多个客户机的请求访问某一个固定的服务器,因此普通的Web代理服务器不 支持外部对内部网络的访问请求。当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。此时代理服务器对外就 表现为一个Web服务器,外部网络就可以简单把它当作一个标准的Web服务器而不需要特定的配置。不同之处在于,这个服务器没有保存任何网页的真实数据, 所有的静态网页或者CGI程序,都保存在内部的Web服务器上。因此对反向代理服务器的攻击并不会使得网页信息遭到破坏,这样就增强了Web服务器的安全 性。   反向代理方式和包过滤方式或普通代理方式并无冲突,因此可以在防火墙设备中同时使用这两种方式,其中反向代理用于外部网络访问内部网络时使用,正向代 理或包过滤方式用于拒绝其他外部访问方式并提供内部网络对外部网络的访问能力。因此可以结合这些方式提供最佳的安全访问方式。

2:反向代理用于架构中的优势-----------------------------------

   大家可以如上面图片所见,反向代理实际上就是一台服务器,充当后端真正服务的主机,提供服务。工作流程如下(参照图片): A,B,C三台用户的主机,分别访问 www.mycompany.com 的网页,按照一般传统和很正常的流程肯定是host-A http请求------->www.mycompany.com WEB server ,接着webserver回应请求,从网页根目录下或者数据库中提取数据(html,jpg,css,js),返回到host-A。同理,B,C的一次访 问网页流程也是一样。但是毕竟多强大的服务器总有瓶颈,当用户的访问量到达一定程度时,服务器总会有撑不住的时候,这个时候负载均衡就是一种比较好的办 法。

(细节:服务器性能限制产生原因:提供服务程序的软件先天设计,网络带宽,磁盘I/O,CPU或内存使用率,系统的设计)

还是参照上图,把图倒转来看就是传统的负载均衡。把webserver看作 client,把A,B,C看作是web server,而proxy_cache就是负载均衡器。这里又会衍生一个问题,多台web server时,就会产生数据不同步问题。这里简单说明一下,假设某用户访问网站,刚好这时调度到A-web server上,它上传了照片或者更新了日志。当她隔了一天再次访问此网站时,调度到了B-web server上,这个时候,由于她在A上上传的图片,所以,在B-server上就会发现上传的东西不见了,这样就会产生问题。这个时 候,proxy+cache就是显示实力的时候。继续参照上述图片

流程:当A,B,C三台client访问www.mycompany.com WEB server时,首先请求是先到proxy_cache的,proxy_cache接到请求时,首先检查本地是否有cache记录,有的话就直接从本地返 回送给用户,当没有记录时,转向后端真正提供服务的web-server提取,当数据返回给用户时,cache也会把数据copy一份下来。这样,当后端 有多台web-server,管理员每次更新的时候都是更新其中一台,用户也不会发生遇到数据不同步现象,因为,proxy_cache会有机制去确保多 台后端主机的响应是正确的,当从其中获取到用户需要的数据时,会保存在本地,所以,当不同用户需要这个数据时都能获取得到。而后台的数据同步,不需要每时 每刻,只有在某个低负载时间时,执行一下即可,因为proxy_cache里面已经能有确保用户都能访问的正常数据。

(细节-1:这里暂时忽略动态文件,jsp,asp,php,net等的讨论,把资源看作是静态资源)

   用proxy_cache时,还有另外的一个好处,当访问量大时,proxy_cache可以分担一部分请求,不需要后端web-server直接回应。 在全局cache的同时,还可以看作是负载均衡中的一部分,后端的web不需要处理大量的请求,从而导致性能问题。所以在架构上,后端的web- server可以看作是无限制性的无限扩展,而proxy_cache层也可以是无限的扩展,行成2层架构,实际上proxy层还可以利用不同软件的优势 配置成3层甚至4层架构,具有很大的灵活性和扩展性。所以一般国内的大型SNS网站如豆瓣或者新浪网,开心网等都是采用了这种形式的多层架构。

参考:http://axislover.blog.163.com/blog/static/10776515200821911137520/

 

3:常用的反向代理有哪些?----------------------------------------------------

一般较为常用的反向代理有:apache,lighttpd,nginx,以及squid

apache 的mod_proxy 基于设计问题,在性能上表现很一般,一般是很少人会使用

squid是专门的proxy软件,其在正向代理的领域表现比较强劲,在反向代理方面也有不错的表现,国内用有不少大型网站使用其作为web-server的前端

lighttpd和nginx:轻量级的web-server和proxy,其轻量 级的特性,对系统资源的要求非常的小,并且能承担的并数远远在如iis,apache等web的巨无霸,一般用在最前端去充当第一层的请求是非常好用的, 架构中使用这2个轻量级别的proxy数量在急剧上升。

 

4:反向代理的设置------------------------------------------------------------

apache不作讨论,因为其性能实在不敢苟同

squid:

lighttpd:http://troyhector./logs/70058093.html 

nginx:


反向代理各种方式区别

 

 

 

反向代理从传输上分可以分为2种:

 

 

 

 

 

小结:apache和squid的反向会增加后端web的负担,因为每个用户请求都会在proxy上与后端server建立的长久链 接,知道数据取完前,连接都不会消失。因为wan速度与lan速度的不同,虽然lan之间的速度是极度快的,但是用户的wan连接决定了这个时间长。而 lighttpd和nginx的异步模式,是不管你用户要求的数据有多大,都是先收下来,再与后端联系,这是非常迅速的速度,所以proxy与后端连接时 间也会很短,几十M的东西也是几秒内。后端不需要维护这么多连接。而lighttpd也和nginx不同的异步,lighttpd是先收完再转向客户浏览 器,而nginx是边收数据边转向用户浏览器。

那么这到底有什么好处呢?

1. 假设用户执行一个上传文件操作,因为用户网速又比较慢,因此需要花半个小时才能把文件传到服务器。squid的同步代理在用户开始上传后就和后台建立了连 接,半小时后文件上传结束,由此可见,后台服务器连接保持了半个小时;而nginx异步代理就是先将此文件收到nginx上,因此仅仅是nginx和用户 保持了半小时连接,后台服务器在这半小时内没有为这个请求开启连接,半小时后用户上传结束,nginx才将上传内容发到后台,nginx和后台之间的带宽 是很充裕的,所以只花了一秒钟就将请求发送到了后台,由此可见,后台服务器连接保持了一秒。同步传输花了后台服务器半个小时,异步传输只花一秒,可见优化 程度很大。

2. 在上面这个例子中,假如后台服务器因为种种原因重启了,上传文件就自然中断了,这对用户来说是非常恼火的一件事情,想必各位也有上传文件传到一半被中断的 经历。用nginx代理之后,后台服务器的重启对用户上传的影响减少到了极点,而nginx是非常稳定的并不需要常去重启它,即使需要重启,利用kill -HUP就可以做到不间断重启nginx。

3. 异步传输可以令负载均衡器更有保障,为什么这么说呢?在其它的均衡器(lvs/haproxy/apache等)里,每个请求都是只有一次机会的,假如用 户发起一个请求,结果该请求分到的后台服务器刚好挂掉了,那么这个请求就失败了;而nginx因为是异步的,所以这个请求可以重新发往下一个后台,下一个 后台返回了正常的数据,于是这个请求就能成功了。还是用用户上传文件这个例子,假如不但用了nginx代理,而且用了负载均衡,nginx把上传文件发往 其中一台后台,但这台服务器突然重启了,nginx收到错误后,会将这个上传文件发到另一台后台,于是用户就不用再花半小时上传一遍。

4. 假如用户上传一个10GB大小的文件,而后台服务器没有考虑到这个情况,那么后台服务器岂不要崩溃了。用nginx就可以把这些东西都拦在nginx上, 通过nginx的上传文件大小限制功能来限制,另外nginx性能非常有保障,就放心的让互联网上那些另类的用户和nginx对抗去吧。

用异步传输会造成问题:

后台服务器有提供上传进度的功能的话,用了nginx代理就无法取得进度,这个需要使用nginx的一个第三方模块来实现。

1:同步模式(apache-mod_proxy和squid)2:异步模式(lighttpd 和 nginx)在nginx的文档说明中,提到了异步传输模式并提到它可以减少后端连接数和压力,这是为何?下面就来讲解下传统的代理(apache/squid)的同步传输和lighttpd,nginx的异步传输的差异。看图:同步传输:浏览器发起请求,而后请求会立刻被转到后台,于是在浏览器和后台之间就建立了一个通道。在请求发起直到请求完成,这条通道都是一直存在的。
异 步传输:浏览器发起请求,请求不会立刻转到后台,而是将请求数据(header)先收到nginx上,然后nginx再把这个请求发到后端,后端处理完之 后把数据返回到nginx上,nginx将数据流发到浏览器,这点和lighttpd有点不同,lighttpd是将后端数据完全接收后才发送到浏览器。

 

 

 

 

  ngin只有硬盘级别cache,没有内置内存级别的cache,如果想利用内存加速,只能将/dev/shm挂载到文件系统,再将这个目录作为cache的目录。

  nginx一般做cache有以下5种办法:

1:这个办法是把nginx的404错误定向到后端,然后用proxy_store把后端返回的页面保存。

2:也是利用 proxy_store,这里利用if判断cache目录是否有文件,没有的话从后端取,取回来后发送给用户并且自身用proxy_store保存起 来                                                                                                            # 这2种办法其实原理都差不多,只是方法不同,都是使用proxy_sore把数据保存起来,这种办法在准确定义上不能算是cache,只能算是镜像 -mirror功能,因为其没有内建机制定时删除cache,等于是永远的静态保存,所以这方案适合基本不会变化的数据,更详细的说明请看下面详细介绍这 2种cache的做法和介绍

3:基于memcached的缓存

4:新版本nginx支持真正的proxy_cache模块。                                                                 #proxy_cache从nginx-0.7.44版开始,nginx支持了类似squid较为正规的cache功能,这个缓存是把链接用md5编码hash后保存。

5:第三方插 件。                                                                                                                           #新浪兄弟开发的一个插件,支持nginx  cache,但功能还有很多地方有待完善

 

几种不同cache的做法

传统缓存之一(404)

这个办法是把nginx的404错误定向到后端,然后用proxy_store把后端返回的页面保存。

配置:

location / {
root /home/html/;#主目录
expires 1d;#网页的过期时间
error_page 404 =200 /fetch$request_uri;#404定向到/fetch目录下
}

location /fetch/ {#404定向到这里
internal;#指明这个目录不能在外部直接访问到
expires 1d;#网页的过期时间
alias /home/html/;#虚拟目录文件系统地址要和locaion /一致,proxy_store会将文件保存到这目录下
proxy_pass http://www./;#后端upstream地址,/fetch同时是一个代理
proxy_set_header Accept-Encoding ”;#让后端不要返回压缩(gzip或deflate)的内容,保存压缩后的内容会引发乱子。
proxy_store on;#指定nginx将代理返回的文件保存
proxy_temp_path /home/tmp;#临时目录,这个目录要和/home/html在同一个硬盘分区内
}

使 用的时候还有要注意是nginx要有权限往/home/tmp和/home/html下有写入文件的权限,在linux下nginx一般会配置成 nobody用户运行,这样这两个目录就要chown nobody,设成nobody用户专用,当然也可以chmod 777,不过所有有经验的系统管理员都会建议不要随便使用777。

2、传统缓存之二(!-e)

原理和404跳转基本一致,但更简洁一些:

location / {
root /home/html/;
proxy_store on;
proxy_set_header Accept-Encoding ”;
proxy_temp_path /home/tmp;
if ( !-f $request_filename )
{
proxy_pass http://www./;
}
}

可以看到这个配置比404节约了不少代码,它是用!-f来判断请求的文件在文件系统上存不存在,不存在就proxy_pass到后端,返回同样是用proxy_store保存。

两种传统缓存都有着基本一样的优点和缺点:
缺点1:不支持带参数的动态链接,比如read.php?id=1,因为nginx只保存文件 名,所以这个链接只在文件系统下保存为read.php,这样用户访问read.php?id=2时会返回不正确的结果。同时不支持http://www./这种形式的首页和二级目录http://www./download/,因为 nginx非常老实,会将这样的请求照链接写入文件系统,而这个链接显然是一个目录,所以保存失败。这些情况都需要写rewrite才能正确保存。
缺点2:nginx内部没有缓存过期和清理的任何机制,这些缓存的文件会永久性地保存在机器上,如果要缓存的东西非常多,那就会撑暴整个硬盘空间。为此可以使用一个shell脚本定期清理,同时可以撰写php等动态程序来做实时更新。
缺点3:只能缓存200状态码,因此后端返回301/302/404等状态码都不会缓存,假如恰好有一个访问量很大的伪静态链接被删除,那就会不停穿透导致后端承载不小压力。
缺点4:nginx不会自动选择内存或硬盘作为存储介质,一切由配置决定,当然在当前的操作系统里都会有操作系统级的文件缓存机制,所以存在硬盘上也不需要过分担心大并发读取造成的io性能问题。

nginx传统缓存的缺点也是它和squid等缓存软件的不同之特色,所以也可看作其优点。在生产应用中它常常用作和squid的搭档,squid 对于带?的链接往往无法阻挡,而nginx能将其访问拦住,例如:http:///?和http:///在 squid上会被当做两个链接,所以会造成两次穿透;而nginx只会保存一次,无论链接变成http:///?1还是http: //marry5.com/?123,均不能透过nginx缓存,从而有效地保护了后端主机。

nginx会非常老实地将链接形式保存到文件系统中,这样对于一个链接,可以很方便地查阅它在缓存机器上的缓存状态和内容,也可以很方便地和别的文件管理器如rsync等配合使用,它完完全全就是一个文件系统结构。

这 两种传统缓存都可以在linux下将文件保存到/dev/shm里,一般我也是这么做的,这样可以利用系统内存来做缓存,利用内存的话,清理过期 内容速度就会快得多。使用/dev/shm/时除了要把tmp目录也指向到/dev/shm这个分区外,如果有大量小文件和目录,还要修改一下这个内存分 区的inode数量和最大容量:

mount -o size=2500M -o nr_inodes=480000 -o noatime,nodiratime -o remount /dev/shm

上 面的命令在一台有3G内存的机器上使用,因为/dev/shm默认最大内存是系统内存的一半就是1500M,这条命令将其调大成2500M,同时 shm系统inode数量默认情况下可能是不够用的,但有趣的是它可以随意调节,这里调节为480000保守了点,但也基本够用了。但是这种方式的cache,当网站结构很复杂时,生成N多的cache小文件,if的判断是否会造成比较大的资源损耗和效率较低?这个问题值得思考,但没做过测试不能有实际数据去说明,只是从理论上来说,if必然会导致磁盘的io搜索,会有性能损耗和时间损耗。

3、基于memcached的缓存

nginx对memcached有所支持,但是功能并不是特别之强,性能上还是非常之优秀。

location /mem/ {
if ( $uri ~ “^/mem/([0-9A-Za-z_]*)$” )
{
set $memcached_key “$1″;
memcached_pass     192.168.1.2:11211;
}
expires 70;
}

这个配置会将http:///mem/abc指明到memcached的abc这个key去取数据。

nginx目前没有写入memcached的任何机制,所以要往memcached里写入数据得用后台的动态语言完成,可以利用404定向到后端去写入数据。

4、基于第三方插件ncache

ncache是新浪兄弟开发的一个不错的项目,它利用nginx和memcached实现了一部分类似squid缓存的功能,我并没有使用这个插件的经验,可以参考:

http://code.google.com/p/ncache/

5、nginx新开发的proxy_cache功能

从nginx-0.7.44版开始,nginx支持了类似squid较为正规的cache功能,目前还处于开发阶段,支持相当有限,这个缓存是把链接用md5编码hash后保存,所以它可以支持任意链接,同时也支持404/301/302这样的非200状态。

配置:

首先配置一个cache空间:

proxy_cache_path /pathforcache levels=1:2 keys_zone=NAME:10m inactive=5m max_size=2m clean_time=1m; #定义cache目录,这一句话务必记得,放在http{}中而不是放到server{}里面

 

接着再配置一个proxy缓存目录

proxy_temp_path /pathfortmp;  

注 意这个配置是在server标签外,levels指定该缓存空间有两层hash目录,第一层目录是1个字母,第二层为2个字母,保存的文件名就会 类似/path/to/cache/c/29/b7f54b2df7773722d382f4809d65029c;keys_zone为这个空间起个名 字,10m指空间大小为10MB;inactive的5m指缓存默认时长5分钟;max_size的2m是指单个文件超过2m的就不缓 存;clean_time指定一分钟清理一次缓存。

location / {
proxy_pass http://www./;

proxy_cache NAME;#使用NAME这个keys_zone

proxy_cache_valid 200 302 1h;#200和302状态码保存1小时
proxy_cache_valid 301 1d;#301状态码保存一天
proxy_cache_valid any 1m;#其它的保存一分钟
}

ps: 支持cache的0.7.44到0.7.51这几个版本的稳定性均有问题,访问有些链接会出现错误,所以这几个版本最好不要在生产环境中使 用。nginx-0.7下目前所知较为稳定的版本是0.7.39。稳定版0.6.36版也是近期更新,如果在配置里没有使用到0.7的一些新标签新功能, 也可以使用0.6.36版。这个cache模块还在开发阶段,在功能上还有许多等待改进的地方,例如针对不同文件类型设置不同的过期时间等.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多