文章目录
如何实现服务器之间的协同功能呢?通过Nginx提供的反向代理和负载均衡功能,可以合理地完成业务的分配,提高网站的处理能力;同时利用缓存功能,还可以将不需要实时更新的动态页面输出结果,转化为静态页面形成缓存,从而提高网站的响应速度。
1. 正向代理与反向代理
正向代理:如果把局域网中的Internet想象成一个巨大的资源库,则局域网中的客户端想要访问Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。即在客户端(浏览器)配置代理服务器,通过代理服务器进行互联网访问。
相比于正向代理服务,反向代理对于对于客户端而言就是目标服务器,客户端向反向代理服务器发送请求后,反向代理服务器将该请求转发给内部网络上的后端服务器,并将从后端服务器上得到的响应结果返回给客户端。反向代理服务器的整个处理过程,用户并不知情。
正向代理和反向代理的特性如下:
- 安全性:正向代理的客户端能够在隐藏自身信息的同时访问任意网站,这个网站安全带来了极大的威胁。因此,在使用时必须采取安全措施以确保仅为经过授权的客户端用户提供服务。而反向代理的客户端用户只能通过外网来访问代理服务器,并且用户并不知道自己访问的是一个代理服务器,好处就是反向代理将真正的处理放在内网中,有效的提高了网络安全性。
- 功能性:正向代理的主要用途是为在防火墙内的局域网用户提供访问Internet的途径。而反向代理的主要用途是将防火墙后的服务器提供给Internet用户访问,还可以为多个后端服务器提供负载均衡、缓存功能等。
# 配置域名为 test.xingze00.com的虚拟主机
server {
listen 80;
server_name test.xingze00.com;
# 将域名test.xingze00.com 的请求全部转发到192.168.78.06
location / {
proxy_pass http://192.168.78.06
}
}
# 配置域名为 test.xingze01.com的虚拟主机
server {
listen 80;
server_name test.xingze01.com;
# 将域名test.xingze01.com 的请求全部转发到192.168.78.07
location / {
proxy_pass http://192.168.78.07
}
}
proxy_pass http://192.168.78.06
和proxy_pass http://192.168.78.07
用于配置反向代理,proxy_pass
指令后的http://
表示传输数据所使用的协议,在服务器支持HTTPS服务的情况下,还可以将其指定为https://
安全网络传输协议。其他常用的反向代理命令如下:
反向代理命令 | 说明 |
---|---|
proxy_set_header | 在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息 |
proxy_connect_timeout | 配置Nginx与后端服务器组尝试连接的超时时间 |
proxy_read_timeout | 配置Nginx向后端服务器组发出read请求后,等待响应的超时时间 |
proxy_send_timeout | 配置Nginx向后端服务器组发出write请求后,等待响应的超时时间 |
proxy_redirect | 用于修改后端服务器返回的响应头的Location和Refresh |
2. 负载均衡
Nginx不仅可以作为一个Web服务器或反向代理服务器,还可以按照权重、轮询、ip_hash、URL hash等多种方式实现对后端服务器的负载均衡。
2.1 负载均衡概念
负载均衡(load balance)就是将多个负载请求分摊到多个服务器上执行,从而提高服务的可用性和响应速度,带给用户更好的体验。
2.2 负载均衡的配置
通过Nginx中的upstream
指令可以实现负载均衡,在该指令中能够配置负载均衡器组。目前负载均衡有4种典型的配置方式,分别为轮询方式、权重方式、ip_hash、利用第三方模块的方式。详情如下:
配置方式 | 说明 |
---|---|
轮询方式 | 默认的负载均衡算法,每个请求按照时间顺序逐一分配到不同的后端服务器进行处理,如果有服务器宕机,会自动删除 |
权重方式 | 利用weight权重指定轮询的权重比率,与访问率成正比,用于后端服务器性能不均的情况 |
ip_hash | 每个请求按照访问IP的hash结果分配,这样可以使每个访客固定访问一个后端服务器,可以解决Session共享 的问题 |
第三方模块 | 第三方模块采用fair时,按照每台服务器的响应时间来分配请求,响应时间短的优先分配;若第三方模块采用URL hash时,按照访问URL 的hash值来分配请求 |
在upstream 指定的服务器组中,若每个服务器的权重都设置为1(默认值)时,表示当前的负载均衡是一般轮询方式。 |
注:Nginx本身不包含第三方模块的实现方式,如fair或URL hash等,在使用时必须下载相应的upstream_fair模块或安装hash软件包,才可以实现第三方模块提供的负载均衡配置。
2.2.1 配置一般轮询负载均衡
# 配置域名为test.xingze.com的虚拟主机
server {
listen 80;
server_name test.xingze.com;
location / {
proxy_pass http://web_server;
}
# 配置负载均衡服务器组
upstream web_server {
server 192.168.12.123;
server 192.168.12.124;
}
}
proxy_pass http://web_server
用于指定代理的URL,upstream块
用于指定代理的后端web服务器主机名,这些服务器可以有一个或多个,从而形成负载均衡服务器组。
注:如果Nginx检测到某台服务器宕机,则会在负载均衡时自动剔除该服务器。
2.2.2 加权负载均衡
如果负载均衡服务器组中的服务器硬件配置强弱不一,则可以通过weight
参数设置权重大小。对于配置较好的服务器,可以为其设置成比较高的权值,对于配置较差的服务器,可以为其分配较小的权值。即通过加权轮询,可以让每台服务器承担与之硬件配置相符合的工作量,从而在整体上发挥最佳的效果。具体配置如下:
server {
listen 80;
server_name test.xingze.com;
location / {
proxy_pass http://web_server;
}
# 配置负载均衡服务器组,并设置权重值
upstream web_server {
server 192.168.12.123 weight=2;
server 192.168.12.124 weight=3;
}
}
weight
参数表示权值,权值越高则被分配到的概率越大。在负载均衡的过程中,Nginx将按照平滑加权轮询算法进行具体分配。其中,权值总和为一个循环,这里的配置就是以5次请求为一个循环,在循环过程中,在循环过程中,服务器192.168.12.123会在5次请求中被分到2次,服务器192.168.12.124则会被分到3次,但是3次被选取的机会并不会连续执行,而是按照算法分散执行。
除此之外,还可以设定每台Web服务器在负载均衡调度中的状态,常用的参数说明如下:
配置参数 | 说明 |
---|---|
max_fails | 允许请求失败的次数,默认是1。当超过最大次数时,返回proxy_next_upstream 指令定义的错误 |
fail_timeout | 在经历max_fail次失败后,暂停服务的时间。且在实际应用中max_fails一般与fail_timeout一起使用 |
backup | 预留的备份机器 |
down | 表示当前的server暂时不参与负载均衡 |
参数设置如下: |
upstream web_server {
server 192.168.12.123 weight=2 max_fails=1 fail_timeout=2;
server 192.168.12.124 weight=3 max_fails=2 fail_timeout=2;
server 192.168.12.125 backup;
}
注:在所有服务器都停止工作后,再访问时会出现502 Bad Gateway错误。因此,在配置负载均衡服务时,利用备份服务器可以应对一些意外情况,提高服务的可用性。
2.2.3 ip_hash负载均衡
ip_hash方式的负载均衡,是将每个请求按照访问IP的hash结果分配,这样就可以使来自同一个IP的客户端用户固定访问一台web服务器,有效的解决了动态网页存在的Session共享问题。配置如下:
upstream web_server {
ip_hash;
server 192.168.12.123;
server 192.168.12.124;
server 192.168.12.125 down;
}
ip_hash
指令用于表示当前负载均衡的处理方式。其中,对于一个暂时性宕机的服务器,可以使用down
参数标识出来,这样在负载均衡时,就会忽略该服务器的分配。
注:在使用ip_hash方式的负载均衡算法时,Web服务器在负载均衡列表中的状态不能用weight和backup设置。
2.2.4 利用第三方模块
第三方提供的方式有多种,以fair方式为例,从Github中获取fair模块,下载nginx-upstream-fair-master.zip
,配置fair方式的负载均衡如下:
upstream web_server {
server 192.168.12.123;
server 192.168.12.124;
fair;
}
3. Nginx + Tomcat实现动静分离
Nginx作为前端web服务器,而Apache或Tomcat在后端只处理动态请求,实现动静态分离。这种方式既避免了 更换Web服务器带来的不稳定性,又利用Nginx提高了性能,是一种便捷的优化方案。
Nginx + Tomcat实现动静分离时,只需要将站点文档目录配置到同一目录下,然后利用Nginx的proxy_pass
指令代理请求动态文件即可。
server {
listen 80;
server_name test.xingze.com;
root /user/local/tomcat/webapps/ROOT;
index index.html index.htm index.jsp index.do;
location ~/ (WEB-INF|META-INF){
deny all;
}
location ~\.(jsp|do)${
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Client-IP $remote_addr;
}
location ~^/(docs|examples)(/.*) * $ {
root /user/local/tomcat/webapps;
}
}
4. 缓存
对于一个含有大量内容的网站来说,随着访问量的增多,对于经常被用户访问的内容,若每一次都从后端服务器中获取,会给服务器造成很大的压力。为此,利用反向代理服务器对访问频率较多的内容进行缓存,有利于节省后端服务器的资源。Nginx提供了两种Web缓存方式:永久性缓存、临时性缓存。
4.1 缓存实现原理
Web缓存服务器位于内容源Web服务器和客户端之间,当客户端用户访问一个URL时,Web缓存服务器就会请求相应的内容源Web服务器,并将响应的信息缓存到内存或磁盘;然后,当下一个请求到达时,如果访问的是相同的URL,Web缓存服务器会直接将已缓存的内容输出给客户端,而不用再次向内容源Web服务器发送请求。
利用缓存服务器,可以有效降低内容源服务器和数据库的负载,提高用户访问的响应速度。即当用户向web缓存服务器中发送请求时,缓存服务器要检查一下当前URL请求是否已经存在缓存。否则,向内容源服务器发送请求,获取响应结果,将其缓存之后返回给发送请求的客户端。
4.2 永久缓存配置
Nginx提供的proxy_store
指令可以用于将内容源服务器响应的内容缓存到本地,若不手动删除,该缓存文件会一直生效。因此,永久缓存方式适用于缓存网站中几乎不会更改的一些内容。
永久缓存的配置过程如下,打开Nginx的配置文件nginx.conf
:
server {
listen 80;
server_name 192.168.12.123;
location / {
root cache;
proxy_store on;
proxy_store_access user:rw group:rw all:r;
proxy_temp_path cache_tmp;
proxy_pass http://192.168.12.125;
}
}
- 第五行配置
root cache;
用于指定缓存文件的保存目录,这里将其设定在Nginx安装目录下的cache目录中,需要用户手动创建,创建后修改此目录的用户权限,要求与Nginx工作进程的用户相同。 proxy_store on;
:用于开启本地缓存;proxy_store_access user:rw group:rw all:r;
设置缓存的读写规则;proxy_temp_path cache_tmp;
设置方向代理时接收的数据临时存储文件的目录,该目录会由Nginx在配置生效后自动创建。
4.3 临时缓存配置
Nginx服务器中,还有一种使用proxy_cache
指令设置的临时缓存配置,它采用md5
算法将请求链接进行哈希(hash)后,根据具体配置生成缓存文件目录,保存响应的数据。
打开Nginx的配置文件nginx.conf,在http块中添加如下配置:
# 代理临时目录
proxy_temp_path /usr/local/nginx/proxy_temp_dir;
# Web缓存目录和参数设置
proxy_cache_path /usr/local/nginx/proxy_cache_dir levels=1:2 keys_zone=cache_one:50m inactive=1m max_size=500m
proxy_temp_path
用于设置缓存服务器接收内容源服务器响应内容时使用的临时目录。proxy_cache_path
用于设置缓存目录,其中的参数各自含义如下:
/usr/local/nginx/proxy_cache_dir
参数:表示用户自定义的缓存文件保存目录;
levels
参数:表示缓存目录下的层级目录结构,它是根据哈希后的请求URL地址创建的,目录名称从哈希后的字符串结尾处开始截取;
keys_zone
参数:指定缓存区名称及大小;
inactive
参数:表示主动清空在指定时间内未被访问的缓存。例如1h表示一小时内未被访问过的缓存,1m表示一分钟,1d表示1天;
max_size
参数:表示指定磁盘空间大小。
接着,在server块中添加临时缓存的相关配置:
server {
listen 80;
server_name test.xingze.com;
# 增加两个响应头信息,用于获知访问的服务器地址与缓存是否成功
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
location / {
# 设置缓存区域名称
proxy_cache cache_one;
# 以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希
proxy_cache_key $host$uri$is_args$args;
# 对不同的HTTP状态码设置不同的缓存时间
proxy_cache_valid 200 10m; # 200缓存10分钟
proxy_cache_valid 304 1m; # 304缓存1分钟
proxy_cache_valid 404 20m; # 404缓存20分钟
proxy_cache_valid any 1m; # 其他未设置的状态码缓存1分钟
# 设置反向代理
proxy_pass http://192.168.12.123
}
}
proxy_cache_key
指令中参数中使用的具体变量如下:
$host
:服务器的域名,如test.xingze.com;$uri
:域名和参数之间的部分,如index.html;$is_args
:有URL参数时,则值为?,否则为空字符串;$args
:保存URL参数,如a=1&b=2,没有参数时为空字符串。- 利用
$is_args
和$args
参数,可以实现根据不同URL参数缓存不同文件。
4.4 缓存清理配置
利用Nginx缓存虽然减轻了后端服务器的压力,但是会导致文件修改后无法及时更新缓存,只有删除服务器中的缓存文件,Nginx才会重新请求后端服务器。
目前的Nginx提供缓存相关的指令不支持清理指定URL的缓存,需要借助第三方模块才可以实现。如ngx_cache_purge
.