1、Nginx介绍
Nginx专为性能优化而开发,其最大的优势就是它的稳定性和低系统资源消耗,以及对http并发链接的高处理能力,单台物理服务器可支持20000~50000个并发请求,正是如此,大量提供社交网络、新闻资讯、电子商务及虚拟主机等服务的企业纷纷选择Nginx来提供web服务,目前中国大陆使用nginx网站用户有:新浪、网易、腾讯,另外知名的微网志Plurk也使用nginx。css
Nginx是一个很牛的高性能Web和反向代理服务器,它具备有不少很是优越的特性:html
高并发链接:官方测试能支撑5万并发链接,在实际生产环境中跑到2,~3W并发链接。
内存消耗少:在3W并发链接下,开启的10个NGINX进程才消耗150M内存(15M*10=150M)
配置文件很是简单:风格跟程序同样通俗易懂。
成本低廉:Nginx做为开源软件,能够无偿使用,而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则须要十多万至几十万人民币。
支持rewrite重写规则:可以根据域名、URL的不一样,将HTTP请求分发到不一样的后端服务器群组。
内置的健康检查功能:若是Nginx Proxy后端的后台web服务器宕机了,不会影响前端访问。
节省带宽:支持GZIP压缩,能够添加浏览器本地缓存的Header头。
稳定性高:用于反向代理,宕机的几率微乎其微。
对于一个 Web 服务器来讲,一个请求的基本过程是:创建链接—接收数据—发送数据,在系统底层看来 :上述过程(创建链接—接收数据—发送数据)在系统底层就是读写事件。
若是采用阻塞调用的方式,当读写事件没有准备好时,那么就只能等待,当前线程被挂起,等事件准备好了,才能进行读写事件。
若是采用非阻塞调用的方式:事件立刻返回,告诉你事件还没准备好呢,过会再来吧。过一会,再来检查一下事件,直到事件准备好了为止,在这期间,你就能够先去作其它事情,而后再来看看事件好了没。虽然不阻塞了,但你得不时地过来检查一下事件的状态,你能够作更多的事情了,但带来的开销也是不小的。非阻塞调用指在不能马上获得结果以前,该调用不会阻塞当前线程前端
非阻塞经过不断检查事件的状态来判断是否进行读写操做,这样带来的开销很大,所以就有了异步非阻塞的事件处理机制。这种机制让你能够同时监控多个事件,调用他们是非阻塞的,但能够设置超时时间,在超时时间以内,若是有事件准备好了,就返回。这种机制解决了上面阻塞调用与非阻塞调用的两个问题。
以 epoll 模型为例:当事件没有准备好时,就放入 epoll(队列)里面。若是有事件准备好了,那么就去处理;当事件没有准备好时,才在 epoll 里面等着。这样,咱们就能够并发处理大量的并发了,固然,这里的并发请求,是指未处理完的请求。线程只有一个,因此同时能处理的请求固然只有一个了,只是在请求之间进行不断地切换而已,切换也是由于异步事件未准备好,而主动让出的。这里的切换是没有任何代价,能够理解为循环处理多个准备好的事件。
多线程方式相比,这种事件处理方式是有很大的优点的,不须要建立线程,每一个请求占用的内存也不多,没有上下文切换, 事件处理很是的轻量级,并发数再多也不会致使无谓的资源浪费(上下文切换)。对于 apache 服务器,每一个请求会独占一个工做线程,当并发数上到几千时,就同时有几千的线程在处理请求了。这对操做系统来讲,是个不小的挑战:由于线程带来的内存占用很是大,线程的上下文切换带来的 cpu 开销很大,天然性能就上不 去,从而致使在高并发场景下性能降低严重。
总结:经过异步非阻塞的事件处理机制,Nginx 实现由进程循环处理多个准备好的事件,从而实现高并发和轻量级。
2、搭建Nginx服务器
Nginx官方下载地址:http://nginx.org/download/
本人提供的下载地址:https://pan.baidu.com/s/1PL0GyzRQ8zSPD74309R44g
提取码:4mt4
一、将nginx-1.14.0.tar.gz上传至服务器(因为后面有一个升级Nginx的操做,因此先安装一个低版本的Nginx)nginx
[root@nginx ~]# rz #在xshell中上传所需源码包 [root@nginx ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src #解包 [root@nginx ~]# cd /usr/src/nginx-1.14.0/ #切换至解压后的目录 [root@nginx nginx-1.14.0]# useradd -M -s /sbin/nologin nginx #建立运行Nginx的用户 [root@nginx nginx-1.14.0]# yum -y erase httpd #卸载系统自带的httpd服务,以避免冲突 [root@nginx nginx-1.14.0]# yum -y install openssl-devel pcre-devel [root@nginx nginx-1.14.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module && make && make install
3、Nginx服务的版本升级至1.2web
[root@nginx nginx-1.14.0]# /usr/local/nginx/sbin/nginx #启动Nginx服务 [root@nginx nginx-1.2.4]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.14.0 #注意,如今版本为nginx/1.14.0 .......................#省略部分信息 [root@nginx ~]# rz #在xshell中上传所需源码包 [root@nginx ~]# tar zxf nginx-1.2.4.tar.gz -C /usr/src #解压 [root@nginx ~]# cd /usr/src/nginx-1.2.4/ #切换至解压后的路径 [root@nginx nginx-1.2.4]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module && make #注意,升级时,不要执行make install 命令,不然会覆盖原有的低版本配置文件 [root@nginx nginx-1.2.4]# pwd #确认当前路径 /usr/src/nginx-1.2.4 [root@nginx nginx-1.2.4]# mv /usr/local/nginx/sbin/nginx nginx.bak #将旧版本的服务控制命令进行改名 [root@nginx nginx-1.2.4]# cp objs/nginx /usr/local/nginx/sbin/ #复制新生成的控制命令至指定目录 [root@nginx nginx-1.2.4]# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` #生成新的PID号 [root@nginx nginx-1.2.4]# kill -HUP `cat /usr/local/nginx/logs/nginx.pid` #重启Nginx服务 [root@nginx nginx-1.2.4]# /usr/local/nginx/sbin/nginx -V #查看是否已经升级 nginx version: nginx/1.2.4 #版本为1.2.4,升级成功
4、修改Nginx服务头部信息
通常是为了提升安全性,咱们会对客户端进行隐藏Nginx的版本信息,具体操做以下:正则表达式
#修改前,客户端访问,能够看到咱们Nginx服务器的版本等信息,以下: [root@nginx nginx-1.2.4]# curl -I 127.0.0.1 #获取头部信息 HTTP/1.1 200 OK Server: nginx/1.2.4 #版本信息显示的很详细 Date: Thu, 17 Oct 2019 14:40:50 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Thu, 17 Oct 2019 14:20:40 GMT Connection: keep-alive Accept-Ranges: bytes #如今进行修改以下: [root@nginx nginx-1.2.4]# pwd #肯定当前工做路径在源码包中 /usr/src/nginx-1.2.4 [root@nginx nginx-1.2.4]# vim src/core/nginx.h #修改该文件,随便修改便可 #define nginx_version 1002004 #define NGINX_VERSION "666" #这里为版本号信息 #define NGINX_VER "ljz/" NGINX_VERSION #这里原来为Nginx,现更改成ljz #注意,上述配置项前面的注释符号不用删除 #更改完成后,保存退出便可 [root@nginx nginx-1.2.4]# vim src/http/ngx_http_header_filter_module.c #编辑该配置文件 static char ngx_http_server_string[] = "Server: ljz" CRLF; #搜索“nginx”,定位到该行,而后更改其中原来的nginx为ljz,注意,这里必须和前一个配置文件中指定的名字同样 #更改完成后,保存退出便可 [root@nginx nginx-1.2.4]# vim src/http/ngx_http_special_response.c #编辑此配置文件 static u_char ngx_http_error_tail[] = #注意,有一段配置和这段内容很是类似,主要区分这一行便可 #若是改错了,在后面将会报错 "<hr><center>ljz</center>" CRLF #将此行中间的nginx更改成ljz。 "</body>" CRLF "</html>" CRLF #更改完成后,保存退出便可 [root@nginx nginx-1.2.4]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module && make #从新配置及编译 [root@nginx nginx-1.2.4]# mv /usr/local/nginx/sbin/nginx nginx2.bak #将原有的nginx命令更名 [root@nginx nginx-1.2.4]# cp objs/nginx /usr/local/nginx/sbin/ #复制新生成的nginx命令到指定目录 [root@nginx nginx-1.2.4]# /usr/local/nginx/sbin/nginx -s stop #中止nginx服务 [root@nginx nginx-1.2.4]# /usr/local/nginx/sbin/nginx #启动nginx [root@nginx nginx-1.2.4]# curl -I 127.0.0.1 #查看其头部信息 HTTP/1.1 200 OK Server: ljz/666 #已经更改为功 ...............#省略部份内容
5、nginx主配置文件中 location选项的详解
在nginx的主配置文件中,有一个http{ }的段落,在http{ }中还包含了server { },其中一个server { }就表明一个虚拟主机,能够在其中针对某个web服务配置不一样的参数,这里说一下location { }的详细配置。
一、root和alias的区别shell
在下面的配置中,“ ^ ”表示以什么开头,“ ~ ”表示使用正则匹配表达式
1)如今将配置文件中的location改成以下内容:apache
[root@nginx conf]# vim nginx.conf #编辑主配置文件 http { ...............#省略部份内容 server { listen 80; location ^~ /www { root /var/www/html; #当访问127.0.0.1/www时,会寻找/var/www/html路径下的www目录 index index.html index.htm; } ...............#省略部份内容 } } [root@nginx nginx]# nginx -t [root@nginx nginx]# nginx -s reload #多重载两次服务,不然可能不生效 [root@nginx nginx]# nginx -s reload [root@nginx conf]# mkdir -p /var/www/html/www [root@nginx conf]# echo "/var/www/html/www/index.html" > /var/www/html/www/index.html
客户端访问192.168.20.5/www进行测试:
2)如今将配置文件中的location改成以下内容:
vim
[root@nginx conf]# vim nginx.conf #编辑主配置文件 http { ...............#省略部份内容 server { listen 80; location ^~ /test02 { alias /var/www/test02; #访问127.0.0.1/test02会寻找/var/www/test02目录下的网页文件 index index.html index.htm; } ...............#省略部份内容 } } [root@nginx nginx]# nginx -t [root@nginx nginx]# nginx -s reload [root@nginx nginx]# nginx -s reload [root@nginx conf]# mkdir -p /var/www/test02 [root@nginx conf]# echo "/var/www/test02/index.html" > /var/www/test02/index.html
客户端访问192.168.20.5/test02进行测试:
二、匹配指定的后缀时,就重定向到指定的文件
示范一:后端
[root@nginx conf]# vim nginx.conf #编辑主配置文件 http { ...............#省略部份内容 server { listen 80; location ~* .(gif|jpg|png)$ { rewrite .(gif|jpg)$ /error.png; } #以上表示当访问gif和jpg结尾的文件跳转到/usr/local/nginx/html/error.png ...............#省略部份内容 } } [root@nginx nginx]# nginx -t [root@nginx nginx]# nginx -s reload [root@nginx nginx]# nginx -s reload [root@nginx html]# pwd #查看当前路径 /usr/local/nginx/html [root@nginx html]# ls #error.png需存放在这个目录下 50x.html error.png index.html
客户端访问192.168.20.5/bb.gif进行测试:
示范二:
[root@nginx res]# pwd /webroot/res [root@nginx res]# ls #该路径下存放的图片 test1.jpg [root@nginx html]# pwd #当前路径 /usr/local/nginx/html [root@nginx html]# cat index.html #有一个首页文件 /usr/local/nginx/html/index.html [root@nginx html]# vim ../conf/nginx.conf #编辑主配置文件 server { listen 80; server_name localhost; location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { #“~”表示使用正则表达式,“ * ”表示不区分大小写 root /webroot/res; #当访问以以上gif、jpg等结尾的文件时,就去/webroot/res目录下找 index index.html index.html; } location / { root html; index index.html index.htm; } [root@nginx html]# nginx -s reload #重启服务,使更改生效
客户端访问Nginx的192.168.20.5进行测试:
看到的是html下的index.html文件的内容。如今访问192.168.20.5/test1.jpg进行测试:
这样,看到的就是/webroot/res/目录下的test1.jpg图片。
三、当匹配指定的请求方式,就返回特定的状态码
[root@nginx conf]# vim nginx.conf #编辑主配置文件 http { ...............#省略部份内容 server { listen 80; if ($request_method = TEST) { return 666; } #当客户端以TEST的方式访问时,返回状态码666 ...............#省略部份内容 } } [root@nginx nginx]# nginx -t [root@nginx nginx]# nginx -s reload [root@nginx nginx]# nginx -s reload
在本机执行命令 curl -X TEST -I 127.0.0.1 进行测试:
能够看到返回了咱们指定的状态码
四、当客户端不是以指定域名访问时,就跳转到指定的域名
[root@nginx conf]# vim nginx.conf #编辑主配置文件 http { ...............#省略部份内容 server { listen 80; if ($host != 'www.test.com'){ rewrite ^/(.*)$ https://www.baidu.com/$1; } #以上表示当客户端不是经过www.test.com域名访问时,就跳转到百度首页 ...............#省略部份内容 } } [root@nginx nginx]# nginx -t [root@nginx nginx]# nginx -s reload [root@nginx nginx]# nginx -s reload
客户端访问192.168.20.5进行测试:
因为我在截图以前,就访问了一次,因此,这里输入IP时,自动会和百度对应上。
6、配置https访问Nginx
咱们都知道http是80端口,https是443端口,因为https更加安全,因此如今大多数web服务都是经过https方式进行访问的,接下来,就配置一下https访问nginx服务器。
因为互联网认证的CA证书须要付费购买,因此这里就本身作一个,没有通过互联网认证的CA证书。
[root@nginx ca]# pwd #切换至指定目录 /usr/local/nginx/ca [root@nginx ca]# openssl genrsa -out ca.key 4096 #生成秘钥文件 [root@nginx ca]# openssl req -new -x509 -days 7304 -key ca.key -out ca.crt #如下全部填写的内容,可直接按回车,接收默认值 ..................#省略部份内容 Country Name (2 letter code) [XX]:zh #国家名称 State or Province Name (full name) []:beijing #州或省名(全称) Locality Name (eg, city) [Default City]:beijing #城市名称 Organization Name (eg, company) [Default Company Ltd]:test #公司名称 Organizational Unit Name (eg, section) []:operation #所在部门 Common Name (eg, your name or your server's hostname) []:test.com #主机名 Email Address []:lv916551516@163.com #邮箱 [root@nginx ca]# ls #确保当前目录下有下面两个文件 ca.crt ca.key [root@nginx ca]# vim /usr/local/nginx/conf/nginx.conf #编辑主配置文件 ..................#省略部份内容,搜索“HTTPS”定位到下面的配置项,并删除HTTPS下面server{ }全部的注释符号 #更改后以下(共修改两行便可): server { listen 443 ssl; server_name localhost; ssl_certificate /usr/local/nginx/ca/ca.crt; #就改这一行,指定ca.crt的绝对路径 ssl_certificate_key /usr/local/nginx/ca/ca.key; #再改这一行,指定ca.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; } } } #更改完成后,保存退出便可 [root@nginx ca]# nginx -s reload #重启nginx [root@nginx ca]# nginx -s reload
客户端使用https访问测试(因为证书没有通过互联网认证的,因此会出现下面的警告信息,单击“高级”,选择继续访问便可):
https访问成功:
7、开启Nginx访问认证
有些时候,咱们web服务的一些页面,不方便对全部人开放,这事,能够开启该网页的访问认证,开启后,就须要使用用户名密码进行登陆,才可看到相应的页面。
没有开启访问认证的状况下访问咱们192.168.20.5/auth/的网页文件,,能够直接访问,以下:
如今开启认证:
[root@nginx ~]# yum -y install httpd-tools #安装所需htpasswd工具 [root@nginx ~]# htpasswd -c /usr/local/nginx/.passwd admin #建立一个admin用户 New password: #输入用户密码 Re-type new password: #确认密码 #注:若要向.passwd中添加第二个用户,须要省略“-c”选项,不然会覆盖以前的全部用户。 Adding password for user admin [root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf #编辑Nginx配置文件 ......................#省略部份内容,编辑须要开启认证的server配置段 server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location /auth { #注意这里实际的路径至关于“/usr/local/nginx/html/auth” root html; index index.html index.htm; auth_basic "请输入登陆帐号"; #添加提示语句 auth_basic_user_file /usr/local/nginx/.passwd; #指定密码文件的存放路径 } #编辑完成后,保存退出便可 [root@nginx nginx]# nginx -s reload #重启Nginx服务
客户端进行访问测试(会提示输入用户名及密码,只要是.passwd文件中包含的用户和密码,都能进行登陆):
登陆成功后,就能够看到了网页文件: