最近发现各类招聘网站的JD(job description)里面,在招聘Java时都要求会nginx,三年半前,我在工作中接触过nginx,当时仅仅是在用的层面,没有去总结。过年在家无聊就写一篇总结下。
按照日常套路:
一、什么是Nginx?
Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。Nginx是由俄罗斯人 Igor Sysoev为俄罗斯访问量第二的 Rambler.ru站点开发的,它已经在该站点运行超过几年。Igor Sysoev在建立的项目时,使用基于BSD(BSD开源协议是一个给予使用者很大自由的协议。基本上使用者可以"为所欲为",可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布)许可。自Nginx 发布来,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
二、Nginx的优点
1、高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2~3万并发连接数
2、内存消耗低:在3万并发连接下,开启的10个Nginx 进程才消耗150M内存(15M*10=150M)
3、配置文件非常简单:风格简单易懂
4、成本低廉:Nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币
5、支持Rewirte重写规则:能够根据域名、URL的不同,将 HTTP 请求分到不同的后端服务器群组
6、内置的健康检查功能:如果 Nginx Proxy 后端的某台 Web 服务器宕机了,不会影响前端访问
7、节省带宽:支持 GZIP 压缩,可以添加浏览器本地缓存的 Header 头
8、稳定性高:用于反向代理,宕机的概率微乎其微
Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 。它支持内 核Poll模型,能经受高负载的考验,有报告表明能支持高达 50,000个并发连接数。 Nginx具有很高的稳定性,其它HTTP服务器当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应只能重启服务器。例如当前Apache一旦上到200个以上进程,web响应速度就明显非常缓慢了。而Nginx采取了分阶段资源分配技术,使得它的CPU与内存占用率非常低。Nginx官方表示保持 10,000个没有活动的连接,它只占2.5M内存,所以类似DOS这样的攻击对Nginx来说基本上是毫无用处的。就稳定性而言,nginx比lighttpd更胜一筹。 Nginx支持热部署,它的启动特别容易, 并且几乎可以做到7*24不间断运行,即使运 行数个月也不需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。 Nginx采用master-slave(现在大家提倡用master-follower描述,slave一词具有歧视,世界范围内慎用)模型,能够充分利用SMP的优势,且能够减少工作进程在磁 盘I/O的阻塞延迟。 Nginx代码质量非常高,代码很规范,手法成熟, 模块扩展也很容易。 Nginx采用了一些os提供的最新特性如对sendfile (Linux2.2+),accept-filter(FreeBSD4.1+),TCP_DEFER_ACCEPT (Linux 2.4+)的支持,从而大大提高了性 能
三、谁在使用nginx
Nginx所占市场份额不断提升:
国内有企业有哪些在使用nginx服务器:新浪、网易、腾讯、CSDN、酷六、水木社区、豆瓣、六房间、小米等
四、Nginx与Apache的区别
Nginx和Apache一样,都是一个HTTP服务器软件,功能实现上都采用模块化结构设计,都支持通用的语言接口,如PHP、Perl、Python等,同时还支持正、反向代理,虚拟主机,URL重写,压缩传输,SSL加密传输等。它们之间最大的差别是Apache处理速度很慢,且占用很多内存资源,而Nginx却恰恰相反;在功能实现上,Apache的所有模块都支持动、静态编译,而Nginx模块都是静态编译的,同时,Apache对Fcgi(快速通用网关接口)支持不好,而Nginx对Fcgi的支持非常的好;最重要的是,在处理连接方式上,Nginx支持epoll(epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率),而Apache却不支持;在大小上,Nginx安装包仅仅有几百K,和Nginx比起来Apache绝对是庞然大物。在了解了Nginx和Apache之间的异同点后基本知道了Nginx作为HTTP服务器的优势所在。
五、Nginx的安装
①在windows上的安装
1、下载nginx的windows版本: http://nginx.org/download
选择一个版本进行下载即可。
2、将压缩文件解压到非中文的目录下(绿色软件只需要压缩即可)
3、Nginx的启动和停止(前提:确保apache关闭),进入解压目录,在解压目录下执行 start nginx.exe 命令,启动后再浏览器中可以访问地址即可。
nginx -s stop 快速关闭
nginx -s quit 安全关闭
nginx -s reload 重载配置文件
nginx -s reopen 重新打开日志文件
以上是Nginx停止命令。
配置重启和关闭的控制器台:
3.1 拷贝nginx.bat 文件到nginx文件夹下:
3.2 修改nginx.bat 文件中配置。配置nginx的安装路径
3.3 使用nginx.bat控制nginx
①在linux上的安装。linux上的安装,流程多一点,为了不让一篇文档篇篇幅过长,我后面单独写一篇linux服务器上安装Nginx的安装流程。
六、Nginx的配置文件详细分析
1、认识配置文件:
Linux 下基本上每个服务都会有它的主配置文件,该文件会定义服务应该如何去运行,使用些什么参数,启用些什么功能,相关会涉及到的一些操作文件在哪,所以主配置文件对 服务是至关重要的。下面我们来分析一下 Nginx 的主配置文件。
Nginx的主配置文件默认情况下位于/usr/local/nginx/nginx.conf 以下为Nginx配置文件一些参数的注释。
样例参考该配置文件:
#指定使用的用户
#user nobody;
#启动进程,通常设置成和cpu的数量相等
worker_processes 1;
#全局错误日志
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#PID文件--存放进程号的文件
#pid logs/nginx.pid;
#工作模式及连接数上限
events {
#单个后台worker process进程的最大并发链接数
worker_connections 1024;
#并发总数是 worker_processes 和 worker_connections 的乘积
#Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过 use指令指定。
#use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
#use epoll; #使用 epoll(linux2.6的 性能方式 )
#select - 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-select_module 和 –without-select_module 来启用或禁用这个模块。
#poll - 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数–with-poll_module 和 –without-poll_module 来启用或禁用这个模块。
#kqueue - 效的方法,使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的 MacOS X系统使用 kqueue可能会造成内核崩溃。
#epoll - 效的方法,使用于Linux内核2.6版本及以后的系统。在某些发行版本中,如 SuSE 8.2,有让2.4版本的内核支持epoll的补丁。
#rtsig - 可执行的实时信号,使用于Linux内核版本 2.2.19以后的系统。可是从Linux内核版本2.6.6-mm2开始,这个参数就不再使用了.
#/dev/poll - 效的方法,使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+.
#eventport - 效的方法,使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装 这个 安全补丁。
}
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
#开启gzip压缩
#gzip on;
#设定虚拟主机配置
server {
#侦听80端口
listen 80;
#定义使用 www.nginx.cn访问
server_name localhost;
#定义服务器的默认网站根目录位置
root html;
#设置编码
#charset koi8-r;
#设定本虚拟主机的访问日志
#access_log logs/host.access.log main;
#默认请求
location / {
root html;
#定义首页索引文件的名称
index index.html index.htm;
}
# 定义错误提示页面
#error_page 404 /404.html;
#redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#PHP脚本转给apache处理
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
# 禁止访问 .htxxx 文件
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
2、配置文件的结构:
nginx.conf由多个块组成,最外面的块是main,main包含events和http,http包含多个upstream和多个server,server又包含多个location:
main(全局设置)、server(虚拟主机设置)、upstream(负载均衡服务器设置)和 location(URL匹配特定位置的设置)。
- main块设置的指令将影响其他所有设置;
- server块的指令主要用于指定主机和端口;
- upstream指令主要用于负载均衡,设置一系列的后端服务器;
- location块用于匹配网页位置。
这四者之间的关系式:server继承main,location继承server,upstream既不会继承其他设置也不会被继承。
在这四个部分当中,每个部分都包含若干指令,这些指令主要包含Nginx的主模块指令、事件模块指令、HTTP核心模块指令,同时每个部分还可以使用其他HTTP模块指令,例如Http SSL模块、HttpGzip Static模块和Http Addition模块等。
2.1 Nginx 的全局配置
#指定使用的用户和组
#user nginx nginx;
#启动进程,通常设置成和cpu的数量相等
worker_processes 1;
#全局错误日志
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#PID文件--存放进程号的文件
#pid logs/nginx.pid;
创建全局配置中nginx需要的运行用户:
groupadd nginx
useradd -g nginx nginx
2.2 events 配置: 服务器为linux时, 请将use epoll打开,利用linux的内核提供性能优化方案
#工作模式及连接数上限
events {
#单个后台worker process进程的最大并发链接数
worker_connections 1024;
#并发总数是 worker_processes 和 worker_connections 的乘积
#Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过 use指令指定。
#use [ kqueue | rtsig | epoll | /dev/poll | select | poll];
use epoll; #使用 epoll(linux2.6的 性能方式 )
}
2.3 http 配置:
http {
#Nginx对HTTP服务器相关属性的配置
include mime.types;
default_type application/octet-stream;
#设定虚拟主机配置
server {
#侦听80端口
listen 80;
#定义使用 www.itsource.cn访问
server_name www.itsource.cn;
location {
}
location {
}
…..
}
server {
#侦听80端口
listen 80;
#定义使用 www.example.cn访问
server_name www.example.cn;
location {
}
location {
}
…..
}
}
include是个主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度。类似于Apache中的include方法。
default_type属于HTTP核心模块指令,这里设定默认类型为二进制流,也就是当文件类型未定义时使用这种方式,例如在没有配置PHP环境时,Nginx是不予解析的,此时,用浏览器访问PHP文件就会出现下载窗口。
server块的指令主要用于指定主机和端口(虚拟主机);
location部分主要用于匹配网页位置,设置不同的功能特征. 比如:缓存,重定向等
2.4 重要指令之 location
location部分主要用于匹配网页位置,设置不同的功能特征. 比如:缓存,重定向等..
实例:
有扩展名以.gif、.jpg、.jpeg、.png、.bmp、.swf结尾的静态文件都交给nginx处理,而expires用来指定静态文件的过期时间,这里是30天
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
root /wwwroot/www.itsource.com;
expires 30d;
}
upload和html下的所有文件都交给nginx来处理,当然,upload和html目录包含在/web/wwwroot/www.itsource.cn目录中
location ~ ^/(upload|html)/ {
root /web/wwwroot/www.itsource.com;
expires 30d;
}
location是对此虚拟主机下动态网页的过滤处理,也就是将所有以.php为后缀的文件都交给本机的8080端口处理
location ~ .*.php$ {
index index.php;
proxy_pass http://localhost:8080;
}
location的语法:
- ~ #波浪线表示执行一个正则匹配,区分大小写
- ~* #表示执行一个正则匹配,不区分大小写
- ^~ #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
- = #进行普通字符精确匹配
- location中可以接受一下的语法规则
location = / {
# 只匹配"/".
[ configuration A ]
}
location / {
# 匹配任何请求,因为所有请求都是以"/"开始
# 但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg结尾的请求.
# 但是所有 /images/ 目录的请求将由 [Configuration C]处理.
[ configuration D ]
}
优先级:
1、=前缀的指令严格匹配这个查询。如果找到,停止搜索。
2、所有剩下的常规字符串,最长的匹配。如果这个匹配使用^〜前缀,搜索停止。
3、正则表达式,在配置文件中定义的顺序。
4、如果第3条规则产生匹配的话,结果被使用。否则,如同从第2条规则被使用。
请求URI例子:
/ -> 符合configuration A
/documents/document.html -> 符合configuration B
/images/1.gif -> 符合configuration C
/documents/1.jpg ->符合 configuration