以下所有的实操都是在redhat7.3上
关于nginx的简介资料
server1 | 172.25.70.1 | nginx服务器 |
---|---|---|
server2 | 172.25.70.2 | 后端服务器1 |
server3 | 172.25.70.3 | 后端服务器2 |
客户端 | 172.25.70.250 | 测试 |
[root@server1 ~]# ls
nginx-1.17.0.tar.gz
nginx-1.16.0.tar.gz
[root@server1 ~]# tar zxf nginx-1.17.0.tar.gz
[root@server1 ~]# cd nginx-1.17.0
[root@server1 nginx-1.17.0]# yum install -y zlib-devel# 这是编译nginx的依赖包
[root@server1 nginx-1.17.0]# yum install -y openssl-devel # 这是编译nginx的依赖
[root@server1 nginx-1.17.0]# ./configure --prefix=/usr/local/nginx --with-file-aio # 开始编译
[root@server1 nginx-1.17.0]# make && make install #安装编译
[root@server1 nginx-1.17.0]# ./configure --help #查看关于configure的参数内容
[root@server1 nginx-1.17.0]# du -sh /usr/local/nginx/ #查看nginx软件大小
[root@server1 nginx-1.17.0]# rm -fr /usr/local/nginx
[root@server1 nginx-1.17.0]# make clean #清除Makefile,否则版本查看不了
rm -rf Makefile objs
[root@server1 nginx-1.17.0]# vim src/core/nginx.h
14 #define NGINX_VER "nginx/" NGINX_VERSION #隐藏版本类型,将NGINX_VERSION删除;
[root@server1 nginx-1.17.0]# vim auto/cc/gcc #关闭debug日志,软件件包变小,占内存更小
172 #CFLAGS="$CFLAGS -g"
[root@server1 nginx-1.17.0]# ./configure --prefix=/usr/local/nginx --with-file-aio ## 自定义添加模块编译nginx
[root@server1 nginx-1.17.0]# make && make install
[root@server1 nginx-1.17.0]# du -sh /usr/local/nginx # 可以看到nginx非常小,如果打开debug日志的话,就会大得多,实际生产环境也不开debug日志
876K /usr/local/nginx
[root@server1 sbin]# /usr/local/nginx/sbin/nginx -V #查看软件版本,建立时间,以及部署的
[root@server1 sbin]# pwd
/usr/local/nginx/sbin
[root@server1 sbin]# ./nginx # 开启nginx服务,出现这种情况的原因可能是,nginx的默认生成端口是80,与httpd端口冲突,解决方案是把httpd卸载掉或者把httpd的服务关闭
[root@server1 sbin]# netstat -tnlp #这里所开的80端口是nginx的
[root@server1 html]# pwd
/usr/local/nginx/html
[root@server1 html]# ls
50x.html #报错发布页面 index.html#ngnix默认的发布页面
[root@server1 conf]# cd
[root@server1 ~]# mkdir .vim
[root@server1 ~]# cp -r nginx-1.17.0/contrib/vim/* ~/.vim
[root@server1 ~]# vim /usr/local/nginx/conf/nginx.conf # 此时再次查看配置文件就会有颜色,方便我们排错
[root@server1 ~]# vim /usr/local/nginx/conf/nginx.conf
2 user nginx nginx; #设置用户和用户组
3 worker_processes 2;#改为双核的;
[root@server1 sbin]# ./nginx -s reload
[root@server1 conf]# useradd nginx #添加用户
nginx: [error] invalid PID number "" in "/usr/local/nginx/logs/nginx.pid"
[root@server1 sbin]# ps ax|grep nginx 将其master process 和两个 worker process
[root@server1 sbin]# ./nginx #重启服务
[root@server1 conf]# /usr/local/nginx/sbin/nginx #重启服务
[root@server1 conf]# /usr/local/nginx/sbin/nginx -t #查看报错
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@server1 conf]# ps aux|grep nginx
1. 什么是nginx热部署?
1. 先来说一下运行nginx服务开启的进程情况
Ngnix中的进程分为两类,一类是master进程,一类是worker进程
其中master进程是用来管理监控控制其下边的worker进程的主进程,这个进程由root发起
其中原因是http这个服务需要启用80端口,而只有root才有权限启用80端口
而顾名思义,worker进程才是真正working的进程,才是真正处理请求的进程
这些进程全部都是master进程的子进程,这些进程是以普通用户的身份进行运行的,这样就可以极大增加程序的安全性
就算是万一有一个进程被劫持,那也不会有管理员权限
Worker进程中,原生的功能只有最基本的web服务
但是由于nginx是高度模块化的应用程序,所以,在每一个worker进程中,有着一个或者多个模块
但是需要注意的是,装载的模块可不是全部一次加载进去的,只有当这个进程真的需要这个模块的时候,才会被这个工作进程加载
在我看来,模块化的思想和面向对象的思想,是推动现代整个开发的重要思想
由于nginx这个高度模块化的机制,也成就了其高效轻量的特点
2. 进行热部署的前提条件(也就是为什么nginx可以进行热部署)
nginx 的热部署和其并发模型有着密不可分的关系,是因为 master 进程和worker进程的关系
当系统通知 ngnix 重读配置文件的时候,master 进程会进行语法错误的判断
如果存在语法错误的话,返回错误,不进行装载;如果配置文件没有语法错误,那么 ngnix 也不会将新的配置调整到所有 worker 中
而是,先不改变已经建立连接的 worker,等待 worker 将所有请求结束之后,将原先在旧的配置下启动的 worker 杀死
然后使用新的配置创建新的 worker
所以可以做到在线更新版本,新版本和旧版本的进程可以同时存在,不影响客户的访问
3. 什么是热部署?
热部署在nginx中还是一个强大的功能,就是
在线升级
其原理就是首先我们先会替换master进程,同时我们替换的master是与老版本的worker兼容的
下一步,就是想大家已经想到的一样。保持还有连接的worker进程,待其老去退休,进行替换
高度的模块化加上精巧的两层模型,让ngnix成为大家非常热爱的web service实现的方案
nginx支持热加载热部署 ,其实就是在不打断用户请求的情况下更新版本,也就是在线更新版本
2.热部署的分类?
(1)热部署成功(平滑更新)
在线更新nginx服务的版本并且更新成功,这个时候nginx的新版本和旧版本进程都可以同时工作,不影响客户的正常访问
(2)热部署失败(回滚)
在线更新nginx服务的版本并且更新失败,这个时候就直接回退到原来的nginx版本进程,保证客户可以正常访问
问题1:将nginx/1.17.0版本更新nginx/1.16.0版本
[root@server1 sbin]# /usr/local/nginx/sbin/nginx -V #先查看版本
[root@server1 ~]# tar zxf nginx-1.16.0.tar.gz
[root@server1 ~]# cd nginx-1.16.0/
[root@server1 nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --with-file-aio
[root@server1 nginx-1.16.0]# make #不能执行make install,否则会覆盖之前的1.7.0版本的所有内容
[root@server1 nginx-1.16.0]# cd objs/
[root@server1 objs]# ll
[root@server1 objs]# ./nginx -V #查看出是1.16.0版本;
[root@server1 objs]# cd /usr/local/nginx/sbin/
[root@server1 sbin]# ls
[root@server1 sbin]# cp nginx nginx.old 需要将/usr/local/nginx/sbin/nginx下的nginx进行备份,便于恢复旧版本或防止新版本的nginx出问题,否则1.6.0会直接覆盖它,导致服务断掉;
[root@server1 ~]# cd nginx-1.16.0/objs/
[root@server1 objs]# cp nginx /usr/local/nginx/sbin/nginx 将1.16.0版本去覆盖1.17.0的版本,还有备份;
[root@server1 objs]# ps -ef | grep nginx
[root@server1 objs]# kill -USR2 31249 #master之前的所有的服务停止接受服务,并且生成一个的master服务接受服务;发送信号告诉系统要升级,31249是旧版本nginx的进程号
[root@base1 objs]# ps -ef | grep nginx # 查看,发现新版本的nginx
出现报错:如果没有新版本生成的,那么关闭进程
[root@server1 sbin]# ./nginx -s reload
nginx: [error] invalid PID number “” in “/usr/local/nginx/logs/nginx.pid”
[root@server1 sbin]# ps ax|grep nginx 将其master process 和两个 worker process 关闭kill进程
[root@server1 sbin]# ./nginx #重启服务即可;
[root@server1 sbin]# kill -WINCH 31249 #-WINCH:平滑的杀死master之前的1.17.0下面的worker服务,停止旧的nginx,只会停止掉旧的nginx的worker
[root@server1 sbin]# cd
[root@server1 ~]# /usr/local/nginx/sbin/nginx -V #查看版本,将1.17版本已经变成1.16版本;
问题2:将nginx/1.16.0版本回退到nginx/1.17.0版本;
[root@server1 ~]# ps -ef | grep nginx
[root@server1 ~]# kill -HUP 31249 将旧版本nginx/1.17.0的worker服务进行重新拉起来
[root@server1 ~]# ps -ef | grep nginx ##新worker process是后两行;
[root@server1 ~]# kill -WINCH 31254 #平滑杀死1.16.0新版本的下面ngnix的worker process,停止新的nginx,只会停止掉新的nginx的worker
[root@server1 ~]# ps -ef | grep nginx
[root@server1 ~]# kill -9 31254 #关闭1.16.0新版本的进程;
[root@server1 ~]# ps -ef | grep nginx
[root@server1 ~]# cp -f /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx
#将1.17.0版本的nginx的主程序将1.16.0覆盖,进行恢复1.17.0版本的
[root@server1 ~]# ps -ef | grep nginx#查看nginx的master和worker服务;当master毁掉,worker进行服>务,当master恢复,则worker进入备胎模式;
[root@server1 ~]# /usr/local/nginx/sbin/nginx -V #显示为nginx/1.17.0版本
[root@server1 sbin]# cd /usr/local/nginx/html/
[root@server1 html]# vim index.html #扩大index.html文件大小;
[root@server1 html]# du -sh index.html #查看大小;
浏览器测试:172.25.10.1
按f12---->选择Network
[root@server1 ~]# vim /usr/local/nginx/conf/nginx.conf
2 user nginx nginx;
3 worker_processes 2;
33 gzip on;
34 gzip_comp_level 2;
35 gzip_min_length 1;
36 gzip_types text/plain application/x-javasc ript text/css application/xml text/javascript application/x-httpd-php image/jped image/gif image/png;
[root@server1 ~]# /usr/local/nginx/sbin/nginx -s reload #修改完配置文件需要重新加载一下配置文件;
[root@server1 conf]# systemctl status httpd #查看httpd是否存在,不存在时需要安装:yum install -y httpd
[root@server1 system]# cd /etc/systemd/system
[root@server1 system]# ls
[root@server1 system]# cp /usr/lib/systemd/system/httpd.service nginx.service
[root@server1 system]# vim /etc/systemd/system/nginx.service #配置systemctl的配置脚本
[Unit]
Description=The Nginx HTTP Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@server1 logs]# systemctl start nginx.service ##启动的时候记得关闭nginx服务,否则报错,如果关闭不了,直接结束进程;
解决办法:
[root@server1 logs]# ps -ef |grep nginx #查看进程,结束进程
[root@server1 logs]# kill -9 4695
[root@server1 logs]# kill -9 4736
[root@server1 logs]# kill -9 4737 #之前的nginx是通过二进制指令启动的,所以编写好启动脚本之后需要先kill掉之前的进程,重新开启即可
[root@server1 logs]# systemctl start nginx.service
[root@server1 logs]# systemctl status nginx.service
在官网上:nginx官网查看相关配置文件信息
查看文档Documentation
[root@server1 conf]# pwd
/usr/local/nginx/conf
[root@server1 conf]# vim nginx.conf
user nginx nginx; ## 设置用户和用户组
worker_processes 2; ##将系统改为2个CPU,然后用两个CPU进行处理
#事件模块
events {
worker_connections 30000; #最大接受文件数
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;# 启动高效传输文件的模式,这个开启下面的tcp_nopush才生效
#tcp_nopush on;# 避免磁盘阻塞
#keepalive_timeout 0; # 避免网络阻塞
keepalive_timeout 65; # 保持连接
#gzip on; #网页压缩
limit_conn_zone $binary_remote_addr zone=addr:10m; ###
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /download/ {
#这里/download/指的是/usr/local/nginx/html/download
limit_conn addr 1;# 只允许并发数为1
}
#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;
}
}
}
[root@server1 conf]# ln -s /usr/local/nginx/sbin/nginx /sbin/ #可以table补全
[root@server1 conf]# /usr/local/nginx/sbin/nginx -t
[root@server1 conf]# systemctl restart nginx.service #重启服务
[root@server1 html]# pwd
/usr/local/nginx/html
[root@server1 html]# mkdir download
[root@server1 html]# cd download/
[root@server1 download]# ls
5bcd335dbe0e5.jpg #随便下载一张照片放在该目录下;
[root@server1 download]# du -sh 5bcd335dbe0e5.jpg #文件大小
156K 5bcd335dbe0e5.jpg
[root@server1 download]# /usr/local/nginx/sbin/nginx -s reload #利用配置文件启动nginx服务
测试:
[root@foundation70 ~]# ab -c 1 -n 10 http://172.25.70.1/download/5bcd335dbe0e5.jpg
当并发数小于限制的并发数时,就不会有失败
[root@foundation70 ~]# ab -c 2 -n 10 http://172.25.70.1/download/5bcd335dbe0e5.jpg
#有并发报错:有失败是为了限制了并发数,即使是2个CPU;
[root@server1 conf]# vim /usr/local/nginx/conf/nginx.conf
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;#每一秒只处理一个请求
server {
listen 80;
server_name localhost;
location / {
root html;
set $limit_rate 50k;
index index.html index.htm;
}
location /download/ {
# limit_conn addr 1;
# limit_req zone=one burst=5; #最大连接数5个
limit_rate 50k; #带宽为50k
# set
}
}
[root@server1 sbin]# systemctl reload nginx.service ##重启服务;
[root@server1 conf]# vim /usr/lib/systemd/system/varnish.service
14 LimitNOFILE=30000
18 LimitMEMLOCK=64000
测试:
[kiosk@foundation70 ~]$ ab -c 1 -n 2 http://172.25.70.1/download/5bcd335dbe0e5.jpg
[kiosk@foundation70 ~]$ ab -c 1 -n 2 http://172.25.70.1/index.html
[root@server1 sbin]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
# set $limit_rate 50k;
index index.html index.htm;
}
location /download/ {
#limit_conn addr 1;
limit_req zone=one burst=5; #最大连接数为5;
# limit_rate 50k;
}
}
[root@server1 sbin]# ./nginx -s reload
[kiosk@foundation70 ~]$ ab -c 4 -n 10 http://172.25.70.1/download/5bcd335dbe0e5.jpg 无错误文件
[kiosk@foundation70 ~]$ ab -c 6 -n 10 http://172.25.70.1/download/5bcd335dbe0e5.jpg #6次并发,共进行10次;
原因:不然每天的存储的太多,太占内存
手动备份
[root@server1 logs]# cd /usr/local/nginx/conf/
[root@server1 conf]# ls
[root@server1 conf]# vim nginx.conf ## 注释压缩
[root@server1 conf]# sysctl -a | grep file ##查看系统文件最大限度
[root@server1 conf]# vim /etc/security/limits.conf #修改为网络连接数满足当前的最大软件限制
[root@server1 conf]# pwd
/usr/local/nginx/conf
[root@server1 conf]# vim nginx.conf
12 events {
13 worker_connections 30000;
14 }
[root@server1 logs]# pwd
/usr/local/nginx/logs
[root@server1 logs]# ls
[root@server1 logs]# mv access.log access.log.backup #将之前的日志备份起来;
[root@server1 logs]# ls
[root@server1 logs] # vim /usr/local/nginx/html/index.html
[root@server1 logs]# /usr/local/nginx/sbin/nginx -s reopen #进行加载后生成新的日志文件
[kiosk@foundation70 ~]$ curl 172.25.70.1
server1.example.com
[root@server1 logs]# cat access.log #访问来源为客户端
脚本形式执行
;文件命名为2019-09-18[root@server1 logs]# vim backup.sh
#!/bin/bash
LOGS_PATH=/usr/local/nginx/logs/oldlogs
CUR_LOGS_PATH=/usr/local/nginx/logs
YESTERDAY=$(date +%F -d -1day)
mv $CUR_LOGS_PATH/access.log $LOGS_PATH/${
YESTERDAY}_access.log
mv $CUR_LOGS_PATH/error.log $LOGS_PATH/${
YESTERDAY}_error.log
#/usr/local/nginx/sbin/nginx -s reopen
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)
[root@server1 logs]# mkdir /usr/local/nginx/logs/oldlogs
[root@server1 logs]# ls
access.log access.log.backup backup.sh error.log nginx.pid oldlogs
[root@server1 logs]# rm -fr access.log.backup
[root@server1 logs]# chmod +x backup.sh
[root@server1 logs]# ./backup.sh #执行脚本
[root@server1 logs]# cd oldlogs/
[root@server1 oldlogs]# ls
2019-09-23_access.log 2019-09-23_error.log
[root@server1 oldlogs]# cd ..
[root@server1 logs]# ls
[root@server1 logs]# cat access.log
测试:
[kiosk@foundation70 ~]$ curl 172.25.70.1
server1.example.com
[root@server1 logs]# cat access.log
172.25.70.250 - - [24/Sep/2019:07:17:08 +0800] "GET / HTTP/1.1" 200 20 "-" "curl/7.29.0"
nginx配置
文件中写入日志信息,在客户端进行访问,就可以查看访问来自那里;[root@server1 conf]# pwd
/usr/local/nginx/conf
[root@server1 conf]# vim nginx.conf
21 log_format main '$remote_addr - $remote_user [$time_local] "$reques t" '
22 '$status $body_bytes_sent "$http_referer" '
23 '"$http_user_agent" "$http_x_forwarded_for"';
47 access_log logs/westos.access.log main;
[root@server1 conf]# ../sbin/nginx -s reload
[root@server1 logs]# ls
access.log backup.sh error.log nginx.pid oldlogs westos.access.log
测试:
[kiosk@foundation70 ~]$ ab -c 1 -n 100 http://172.25.70.1/index.html
[kiosk@foundation70 ~]$ curl 172.25.70.1
server1.example.com
再次查看
[root@server1 logs]# cat westos.access.log 日志
注意:日志测试完毕,记得还原nginx.conf的配置文件;
重定向的概念
配置文件–>虚拟主机
[root@server1 ~]# cd /usr/local/nginx/
[root@server1 conf]# vim nginx.conf
#当访问域名server1.example.com,实际访问的是直接返回client real ip: $remote_addr\n
server {
listen 80; #监听80端口
server_name server1.example.com; #定义域名
set_real_ip_from 172.25.70.1; #真正的ip地址;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
return 200 "client real ip: $remote_addr\n";
}
}
[root@server1 conf]#/usr/local/nginx/sbin/nginx -t #启动失败;
[root@server1 conf]# systemctl stop nginx
添加-with-http_realip_module选项(后台Nginx服务器记录原始客户端的IP地址 )
[root@server1 nginx-1.17.0]# ./configure --prefix=/usr/local/nginx --with-file-aio --with-http_realip_module
--with-file-aio 启用file aio支持(一种APL文件传输格式)
--with-http_realip_module:它的意义在于能够使得后台服务器记录原始客户端的IP地址。
[root@server1 nginx-1.17.0]# make && make install
[root@server1 nginx-1.17.0]# vim /usr/local/nginx/conf/nginx.conf
添加虚拟机(最后一行):
132 server {
133 listen 80;
134 server_name server1.example.com;
135 set_real_ip_from 172.25.70.1; ###set_real_ip_from: 功能:通过该指令指定信任的地址,将会被替代为精确的IP地址。从0.8.22版本后也可以使用信任的Unix套接字。这里设置的IP就是指前端Nginx 、Varnish或者 Squid 的 IP地址。
136 real_ip_header X-Forwarded-For; # real_ip_header::这个指令用于设置使用哪个头来替换IP地址。如果使用了X-Forwarded-For,那么该模块将会使用X-Forwarded-For头中的最后一个IP地址来替换前端代理的IP地址。
137 real_ip_recursive on;
138 location / {
139 return 200 "client real ip: $remote_addr\n";
140 }
141
142
143 }
[root@server1 nginx-1.17.0]# cd /usr/local/nginx/conf/
[root@server1 conf]# systemctl restart nginx.service
[root@server1 conf]# vim /etc/hosts
172.25.70.1 server1 server1.example.com
[root@server1 conf]# curl -H "X-Forwarded-For:1.1.1.1,172.25.70.1" server1.example.com
[root@server1 conf]# scp -r /usr/local/nginx/ server2: #serve1将其nginx发送给server2