初识Nginx
常见Web服务器介绍
Web服务器常指的是(world wide web ,www)服务器、也是HTTP服务器,主要用于提供网上信息浏览。
我们大部分人接触互联网,都基本上是通过浏览器访问互联网中各种资源。
Web 网络服务是一种被动访问的服务程序,即只有接收到互联网中其他主机发出的 请求后才会响应,最终用于提供服务程序的 Web 服务器会通过 HTTP(超文本传输协议)或 HTTPS(安全超文本传输协议)把请求的内容传送给用户。
Unix和Linux平台下的常用Web服务器常见有:
- Apache (国企性质,只需要系统架构稳定即可)
- Nginx (主流的互联网公司)
- Lighttpd (性能非常接近nginx)
- Tomcat (应用服务器,Java做程序解析)
- IBM WebSphere
其中最为广泛的是Nginx,在Windows平台上最常用的是微软的IIS(Internet Information Server,互联网信息服务)是 Windows 系统中默认的 Web 服务程序。
Apache

Apache是世界主流的Web服务器,世界上大多著名网站都是Apache搭建,优势在于开放源代码,开发维护团队强大、支持跨平台应用(Unix、Linux、Windows),强大的移植性等优点。
Apache属于重量级产品,功能以模块化定制,消耗内存较高,性能稍弱于其他轻量级Web服务器。
Lighttpd

Lighttpd是一款高安全性、快速、且灵活的Web服务器产品,专为高性能环境而设计,相比其他Web服务器,内存占用量小,能够有效管理CPU负载,支持(FastCGI、SCGI,Auth,输出压缩,url重写,别名)等重要功能,是Nginx的重要对手之一。
Tomcat服务器


Tomcat是一个开源、运行基于Java的Web应用软件的容器,Tomcat Server根据servlet和JSP规范执行,但是Tomcat对于平台文件、高并发处理较弱。要使用Tomcat需要对Java的应用部署有足够的了解。
IBM WebSphere Application Server

WebSphere Applicaiton Server是一种强大的Web应用服务器,基于Java的应用环境、建立、部署和管理网站应用。
Microsoft IIS

微软的IIS是一种灵活,安全易管理的Web服务器,从流媒体到Web应用程序,IIS提供了图形化的管理界面,用于配置和管理网络服务。
IIS是一整套Web组件,包含了Web服务器,FTP服务器,SMTP服务器等常用的网页浏览、文件传输,邮件新闻等功能。
缺点是只能运行在Windows平台,还得购买商业化的操作系统。
Nginx

Nginx是俄罗斯人Igor Sysoev(伊戈尔·塞索耶夫)开发的一款高性能的HTTP和反向代理服务器。
Nginx以高效的epoll、kqueue、eventport作为网络IO模型,在高并发场景下,Nginx能够轻松支持5w并发连接数的响应,并且消耗的服务器内存、CPU等系统资源消耗却很低,运行非常稳定。
国内著名站点,新浪博客、网易、淘宝、豆瓣、迅雷等大型网站都在使用Nginx作为Web服务器或是反向代理服务器。
为何选择Nginx

在互联网的快速普及,全球化、物联网的迅速发展,世界排名前3的分别是Apache、IIS、Nginx,而Nginx一直在呈现增长趋势。
Nginx资源消耗低/性能强
官方提供的测试数据,Nginx能支持5W的并发连接,在实际生产环境下可支撑2~4W的并发连接数。
Apache使用的网络I/O模型是传统的select模型,以Prefork多进程模式运转,需要经常派生子进程,消耗系统资源要比Nginx高得多。且一个进程在同一时间只会处理一个请求。
如Apache Web Server支撑这日均千万PV的网站,服务器平均负载在50~60,CPU消耗在70%~90%,而整体迁移到Nginx后,系统平均负载降低至1~4,CPU使用率在20%~40%,效果可见。
常见LNMP(linux、Nginx、Mysql、PHP)服务器在3万并发连接下,开启10个Nginx进程消耗不过(15MB10=150MB)内存。就算开启64个php-cgi进程,也就消耗20MB64=1280MB,总共后台进程使用不到2GB内存,且服务器如果内存较小,开启php-cgi进程数量可以再少点。
在压力测试,3W的并发连接下,Nginx+PHP的程序任然能够飞速运转,从Nginx的日志统计下(每分钟的第15秒有多少条日志),单机处理请求能力在700次/秒,那么日承受访问量在7006060*24=6048,0000,且服务器的负载不会太高。
Nginx成本低
Nginx强大功能其一在于反向代理、负载均衡,属于是软件负载均衡,企业购买硬件的F5、NetScaler等硬件负载均衡设备价格昂贵,而Nginx属于开源软件,遵循BSD协议,可以免费试用,甚至二次开发用于商业用途。
BSD协议指的是给与用户更自由的协议,可以自由试用、修改源代码
Nginx优势
- 配置文件简单易读
- 支持Rewrite重写,根据域名、URL的不同,转发HTTP请求到不同的后端服务器组
- 高可用性,稳定性,宕机几率很低
- 节省资源,支持GZIP压缩静态资源
- 支持热部署,可以7*24小时不间断运行,数月时间可不重启,在kill进程的情况下对软件修改。
Nginx的网络模型
网络IO概念说明
内核空间/用户空间
内核:操作系统的核心是内核,独立于普通的应用程序,可以操作底层硬件,处理受保护的内存空间。
操作系统为了保护内核,使得用户进程无法直接操作内核(kernel),操作系统单独开辟了两个虚拟内存空间,一是内核空间,二是用户空间。进程切换
为了控制进程执行,操作系统内核得有能力挂起CPU上运行的进程(暂停一个CPU正在处理的进程),或是恢复之前已挂起的进程,这种行为称之为进程切换。进程阻塞
正在执行的进程,由于某些事件的等待,如请求资源加载中,资源加载失败等,系统自动执行阻塞语句,block,让该进程处于阻塞状态,因此进程的阻塞是一种主动行为,因此也之后又处于运行状态的进程(获取到CPU)才能转变为阻塞状态,阻塞状态下不吃CPU资源。文件描述符
这是计算机科学里的一个术语,表述指向文件引用的一个抽象概念。它是一个索引值,指向内核为每一个进程打开文件的记录表。
程序打开一个文件,系统内核就向该进程发送一个文件描述符。Linux IO模型
数据的IO操作,例如读取文件,数据会被拷贝到操作系统内核的缓冲区,然后从缓冲区拷贝到应用程序的内存空间。
对于网络IO ```shell 1.等待网络上的数据分段到达,然后复制到内核的缓冲区 2.数据从内核缓存区拷贝到进程 从内核拷贝到用户空间的应用程序一个读取操作,经历两个阶段1.等待数据准备2.数据从内核拷贝到进程
网络应用主要处理两个问题,网络IO,数据计算 网络IO的延迟等待,是最主要的性能瓶颈。
为何选择Nginx,重点在于网络模型的区别<br />常见的IO模型- 阻塞- 非阻塞- IO多路复用- 异步IO网络IO指的是输入、输出,本质上是socket读取,socket在linux中被抽象为流,IO就是对流的操作。<a name="q4fIP"></a>### 同步阻塞IO(block IO)```shell超哥和媳妇在麦当劳点餐,点过之后不知道什么时候能做好,只能坐在餐厅等待,直到用餐结束才离开。但是媳妇其实还想去买个包包的,但是不知道饭菜什么时候好,只能慢慢等,浪费了时间,也没去逛街买包。
在linux下默认所有的socket都是blocking阻塞的,阻塞指的是进程被等待了,CPU处理其他任务了。
用户进程调用recv()进行系统调用,内核开始IO第一个阶段,准备数据(网络IO情况下,内核要等待所有数据接收完毕)。这个过程指的是,数据拷贝到操作系统内核是需要一定时间的。用户进程这里整个进程被阻塞,当内核数据准备好之后,将数据从内核中再拷贝到用户内存,内核返回结果后,用户进程解除block阻塞状态,重新运行。同步阻塞IO特点是,IO执行的2个阶段都是阻塞的,用户空间发起调用,内核准备数据阻塞,内核拷贝数据到用户空间阻塞。
同步阻塞模型,优/缺点是
1.能够及时返回数据,无延迟2.对于开发人员负担较低3.对用户不友好,性能较弱
同步非阻塞
超哥和媳妇还是在麦当劳,点好了餐,但是不愿意白等着,又想去逛会商场,又害怕餐好了来迟了。因此我们去逛一会,回来问一下客服,餐做好没没好的话,待会再来问一遍
同步非阻塞就是每隔一会检索一次的轮询polling方式。
在网络IO时候,非阻塞IO同样进行recvform系统调用,且检查数据是否准备好了,这里和阻塞IO不一样,非阻塞模式将整个阻塞时间片拆分成N小的阻塞,CPU仍有机会不断的操作该进程。
当用户进程发起read操作,内核若是没有数据,不会立即阻塞用户进程,而是立即返回了error报错对于用户进程而言,这就不再是等待了,而是立即有了一个结果,已知是error的时候,知道了数据还未准备好,于是再次发起系统调用。一旦内核准备好了数据,且在此收到用户的系统调用,内核立即将数据拷贝到用户内存,然后返回给用户进程。区别就在于发起recvfrom时候的阻塞拆分了,用户进程需要不断的主动询问内核数据是否准备好
同步阻塞和非阻塞的区别
非阻塞优点是,能够在等待某一任务的时间里继续处理其他任务,也包括继续提交新任务非阻塞缺点缺点是:任务完成的延迟变大,因为要多次轮询系统调用操作,而有可能任务就在轮询过程中完成了,造成整体数据吞吐量降低。
IO多路复用
超哥还是和媳妇在餐厅吃饭点餐,这回餐厅装了电子屏,可以显示食物制作进度,这样超哥和他媳妇逛街一回,回来不用再去问服务员了,可能服务员压根不想理你呢,直接看电子屏即可快速知道结果
由于刚才所说的同步非阻塞需要不断的主动轮询,轮询会消耗大量CPU时间。
计算机系统后台可能存在N个任务,如果能循环的查询多个任务的进度,并且这个轮询还不是用户进程发起的(不是超哥反复回来询问),而是有人帮忙查询,那可太方便了。
因此Linux下的select、poll、epoll就是做这个事的,且epoll效率最高并且nginx就是使用的epoll网络模型
select
select轮询方式和非阻塞轮询区别在于
select轮询可以同时监听多个socket,当一个socket的数据准备好了,即可进行IO操作,进程发起recvform系统调用,将数据由内核拷贝到用户进程,这个过程是阻塞的。但是这里的select或是poll阻塞进程,和同步IO的阻塞不一样,同步IO的阻塞是数据全部准备好,一次性处理,而select是有一部分数据就调用用户进程来处理。IO多路复用,就是轮询多个socket,好比餐厅的电子屏,监控着多个食品订单的完成情况好处:IO多路复用select事件可以同时处理多个连接注意:其实IO多路复用和阻塞IO形式区别不大,并且有可能性能还更差一点。因为IO多路复用还额外调用了select事件,还有额外的系统开销。

IO多路复用指的就是linux下的select,poll,epoll,也被称作事件驱动IO它们的好处在于:单进程就可以同时处理多个socket连接。原理就是select,poll,epoll这个函数会不断的轮询负责的所有socket,当某个socket有数据到达了,就通知用户进程。当用户进程调用了select这个函数,整个进程就会被阻塞了,kernel内核会监视所有select负责的socket,有一个socket准备好了数据,select就返回给用户进程,用户进程发起系统调用,数据拷贝到用户进程。
其实IO多路复用和阻塞IO并没有太大的区别,有可能还更差一点,因为还额外的调用了select,有了额外的消耗。好处就是select可以同时处理多个连接。
如果连接数不是很多的情况下,用IO多路复用还不如使用(多线程+阻塞IO)的性能更好。IO多路复用优势在于同时处理更多的连接,而不是处理速度
异步非阻塞IO模型
超哥媳妇不想逛街了,又不想在餐厅等着,因此他俩直接选择回家休息。拿起手机点外卖,饭好了外卖员直接送到家,这也太舒服了,又不用干等着,还能做些别的事,饭菜就能送来了。

用户进程发起aio_read系统调用,无论内核数据是否准备好,都会直接返回给用户进程,用户进程可以继续做其他事情。等待socket数据准备好了,内核直接复制给用户进程,接着向进程发出通知,整个过程都是非阻塞的。
网络IO模型总结
1.阻塞和非阻塞的区别阻塞IO会一直阻塞对应的进程,直到数据操作完毕,非阻塞IO在内核准备数据阶段就立刻返回2.同步IO和异步IO的区别区别在于,同步IO在IO操作的时候会被进程阻塞,blocking io,non-blocking io,IO multiplexing都属于同步IO异步IO,在进程发起IO操作之后,内核就直接返回了,直到内核发送一个信号,告诉进程IO完成了,整个进程完全没有被阻塞。
Nginx架构组成
Nginx安装配置
Nginx如今分为商业版,开源版,支持Linux与Windows平台下载使用
nginx.com 商业版nginx.org 开源版https://tengine.taobao.org/
【环境准备】
# 首先需要配置阿里云的yum源操作系统:CentOS Linux release 7.3.1611 (Core)GCC编译环境:yum install -y gcc gcc-c++ autoconf automake make模块依赖性:Nginx支持的功能模块需要有第三方的库支持,例如gzip的zlib库,rewrite重写需要的pcre库,HTTPS需要的openssl库等等。yum install zlib zlib-devel openssl openssl-devel pcre pcre-devel wget httpd-tools vim系统基础开发环境:yum groupinstall "Development Tools" "Basic Web Server"确保防火墙关闭 iptables -Fiptables -L # 查看防火墙是否被关闭关闭selinuxyum源配置正确网络连接状态正常
【Nginx下载】
- yum自动安装,不支持自由扩展第三方功能
- 源码编译安装 ```shell 1.下载Nginx源代码 nginx.org官网 [root@chaogelinux Learn_Nginx]# wget nginx.org/download/nginx-1.14.0.tar.gz
下载淘宝的tengine wget http://tengine.taobao.org/download/tengine-2.3.2.tar.gz
2.解压缩Nginx源代码 [root@chaogelinux Learn_Nginx]# tar -zxf nginx-1.14.0.tar.gz
解压缩淘宝的 tar -zxvf tengine-2.3.2.tar.gz # f必须写在结尾
3.复制Nginx默认提供的vim语法插件 [root@chaogelinux nginx-1.14.0]# mkdir ~/.vim [root@chaogelinux nginx-1.14.0]# cp -r contrib/vim/* ~/.vim/
4.Nginx源代码目录介绍 auto 检测系统模块依赖信息 CHANGES nginx更改记录文件(版本迭代、升级等) conf 存放nginx配置文件 configure 释放编译文件的定制脚本 contrib 提供了perl与vim插件 html 存放标准html页面语法 src 存放nginx源码
开始准备编译三部曲 第一曲:进入软件源代码目录,执行编译脚本,如指定安装路径,以及开启 首先,查看编译脚本的信息 [root@localhost tengine-2.3.2]# ./configure —help # 查看编译帮助信息 执行编译脚本文件,释放makefile等信息
5.开始编译Nginx,扩展编译模块
列出Nginx的编译选项,如制定安装路径,配置文件、日志文件等路径,指定开启模块功能等
[root@chaogelinux nginx-1.14.0]# ./configure —help
编译Nginx初步,
[root@chaogelinux nginx-1.14.0]# ./configure —prefix=/home/Learn_Nginx/nginx/ —with-http_ssl_module —with-http_flv_module —with-http_gzip_static_module —with-http_stub_status_module —with-threads —with-file-aio
第二曲:(相当于Windows的直接开始下一步安装) 输入make 6.执行make编译 make
第三曲:(如同点击开始安装) 7.首次编译安装,生成Nginx的可执行命令 make install
8.检查Prefix指定的安装目录 [root@chaogelinux nginx-1.14.0]# ls /home/Learn_Nginx/ nginx nginx-1.14.0 nginx-1.14.0.tar.gz drwxr-xr-x 2 root root 333 Apr 22 16:34 conf # 存放nginx的配置文件 drwxr-xr-x 2 root root 40 Apr 22 16:34 html # 存放nginx的网页根目录文件,存放站点的静态文件数据 drwxr-xr-x 2 root root 6 Apr 22 16:34 logs # 存放各种nginx的各种日志目录 drwxr-xr-x 2 root root 19 Apr 22 16:34 sbin # 存放该软件的可执行命令 netstat -tunlp
9.Nginx的程序目录 [root@chaogelinux nginx]# pwd /home/Learn_Nginx/nginx [root@chaogelinux nginx]# ls conf html logs sbin
依次是配置文件,静态文件,日志,二进制命令目录
[root@localhost sbin]# ps -ef | grep nginx | grep -v grep root 7758 1 0 19:56 ? 00:00:00 nginx: master process ./nginx nobody 7759 7758 0 19:56 ? 00:00:00 nginx: worker process 上边是工头,下边是工人
10.创建nginx的环境变量文件,修改如下,创建/etc/profile.d/nginx.sh脚本文件便于以后维护 [root@chaogelinux ~]# cat /etc/profile.d/nginx.sh export PATH=/home/Learn_Nginx/nginx/sbin:$PATH
11.退出会话,重新登录终端,此时可以正常使用nginx [root@chaogelinux ~]# echo $PATH /home/Learn_Nginx/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
停止当前nginx进程 [root@localhost profile.d]# nginx -s stop [root@localhost profile.d]# netstat -tunlp | grep 80
如果不想重启nginx,直接加载配置文件,nginx提供了一个reload功能,在不停止nginx的情况下,直接重新读取配置文件功能。 [root@localhost profile.d]# nginx -s reload
12.检查nginx的编译模块信息 [root@chaogelinux ~]# nginx -V nginx version: nginx/1.14.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: —prefix=/home/Learn_Nginx/nginx114/ —with-http_ssl_module —with-http_flv_module —with-http_gzip_static_module —with-http_stub_status_module —with-threads —with-file-aio
<a name="klOW1"></a>### Nginx配置文件语法- nginx.conf由指令与指令块构成- 每行语句由分号结束,指令和参数之间由空格分隔- 指令块可以大括号{}组织多条指令块- 配置文件中#号添加注释信息- 支持$变量使用变量- 支持include语句,组合多个配置文件- 部分指令支持正则表达式<a name="WjZAr"></a>### nginx.conf指令注释```shell######Nginx配置文件nginx.conf中文详解######定义Nginx运行的用户和用户组user www www;#nginx进程数,建议设置为等于CPU总核心数。worker_processes 8;#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]error_log /usr/local/nginx/logs/error.log info;#进程pid文件pid /usr/local/nginx/logs/nginx.pid;#指定进程可以打开的最大描述符:数目#工作模式与连接数上限#这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。#现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。#这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。worker_rlimit_nofile 65535;events{#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型#是Linux 2.6以上版本内核中的高性能网络I/O模型,linux建议epoll,如果跑在FreeBSD上面,就用kqueue模型。#补充说明:#与apache相类,nginx针对不同的操作系统,有不同的事件模型#A)标准事件模型#Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll#B)高效事件模型#Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。#Epoll:使用于Linux内核2.6版本及以后的系统。#/dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。#Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。use epoll;#单个进程最大连接数(最大连接数=连接数*进程数)#根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为。worker_connections 65535;#keepalive超时时间。keepalive_timeout 60;#客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。#分页大小可以用命令getconf PAGESIZE 取得。#[root@web001 ~]# getconf PAGESIZE#4096#但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。client_header_buffer_size 4k;#这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。open_file_cache max=65535 inactive=60s;#这个是指多长时间检查一次缓存的有效信息。#语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.open_file_cache_valid 80s;#open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。#语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location 这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.open_file_cache_min_uses 1;#语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.open_file_cache_errors on;}#设定http服务器,利用它的反向代理功能提供负载均衡支持http{#文件扩展名与文件类型映射表include mime.types;#默认文件类型default_type application/octet-stream;#默认编码#charset utf-8;#服务器名字的hash表大小#保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.server_names_hash_bucket_size 128;#客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。client_header_buffer_size 32k;#客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。large_client_header_buffers 4 64k;#设定通过nginx上传文件的大小client_max_body_size 8m;#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。#sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。sendfile on;#开启目录列表访问,合适下载服务器,默认关闭。autoindex on;#此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用tcp_nopush on;tcp_nodelay on;#长连接超时时间,单位是秒keepalive_timeout 120;#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。fastcgi_connect_timeout 300;fastcgi_send_timeout 300;fastcgi_read_timeout 300;fastcgi_buffer_size 64k;fastcgi_buffers 4 64k;fastcgi_busy_buffers_size 128k;fastcgi_temp_file_write_size 128k;#gzip模块设置gzip on; #开启gzip压缩输出gzip_min_length 1k; #最小压缩文件大小gzip_buffers 4 16k; #压缩缓冲区gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)gzip_comp_level 2; #压缩等级gzip_types text/plain application/x-javascript text/css application/xml; #压缩类型,默认就已经包含textml,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。gzip_vary on;#开启限制IP连接数的时候需要使用#limit_zone crawler $binary_remote_addr 10m;#负载均衡配置upstream pythonav.cn {#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。server 192.168.80.121:80 weight=3;server 192.168.80.122:80 weight=2;server 192.168.80.123:80 weight=3;#nginx的upstream目前支持4种方式的分配#1、轮询(默认)#每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。#2、weight#指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。#例如:#upstream bakend {# server 192.168.0.14 weight=10;# server 192.168.0.15 weight=10;#}#2、ip_hash#每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。#例如:#upstream bakend {# ip_hash;# server 192.168.0.14:88;# server 192.168.0.15:80;#}#3、fair(第三方)#按后端服务器的响应时间来分配请求,响应时间短的优先分配。#upstream backend {# server server1;# server server2;# fair;#}#4、url_hash(第三方)#按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。#例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法#upstream backend {# server squid1:3128;# server squid2:3128;# hash $request_uri;# hash_method crc32;#}#tips:#upstream bakend{#定义负载均衡设备的Ip及设备状态}{# ip_hash;# server 127.0.0.1:9090 down;# server 127.0.0.1:8080 weight=2;# server 127.0.0.1:6060;# server 127.0.0.1:7070 backup;#}#在需要使用负载均衡的server中增加 proxy_pass http://bakend/;#每个设备的状态设置为:#1.down表示单前的server暂时不参与负载#2.weight为weight越大,负载的权重就越大。#3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误#4.fail_timeout:max_fails次失败后,暂停的时间。#5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。#nginx支持同时设置多组的负载均衡,用来给不用的server来使用。#client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug#client_body_temp_path设置记录文件的目录 可以设置最多3层目录#location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡}#虚拟主机的配置server{#监听端口listen 80;#域名可以有多个,用空格隔开server_name www.w3cschool.cn w3cschool.cn;index index.html index.htm index.php;root /data/www/w3cschool;#对******进行负载均衡location ~ .*.(php|php5)?${fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;include fastcgi.conf;}#图片缓存时间设置location ~ .*.(gif|jpg|jpeg|png|bmp|swf)${expires 10d;}#JS和CSS缓存时间设置location ~ .*.(js|css)?${expires 1h;}#日志格式设定#$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;#$remote_user:用来记录客户端用户名称;#$time_local: 用来记录访问时间与时区;#$request: 用来记录请求的url与http协议;#$status: 用来记录请求状态;成功是200,#$body_bytes_sent :记录发送给客户端文件主体内容大小;#$http_referer:用来记录从那个页面链接访问过来的;#$http_user_agent:记录客户浏览器的相关信息;#通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。log_format access '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" $http_x_forwarded_for';#定义本虚拟主机的访问日志access_log /usr/local/nginx/logs/host.access.log main;access_log /usr/local/nginx/logs/host.access.404.log log404;#对 "/" 启用反向代理location / {proxy_pass http://127.0.0.1:88;proxy_redirect off;proxy_set_header X-Real-IP $remote_addr;#后端的Web服务器可以通过X-Forwarded-For获取用户真实IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#以下是一些反向代理的配置,可选。proxy_set_header Host $host;#允许客户端请求的最大单文件字节数client_max_body_size 10m;#缓冲区代理缓冲用户端请求的最大字节数,#如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。#无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误client_body_buffer_size 128k;#表示使nginx阻止HTTP应答代码为400或者更高的应答。proxy_intercept_errors on;#后端服务器连接的超时时间_发起握手等候响应超时时间#nginx跟后端服务器连接超时时间(代理连接超时)proxy_connect_timeout 90;#后端服务器数据回传时间(代理发送超时)#后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据proxy_send_timeout 90;#连接成功后,后端服务器响应时间(代理接收超时)#连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)proxy_read_timeout 90;#设置代理服务器(nginx)保存用户头信息的缓冲区大小#设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小proxy_buffer_size 4k;#proxy_buffers缓冲区,网页平均在32k以下的设置#设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8kproxy_buffers 4 32k;#高负荷下缓冲大小(proxy_buffers*2)proxy_busy_buffers_size 64k;#设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长#设定缓存文件夹大小,大于这个值,将从upstream服务器传proxy_temp_file_write_size 64k;}#设定查看Nginx状态的地址location /NginxStatus {stub_status on;access_log on;auth_basic "NginxStatus";auth_basic_user_file confpasswd;#htpasswd文件的内容可以用apache提供的htpasswd工具来产生。}#本地动静分离反向代理配置#所有jsp的页面均交由tomcat或resin处理location ~ .(jsp|jspx|do)?$ {proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://127.0.0.1:8080;}#所有静态文件由nginx直接读取不经过tomcat或resinlocation ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)${expires 15d;}location ~ .*.(js|css)?${expires 1h;}}}######Nginx配置文件nginx.conf中文详解#####nginx.conf详解
nginx.conf重要的指令块
核心功能都在于http{}指令块里,http{}块还包含了以下指令
- server{} 指令块 ,对应一个站点配置,反向代理,静态资源站点
- location{} ,对应一个url
-
Nginx命令行
启停指令
nginx -s stopnginx -s reloadnginx 首次输入表示启动
- nginx帮助指令 ```shell [root@chaogelinux nginx114]# nginx -h nginx version: nginx/1.14.0 Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options: -?,-h : this help #帮助信息 -v : show version and exit #显示版本 -V : show version and configure options then exit #显示编译信息与版本 -t : test configuration and exit #测试配置文件语法,检查nginx配置文件,语法是否正确。 -T : test configuration, dump it and exit #测试语法且输出内容 -q : suppress non-error messages during configuration testing # 在检测配置文件期间屏蔽非错误信息。 -s signal : send signal to a master process: stop, quit, reopen, reload #发送信号,stop立即停止,quit优雅停止,reload重读配置文件,reopen重新记录日志 -p prefix : set prefix path (default: /home/Learn_Nginx/nginx114//) # 设置nginx目录前缀 -c filename : set configuration file (default: conf/nginx.conf) #使用指定配置文件 -g directives : set global directives out of configuration file #覆盖默认参数
<a name="XttNn"></a>### 命令行功能案例<a name="s0jvh"></a>#### 配置文件重读在nginx正在运行时,如实修改了nginx.conf或是新增了一些功能配置,让其生效,可能需要重启整个nginx进程、<br />但是你不能保证某个时间段没有用户在访问nginx,重启会断开用户的连接,造成莫名的故障<br />因此nginx提供了reload重载功能,不停止服务,更新配置文件```shell1.修改nginx.confworker_processes 3; #定义nginx工作进程数的2.重载配置文件nginx -s reload3.检查linux进程[root@chaogelinux nginx114]# vim conf/nginx.conf[root@chaogelinux nginx114]#[root@chaogelinux nginx114]# ps -ef|grep nginxroot 6191 1 0 10:33 ? 00:00:00 nginx: master process nginxnobody 6213 6191 0 10:33 ? 00:00:00 nginx: worker processnobody 6214 6191 0 10:33 ? 00:00:00 nginx: worker processnobody 6215 6191 0 10:33 ? 00:00:00 nginx: worker processroot 6345 5283 0 10:38 pts/0 00:00:00 grep --color=auto nginx
Nginx-master信号
nginx进程信号传递如图
1.master不处理请求,而是分配worker进程,负责重启,热部署,重载等功能。2.master根据worker_processes 定义开始的workers数量3.worker运行后,master处于挂起状态,等待信号4.可以发送kill,或者nginx -s 参数发出信号
信号集
| nginx -s 对应参数 | 信号 | 含义 | English |
|---|---|---|---|
| stop | TERM | 强制关闭整个服务 | Shut down quickly. |
| null | INT | 强制关闭整个服务 | Shut down quickly. |
| quit | QUIT | 优雅地关闭整个服务 | Shut down gracefully. |
| reopen | USR1 | 重新打开日志记录 | Reopen log files. |
| reload | HUP | 重新读取配置文件,并且优雅地退出老的worker | Reload configuration, start the new worker process with a new configuration, and gracefully shut down old worker processes. |
| null | USR2 | 平滑升级到新版本 | Upgrade the nginx executable on the fly. |
| null | WINCH | 优雅地关闭worker(在热更新的时候必用) | Shut down worker processes gracefully. |
热部署
nginx作为一个优秀的反向代理服务器,同时具备高可用的特性,Nginx也支持热部署。
热部署指的是在不重启或关闭进程情况下,新应用直接替换掉旧的应用
热部署大致流程1.备份旧的二进制文件2.编译安装新的二进制文件,覆盖旧的二进制文件(再女装一个版本的nginx,且替换旧版本的nginx命令)3.发送USR2信号给旧master进程4.发送WINCH信号给旧master进程5.发送QUIT信号给旧master进程
环境准备:1.旧nginx版本 nginx version: nginx/1.14.02.新nginx版本 nginx version: nginx/1.17.8
【nginx热部署】
nginx工作模式是master-worker(包工头-工人)
刚才所说的nginx支持reload重载仅仅是nginx的master进程,检查配置文件语法是否正确,错则返回错误、正确也不会改变已经建立连接的worker,只得等待worker处理完毕请求之后,杀死旧配置文件的worker,启动新配置文件的worker。
但是Nginx这里提提供了热部署功能,就是在不影响用户体验下,进行软件版本升级,也就是不主动杀死worker,替换软件的二进制文件。
1.目前运行的是旧的nginx版本,如下检查[root@chaogelinux sbin]# ps -ef|grep nginxroot 20311 1 0 15:12 ? 00:00:00 nginx: master process nginxnobody 20312 20311 0 15:12 ? 00:00:00 nginx: worker processroot 20314 13589 0 15:12 pts/0 00:00:00 grep --color=auto nginx[root@chaogelinux sbin]#[root@chaogelinux sbin]#[root@chaogelinux sbin]# curl 127.0.0.1/123 #访问错误页面,返回nginx版本了<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>404 Not Found</h1></center><hr><center>nginx/1.14.0</center></body></html>
热部署的坑
如果出现发送 kill -USR2信号后,未出现新的master进程
是因为:
旧的nginx必须用绝对路径启动,然后再发送kill -USR2信号
具体解释看图
热部署具体操作
1.备份旧版本的nginx二进制文件[root@chaogelinux sbin]# pwd/home/Learn_Nginx/nginx/sbin[root@chaogelinux sbin]# mv nginx nginx.old[root@chaogelinux sbin]# lsnginx.old2.检查旧版本nginx的编译参数[root@chaogelinux Learn_Nginx]# nginx.old -Vnginx version: nginx/1.14.0built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)built with OpenSSL 1.0.2k-fips 26 Jan 2017TLS SNI support enabledconfigure arguments: --prefix=/home/Learn_Nginx/nginx/ --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module --with-threads --with-file-aio3.编译安装新版本nginx#下载新nginx源码[root@chaogelinux Learn_Nginx]# wget http://nginx.org/download/nginx-1.17.8.tar.gz#编译安装新版本nginx[root@chaogelinux Learn_Nginx]# tar -zxf nginx-1.17.8.tar.gz#开始编译# 编译参数与旧的一致 路径也一致[root@chaogelinux Learn_Nginx]# cd nginx-1.17.8/[root@chaogelinux nginx-1.17.8]#[root@chaogelinux nginx-1.17.8]# ./configure --prefix=/home/Learn_Nginx/nginx/ --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module --with-threads --with-file-aio#编译安装[root@chaogelinux nginx-1.17.8]# make && make install4.此时发现已存在2个版本nginx程序[root@chaogelinux sbin]# lsnginx nginx.old5.替换旧的nginx可执行文件[root@chaogelinux sbin]# cp -a /home/Learn_Nginx/nginx-1.17.8/objs/nginx /home/Learn_Nginx/nginx/sbin/cp:是否覆盖"/home/Learn_Nginx/nginx/sbin/nginx"? y5.1检查旧的nginx进程,请注意,这里用绝对路径启动nginx请注意,这里用绝对路径启动nginx请注意,这里用绝对路径启动nginx例如/home/Learn_Nginx/nginx/sbin/nginx注意这里的PID和PPID(pid是当前进程的id号,ppid是启动该进程的pid,也就是父ID,可知该pid由谁启动)[root@chaogelinux sbin]# ps -ef|grep nginxroot 20311 1 0 15:12 ? 00:00:00 nginx: master process nginxnobody 20312 20311 0 15:12 ? 00:00:00 nginx: worker processroot 20314 13589 0 15:12 pts/0 00:00:00 grep --color=auto nginx6.发送USR2信号给旧版本主进程,使得nginx旧版本停止接收请求,切换为新nginx版本[root@chaogelinux sbin]# kill -USR2 `cat ../logs/nginx.pid `7.检查此时的nginx进程nginx-master首先会重命名pid文件,在文件后面添加.oldbin后缀然后会再启动一个新的master进程以及worker,且使用的是新版Nginxnginx能够自动将新来的请求,过度到新版master进程下,实现平滑过度#可以发现新的master进程由旧master启动,由PPID可看出[root@chaogelinux sbin]# ps -ef|grep nginxroot 20311 1 0 15:12 ? 00:00:00 nginx: master process nginxnobody 20312 20311 0 15:12 ? 00:00:00 nginx: worker processroot 20335 20311 0 15:13 ? 00:00:00 nginx: master process nginxnobody 20336 20335 0 15:13 ? 00:00:00 nginx: worker processroot 20338 13589 0 15:13 pts/0 00:00:00 grep --color=auto nginx[root@chaogelinux sbin]# ls ../logs/access.log error.log nginx.pid nginx.pid.oldbin8.发送WINCH信号给旧master进程,优雅的关闭旧worker进程[root@chaogelinux sbin]# kill -WINCH `cat ../logs/nginx.pid.oldbin`#再次检查进程情况,旧master的worker已经关闭了,旧master不会自己退出,用作版本回退[root@chaogelinux sbin]# ps -ef|grep nginxroot 20311 1 0 15:12 ? 00:00:00 nginx: master process nginxroot 20335 20311 0 15:13 ? 00:00:00 nginx: master process nginxnobody 20336 20335 0 15:13 ? 00:00:00 nginx: worker processroot 20607 13589 0 15:25 pts/0 00:00:00 grep --color=auto nginx9.如果你觉得没问题了,可以关闭旧master进程[root@chaogelinux sbin]# ps -ef|grep nginxroot 20335 1 0 15:13 ? 00:00:00 nginx: master process nginxnobody 20336 20335 0 15:13 ? 00:00:00 nginx: worker processroot 20665 13589 0 15:28 pts/0 00:00:00 grep --color=auto nginx
nginx日志切割
日志切割是线上很常见的操作,控制单个文件大小,便于管理日志
1.查看当前nginx日志[root@chaogelinux logs]# ll总用量 12-rw-r--r-- 1 root root 1645 2月 11 15:30 access.log-rw-r--r-- 1 root root 2370 2月 11 15:30 error.log-rw-r--r-- 1 root root 6 2月 11 15:13 nginx.pid#大致看下日志内容[root@chaogelinux logs]# tail -2 access.log192.168.178.12 - - [11/Feb/2020:15:32:22 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"192.168.178.12 - - [11/Feb/2020:15:32:23 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"2.给文件重命名,注意用mv而不是cp(涉及到文件inode知识)[root@chaogelinux logs]# mv access.log access.log$(date +"%Y-%m-%d--%H:%M:%S")[root@chaogelinux logs]# ll总用量 16-rw-r--r-- 1 root root 4630 2月 11 15:32 access.log2020-02-11--15:43:49-rw-r--r-- 1 root root 2370 2月 11 15:30 error.log-rw-r--r-- 1 root root 6 2月 11 15:13 nginx.pid3.发送USR1信号给nginx-master,重新打开日志记录,生成新的日志文件nginx -s reopen #等同于 Kill -USR1 nginx.pid4.注意,在以上的nginx重命名日志切割,不要着急立即对文件修改,且要sleep 等待1秒由于nginx的工作模式,master下发指令给worker只是做了标记,当业务量大的时候,这个修改操作可能会慢一点,不会立即生效5.在生产环境下,主要以crontab形式,执行cut_nginx_log.sh脚本的[root@bogon sbin]# pwd/opt/nginx/sbin[root@bogon sbin]# cat cut_nginx_log.sh#!/bin/bash# 脚本写入crontab,每天0点执行,这是一个nginx日志切割脚本#nginx日志存放点logs_path="/opt/tngx232/logs/"mkdir -p ${logs_path}$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m")mv ${logs_path}access.log ${logs_path}$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m")/access_$(date -d "yesterday" +"%Y-%m-%d").logkill -USR1 `cat /opt/tngx232/logs/nginx.pid`6.写入crontabcrontab -l0 0 * * * /bin/bash /opt/nginx/sbin/cut_nginx_log.sh
