Nginx实现负载均衡与Nginx缓存功能
目录
- 一、Nginx是什么
- 二、Nginx实现反向代理
- 2.1 正向代理和反向代理
- 2.2 nginx实现反向代理
- 2.3 nginx实现负载均衡
- 三、tengine
- tengine实现动静分离
- 四、nginx实现缓存
- 4.1 为什么需要缓存
- 4.2 缓存服务的工作原理
- 4.3 nginx缓存模块
- 4.4 配置nginx缓存实例
- 五、memcached
- 5.1 memcached是什么
- 5.2 安装配置memcached
一、Nginx是什么
Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
目前淘宝在nginx做了二次开发:tengine(见下文)。
二、Nginx实现反向代理
2.1 正向代理和反向代理
正向代理:是一个位于客户端和目标服务器之间的服务器,为了从目标服务器取得内容,客户端向代理发送一个请求并指定目标(目标服务器),然后代理向目标服务器转交请求并将获得的内容返回给客户端。
简单来说:
我是一个用户,我访问不了某网站,但是我能访问一个代理服务器;
这个代理服务器呢,他能访问那个我不能访问的网站;
于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容;
代理服务器去取回来,然后返回给我;
从网站的角度,只在代理服务器来取内容的时候有一次记录;
有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。
反向代理:对于客户端而言它就像是目标服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(目标服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样。
简单来说,
用户访问 http://ooxx.me/readme;
但ooxx.me上并不存在readme页面;
他是偷偷从另外一台服务器上取回来,然后作为自己的内容吐给用户;
但用户并不知情┐(゚~゚)┌
这里所提到的 ooxx.me 这个域名对应的服务器就设置了反向代理功能;
正向代理和反向代理的区别:
(1)从用途上来讲:
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。
另外,反向代理还可以启用高级URL策略和管理技术,从而使处于不同web服务器系统的web页面同时存在于同一个URL空间下。
(2)从安全性来讲:
正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。
反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。
2.2 nginx实现反向代理
nigix代理是基于ngx_http_proxy
模块实现的。该模块有很多配置选项,如:
proxy_pass
指定将请求代理至server的URL路径。
proxy_set_header
将发送至server的报文的某首部进行重写。
proxy_send_timeout
在连接断开之前两次发送到server的最大间隔时长;过了这么长时间后端还是没有收到数据,连接会被关闭。
proxy_read_timeout
是从后端读取数据的超时时间,两次读取操作的时间间隔如果大于这个值,和后端的连接会被关闭。
proxy_connect_timeout
是和后端建立连接的超时时间。
接下来,我们就来仔细说说重点的配置选项:
2.2.1 proxy_pass
配置
1)替换uri
常用于页面很固定的时候。比如双十一的大促主页面。
语法如下:
location /uri { proxy_pass http://ip:port/newuri/; //location的/uri将被替换为/newuri }
举例如下:
location /mobi { proxy_pass http://172.17.251.66/mobile/; //将/mobi 的请求跳转到新服务器上/mobile目录下 }
在这里,我们需要注意的是,http://ip:port/newuri;
,这个地方最后面加不加/
意义是不同的。
如上文,我们就加上了/
,则意味着全部替换。
如果我们不加/
,则是将新路径当做其上级目录,访问的是新路径下的原路径。举例如下:
location /mobi { proxy_pass http://172.17.251.66/mobile; //将/mobi 的请求跳转到新服务器上/mobile/mobi目录下 }
2)转换url
相当于分流,基于url来分流,把一类的请求发送到一个机器(一个集群)中,具体操作看机器的设置。
如果location的URI是通过模式匹配定义的,其URI将直接被传递,而不能为其指定转换的另一个URI。
举例如下:
location ~ ^/mobile { proxy_pass http://172.17.251.66; }
这段代码的意思是,只要有/mobile
的网址,会直接转到http://172.17.251.66/mobile
下。
3)URL重定向
也就是整个url的重定向。比如两个网站合并或者更换域名时,原先的域名已经不用了,但是有些页面还在访问,就可以通过这种方法来整个重定向,重定向到新的域名中。
如果在location中使用的URL重定向,那么nginx将使用重定向后的URI处理请求,而不再考虑之前定义的URI。
location /youxi{ rewrite ^(.*)$ /mobile/$1 break; proxy_pass http://172.17.251.66; }
这段代码的意思就是,只要你访问的是带/youxi
的页面,就会自动重定向到http://172.16.100.1/mobile/$1
上。$1
指的是^(.*)$
中括号内的部分。这样就实现了整个url的重定向。
在这里,我们也来详细说说ngx_http_rewrite_module
模块,这是一个非常好用的模块。
2.2.1.1ngx_http_rewrite_module
模块
1)rewrite 用法
将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI。
其语法是:
rewrite regex replacement [flag]
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查。
隐含有循环机制,但不超过10次;如果超过,提示500响应码, [flag]
所表示的标志位用于控制此循环机制。
如果replacement是以http://或https://开头,则替换结果会直接以重向返回给客户端。
下面我们来说一说flag
的具体选项:[flag]
:
last
:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮(从第一个开始)重写检查;提前重启新一轮循环。break
:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用。redirect
:临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头,使用相对路径,状态码: 302。permanent
:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,状态码:301。
由下图我们可以更清楚的看出跳转到的位置:
2)return用法
return的用法语法如下:
return code [text]; return code URL; return URL;
停止处理,并返回给客户端指定的响应码。
2.2.2 proxy_set_header
配置
proxy_set_header
用于将发送至server的报文的某首部进行重写。常用于nginx做负载均衡时, 获取客户端IP时, 添加forward头部。
语法如下:
proxy_set_header Host $host; //目的主机地址 proxy_set_header X-REMOTE-IP $remote_addr; //上一跳地址 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; //客户端主机地址
原有请求报文中如果存在X-Forwared-For
首部, 则将client_addr
以逗号分隔补原有值后, 否则则直接添加此首部;
2.3 nginx实现负载均衡
nginx负载均衡是ngx_http_upstream_module
模块的功能, 需要在配置文件http块
上下文中定义upstream块
, 指定一组负载均衡的后端服务器, 然后在上面讲到的proxy_pass
中引用, 就可以反向代理时实现负载均衡了。
需要注意的是:ngx_http_upstream
段要在server
段前面,要定义在http
段中。
语法如下:
server address [parameters];
接着,我们来看一看选项:paramerters
:
weight
: 负载均衡策略权重, 默认为1;max_fails
: 在一定时间内(这个时间在fail_timeout参数中设置) 检查这个服务器是否可用时产生的最多失败请求数fail_timeout
: 在经历了max_fails
次失败后, 暂停服务的时间。 max_fails
可以和fail_timeout
一起使用, 进行对后端服务器的健康状态检查;backup
: 当所有后端服务器都宕机时, 可以指定代理服务器自身作为备份, 对外提供维护提示页面;down
: 永久不可用。
需要注意一下的是:max_fails
和fail_timeout
是配对使用的,前者是定义在一定时间内检查这个服务器是否连接可用时产生的最多失败请求的次数,后者是规定这个时间,并且这个时间也是在经过前者的失败次数后,暂停服务的时间。
示例:
max_fails=3 fail_timeout=10s
意思就是 10秒内失败3次,则暂停服务10秒。
举例:
upstream dynamic { server backend1.example.com weight=5; server backend2.example.com:8080 max_fails=3; fail_timeout=5s ; server 192.0.2.1 max_fails=3; server backup1.example.com:8080 backup; server backup2.example.com:8080 backup; }
当然,我们还有一个专业的健康检测模块 nginx_upstream_check_module-master
,可以根据需要使用。
upstream
块里可以用多个server
选项配置多个后端服务器,同时还可配置对后端服务器的健康状态检查,可以在server
后面加上max_fails
(
proxy_next_upstream指定检查策略,默认为返回超时为失败)和fail_timeout
参数实现;也可以用health_check
选项来实现,health_check
可以指定的参数较多, 不过需要定义在location
上下文中。
另外, 可以指定代理服务器自身作为备份server
, 当所有后端服务器都宕机时, 对外提供维护提示页面。
还可以指定负载均衡策略: 主要有round_robin
(加权轮询, 默认) 、hash
、ip_hash
、least_conn
(最少连接)和least_time
(最少响应时间,商业版本),策略定义在upstream
上下文即可。
具体实例参照tengine
实现动静分离(见下文)。
三、tengine
Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。
从2011年12月开始,Tengine成为一个开源项目,Tengine团队在积极地开发和维护着它。Tengine团队的核心成员来自于淘宝、搜狗等互联网企业。Tengine是社区合作的成果,我们欢迎大家参与其中,贡献自己的力量。
tengine
实现动静分离
1、下载并解压安装包
进入官网下载安装包,
这里附上官网网址:tengine.taobao.org
小编下载的是2.2.1
版本。大家可以根据自己的需要来下载。接着,我们使用rz
命令上传至虚拟机。
上传完成后,我们来解压:
tar xvf tengine-2.1.1.tar.gz
2、编译安装tengine
首先,我们要安装依赖的包和包组:
yum install pcre-devel openssl-devel -y yum groupinstall "development tools" -y
安装完成后,我们进入这个目录:
cd tengine-2.1.1
然后,我们就可以进行编译安装了:
./configure --prefix=/usr/local/tengine make && make install
3、修改配置文件
我们的需求是让这台机器充当调度器,坐到动静分离,所以我们需要在配置文件中添加下面这些:
配置文件为/usr/local/tengine/conf/nginx.conf
。http
段,添加如下内容:
upstream server-cluster{ server 172.17.77.77:80; server 172.17.252.111:80; check interval=3000 rise=2 fall=5 timeout=1000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; } upstream staticsrvs{ server 172.17.22.22:80; server 172.17.1.7:80; check interval=3000 rise=2 fall=5 timeout=1000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; }
server
段,添加如下内容:
location /stats { check_status; //定义一个web监听页面 } //以下部分用来实现动静分离 location ~* .jpg|.png|.gif|.jpeg$ { proxy_pass http://staticsrvs; } location ~* .css|.js|.html|.xml$ { proxy_pass http://staticsrvs; } location / { proxy_pass http://server-cluster; }
如果有下面这一段,我们需要把它注释掉:
location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
这样,我们的配置文件就修改完成了。
在我们启动服务前,如果我们的机器开启了nginx
服务或者http
服务,要记得把服务关闭,因为tengine
服务使用的也是80端口。
我们来启动服务:
cd /usr/local/tengine/sbin ./nginx -t //检查配置文件语法错误 ./nginx //启动服务 ./nginx -s reload //重新加载服务
当然,我们也可以直接把这个服务写到我们的启动脚本里,这样,以后我们通过service
或者systemctl
就可以控制了。
CentOS7里的启动脚本在/usr/lib/systemd/system/nginx.service
在centos6中,我们如果之前使用yum
安装过nginx
,我们就可以复制一个nginx
的服务脚本,改名为tengine
,并设置开机自启,具体操作如下:
cp /etc/init.d/nginx /etc/init.d/tengine vim /etc/init.d/tengine
4、测试
由于我们在配置文件中定义了一个web的监听页面,所以我们可以去访问一下:
上图中就是我们的监听页面,如果某一服务器出现故障,则会标红提示。
我们的网站也是可以正常访问的:
接着,我们来测试一下我们的动静分离实现情况,我们把两台静态的服务器的nginx
服务down掉:
systemctl stop nginx
然后我们来看看我们的监听页面,需要刷新几次:
我们可以看到,挂掉的两台服务器已经标红了。接着我们来访问一下我们的网站:
可以看到,所有的静态文件,包括图片
和css
、js
等文件都没有显示了,我们的动静分离实验圆满完成。