当前位置: 首页 > 系统 > 正文

如果你也在用负载均衡或者反向代理

【摘要】当你把web应用放到负载均衡( load balancer )或者任何的反向代理后面,下面一些因素就需要你去深入考虑了。本文将会包含对这些疑问解释,并且尝试讨论出通用的解决方案。

(一)资源管理
如果使用负载均衡说明你至少拥有两台以上的web服务器,在这种情况下如何管理你的静态资源(img,js,css文件)将变得非常重要了。

如果你允许用户上传(如一个类CMS的系统),上传的文件不能够仅存在于它所上传的web服务器中,如果上传的img文件只存在其中的一台服务器上,那么当有请求通过 Load balancer 落在其他的服务器(恰好没有该img的服务器)的时候会返回404错误。

最简单的解决办法是让所有的资源同时存在于所有的webserver上。如果你的站点架构不是很复杂,例如不存在用户自己上传图片的状况,所有的图片或者资源作为你的站点的代码资源一起发布到所有的webserver上,这种方式简单粗暴,也很有效。

然而,如果你涉及到了内容管理(CMS)或者允许文件上传的话,这样你的web servers或许需要一个通用的文件存储来解决。

一个办法是通过共享存储(例如NAS,NFS)然而这样的架构下如果文件量特别大或者静态资源带宽需求过大可能会导致资源访问很慢。更有甚者,如果你的架构分布与多个不同的IDC中,这种基于网络的文件共享,web servers在获取静态资源的时候将会因为网络延迟而变得很卡。

(二)资源自动化
一个通用的解决方案是把所有的静态资源存放到一个独立的地方,如Amazon的S3上。

在Amazon内部,还有更进一步的解决方案,所有在S3 桶里的资源文件可以跟CDN进行整合,如CloudFront,这样你的资源文件就通过CDN来提供服务了。

对于你的静态资源,你可以使用自动化工具如:Grunt来自动化完成这样的任务。例如,你可以使用Grunt来监控文件的变化情况,把css,js,images文件联系起来,先部署在预发布文件环境,然后上传它们到需要的地方。

对于用户上传的内容,你可能会需要做些编程工作,将上传的文件暂存到临时目录上,然后再通过AWS提供的API上传到S3上,实际上这也确实比较容易实现。

(三)基于环境的URLS
在项目中我需要做的一件事就是基于环境来改变资源的URL。使用一些额外的辅助功能,我将会写代码,将开发环境机器的整站URL输出到HTML文件中,这样可以在本地读取整个站点。但是对于生产环境,这些辅助功能可以输出URLs到你的文件存储或者CDN上。
加上一些自动化工具(Grunt)的整合,这样就可以在开发和生产环境中进行无缝切换。

(四)会话 sessions
跟静态资源管理类似,如何处理session同样十分重要。会话信息通常保存在指定的web server上,用户登陆后将会在一台web server上保存session信息。然后前端的负载均衡有可能将该用户下次的请求转到了另外的服务器上,但是上面并没有改用户的session信息,这样该用户就会被认为尚未登陆,而强制退出。

下面是两种常用的解决办法:
1. 会话保持 Sticky Sessions
首先是配置你的负载均衡设备使用用户的”Sticky Sessions”,有的叫做”session affinity”,这些配置将会把一个客户端的请求始终分发到同样的web server上。这样仅需要web server在本地保存用户的session信息即可,同一个client每次请求都落到同一台上,这是一个比较偷懒的做法,也是比较容易。
但有的session保持是基于来源IP地址的,如果同一个IP地址拥有大量的用户,会导致负载均衡流量分发不均衡。
2. session 共享存储
第二种方式就是使用共享session存储的方式,比如将所有的应用session存储在内存数据库:redis或者memcache上,或者持久存储数如关系型数据库里面。
既然session信息没有必要非的持久化(存储到磁盘上),所以内存数据库存储是我们推荐的。这样的架构下,所有的web servers连接同样的中央session存储,会让你的架构稍微复杂一些,但是会让你的负载策略更好,实现真正的分布式及负载平衡。

(五)客户端的信息缺失
跟session问题密切相关的是区分具体的客户端都是谁?如果你的负载均衡设备是一个反向代理,这样在应用服务器上(real server)上看到所有的请求都是来自load balancer! 你的应用将无法区别出不同的客户端来。
幸运的是,大多数的负载均衡设备提供了真是客户端信息的功能。如果你从负载均衡设备上检查Http header,你可以使用如下header:

    X-Forwarded-For
    X-Forwarded-Proto
    X-Forwarded-Port

这些header可以告诉你客户端的真实IP地址,使用的协议(http/https)和客户端请求的端口号。如果这些信息存在的话,应用端就可以根据这些信息来区分不同的客户。

(六)IP地址
拥有一个真实的IP地址对与客户端来说非常重要,一些web应用经常会根据用户的IP地址做一些任务:如鉴权、投票等等。使用X-Forwarded-For HTTP头可以获取用户真实的IP地址(假设来自代理的请求是可信的)。

(七)协议和端口
这里的协议主要是针对http和https,一般情况下https的证书终结在了强大的负载均衡设备上,这样应用服务器只需要提供http服务既可,节省了CPU资源。
Amazon AWS SLB同样提供了负载均衡和ssl卸载的功能。

(八)SSL透传
一些场景下,会有SSL透传的需求,这样load balancer上就不需要处理加密请求了,加密机密的重任就落在了后端的web server上。

(九)日志
现在我们有了多台web server,但是每台机器会产生自己的日志文件,收集/合并所有的服务器的日志文件会是很繁琐的事情,集中化日志存储将会变得非常有益处。

最简单的是将日志直接存储到S3上的日志桶里面。

(十)相关资源
下面是一些跟本文相关的资源
1. Grunt和资源管理
Grunt
Grunt-S3
Grunt-AWS
Grunt-Imageoptim
Grunt-Uglify
Grunt-Sass

2. 一些流行的自定义安装的日志服务
Graylog2
Splunk
Syslog-ng
Rsyslog

3. 一些流行的SaaS 日志服务
Loggly
Logstash
Splunk Storm
Paper Trail
logentries
Bugsnap

4. 其他日志工具
Logrotate & Upload to S3
Fingers-Crossed Log Handling

偶然发现的这篇文章,感觉不错,其中用到了很多AWS的服务,这里也转载并翻译一下,原文(英文)地址为:fideloper.com

本文固定链接: https://sudops.com/if-you-are-using-load-banlancing-or-proxy.html | 运维速度

该日志由 u2 于2014年11月26日发表在 系统 分类下,
原创文章转载请注明: 如果你也在用负载均衡或者反向代理 | 运维速度
关键字: ,

报歉!评论已关闭.