本篇一句话总结:Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。
正文开始:
- 什么是Nginx?
- 为什么选择Nginx?
- 怎么用Nginx?
上面这几个问题,是每个刚接触 Nginx 的人都想知道的。下面小兵综合自己的理解和使用情况,在分布式专题里总结一篇关于 Nginx 的内容。全文看完,我们对 Nginx 也有一定的了解了。
什么是Nginx?
总结一句话,就是:
Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。
从这句话我们可以知道Nginx的基本定位是Web服务器,然后Nginx还提供反向代理、负载均衡、动静分离、HTTP缓存的功能。
什么是Web服务器?
Web服务器是指驻留于因特网上某种类型计算机的程序,是可以向发出请求的浏览器提供文档的程序。当Web浏览器(客户端)连到Web服务器上并发送请求时,Web服务器将处理该请求并将文件反馈到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。Web服务器使用HTPP协议与客户机浏览器进行信息交流,这就是人们常把它们称为HTTP服务器的原因。Nginx最基本的功能便是作为Web服务器。目前最主流的三个Web服务器是Apache、 Nginx 、IIS。常用的还有Tomcat、WebLogic、JBoss、Jetty、Netty等。下面简单介绍下几个主流开源的Web服务器:
- Apache是目前市场占用量最高的web服务器,据最新数据统计,市场占有率目前是50%左右。主要优势在于一个是比较早出现的一个Http静态资源服务器,可以作为Web服务器使用,用于处理静态网页,比如HTML、图片、视频、音频等静态文件,Apache稳定性良好,支持的模块丰富。但是其不适宜高并发的请求。
- Nginx是俄罗斯人编写的一款高性能的HTTP和反向代理服务器,在高连接并发的情况下,它能够支持高达50000个并发连接数的响应,但是内存、CPU等系统资源消耗却很低,运行很稳定。目前Nginx在国内很多大型企业都有应用,据最新统计,Nginx的市场占有率已经到33%左右了。虽然Apache的市场占有率虽然仍然是最高的,但是是呈下降趋势。而Nginx的势头很明显。在Nginx的基础上,淘宝还搞出了一个Web服务器Tengine。相信大公司的眼光是不会差的。
- Tomcat是Apache的拓展,更实质的说是Java应用服务器。它主要用于解析servlet/JSP,能够动态地生成资源,同时具备HTTP服务。Tomcat根据请求将动态的内容转化为静态的内容之后,通过 HTTP Server 分发到客户端,对静态页的支持效率就没有Apache高。单纯的Tomcat性能有限,在很多地方表现有欠缺,如活动连接支持、静态内容、大文件和HTTPS等。因此大多数公司都是Tomcat配合Apache或者Nginx一起使用。
为什么选择Nginx?
选择Nginx的理由也很简单:
- 第一,它可以支持每秒5W高并发连接;
- 第二,内存消耗少;
- 第三,成本低,如果采用F5、NetScaler等硬件负载均衡设备的话,需要大几十万。而Nginx是开源的,可以免费使用并且能用于商业用途
下面,我们先把Nginx下载回来,结合实例,一起来认识和理解“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。”的含义。
Nginx安装
(为写本篇博客小兵准备了两台CentOS 7.x服务器,139.155.105.15用于安装nginx,47.112.148.36用于部署tomcat应用。)
一、安装编译工具及库文件
yum -y install make gcc gcc-c++ libtool zlib zlib-devel openssl openssl-devel
二、安装 PCRE
2.1 下载pcre,下载完成后解压:
[root@VM_0_10_centos ~]# cd /usr/local/src/
[root@VM_0_10_centos src]# wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
[root@VM_0_10_centos src]# tar zxvf pcre-8.35.tar.gz
2.2 解压后进入目录并编译安装:
[root@VM_0_10_centos src]# cd pcre-8.35/
[root@VM_0_10_centos pcre-8.35]# ./configure
[root@VM_0_10_centos pcre-8.35]# make && make install
2.3 查看pcre版本,出现版本号即安装pcre成功
[root@VM_0_10_centos pcre-8.35]# pcre-config --version
8.35
三、安装 Nginx
3.1 下载nginx,下载完成后解压:
[root@VM_0_10_centos ~]# cd /usr/local/src/
[root@VM_0_10_centos src]# wget http://nginx.org/download/nginx-1.6.2.tar.gz
[root@VM_0_10_centos src]# tar zxvf nginx-1.6.2.tar.gz
3.2 解压后进入目录并编译安装:
[root@VM_0_10_centos src]# cd nginx-1.6.2/
[root@VM_0_10_centos nginx-1.6.2]# ./configure
[root@VM_0_10_centos nginx-1.6.2]# make && make install
2.3 查看nginx版本,出现版本号即安装nginx成功。(默认安装在/usr/local/nginx)
[root@VM_0_10_centos nginx-1.6.2]# cd /usr/local/nginx/sbin/
[root@VM_0_10_centos sbin]# ./nginx -v
nginx version: nginx/1.6.2
2.4 启动并访问
[root@VM_0_10_centos sbin]# ./nginx
nginx默认监听的是80端口,所以在客户端(浏览器)输入服务器ip即可访问nginx。
nginx相关命令:
/usr/local/nginx/sbin/nginx -t # 检查配置文件语法
/usr/local/nginx/sbin/nginx -c #指定nginx.conf的文件。不指定时默认为NGINX_HOME/conf/nginx.conf
/usr/local/nginx/sbin/nginx -s reload # 重新载入配置文件
/usr/local/nginx/sbin/nginx -s reopen # 重启 Nginx
/usr/local/nginx/sbin/nginx -s stop # 停止 Nginx
Nginx配置文件
我们说“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存”。Nginx能提供这些功能,都是通过配置nginx.conf文件来实现,所以这个配置文件的重要性可想而知。我们查看 conf/nginx.conf 文件,去除注释后得默认配置如下。可以看到nginx的核心配置可以是很简洁的,最主要包括三个模块:main、 events 、 http。每个模块都可以根据自己的需要进行相应的配置,我们也可以添加自己的模块。本篇对配置文件不做过多介绍,可参考常用nginx.conf配置文件解析和nginx配置参数详细说明。
# 一、主模块配置
# nginx要开启的工作进程数。Nginx有一个主线程和一个或多个工作线程。
worker_processes 1;
# 二、事件模块配置
events {
# 单个worker进程打开的最大并发连接数
worker_connections 1024;
}
# 三、http模块配置
http {
# include指在当前文件中包含另一个文件内容
include mime.types;
# 设置文件使用默认的mine-type,默认是未知的类型
default_type application/octet-stream;
# 优化磁盘IO设置,指定nginx是否调用sendfile函数来输出文件,普通应用设为on,下载等磁盘IO高的应用,可设为off
sendfile on;
# 长连接的超时时长
keepalive_timeout 65;
# 虚拟主机
server {
# 监听80端口
listen 80;
# 定义主机名,主机名可以有多个,名称还可以使用正则表达式(~)或通配符
server_name localhost;
# 根据用户请求的URI来匹配定义的某个location,匹配到时,此请求将被相应的location配置块中的配置所处理
location / {
# 定义服务器的默认网站根目录位置
root html;
# 定义首页索引文件的名称
index index.html index.htm;
}
# 定义错误提示页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
Nginx用做Web服务器
Nginx默认就是当作Web服务器来使用,我们能访问到Nginx的默认首页,就是Nginx作为Web服务器给浏览器响应返回了配置文件 nginx.conf 中配置的 html目录下的index.html 文件。
本篇为了更方便直观地介绍Nginx的功能,搞了个静态页面“偷宝网”,内容如下。
然后我们把这个偷宝网放到nginx中,配置nginx.conf,让其作为首页。
然后检查配置是否正确,并重新加载配置文件:
[root@VM_0_10_centos sbin]# /usr/local/nginx/sbin/nginx -t
[root@VM_0_10_centos sbin]# /usr/local/nginx/sbin/nginx -s reload
然后重新访问:
可以看到我们的静态页面已经部署在了nginx中。我们说的“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。”,所以该句中的【Nginx是一款轻量级的Web 服务器】也就不难理解了。
即Nginx用做Web服务器时的简单配置如下:
server {
listen 80;
server_name localhost;
location / {
root resource;
index templates/index.html;
}
}
Nginx用做反向代理
什么是反向代理?什么是正向代理?二者有何区别?找资料时经常可以看到说:
正向代理的代理对象是客户端,反向代理的代理对象是服务端。
但光凭这一句话肯定是理解不了的,不理解的事情,我们就很容易忘记。在学习新知识时,我们对一些新接触的概念得有自己的理解,争取能用自己的话把自己的理解说出来,多思考多总结才有助于我们理解,只有理解了才便于我们的记忆。在工作中接到一项任务时也是,你得有自己的理解,按照自己的理解是要怎么做,能不能做,需要什么支援,有什么风险,大概需要多少时间,你都得做到心里有数,都要及时沟通及时纠正,这样你才能让人放心把事情交给你做,你慢慢地才能成长。说绝大部分工作问题,不来自于技能本身,而来自于沟通,还是很有道理的。关于如何学习与认知,这里强烈推荐咱们毛主席的《实践论》和《矛盾论》,伟人随手的两篇文章就如此惊艳不已,让人拜服。好像又写偏了,回到正文,下面我们举例说明什么是正向代理和反向代理,然后再看Nginx是如何实现反向代理的。
正向代理
举个例子,A同学想去找马云爸爸借钱,可想而知,最后被保安打出来了。然后A同学经过打听知道他的老师王老师是马云的同学,于是A同学找到王老师,托王老师帮忙去马云那借500万过来,当然最后事成了。不过马云并不知道这钱是A同学借的,马云是借给王老师的,最后由王老师转交给A同学。这里的王老师在这个过程中扮演了一个非常关键的角色,就是代理,也可以说是正向代理,王老师代替A同学办这件事,这个过程中,马云(服务端)不知道真正借钱的人(客户端)是谁,这点非常关键。
再举个例子,如今的网络环境下,如果我们有需要去访问某些网站,此时你会发现某些网站我们通过浏览器是没有办法访问的,此时大家可以通过连接一个VPN后进行访问,VPN的方式主要是找到一个可以访问这些网站的代理服务器,我们将请求发送给代理服务器,代理服务器去访问这些网站,然后将访问到的数据传回给我们。
上述这样的代理模式称为正向代理.
正向代理总结:客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式隐藏了真实客户端信息,所以说正向代理的代理对象是客户端。
反向代理
举个栗子,我们很多人都用过淘宝,要知道每天同时连接到淘宝网站的访问人数已经爆表,单个服务器远远不能满足人民日益增长的购买欲望了,此时就出现了一个大家耳熟能详的名词:分布式部署;也就是通过部署多台服务器来解决访问人数限制的问题;淘宝网站中大部分功能也是直接使用nginx进行反向代理实现的。如下图:
上图表示的是全国各地的用户在淘宝客户端发出请求,经过了Nginx 反向代理服务器,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理。此时请求的来源也就是客户端是明确的,但是请求具体是由哪台服务器处理的并不明确。Nginx扮演的就是一个反向代理角色。
反向代理隐藏了真实的服务端,再如我们访问 www.baidu.com 的时候,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道,也不需要知道,你只需要知道反向代理服务器是谁就好了,www.baidu.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到提供真实计算的服务器那里去。Nginx 就是性能非常好的反向代理服务器。
反向代理总结:代理服务器根据客户端的请求,从其关联的一组或多组后端服务器上获取资源,然后再将这些资源返回给客户端;客户端只会得知反向代理的IP地址,而不知道真正提供服务的服务器地址。反向代理隐藏了服务器的信息,所以说反向代理的代理对象是服务端。
所以正向代理和反向代理一起使用就会像下图这样:
所以还是得出:
正向代理的代理对象是客户端,即正向代理隐藏了客户端的信息,代替客户端去向服务器请求资源;
反向代理的代理对象是服务端,即反向代理隐藏了服务端的信息,代替服务端向客户端返回资源。
然后我们看看Nginx是怎么实现的反向代理。
既然要实现反向代理,那首先要有需要代理的服务端,所以我们先建一个基本的springboot项目,打成war包,发布到该服务器的8081端口。(目标服务器可以跟nginx在同一台机器,也可以是不同机器)
然后我们重新配置 nginx.conf 文件,只要简单的配置 proxy_pass 就能够实现反向代理,配置后重新加载nginx。
浏览器再次访问nginx时,nginx就会将请求转发至47.112.148.36:8081端口处理。但是对客户端来说是不知道具体是由哪一台服务器处理的,客户端只知道nginx的ip,即nginx作为反向代理隐藏了服务端的信息。
现在很多公司都是区分内外网的,从安全性考虑,我们要求外网暴露的端口越少越好。我们把nginx暴露给外网,只开放80和443端口,外网请求统一走nginx,nginx调用tomcat全部都走内网ip,这样即使被黑客破解,他能拿到的也是一些静态资源,服务器是安全的。
我们说的“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。”,所以该句中的【Nginx用做反向代理】也就不难理解了。
即Nginx用做反向代理时的简单配置如下:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://47.112.148.36:8081;
}
}
#常用的代理某个api的配置如下:(如将http://ip:80/mapi/list/user请求代理为http://localhost:8080/list/user)
server { listen 80; location /mapi { rewrite ^/mapi/(.*)$ /$1 break; proxy_pass http://localhost:8080; } }
Nginx用做负载均衡
负载均衡,我们就得明白两个概念,什么是负载量?什么是均衡?
客户端向服务器发送的、nginx接收到的请求数量,就是我们说的负载量。
将请求数量按照一定的规则进行分发到不同的服务器处理的规则,就是一种均衡规则。
所以负载均衡就是:将服务器接收到的请求按照规则分发的过程。
负载均衡在实际项目操作过程中,有硬件负载均衡和软件负载均衡两种
硬件负载均衡也称为硬负载,特点:造价昂贵成本较高,数据的稳定性安全性好。
更多的公司考虑到成本原因,会选择使用软件负载均衡,软件负载均衡是利用现有的技术结合主机硬件实现的一种消息队列分发机制。
nginx支持的负载均衡调度算法方式如下:
weight轮询(默认):接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。
ip_hash:每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。
fair:智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块
url_hash:按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。同样要注意nginx默认不支持这种调度算法,要使用的话需要安装nginx的hash软件包。
然后我们看看Nginx是怎么实现的负载均衡。
既然要实现负载均衡,那首先要有两个以上的服务端,所以我们复用之前的tomcat,发布到8082端口。(即需要修改tomcat的server.xml文件中的三个端口,另外为了测试效果,在页面标识一下端口。)
然后我们重新配置 nginx.conf 文件,只要简单的配置 upstream模块和修改 proxy_pass,就能够实现反向代理,配置后重新加载nginx。(server后面可以配置相应属性,如server 47.112.148.36:8081 down | weight=2 | backup | max_fails | fail_timeout 等 ;)
浏览器再次访问nginx时,nginx就会根据负载均衡策略将请求转发给 47.112.148.36:8082 的tomcat处理。但是对客户端来说仍然是不知道具体是由哪一台服务器处理的,客户端只知道nginx的ip,即nginx作为反向代理隐藏了服务端的信息。
再次访问,nginx就会根据负载均衡策略将请求转发给 47.112.148.36:8082 的tomcat处理。但是对客户端来说仍然是不知道具体是由哪一台服务器处理的,客户端只知道nginx的ip,即nginx作为反向代理隐藏了服务端的信息。
总结一点,负载均衡不论是各种软件或硬件上的解决方案,主要还是将大量的并发请求按照一定的规律分发给不同的服务器处理,从而减少某台服务器的瞬时压力,提高网站的抗并发能力。我们可以看到nginx在负载均衡方面是相当灵活的,通过配置一个nginx.conf文件就解决了大部分问题。服务器上只负责把nginx搭好,跑起来即可。而且它本身轻量级,不需要占用服务器太多资源就可以达到较好的效果,毛子写的这个nginx确实腻害。
我们说的“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。”,所以该句中的【Nginx用做负载均衡】也就不难理解了。
即Nginx用做负载均衡时的简单配置如下:
upstream loadBalanceTest {
server 47.112.148.36:8081;
server 47.112.148.36:8082;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://loadBalanceTest;
}
}
#Nginx进行负载均衡时的failover(失效转移)机制实现:Nginx可以通过设置max_fails(最大尝试失败次数)和fail_timeout(失效时间,在到达最大尝试失败次数后,在fail_timeout的时间范围内节点被置为失效)对节点失败的尝试次数和失效时间进行设置
upstream backend_servers {
server localhost:7001 max_fails=3 fail_timeout=30s;
# 下面两行 "backup" 只有在上面 "7001" 服务器失败后才会被访问(此时两台服务器会采用同样的权重进行负载均衡)
server localhost:7002 max_fails=3 fail_timeout=30s backup;
server localhost:7003 max_fails=3 fail_timeout=30s backup;
# 如果为上面两行 "backup" 设定悬殊的 "weight" 参数,可以控制 failover 的顺序(比如设置只有 "7002" 宕机后才会访问到 "7003")
#server localhost:7002 max_fails=3 fail_timeout=30s backup weight=2000000000;
#server localhost:7003 max_fails=3 fail_timeout=30s backup weight=1;
}
Nginx用做动静分离
在用nginx做反向代理并访问首页时,是由tomcat处理并返回首页,可以对比发现tomcat返回首页的效率比nginx做web服务器时的效率慢得多,tomcat最大的优点是它能够通过servlet技术来动态生成资源,实现服务端与客户端的交互,但它对静态资源的处理效率确实比nginx、apache等静态web服务器差得多。所以,为了优化性能,提高访问效率,可以让 Tomcat 处理动态资源,让 Nginx 处理静态资源,就是我们所说的动静分离。
然后我们看看Nginx是怎么实现的动静分离。
既然要实现动静分离,那首先要有动态请求和静态请求,所以在我们项目的index.html页面,添加一个ajax请求,让ajax访问我们后台的资源,相当于模拟一个动态请求。为了直观感受tomcat中请求的变化情况,我们可以在项目中添加一个过滤器来查看所有进入tomcat的请求。相关代码如下:
未配置动静分离前访问nginx,可以看到所有的请求都是nginx交由tomcat来处理。
然后我们重新配置 nginx.conf 文件,只要简单的配置 http 模块,就能够实现动静分离,配置后重新加载nginx。
再次访问,nginx就会根据配置来自己处理静态请求,并根据负载均衡策略将动态请求转发给后端的tomcat处理。
我们说的“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。”,所以该句中的【Nginx用做动静分离】也就不难理解了。
即Nginx用做动静分离时的简单配置如下:
location ~ .*\.(js|css|ico|png|jpg|jpeg|svg|gif|eot|ttf|woff)$ {
root resource;
}#注:nginx又做代理又处理静态资源压力也挺大的,所以一般由一台nginx来专门做代理,另一台nginx专门处理静态资源。
location ~ .*\.(js|css|ico|png|jpg|jpeg|svg|gif|eot|ttf|woff)$ {
proxy_pass 47.112.148.36:80;
}
Nginx用做Http缓存
什么是Http缓存?关于Http缓存可参考这里彻底弄懂HTTP缓存机制及原理。
Nginx除了用做动静分离的方式提高访问效率外,也可以通过设置Http缓存(服务器缓存)的方式提高访问效率。Http缓存主要针如css,js,图片等更新频率不大的静态文件。我们知道未配置动静分离和Http缓存前访问nginx,nginx会把所有请求直接转发到后端的tomcat来处理,配置了Http缓存后,理论上在缓存时间内访问同一个静态资源,Nginx可以直接把资源从缓存中取出并返回,不用再去请求后台。然后我们看看Nginx是怎么实现的Http缓存。
还是通过重新配置 nginx.conf 文件,只要简单的配置 http 模块,就能够实现Http缓存,配置后重新加载nginx。
以上的配置的含义:
- proxy_cache_path:缓存生成的目录路径
- levels:表示创建两级目录结构,缓存目录的第一级目录是1个字符,第二级目录是2个字符;如果将所有文件放在一级目录下的话,文件量很大,会导致文件访问慢。
- keys_zone:设置存储所有缓存key和相关信息的共享内存区,可在location中引用,1M大约能存储8000个key。
- max_size:缓存区硬盘的 最大值。超出闲置数据将被清除。
- inactive:未被访问文件在缓存中保留时间,本配置中如果60分钟未被访问则不论状态是否为expired,缓存控制程序会删掉文件。inactive默认是10分钟。需要注意的是,inactive和expired配置项的含义是不同的,expired只是缓存过期,但不会被删除,inactive是删除指定时间内未被访问的缓存文件。
- proxy_cache:在location中指定缓存区,对应keys_zone中设定的值。
- proxy_cache_valid:对不同的状态码设置缓存有效期。proxy_cache_valid不是唯一设置缓存时间的,还可以通过如下方式(优先级从上到下)。1)以秒为单位的“X-Accel-Expires”响应头来设置响应缓存时间。2)如果没有“X-Accel-Expires”,则可以根据“Cache-Control”、“Expires”来设置响应缓存时间。3)否则,使用proxy_cache_valid设置缓存时间。
- add_header:$upstream_cache_status是缓存响应状态,我们把它添加到响应的头部来观察。其值如HIT:缓存命中,直接返回缓存中内容,不回源到后端;MISS:缓存未命中,回源到后端获取最新的内容等等。
- * use_temp_path:如果为on,则内容首先被写入临时文件(proxy_temp_path ),然后重命名到proxy_cache_path指定的目录;如果设置为off,则内容直接被写入到proxy_cache_path指定的目录,如果需要cache建议off,则该特性是1.7.10提供的。
再次访问nginx,nginx就会根据配置来处理Http缓存,若缓存命中则直接返回,并根据负载均衡策略将动态请求转发给后端的tomcat处理。然后我们看看添加了Http缓存时的访问结果:
可以看到Nginx的Http缓存确实生效了。
我们说的“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。”,所以该句中的【Nginx用做HTTP缓存】也就不难理解了。
即Nginx用做HTTP缓存时的简单配置如下:
proxy_cache_path /usr/local/nginx/tmpcache levels=1:2 keys_zone=mycache:10m max_size=200m inactive=60m;
server {
listen 80;
server_name localhost;location / {
proxy_pass http://loadBalanceTest;
proxy_cache mycache;
proxy_cache_valid 200 304 30m;
proxy_cache_valid any 10m;
#add_header my_cache " cache test: $upstream_cache_status";
}
}
那么,动静分离和HTTP缓存哪个更能提高Web的访问效率呢?可以自己操作试试。或者看看高并发压力下nginx动静分离、nginx代理缓存两种模式的性能比较。
Nginx其它功能简介
我们说“Nginx是一款轻量级的Web 服务器,也可以用做反向代理、负载均衡、动静分离和 HTTP缓存。”,除了上面几个最常见的功能之外,看看Nginx还能怎么玩。(基于反向代理和负载均衡,能玩出很多花样来的)
1. gzip压缩作用
gzip压缩作用:将响应报⽂发送⾄客户端之前可以启⽤压缩功能,这能够有效地节约带宽,并提⾼响应⾄客户端的速度,压缩会消耗nginx的cpu性能。
常用配置:
- gzip on #开启gzip压缩
- gzip_min_length 1k; #最小压缩大小,大于1k才压缩
- gzip_http_version 1.1 #/压缩协议版本
- gzip_comp_level 3 #压缩级别,1-10,数字越大压缩的越好,时间也越长
- gzip_types #压缩类型,根据/usr/local/nginx/conf/mime.types中定义,可以自己补;
- gzip_disable "MSIE [1-6]\." #不压缩,IE6对Gzip不怎么友好,不给它Gzip了
使用实例:
server {
listen 80;
server_name localhost;
location / {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 3;
gzip_types text/plain application/json application/css application/xml application/x-javascript text/javascript image/jpeg image/gif image/png;
}
}
2. Nginx 防盗链
2.1 什么是防盗链
比如http://www.dbspread.com/download/av123.rmvb 这个视频下载地址被其他网站引用,比如在www.test.com的index.html引用xxx/av123.rmvb就叫盗链,我们要禁止这种引用就叫做防盗链
2.2 怎么实现防盗链
在nginx的nginx.conf的server里面配置如下代码
server {
listen 80;
server_name www.dbspread.com *.dbspread.com;
location ~* \.(rmvb|jpg|png|swf|flv)$ { #rmvb|jpg|png|swf|flv表示对rmvb|jpg|png|swf|flv后缀的文件实行防盗链
valid_referers none blocked www.dbspread.com; #表示对www.dbspread.com此域名开通白名单,比如在www.test.com的index.html引用download/av123.rmvb,无效
root html/b;
if ($invalid_referer) { #如果请求不是从www.dbspread.com白名单发出来的请求,直接重定向到403.html这个页面或者返回403
#rewrite ^/ http://www.dbspread.com/403.html;
return 403;
}
}
}
3. Nginx 阻止dos攻击、禁止代理访问
如何设置能限制某个IP某一时间段的访问次数是一个让人头疼的问题,特别面对恶意的ddos攻击的时候。其中CC攻击(Challenge Collapsar)是DDOS(分布式拒绝服务)的一种,也是一种常见的网站攻击方法,攻击者通过代理服务器或者肉鸡向向受害主机不停地发大量数据包,造成对方服务器资源耗尽,一直到宕机崩溃。
cc攻击一般就是使用有限的ip数对服务器频繁发送数据来达到攻击的目的,nginx可以通过HttpLimitReqModul和HttpLimitZoneModule配置来限制ip在同一时间段的访问次数来防cc攻击。
具体实现参考:nginx配置 阻止dos攻击、禁止代理访问
4. Nginx 用做动态服务器
Nginx用做静态资源服务器我们已经知道了,只需要在location中指定root就行,既然Nginx这么强大,那它能不能用做动态资源服务器呢?当然也是可以的!比如Nginx通过Lua语言就可以动态生成 html页面等,这样就相当于是一个动态资源服务器了!
OpenResty(又称:ngx_openresty) 就是一个基于 NGINX 的可伸缩的 Web 平台,由中国人章亦春发起,提供了很多高质量的第三方模块。
OpenResty 是一个强大的 Web 应用服务器,Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,更主要的是在性能方面,OpenResty可以 快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统。
360,UPYUN,阿里云,新浪,腾讯网,去哪儿网,酷狗音乐等都是 OpenResty 的深度用户。
(OpenResty 确实挺好用的,也挺容易!在业务实现比较简单的时候,简直是神器。)
Nginx实现高可用
Nginx作为负载均衡器,所有请求都到了Nginx(对外服务的唯一入口,唯一公网IP),可见Nginx处于非常重点的位置,如果Nginx服务器宕机后端web服务将无法提供服务,或者当并发量真的非常大时,达到十万级别时,一台Nginx还是有极限的。所以必须要有应对方案才行。目前,Nginx实现高可用主要有以下两种解决方案:
方案1:对Nginx进行主从备份保证服务高可用
主从备份,即建立一个备份机。目前Nginx进行主从备份的主流方案是通过Keepalived+Nginx实现双机热备,双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务。大概原理就是主服务器和备份机上都运行高可用(High Availability)监控程序,通过传送诸如“I am alive”这样的信息来监控对方的运行状况(心跳检测机制)。当备份机不能在一定的时间内收到这样的信息时,它就接管主服务器的服务IP并继续提供负载均衡服务;当备份管理器又从主管理器收到“I am alive”这样的信息时,它就释放服务IP地址,这样的主服务器就开始再次提供负载均衡服务。Keepalived具体实现可参考这里。
方案2:通过集群来分担并发压力
如果有多台Nginx想实现负载均衡的话,可建立Nginx分布式集群,方法如下:
1、每台nginx都有公网地址,在域名处设置同个域名多个指向,最简单实现轮洵。但故障切负会慢一点。
2、一台公网nginx通过upstream功能,轮洵、ip、url多方式分发到内网多台nginx。但公网的nginx如果down机的话,内网全段。
3、一对公网nginx加三个公网ip,通过keepalive实现高可用,再upstream到内网(就是我们刚刚上一节讲的主从备份)。
一般来说,上面1、2、3种方法基本可以解决,建议用2或3;
如果并发量真的巨大的话,一般就要借助硬件F5等设备做负载均衡,跟DNS、CDN等服务商合作做域名解析转发、缓存配置,这也是目前大多数大厂的架构配置。
Nginx原理简介
Nginx最初的设计是成为一个Http服务器,一个能够解决C10K问题的服务器,即要能够处理1w以上的连接。Nginx通过基于事件的处理机制解决C10K问题。下面我们看一下Nginx的架构。
Nginx 启动时,会生成两种类型的 进程,一个 主进程(master),一个或多个工作进程(worker)。
主进程(master)充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。
在阻塞式的、一个连接/一个进程的模式中,每个连接需要大量的额外资源和开销,并且上下文切换(从一个进程到另一个进程)非常频繁。而 Nginx 服务器使用 master/worker 多进程模式,在类 unix 系统上,Nginx 可以配置多个 worker,每个worker进程上可以支持数以万计的连接。这些worker进程从不会在网络上停止,每个新连接都会创建一个文件描述符,并消耗工作进程中少量的额外内存,每一个连接的额外消耗都很少。可以说基于异步及非阻塞的事件驱动模型是 Nginx 得以获得 高并发 、 高性能的关键因素 。