Nginx
1、nginx的三个应用场景
图解:一个web请求会,会经过nginx,在到引用服务,比如tomcat,Django,然后在去访问Redis,mysql提供基本的数据功能,注释(应用服务要求开发效率非常的高,所以它的运行效率是很低的它的QPS,DBS,TPS还有并发都是受限的,所以要把这些应用做成集群,像客户提供高可用性,)而一旦很多服务做成集群的时候,这里就需要nginx需要反向代理功能,可以把动态请求,传导给应用服务,而很多应用服务做成集群,它一定会带来俩个需求,第一个需要动态的扩容,第二个问题某些服务器出现问题,需要做容灾。这样nginx必须具备反向代理功能。其次在这样的链路中nginx处于在公司内网边缘节点,随着网络链路的增长,用户体验到的时延会增加,所有我们能把一些客户看起来不变的或者在一段时间内看起来不变的动态内容缓存在nginx部分,由nginx直接向用户提供服务,这样用户的时延就会减少很多,所以反向代理衍生出另外一个功能(缓存)它能加速客户的访问,而很多时候我们访问css,或者JavaScript,js文件或者像一些小图片,那么这样的静态资源是没有必要用应用服务来访问的,它只需要通过本地文件系统上放置的静态资源,直接用nginx访问就可以了,这就是nginx静态资源共能。第三个应用场景:应用服务它本身的性能因为有很多的问题,社区库服务要比应用服务要的好的多,以为它的业务场景比较简单,它并发性能和TPS都要远高于应用服务,所以衍生出第三个应用场景,由nginx直接去访问数据库或者是Redis,利用nginx强大的并发性能实现,如web防火墙这样复杂的业务功能,来提供给用户这需要ATR服务有非常强大的业务处理功能所以像openResty或者是nginx机身的JavaScript利用JavaScript这样的语言功能和他们语言先天自带的一些工具库来提供完整的API服务
1.1 静态资源服务
通过本地文件系统提供服务
1.2反向代理服务
nginx的强大性
缓存
负载均衡
1.3API服务
OpenResty
2、nginx的优点
1.高并发、高性能
2.可扩展性好
3.高可靠性
4.热部署(其原理就是首先我们先会替换master进程,同时我们替换的master是与老版本的worker兼容的。下一步,就是想大家已经想到的一样。保持还有连接的worker进程,待其老去退休,进行替换。)
5.BSD许可证(BSD不只是开源的 免费的,可以在有定制需求得场景下去修改nginx的源代码,在运行在我们的商业场景下这是合法的)
3、nginx的组成
nginx二进制可执行文件
由nginx本身的框架,有官方模块还有我们编译进去的各种第三方模块一起构建的一个文件(它有完整的系统所有的功能都由它提供)
nginx.conf配置文件
虽然二进制文件已经提供了很多功能,但这些功能有没有开启,或者开启了以后定义怎么的行为处理请求都是由nginx.conf这个配置文件决定的。
access.log访问日志
access 会记录下每一条nginx处理过得http请求的请求信息与响应信息
error.log错误日志
当出现了不可预期的问题错误时可通过error.log去把问题定位出来
3、nginx版本发布情况
注释:nginx每发布版本的时候会有三个特性
feature:新增了那些功能
bugfix:表示修复了那些bug
change:表示做了那些小的重构
如果需要开发API服务器web防火墙OpenResty是一个很好的选择
4、编译nginx
安装nginx有两种方法,除了编译以外,还可以使用操作系统自带的一些yum,apt get直接去安装nginx。但是直接安装nginx bander有个大问题,因为nginx的二进制文件它是会把模块给编译进来的nginx的官方模块,默认并不是每一个都会开启的,如果想添加地三方的nginx模块,必须通过编译nginx的方式才能把第三方生态圈强大的功能添加到nginx中
nginx.org(官网下载安装包进行编译)点击download
这里有两个版本一个是Mainline和Stable (最新的功能都会在Mainline但是不是相对稳定)
这里选择Stable
然后进行解压
查看各目录作用
auto中CC目录里有四个子目录CC是用来编译的,还有lib库,对操作系统所有的判断在OS
其他目录和文件都是为了辅助configure脚本执行的时候判定nginx支持哪些模块,当前的操作系统有什么样的特性,可以供给nginx使用
CHANGGES文件是nginx每个版本中提供了那些特性和bugfix
CHANGGES.ru是俄罗斯版本的CHANGES文件
conf是配置文件
configure脚本是用来生成中间文件执行编译前的必备动作
contrib目录提供了两个poer脚本和vim的工具,默认nginx语法没有在vim中
给配置文件添加高亮(也可以不做) [root@server1 ~]# mkdir .vim [root@server1 ~]# cp -r nginx-1.14.2/contrib/vim/* .vim/ |
nginx的语法就可以使用了
man目录是使用帮助目录
src目录是存放源代码的,还有它的一些框架
进行编译
编译前下载依赖包
[root@controller?~/nginx-1.16.1]#yum -y install gcc gcc-c++ make automake autoconf pcre pcre-devel zlib zlib-devel openssl openssl-devel libtool [root@controller ~/nginx-1.16.1]# ./configure --prefix=/home/geek/nginx |
configure中分几个大块,上面那些是nginx执行中它会去找那些目录下的文件,作为它的辅助的文件,进行指定,如果用--modules-path=PATH它的动态模块就会产生作用,--lock-path=PATH来确定nginx .lock文件。如果没有变动直接--prefix=PATH就可以了,底下所有的文件都会在--prefix指定的目录下创建文件。
第二类参数是使用那些模块和不使用那些模块,它的前缀通常是--with和--without
--with开头的模块默认是不会编译到nginx的,需要编译时添加上
--without开头的模块默认会编译到nginx中的,编译时加上,就会移出模块中
第三类参数指定nginx编译中需要的一些特殊参数,
用TCC编译时要添加的什么样的优化参数(--with-cpp=PATH),或者要打印debug级别的日志(--with-debug),以及要加一些第三方的模块(--with-zlib)
编译完成会生成一些中间文件,文件会放在objs这个目录下,目录下会生成ngx_modules.c
这个文件决定了编译时,有那些模块会被编译进nginx。
接下来进行编译
[root@controller ~/nginx-1.16.1]# make && make install |
编译完nginx目录在这里,如果我们做nginx版本升级这个时候不能执行make install,还需要把nginx文件拷贝到安装目录中,c语言编译的文件都会放在src目录。
如果使用了动态模块,动态模块编译时会生成SO动态文件,也会放在objs目录中
nginx配置语法
1.配置文件由指令与指令块构成
nginx配置文件是一个ascll配置文本文件,主要由两部分组成
http加{}就是一个指令块,include mime,types; 就是一条指令,每条指令由分号结尾
2.每条指令以 ;分号结尾、指令与参数间以空格符号分隔
include是个指令名,中间可以一个或者多个空格,后面mime,types;是它的参数
也可以具备多个参数
3.指令快以 { } 大括号将多条指令组织在一起
比如upstream,它把server指令,放在了thwp这个指令块下面。
server放置了listen,limit_req_zone,location,三条指令
4.include语句允许组合多个配置文件以提升可维护性
mime.types这个文件中含有很多条不同文件的后缀名与http协议mime格式的对照关系表
这些关系指令都是整合在一起的
5.使用#符号可以添加注释,提高可读性
6.使用$符号可是使用变量
limit_req_zone是一条限流的空间的指令,它控制了流控$binary_remote_addr,这个描述的是远端的一个地址
7.部分指令的参数支持正则表达式
location
expires 3m;意思是3分钟后cache刷新
不加任何后缀名的时候,默认单位是字节
http大括号里面,里面所有的指令都是由http模块去解析去执行的,一个非http模块,比如stream,mime是无法解析这http里的指令的。upstream表示的是上游服务,当nginx需要于tomcat,Django,或者是公司内网的其他服务,交互的时候,可以定义一个upstream,server对应的是一个域名,或者是对应一组域名,location只是一个URL表达式,
1.重载配置文件
[root@controller ~]# ./nginx -s reload |
热部署,平滑升级
[root@localhost sbin]# ps -ef|grep nginx root 9867 1 0 04:29 ? 00:00:00 nginx: master process ./nginx nobody 9868 9867 0 04:29 ? 00:00:00 nginx: worker process root 16514 3332 0 05:32 pts/0 00:00:00 grep --color=auto nginx [root@ localhost nginx-1.16.2]# cd /usr/local/nginx/sbin/ [root@localhost sbin]# ls nginx nginx.old [root@localhost sbin]# ./nginx -t #查看nginx配置文件是否正确 nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@localhost sbin]# ./nginx -v #查看nginx的版本及测试特性时所加的参数 nginx version: nginx/1.16.2 [root@localhost sbin]# useradd nginx [root@localhost sbin]# vim ../conf/nginx.conf user nginx nginx; worker_processes 2; #设置产生两个worker进程来处理客户请求
#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;
#pid logs/nginx.pid;
events { worker_connections 65535; #更改最大连接数 }
|
修改linux资源限制配置文件:
[root@localhost sbin]# vim /etc/security/limits.conf End of file nginx - nofile 65535 |
启动nginx
[root@localhost sbin]# ./nginx |
将nginx-1.16.1平滑升级到nginx-1.17.3
解压缩
[root@localhost ~]# tar zxf nginx-1.17.3.tar.gz [root@localhost ~]# ls nginx-1.16.1 nginx-1.16.1.tar.gz nginx-1.17.3 nginx-1.17.3.tar.gz |
测试存在特性、编译
[root@localhost ~]# cd nginx-1.17.3 [root@localhost nginx-1.17.3]# /usr/local/nginx/sbin/nginx -v nginx version: nginx/1.16.1 [root@localhost nginx-1.17.3]# ./configure --prefix=/usr/local/nginx --with-file-aio [root@localhost nginx-1.17.3]# make ##切忌不能make install负责会覆盖老版本的所有相关文件 |
查看新版本的二进制执行文件版本
[root@localhost nginx-1.17.3]# cd objs/ [root@localhost objs]# ls autoconf.err nginx ngx_auto_config.h ngx_modules.c src Makefile nginx.8 ngx_auto_headers.h ngx_modules.o [root@localhost objs]# ./nginx -V nginx version: nginx/1.17.3 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) configure arguments: --prefix=/usr/local/nginx --with-file-aio |
备份老版本的二进制可执行文件,可以防止升级失败无法版本回退。
[root@localhost objs]# cd /usr/local/nginx/sbin/ [root@localhost sbin]# ./nginx -v nginx version: nginx/1.16.1 [root@localhost sbin]# cp nginx nginx.old [root@localhost sbin]# ls nginx nginx.old |
将新版本的脚本复制到旧版本的脚本目录下
[root@localhost sbin]# cd - /root/nginx-1.17.3/objs [root@localhost objs]# ls autoconf.err nginx ngx_auto_config.h ngx_modules.c src Makefile nginx.8 ngx_auto_headers.h ngx_modules.o [root@localhost objs]# cp -f nginx /usr/local/nginx/sbin/ cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y |
平滑升级
查看到此时nginx的master进程和两个worker进程:
[root@server1 objs]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin nobody 3564 3563 0 08:54 ? 00:00:00 nginx: worker process nobody 3565 3563 0 08:54 ? 00:00:00 nginx: worker process root 6135 977 0 09:01 pts/0 00:00:00 grep --color=auto nginx |
客户端查看此时生效的nginx服务器:
[root@foundation60 ~]# curl -I 172.25.60.1 HTTP/1.1 200 OK Server: nginx/1.16.1 Date: Fri, 17 May 2019 01:01:45 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Thu, 16 May 2019 07:52:45 GMT Connection: keep-alive ETag: "5cdd16cd-264"
Accept-Ranges: bytes |
此时生效的是nginx-1.14.2
在不停掉老进程的情况下,启动新进程。
[root@server1 objs]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin nobody 3564 3563 0 08:54 ? 00:00:00 nginx: worker process nobody 3565 3563 0 08:54 ? 00:00:00 nginx: worker process root 6135 977 0 09:01 pts/0 00:00:00 grep --color=auto nginx |
注意:此时3563为旧版本的master进程,3564,3565为旧版本接收用户请求的worker进程!!
[root@server1 objs]# kill -USR2 3563 #3563 master进程的两个工作进程不再接收新的请求,只处理当前的请求。同时打开新版本的nginx的master进程,和它的两个工作进程,处理新的用户请求 [root@server1 objs]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin nobody 3564 3563 0 08:54 ? 00:00:00 nginx: worker process nobody 3565 3563 0 08:54 ? 00:00:00 nginx: worker process root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process root 6141 977 0 09:09 pts/0 00:00:00 grep --color=auto nginx |
此时访问,是新的nginx在接受访问
[root@foundation60 ~]# curl -I 172.25.60.1 HTTP/1.1 200 OK Server: nginx/1.17.3 Date: Fri, 17 May 2019 01:10:16 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Thu, 16 May 2019 07:52:45 GMT Connection: keep-alive ETag: “5cdd16cd-264” Accept-Ranges: bytes |
老进程处理完所有请求,关闭所有连接后,停止
[root@server1 objs]# kill -WINCH 3563 [root@server1 objs]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process root 6145 977 0 09:11 pts/0 00:00:00 grep --color=auto nginx |
kill -WINCH 只会杀掉旧版本master进程的两个worker进程,不会杀掉master进程。等更新完毕后,没有出现问题,才可以杀死旧版本的master进程,则平滑升级完毕!!!
kill主进程支持的信号
TERM, INT: 立刻退出
QUIT: 等待工作进程结束后再退出
KILL: 强制终止进程
HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。
USR1: 重新打开日志文件
USR2: 启动新的主进程,实现热升级
WINCH: 逐步关闭工作进程
工作进程支持的信号
TERM, INT: 立刻退出
QUIT: 等待请求处理结束后再退出
USR1: 重新打开日志文件
版本回退
在实际生产环境中,一旦升级出现任何问题,马上回退到之前的版本
1、将备份好的旧版本的脚本还原
[root@server1 sbin]# pwd /usr/local/nginx/sbin [root@server1 sbin]# ls nginx nginx.old [root@server1 sbin]# cp -f nginx.old nginx cp: overwrite ‘nginx’? y [root@server1 sbin]# ls nginx nginx.old |
2、唤醒旧版本的master进程,使之产生新的worker进程
[root@server1 sbin]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process root 6153 977 0 09:18 pts/0 00:00:00 grep --color=auto nginx [root@server1 sbin]# kill -HUP 3563 [root@server1 sbin]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process nobody 6154 3563 0 09:18 ? 00:00:00 nginx: worker process nobody 6155 3563 0 09:18 ? 00:00:00 nginx: worker process root 6157 977 0 09:19 pts/0 00:00:00 grep --color=auto nginx |
3、使回退版本的worker进程接收新的用户请求。同时新版本的master进程的worker进程不再接收新的用户请求,只处理当前的用户请求
[root@server1 sbin]# kill -USR2 6137 [root@server1 sbin]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin nobody 6138 6137 0 09:09 ? 00:00:00 nginx: worker process nobody 6139 6137 0 09:09 ? 00:00:00 nginx: worker process nobody 6154 3563 0 09:18 ? 00:00:00 nginx: worker process nobody 6155 3563 0 09:18 ? 00:00:00 nginx: worker process root 6160 977 0 09:20 pts/0 00:00:00 grep --color=auto nginx |
4、关闭新版本master进程的两个worker进程
[root@server1 sbin]# kill -WINCH 6137 [root@server1 sbin]# ps -ef | grep nginx root 3563 1 0 08:54 ? 00:00:00 nginx: master process ./ngin root 6137 3563 0 09:09 ? 00:00:00 nginx: master process ./ngin nobody 6154 3563 0 09:18 ? 00:00:00 nginx: worker process nobody 6155 3563 0 09:18 ? 00:00:00 nginx: worker process root 6162 977 0 09:20 pts/0 00:00:00 grep --color=auto nginx |
现在工作的又是旧版本;
[root@foundation60 ~]# curl -I 172.25.60.1 HTTP/1.1 200 OK Server: nginx/1.14.2 Date: Fri, 17 May 2019 01:21:08 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Thu, 16 May 2019 07:52:45 GMT Connection: keep-alive ETag: "5cdd16cd-264" Accept-Ranges: bytes |