Nginx是一个开源的,支持高性能、高并发(特别是静态资源)的www服务和代理服务软件,还具有反向代理复杂均衡功能和缓存服务功能,与lvs负载均衡及Haproxy等专业代理软件相比,nginx部署更简单方便
重要特性:
(1)支持高并发:能支持几万并发连接(静态小文件业务环境)
(2)资源消耗少:在3万并发连接下,开启10个nginx线程消耗的内存不到200MB
(3)可以做HTTP反向代理及加速缓存,即负载均衡功能
(4)具备专业缓存软件的缓存功能
(5)支持异步网络I/O事件模型epoll
Nginx软件的主要企业功能该应用
(1)作为Web服务器
(2)作为反向代理或负载均衡服务器
(3)作为前端业务数据缓存服务(缓存的是图片和视频,用来降低存储压力,作为web缓存而非数据库缓存,静态文件)
Web服务产品性能对比测试
在处理静态小文件(小于1MB时),nginx和Lighttpd比Apache更有优势,nginx处理小文件的优势明显,Lighttpd综合最强。
在处理动态数据时。Apache更有优势,因为处理动态数据的能力取决于PHP(Java)和后端数据库的服务能力。
Nginx总体性能比Apache高的原因
Nginx使用最新的epoll和kqueue(freebsd)异步网络I/O模型,而Apache使用的是select模型(同步阻塞I/O网络模型)。目前Linux下能够承受高并发访问的Squid,Memcached软件采用的都是epoll(异步I/O非阻塞模型)
模型。
处理大量连接的读写时,Apache所采用的select网络I/O模型比较低效。
Nginx承受的并发大,Apache承受的并发小
(1)同步阻塞I/O模型:线程干活时,是一件事一件事的干,向磁盘读写数据时,线程需要等待磁盘I/O完成
(2)异步非阻塞I/O模型:线程干活时,可以同时做多件事情,永不等待,向磁盘读写数据时,线程不需要等待而是先做其他事情
Nginx是利用线程来接待用户,而一个进程里有很多很多的进程(最多可以65536个,线程本身堆内存的占用非常少
但是,在极高并发状态下,线程间并不稳定,容易产生资源上的冲突
(1)静态业务(无人工参与就无法改变的数据,图片、视频、以.html结尾的静态网页):若是高并发场景,尽量采用nginx或Lighttpd,二者首选nginx
(2)动态业务(需要从MySQL里取数据):理论上采用nginx和Apache均可,建议选择nginx,为了避免相同业务的服务软件多样化,增加额外维护成本。动态业务可以由nginx兼做前端代理,再根据页面元素的类型或目录,转发到后端相应的服务器进行处理。
既有静态业务又有动态业务:采用nginx
Nginx的编译安装
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
# wget -O /etc/yum.repos.d/163.repo http://mirrors.163.com/.help/CentOS6-Base-163.repo
# yum -y install pcre-devel openssl-devel
# yum -y install gcc gcc-c++ make
# tar xf nginx-1.10.2.tar.gz -C /usr/src/
# useradd -s /sbin/nologin -M www
# cd /usr/src/
# ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
# make
# make intall
创建软链接
# ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
# cd /usr/local/nginx/
# ls
conf html logs sbin(配置文件、网页、日志、命令)
# cd conf/
# pwd
/usr/local/nginx/conf
排除#和空行,查看nginx.conf配置文件
# egrep -v "#|^$" nginx.conf.default > nginx.conf
# cat nginx.conf | wc -l
22
# vim nginx.conf
精简nginx配置文件
函数体外面的配置命令都是全局生效
(1)worker_processes Nginx工作的进程个数,CPU是几核的就可以配几
(2)events函数(事件函数)
worker connections表示进程里工作的线程个数,每个线程可以接待一个用户,默认值1024;工作中配成它的20倍,20480为参考值(同时结合Linux系统一同优化,eg,文件打开数(Linux每个进程默认1024个)等)
(3)http函数表示Web服务
(4)include支持的数据类型,把媒体类型的所有内容导入到当前脚本(相对路径是当前配置文件的路径)
(shell语言中,include可以将另一个文件的代码导入当前文件的相对位置)
(5)default_type默认类型 nginx默认一程序模式启动
(6)sendfile文件的高效传输功能,默认开启
(7)keepalive连接保持功能持续(超时时间)65秒;工作环境中,可以考虑90-180秒,最多不超过5分钟
连接保持指打开网页需要建立三次握手,若没有连接保持代表浏览器完成解析后,TCP三次握手直接断开,若有连接保持,解析完成后TCP三次握手仍然建立状态,等待下次请求,无需频繁建立三次握手;可以节约系统资源
(8)server函数 虚拟网站
一个Server函数代表一个虚拟网站,几个server代表几个网站
listen:socket进程的监听端口:80
server_name:域名(主机名)www.yunjisuan.com
(9)location函数
root:网页的根目录路径,该相对路径是nginx的安装路径
index:索引(首页)指网站的首页是哪个网页文件;默认跳转首页的名字
将域名修改为www.yunjisuan.com
启动nginx进程(绝对路径或通关软链接)
# /usr/local/nginx/sbin/nginx
# cd ..
# ls
# cd html
# rm -rf *
# echo "`hostname -I` www.yunjisuan.com" >> /etc/hosts
# mkdir www
# echo "`hostname -I` www.yunjisuan.com" > www/index.html
# cat www/index.html
192.168.214.140 www.yunjisuan.com
# curl www.yunjisuan.com
192.168.214.140 www.yunjisuan.com
查看Web服务器当前状态的并发连接数(进入数据传输状态的情况下)
# netstat -an | grep ESTAB | wc -l
用Windows系统访问浏览器
我的电脑——Windows——Windows——system32——drivers——etc——hosts
复制文件,在文件中更改相应的IP地址,在覆盖原有hosts文件;用原始浏览器输入相应域名,此时浏览器显示网页
修改nginx.conf的root 将html改为html/www
重启配置文件
# /user/local/nginx/sbin/nginx -s reload
此时,Windows的浏览器无法访问网页
在html目录下,创建www目录,将源html目录下的index.html移动到www目录下,此时浏览器可以正常访问
若在www目录下创建zzz目录,在zzz目录下的index.html文件下写入内容,在不修改配合文件的情况下访问浏览器,如下操作:
在网址处输入www.yunjisuan.com/zzz/index.html,其中www.yunjisuan.com/已经在www目录下,/表示根,因此www目录下的zzz目录下的index.html用/zzz/index.html表示就可以正常访问浏览器
创建三个网页
套用三个server函数
重启配置文件
# /usr/local/nginx/sbin/nginx -s reload
# cd html/
# mkdir bbs blog(在html目录下)
# echo “`hostname -I` bbs.yumjisuan.com” > bbs/index.html
# echo “`hostname -I` blog.yumjisuan.com” > blog/index.html
追加域名到映射文件
# vim /etc/hosts
用域名访问浏览器,浏览器能够接收到IP地址
用IP地址访问浏览器时,多网页使用同一个IP地址时,浏览器默认访问IP地址对应的第一个域名所在的网页
一个web服务器搭建多个网站有三种方法:
(1)基于不同域名的虚拟网站
所谓基于域名的虚拟主机,意思就是通过不同的域名区分不同的虚拟主机,基于域名的虚拟主机是企业应用最广的虚拟主机类型,几乎所有对外提供服务的网站都是使用基于域名的虚拟主机,例如:www.etiantian.org
(1)基于不同监听端口的虚拟网站
所谓基于端口的虚拟主机,意思就是通过不同的端口来区分不同的虚拟主机,此类虚拟主机对应的企业应用主要为公司内部的网站,例如:一些不希望直接对外提供用户访问的网站后台等,访问基于端口的虚拟主机地址里要带有端口,例如:http://www.baidu.com:80
(2)基于不同IP的虚拟网站(一台服务器可以有两个网卡)
所谓基于IP的虚拟主机,意思就是通过不同的IP区分不同的虚拟主机,此类虚拟主机对应的企业应用非常少见,一般不同业务需要使用多IP的场景都会在负载均衡器上进行VIP绑定,而不是在Web上通过绑定IP区分不同的虚拟机
#default_server
这种方法可以禁止非发用户(直接用IP地址访问,不经过DNS解析的用户)访问该网页,操作:添加一个server,设置返回码,也可以然该用户看一个错误页面;可以用deny all拒绝所有用户的访问
套用include参数
在extra/bbs.conf中编辑server函数
在extra/www.conf中编辑server函数
此时nginx.conf配置文件中值保留blog的server函数,并在该函数中添加include参数,启动www域名的server函数及bbs域名的server函数
修改配置文件后平滑重启reload,访问浏览器
Include的作用:当网站的server越来越大,去专门的配置文件下就能进行修改;工作中每一个网站会独立出它的配置来,具体要修改的内容在网站配置文件就可以进行修改,无需再主配置文件中修改,这是降低耦合度的一种方式(高聚内低耦合)
Nginx状态信息功能实战
(1)确认编译时是否设定了此模块
这个状态信息检测可以显示nginx目前有多少人访问、处理了多少需求、进行了多少次TCP三次握手的数据等
--with-http_stub_status_module模块就是状态信息模块
(2)设定信息模块配置
# cd /usr/local/nginx/conf
# mkdir extra
# cd extra
# vim status.conf
stub_status on; #开启状态信息功能
access_log off; #不记录访问日志
需要重启nginx服务
(3)Nginx status显示结果详解
第一个server表示你想你想启动到现在一共处理了39个连接
第二个accepts表示nginx启动到现在共成功创建了39次握手
请求丢失书=(握手数-连接数)
第三个handled requests,表示总共处理了41次请求
Reading为nginx读取到客户端的header信息数
Writing为nginx返回给客户端的header信息数
Waiting为nginx已经处理完正在等候下一次请求指令的驻留连接;在开启keep-alive的情况下,这个值等于active - (reading+writing)
(4)添加错误日志(全局环境,函数体之前定义)
错误日志error_log的默认值为:error_log logs/error.log error;
访问日志access_log
(5)Nginx访问日志轮训切割(移动并改名)
默认情况下nginx会把所有的访问日志生成到一个指定的访问文件access.log里,仍有必要对nginx日志,按天或小时进行切割,使其分成不同的文件保存。
# vim /server/scripts/cut_nginx_log.sh
切割后需要重启nginx配置文件
添加server时要注意的步骤(非常重要!):
(1)在服务器映射文件/etc/hosts中添加IP地址及域名
# vim /etc/hosts
在Windows系统映射文件/etc/hosts中添加IP地址及域名
我的电脑——Windows——Windows——system32——drivers——etc——hosts
复制文件,在文件中更改相应的IP地址,在覆盖原有hosts文件;用原始浏览器输入相应域名,此时浏览器显示网页
(2)在nginx.conf配置文件中编辑server函数
# vim /usr/local/nginx/conf/nginx.conf
(3)在网页目录的索引文件中添加内容
# cd html
# mkdir bbs blog
# echo “`hostname -I` bbs.yumjisuan.com” > bbs/index.html
# echo “`hostname -I` blog.yumjisuan.com” > blog/index.html
(4)重启配置文件
# /user/local/nginx/sbin/nginx -t 查看配置文件编辑是否正确
# /usr/local/nginx/sbin/nginx -s reload
(5)若配置文件中只引用一个server函数,其他域名用include参数导入配置文件,则需要在conf目录中额外创建一个目录,在新创建的extra目录中编辑其他域名的配置文件
# mkdir extra
# cd extra/
# vim bbs.conf
# vim www.conf
# vim status.conf
(6)模拟浏览器访问
# curl status.yunjisuan.com
Nginx location
(1)location使用的语法
(2)location函数是过滤函数,可以通过正则表达式来匹配不同URL里的URI部分。匹配到不同的URI进入到不同的location,也就可以进入到不同的网页目录
因此,location过滤的优先级
(1)location / 模糊匹配一个根/,只要含有一个根/就行(URI部分永远有一个根/符号)
(2)location = / 精确匹配,URI部分只能有根符号/才行(精确匹配优先级比默认匹配高)
(3)location = /images/ 精确匹配到/images/才可以
(4)location /images 字符串匹配
(5)location /documents/ 模糊匹配常规/documents/字符串,前缀型模糊匹配(必须从根URI开始,后面可以任意);如果有正则检查,正则优先(字符串之间的优先级:字符串长度越大优先级越高)
(6)location ~ /images/ 精确匹配,~普通正则,区分大小写
(7)location ^~ /images/ 精确匹配(优先级高于location /images/字符串匹配 )前缀型正则匹配(以/images/开头才识别)先进行字符串的前缀匹配,如果匹配到就不做正则匹配检查
(8)location ~* . (gif|jpg|jpeg) $ 正则匹配不需要从头开始,只要含有就行(优先级高于字符串匹配),*为对后面不区分大小写
~普通正则,区分大小写
*不区分大小写
~*对后面不区分大小写
= 表示URI部分只能是=等号后边的部分,不能有多余的东西
通过location的匹配实验,确定location五种过滤方式的优先级关系
(1)精确匹配(=)
(2)特殊正则(^~)
(3)普通正则(~或者~*)
(4)字符串前缀匹配(/images/优先级高于/images)
(5)默认匹配(/)
验证写入配置文件的内容是否正确
# /user/local/nginx/sbin/nginx -t
Ngnix rewrite
作用:实现URL地址的重写
Nginx的rewrite规则需要PCRE软件的支持,即通过Perl兼容正则表达式语法进行规则匹配。默认参数编译时,Nginx就会安装支持rewrite的模块,但是,也必须要有PCRE软件的支持。
(1)指令语法:rewrite regex replacement 【flag】
默认值:none
应用位置:server,location,if
rewrite是实现URI重写的关键指令(表示开启一条rewrite匹配规则),根据regex(正则表达式)部分的内容 ,重定向到replacement部分(把匹配到的URL进行重写),结尾是flag标记
rewrite ^/(.*) http://www.baidu.com/$1 permanent
在上述指令中,rewrite为固定关键字,表示开启一条rewrite匹配规则,regex部分是URI ^(.*),这是一个正则表达式,表示匹配所有,匹配成功后跳转到http://www.baidu.com/$1 。这里的$1(相当于sed命令中的1)是取前面regex部分括号里的内容,结尾的permanent;是永久301重定向标记,即跳转到后面的http://www.baidu.com/$1 地址上。
(2)regex常用正则表达式说明
(3)rewrite指令的最后一项参数flag标记的说明
在以上的flag标记中,last和break用来实现URL重写,浏览器地址栏的URL地址不变,但在服务器端访问的程序及路径发生了变化。redirect和permanent用来实现URL跳转,浏览器地址栏会显示跳转后的URL地址。
last和break标记的实现功能类似,但二者之间有细微的差别,使用alias指令时必须用last标记,使用proxy_pass指令时要使用break标记。last标记在本条rewrite规则执行完毕后,会对其所在的server{...}标签重新发起请求,而break标记则会在本条规则匹配完成后,终止匹配,不再匹配后面的规则。
Nginx的rewrite功能在企业里应用非常广泛:
可以调整用户浏览的URL,使其看起来更规范,合乎开发及产品人员的需求。
为了让搜索引擎收录网站内容,并让用户体验更好,企业会将动态URL地址伪装成静态地址提供服务
网站换新域名后,让旧域名的访问跳转到新的域名上,例如:让京东的360buy换成了jd.com
根据特殊变量,目录,客户端的信息进行URL跳转等。
Nginx rewrite 301 跳转
通过别名方式实现yunjisuan.com和www.yunjisuan.com访问同一个地址的
实现不同域名的URL跳转
实现访问http://mail.yunjisuan.com时跳转到http://www.yunjisuan.com/mail/yunjisuan.html
(.*)在重写中为$1(只能重复一次),再出现(.*)时它的值就会发生变化;因此,将$1的值赋给别的变量$domain ,set设置命令:set 变量=值;
把$1d的值赋给了前面的变量,再将这个临时变量重新赋给了“重写”指令
rewrite跳转标记flag使用总结
(1)在根location(即location / {...})中或server{...} 标签中编写rewrite规则,建议使用last标记
(2)在普通的location(例 location/yunjisuan/{...}或if{}中编写rewrite规则,则建议使用break标记)
Nginx访问认证
有时,在实际工作中企业要求我们为网站设置访问账号和密码权限,这样操作后,只有拥有账号密码的用户才可以访问网站内容。
这种使用账号密码才可以访问网站的功能主要应用在企业内部人员访问的地址上,例如:企业网站后台,MySQL客户端phpmyadmin,企业内部的CRM,WIKI网站平台。
创建密码文件
借用apache的htpasswd软件,来创建加密的账号和密码
# which htpasswd
# htpasswd -bc /usr/local/nginx/conf/htpasswd yunjisuan 123123
Adding password for user yunjisuan
# cat /usr/local/nginx/conf/htpasswd
yunjisuan:FC1/eEc/iK0Mo #账号密码是加密的(htpasswd是文件的名字)
在虚拟主机配置文件里加入两条配置信息
网页登陆验证
Tengine是淘宝开源Nginx的分支,官方站点为http://tengine.taobao.org/
访问Nginx时出现状态码“403 forbidden”的原因
如果输入域名时,不告诉浏览器看哪个页面,nginx会自动将页面跳转到首页;然而,跳转过程中发现找不到首页时,会默认将整个网页的内容显示出来,此时nginx的安全机制拒绝用户访问,就触发了nginx安全模块,显示403。
(1)Nginx配置文件里没有配置默认首页参数,或者首页文件在站点目录下没有如下内容:
index index.php index.html index.htm;
# vim /usr/local/nginx/conf/extra/www.conf
重启配置文件,此时显示网页目录全部显示出来
(2)站点目录或内部的程序文件没有Nginx用户访问权限
如果用户对目录没有x权限,就进不去这个目录
(3)Nginx配置文件中设置了allow,deny等权限控制,导致客户端没有访问权限。
(4)return 403
nginx的404访问报错有可能是什么原因?
服务器找不到客户端请求的指定页面,可能是客户端请求了服务器上不存在的资源导致。
排错:
# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf