nginx配置与应用

Nginx

初识nginx

介绍Nginx

1.为什么选择nginx
高性能,高并发,高可靠
热部署 nginx使用网络模型epool
高扩展:丰富的模块,能随时能够集成

2.其他的web服务器
Apache
Lls
Nginx
Tengine
GWS
Openrestry

3.NGINX有哪些应用场景
   静态资源服务
   代理资源服务
   安全服务

场景介绍
   用户请求先到达NGINX,然后到tomcat(运行java)或者django(运行python)这样的应用服务器,然后在去访问redis,mysql这样的数据库,提供基本的数据功能。
   很多服务构成集群的时候,需要nginx具有反向代理功能,这样可以将动态请求传导给应用服务。集群架构需要两个需求:
   1.应用服务器需要动态扩展
   2.有些服务出问题需要容灾。反向代理必须具备负载均衡功能。
代理:
   负载均衡
   缓存
静态资源:
   静态资源和nginx和动态资源tomcat分开处理。
安全服务:
   https
   限速
   限流
   访问控制
   nginx+lua构建web应用的防火墙 waf

Nginx安装

  源码编译,
   yum安装(推荐)
   epel的仓库
   
   安装:
   配置nginx官方仓库
cat >>/etc/yum.repos.d/nginx.repo<<-EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
   然后命令行输入
   yum install nginx -y

配置文件

[root@Cc ~]# rpm -ql nginx
nginx配置文件
/etc/nginx/nginx.conf			 nginx主配置文件
/etc/nginx/conf.d/default.conf	 默认网站配置文件


nginx代理相关参数
/etc/nginx/fastcgi_params		 fastog代理配置文件
/etc/nginx/scgi_params			 scgi代理配置文件
/etc/nginx/uwsgi_params			 uwsgi代理配置文件

nginx编码相关配置文件
/etc/nginx/win-utf				 nginx编码转换映射文件
/etc/nginx/koi-utf			     nginx编码转换映射文件
/etc/nginx/koi-win				 nginx编码转换映射文件
/etc/nginx/mime.types			 content-type与扩展名

nginx管理相关命令
/usr/sbin/nginx					 nginx命令行管理终端工具
/usr/sbin/nginx-debug			 nginx命令行与终端调试工具
/var/log/nginx				     nginx默认存放的日志目录
/etc/logrotate.d/nginx			 nginx默认的日志切割

启动Nginx

启动前检查语法:
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
报错:可能是80端口被占用。
Failed to start nginx - high performance web server.

Nginx配置文件

vim nginx.conf
core module									核心模块
user  nginx;								运行nginx进程的用户
worker_processes  1;		 				worker的进程数量,按cup个数绑定;
error_log  /var/log/nginx/error.log warn;	错误日志
pid        /var/run/nginx.pid;				nginx进程运行后的PID存放的位置,用以判断服务是否启动,是否有PID重叠;
events						      			事件驱动模块
events {
    worker_connections  1024;				worker的最大连接数
    use epoll;					   			使用网络模型epoll 
}
http内核模块
http {
    include       /etc/nginx/mime.types;	包含nginx支持的资源类型
    default_type  application/octet-stream;	默认的类型。如果出现mime.types中不支持的类型,则以下载的方式发送给浏览器

日志格式

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    访问日志的路径
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;			    长连接,默认链接65S
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;	包含/ect/nginx/conf.d/目录下所有以.conf结尾的文件。编写网站访问规则
}

网站配置

server配置网站

server {				    		每个server代表一个网站,简称虚拟主机。
listen		80;			    		监听的端口。默认80
server_name	bgx.com;				提供的域名
access_log		access.log;			该网站的访问日志

  location / { 				    	控制网站的访问uri
  root  /usr/share/nginx/html;		存放网站源代码的位置
  index	  index.html;				默认返回网站的文件
}
}
include /etc/nginx/conf.d/*.conf;   包含conf.d目录下所有以.conf为结尾的文件


nginx中的http	server location之间的关系
  http{ }  	层下允许有多个server{ }层,一个server{ }层下又允许有多个location{ }层
  http	    标签主要用来解决用户的请求与响应
  server	标签主要用来响应具体的某一个网站
  location	标签主要用于匹配网站具体URI路径

快速搭建一个游戏网站:

进入nginx目录下conf.d目录
vim game.conf
“ ; ”分号是结束符必须要加

server {
listen			80;				  要监听的端口
server_name		www.game.com;	  提供的域名
access_log		access.log;	      该网站的访问日志

location	/	{				  控制网站的访问uri
root	/usr/share/nginx/html;	  存放网站源代码的位置
index	index.html	index.htm;	  默认返回网站的文件/usr/share/nginx/html/index.html
}
}
检查nginx语法
  nginx -t确认无误后
  重启nginx
  修改windows hosts域名解析文件
  IP地址   www.game.com
C:\Windows\System32\drivers\etc

http://game.caoxueming.com/index.html   真实路径:/code/index

虚拟化主机

添加IP的方式:ip addr add 10.0.0.8/24  dev eth0
nginx配置虚拟主机有以下三种方式:
1.基于主机多IP方式
2.基于端口的配置方式
3.基于多个hosts名称方式(多域名方式)
    虚拟主机多IP配置
    多IP设置有两种方式:
1.多网卡多IP方式
server {
…
listen 10.0.0.7:80;
location / {
			root /ip1;
   		     index index.html;
}
…
}
server {
…
listen 10.0.0.8:80;
location / {
	     root /ip2;
   		 index index.html;
}
…
}

2.单网卡多IP方式
多端口的配置方式 就不用添加域名了。
server{
			listen 81;
			loaction / {
			root /port1;
			index index.html;

}

}
server{
			listen 82;
			loaction / {
			root /port2;
			index index.html;

}

}

通过不同的端口访问到不同的域名
基于多个host名称方式(多域名方式)

a.oldboy.com——>hello a_name
b.oldboy.com——>hello b_name

1准备两份nginx配置文件
vim a.oldboy.com.conf
server	{
			listen 80;
			server_name a.oldboy.com;
			location / {
			root /a;
			index index.html;
}
}
vim b.oldboy.com.conf
server	{
			listen 80;
			server_name b.oldboy.com;
			location / {
			root /b;
			index index.html;
}
}
创建目录
mkdir /a
mkdir /b
echo “hello_a.oldboy.com” > /a/index.html
echo “hello_b.oldboy.com” > /b/index.html
语法检查nginx -t 重启nginx服务
host域名解析
10.0.0.7  a.oldboy.com
10.0.0.7  b.oldboy.com
也可以将两个域名绑定到同一台主机
10.0.0.7  a.oldboy.com b.oldboy.com

nginx日志

tail /var/log/nginx/access.log 

$remote_addr          记录客户端(公网)IP地址
$remote_user          记录客户端(登录)用户名
$time_local           记录通用的本地时间
$time_iso8601         记录ISO8601标准格式下的本地时间
$request              记录请求的方法以及请求的http协议
$status               记录请求状态码(用于定位错误信息)
$body_bytes_sent      发送给客户端的资源字节数,不包括响应头的大小
$bytes_sent           发送给客户端的总字节数
$msec                 日志写入时间。单位为秒,精度是毫秒。
$http_referer         记录从哪个页面链接访问过来的
$http_user_agent      记录客户端浏览器相关信息
$http_x_forwarded_for 记录客户端IP地址(记录请求头部ip信息)
$request_length       请求的长度(包括请求行,请求头和请求正文)。
$request_time         请求花费的时间,单位为秒,精度毫秒

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

10.0.0.11 - 				
- 							    
[23/Apr/2020:16:00:39 +0800] 	
"GET /favicon.ico HTTP/1.1" 
401 
4 
"http://test.caoxueming.com/down/" 
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36" "-"

			   
access_log /var/log/nginx/access.log main;必须这么写访问日志记录路径

vim /etc/nginx/nginx.conf

将b站的日志信息记录/var/log/nginx/test2.log
[root@web01 conf.d]# cat test2.conf 
server{
	listen 80;
	server_name b.caoxueming.com;
	access_log /var/log/nginx/test2.log	main;
	location / {
	root /b;
	index b.html;
}
一个配置文件有多个location,如果不想记录location日志。
	location / {
	root /a;
	index a.html;
	access_log off;
}
}

建议
1.保留http的access_log
2.新增加一个server,就添加一个server的记录日志

server{
	listen 80;
	server_name b.caoxueming.com;
	access_log /var/log/nginx/test2.log	main;
	location / {
	root /b;
	index b.html;
}

3.至于location有些不重要的内容不想记录。
	location / {
	root /a;
	index a.html;
	access_log off;
}

切割日志

cat	/etc/logrotate.d/nginx
/var/log/nginx/*.log{
			daily						每天切割日志
			missingok					日志丢失忽略
			rotate 52					日志保留52天
			compress					日志文件压缩
			delaycompress				延迟压缩日志
			notifempty					不切割空文件
			create 640 nginx adm		日志文件权限
			sharedscripts
			postrotate					日志切割执行的命令
						if [ -f	/var/run/nginx.pid ]; then
								kill -USR1 `cat	/var/run/nginx.pid`
						fi
			endscript
}

nginx模块

nginx目录索引

  • index模块不能与autoindex同时出现,系统默认先读取index模块;
模块
server {
        listen 80;
        server_name module.caoxueming.com;
        charset utf-8,gbk;		 		解决目录浏览模式的中文乱码问题,要在server下面添加。如果在server下配置,则整个server生效,如果在location下配置,只对location下生效。
        location / {
        root /game;		
        index index.html oldboy.html;	找不到index.html就找oldboy.html
        autoindex on;					开启目录自动浏览 ,要把目录下的index.html文件移走。
        autoindex_exact_size off;		人类可读数据大小
        autoindex_localtime on;			显示localtimeUTC时间
	    
}
}


目录索引显示不同页面
server {
		listen 80;
		server_name module.caoxueming.com;
		charset utf-8,gbk;
		location / {			# /game 找资源	 一个是 module.caoxeming.com
		root /game;
		index index.html;	
}
		location /down {		# /game/down/xxx 找资源	一个是 module.caoxueming.com/down
		root /game;
		autoindex on;
		autoindex_exact_size off;
		autoindex_localtime on;
}
	

}

nginx访问控制

ngx_access_module模块允许限制对某些客户端地址的访问
server	{
		listen 80;
		server_name module.caoxueming.com;
		charset utf-8,gbk;			   
		location / {
		root /game;
		index  index.html oldboy.html;	
}
		localtion /down {		   
		root /game;				   
		autoindex on;			  
		autoindex_exact_size off;   
		aotuindex_localtime on;	    
		deny	10.0.0.1/32;	  拒绝这台主机访问 module.caoxueming.com/down这个地址。
		allow	all;			  允许其他主机访问
}
}

server	{
		listen 80;
		server_name module.caoxueming.com;
		charset utf-8,gbk;			       解决目录浏览模式的中文乱码问题,要在server下面添加。
		location / {
		root /game;
		index  index.html oldboy.html;	   找不到index.html就找oldboy.html
}
		localtion /down { 				   当用户输入down的时候进入目录自动浏览页面。
		root /game;						
		autoindex on;					   开启目录自动浏览 
		autoindex_exact_size off; 		   人类可读数据大小
		aotuindex_localtime on;			   显示localtimeUTC时间
		allow	10.0.0.1/32;			   允许这台主机访问
		allow	10.0.0.0/24;			   允许这个网段访问
		deny	all;					   拒绝其他主机
} 
}
/admin {
		allow  36.155.155.236;
		deny   all;
}

nginx资源限制

创建用户和密码并结合访问控制:
htpasswd -c /etc/nginx/auth_conf oldboy	      指定认证文件和用
New password: 
Re-type new password: 
Adding password for user oldboy

htppasswd -cb /etc/nginx/auth_conf oldboy 123456 此方法会覆盖密码前密码

vim test4.conf 
server {
        listen 80;
        server_name module.caoxueming.com;
        charset utf-8,gbk;
        location / {
        root /game;
        index index.html;
}
        location /down {
        root /game;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        allow 10.0.0.0/24;
        deny all;
        auth_basic "oldboyedu.com";				     # 验证模块
        auth_basic_user_file /etc/nginx/auth_conf;	 # 验证账户密码文件路径位置
}
}
复制无效,要手敲 
在location下面加验证,登录这个location需要验证。
在location下面有验证,则跳过server层验证。
在server添加验证,即所有location都添加了验证。输入server验证即可浏览所有location页面。
也可以添加双重验证。如下:登录module.caoxueming.com和module.caoxueming.com/down都需要验证。

[root@web01 conf.d]# htpasswd -cb /etc/nginx/down_conf  caoxueming 123456
Adding password for user caoxueming
server {
        listen 80;
        server_name module.caoxueming.com;
        charset utf-8,gbk;
        auth_basic "oldboyedu.com";
        auth_basic_user_file /etc/nginx/auth_conf;
        location / {
        root /game;
        index index.html;
}
        location /down {
        root /game;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        allow 10.0.0.0/24;
        deny all;
        auth_basic "oldboyedu.com";
        auth_basic_user_file /etc/nginx/down_conf;        
 }             
        location /game_status{	   # 监控的状态名称和业务有关
        stub_status;			   # 监控模块
        allow  127.0.0.1;		   # 本地访问
        deny   all				   # 拒绝其他人
        auth_basic "chengjizhen";  # 进入验证	
        auth_basic_user_file /etc/nginx/down_conf;
}
}


nginx监控模块

[root@web01 conf.d]# vim test4.conf 
server {
        listen 80;
        server_name module.caoxueming.com;
        charset utf-8,gbk;
        location / {
        root /game;
        index index.html;
}
        location /down {
        root /game;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        allow 10.0.0.0/24;
        deny all;
        auth_basic "oldboyedu.com";				    
        auth_basic_user_file /etc/nginx/auth_conf;
}
        location /game_status{		 # 监控的状态名称和业务有关
        stub_status;			     # 监控模块
        auth_basic "chengjizhen";    # 进入验证	
        auth_basic_user_file /etc/nginx/down_conf;
}
}

nginx七种状态模块

状态模块
Active connections: 2 
server accepts handled requests
 		3 		3 		4 
Reading: 0 Writing: 1 Waiting: 1 

active connections	当前活动客户端连接数,包括waiting等待连接数
accepts				已接受总的tcp连接数
handled				已处理总的tcp连接数
requests			客户端总的http请求数
	
reading				当前nginx读取请求头的连接数
writing				当前nginx将响应写回客户端的连接数
waiting				当前等待请求的空闲客户端连接数

失败连接数计算:accepts-handled=失败的连接数
一个链接可以发送多个HTTP的请求。
模拟发送请求:
ab -n模拟10000次 -c并发200个 对象——>10.0.0.7/game_status
ab -n10000 -c 200 10.0.0.7/game_status

限制与优先读取

nginx访问限制

ab -n10000 -c 200 10.0.0.7/game_status
链接:(虚拟环境无法模拟效果)
请求:
指令:
syntax:limit_conn_zone key zone=name:size; 
key=存储的Ip地址。从remote_addr捕捉到某一个IP
zone=name:size 开辟一块内存的空间
示例:limit_conn_zone $remote_addr zone=conn_zone:10m;

$remote_addr			 占用十五个字节
$binary_remote_addr		 占用四个字节
default: -
context: http			 只能在HTTP层使用,一般设置在nginx.conf的配置文件中。
	
syntax: limit_conn zone number;	 同一时间允许多少个客户端连接。
default: -
context: http,server,location
设置共享内存区域和给定关键之的最大允许连接数,超过此限制时,服务器将返回错误以回复请求
http标签段定义连接限制:

vim /etc/nginx/conf.d/nginx.conf
http{
	limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
	}

vim /etc/nginx/test4.conf
server{
	listen 80;
	server_name module.caoxueming.com
	limit_conn conn_zone 1;  同一时间只允许一个客户端连接
	location / {
	root /game;
	index index.html;
}
}

限制来源的IP,不是用户。
limit_rate_after  200M以后限速。
limit_rate  	  200K限速。

错误503跳转返回页面'飞天大草'
error_page 503 @err;
location @err {
default_type text/html;
return 200 '飞天大草'
}

错误传递 
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server {
        listen 80;
        server_name game.test.com;
        auth_basic "123";
        auth_basic_user_file /etc/nginx/auth_game.conf;
#       limit_req zone=req_zone;
#       limit_req zone=req_zone burst=3 nodelay;
        charset utf-8,gpk;
        root /game;
        location / {
        index index.html;
}
        location /down {
        autoindex on;
        autoindex_exact_size on;
        autoindex_localtime on;
}
        location /game_status {
        stub_status;
}
        error_page 401 @err;
        location @err {
        default_type text/html;
        return 200 "gogogogo";
}
}

nginx 请求限制

当处理速度,达不到请求的速度,则会讲请求放置缓存,如果缓存被占满。多余的请求将被丢弃。
设置共享内存区域和请求的最大突发大小,过多的请求被延迟,直到它们的数量超过最大的限制,在这种情况下请求以错误终止。
测试:
ab -n10000 -c 200 10.0.0.7/game_status
http标签段定义请求限制,rate限制速率,限制一秒钟最多一个IP请求
vim /etc/nginx/nginx.conf
http	{
	limit_req_zone	$binary_remote_addr	zone=req_zone:10m	rate=1r/s;
}

vim /etc/nginx/conf.d/test4.conf
server	 {
	listen 80;
	server_name	module.caoxueming.com;
	1r/s;				     只接收一个请求,其余请求拒绝处理并返回错误码给客户端
	limit_req zone=req_zone; 请求超过1r/s剩下的将被延迟处理,请求数超过burst定义的数量,多余的请求返回到503
	limit_req zone=req_zone burst=3	nodelay;	使用定义,burst=3允许延迟处理三个请求,其他全部拒绝。
	location / {
	root /game;
	index index.html;
}
}

压力测试1(关闭burst+nodelay)

配置:
[root@backup01 ~]#cat /etc/nginx/conf.d/p6.com.conf 
	limit_conn_zone $remote_addr zone=old:10m;
	limit_req_zone $remote_addr zone=xu:10m rate=15r/m;
server {
	listen 80;
	server_name oldxu6.com;
	root /html;
	location /{
		autoindex on;
		autoindex_exact_size off;
		charset utf-8;			
		autoindex_localtime on;		
		allow 10.0.0.1;
		deny	all;
		auth_basic           "closed site";
    		auth_basic_user_file  /htpasswd;
		limit_conn old 1;
		limit_req zone=xu;     #burst=2 nodelay;
	}		
	location = /basic_status {
		    stub_status;
		auth_basic "qiucong"; 	
		auth_basic_user_file  ps;
        }
    }


#压力测试):
[root@backup01 ~]#ab -n10 -c 10 10.0.0.8/basic_status  #发送10个请求,最大10个一次,发送10.0.0.8/basic_status ;
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.0.0.8 (be patient).....done


Server Software:        nginx/1.18.0
Server Hostname:        10.0.0.8
Server Port:            80

Document Path:          /basic_status
Document Length:        179 bytes

Concurrency Level:      10
Time taken for tests:   0.003 seconds
Complete requests:      10
Failed requests:        0
Write errors:           0
Non-2xx responses:      10
Total transferred:      3730 bytes
HTML transferred:       1790 bytes
Requests per second:    3765.06 [#/sec] (mean)
Time per request:       2.656 [ms] (mean)
Time per request:       0.266 [ms] (mean, across all concurrent requests)
Transfer rate:          1371.45 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       0
Processing:     0    1   0.4      0       2
Waiting:        0    0   0.1      0       1
Total:          1    1   0.3      1       2
ERROR: The median and mean for the processing time are more than twice the standard
       deviation apart. These results are NOT reliable.

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      2
  95%      2
  98%      2
  99%      2
 100%      2 (longest request)

#日志检查结果:
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 200 1063 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:43:03 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
*从日志可看出:成功连接了1个,其他9个都被服务器拒绝连接;

[root@backup01 ~]#netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ESTABLISHED 2    #成功连接1个;
SYN_SENT 1       #有一个在发送状态;
TIME_WAIT 11     #服务器拒绝了所有TCP连接;

压力测试1(关闭nodelay)

配置:
[root@backup01 ~]#vim  /etc/nginx/conf.d/p6.com.conf 

        limit_conn_zone $remote_addr zone=old:10m;
        limit_req_zone $remote_addr zone=xu:10m rate=15r/m;
server {
        listen 80;
        server_name oldxu6.com;
        root /html;
        location /{
                autoindex on;
                autoindex_exact_size off;
                charset utf-8;
                autoindex_localtime on;
                #allow 10.0.0.1;
                allow   all;
                #auth_basic           "closed site";
                #auth_basic_user_file  /htpasswd;
                #limit_conn old 1;
                limit_req zone=xu burst=2;   # nodelay;
        }



测试:
[root@backup01 ~]#ab -n 10 -c10 10.0.0.8/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.0.0.8 (be patient).....done


Server Software:        nginx/1.18.0
Server Hostname:        10.0.0.8
Server Port:            80

Document Path:          /
Document Length:        1063 bytes

Concurrency Level:      10
Time taken for tests:   8.007 seconds
##总共执行8秒,4秒执行1个,burst=2,所以8s;
Complete requests:      10
Failed requests:        7
   (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
Write errors:           0
Non-2xx responses:      7
Total transferred:      6288 bytes
HTML transferred:       4568 bytes
Requests per second:    1.25 [#/sec] (mean)
Time per request:       8006.974 [ms] (mean)
Time per request:       800.697 [ms] (mean, across all concurrent requests)
Transfer rate:          0.77 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      1       1
Processing:     1 1201 2700.7      1    8004
Waiting:        1 1201 2700.8      1    8004
Total:          1 1202 2700.9      2    8005
ERROR: The median and mean for the initial connection time are more than twice the standard
       deviation apart. These results are NOT reliable.

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%   4002
  90%   8005
  95%   8005
  98%   8005
  99%   8005
 100%   8005 (longest request)

日志检查:
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 200 1063 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:21 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:25 +0800] "GET / HTTP/1.0" 200 1063 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:16:54:29 +0800] "GET / HTTP/1.0" 200 1063 "-" "ApacheBench/2.3" "-"
*以上看出有3个通过连接,其他被服务器拒绝;
*这是因为设置了burst=2,在服务器接收到10个并发请求后,先处理1个请求,同时将2个请求放入burst缓冲队列中,等待处理。而超过(burst+1)数量的请求就被直接抛弃了,即直接抛弃了7个请求。
*1 + burst + [delaying request + limiting requests] =1+2----->+2*n----->+剩下 

测试3:全部打开

配置:
[root@backup01 ~]#vim  /etc/nginx/conf.d/p6.com.conf 
        listen 80;
        server_name oldxu6.com;
        root /html;
        location /{
                autoindex on;
                autoindex_exact_size off;
                charset utf-8;
                autoindex_localtime on;
                #allow 10.0.0.1;
                allow   all;
                #auth_basic           "closed site";
                #auth_basic_user_file  /htpasswd;
                #limit_conn old 1;
                limit_req zone=xu burst=2 nodelay;
        }

压力测试:
[root@backup01 ~]#ab -n 10 -c 10 10.0.0.8/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 10.0.0.8 (be patient).....done


Server Software:        nginx/1.18.0
Server Hostname:        10.0.0.8
Server Port:            80

Document Path:          /
Document Length:        1063 bytes

Concurrency Level:      10
Time taken for tests:   0.005 seconds
Complete requests:      10
Failed requests:        7
   (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
Write errors:           0
Non-2xx responses:      7
Total transferred:      6288 bytes
HTML transferred:       4568 bytes
Requests per second:    1854.94 [#/sec] (mean)
Time per request:       5.391 [ms] (mean)
Time per request:       0.539 [ms] (mean, across all concurrent requests)
Transfer rate:          1139.05 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.2      1       1
Processing:     2    2   0.2      2       3
Waiting:        2    2   0.0      2       2
Total:          3    3   0.1      3       3

Percentage of the requests served within a certain time (ms)
  50%      3
  66%      3
  75%      3
  80%      3
  90%      3
  95%      3
  98%      3
  99%      3
 100%      3 (longest request)

*以上看出执行时间为:Time per request:0.539s ;
*立马返回不需要等待burst执行时间(15r/1m);
*每个请求时间为4s ;


日志检查:
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 200 1063 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 200 1063 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 200 1063 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"
10.0.0.8 - - [10/Sep/2020:17:13:24 +0800] "GET / HTTP/1.0" 503 197 "-" "ApacheBench/2.3" "-"

*从日志看出立马执行3个请求,其他多出请求抛弃;
*可以发现在1s内,服务器端处理了3个请求(峰值速度:burst+原来的处理速度)。
*对于剩下的7个请求,直接返回503*
*在下一秒如果继续向服务端发送10个请求,服务端会直接拒绝这10个请求并返回503。
*因为设定了每4s处理1个请求,所以直到4 s 之后,才可以再处理一个请求,即如果此时向服务端发送10个请求,会返回9个503,一个200;

•查看/var/log/nginx/error.log日志,发现有4个请求被直接拒绝了,没有延时请求。

  • limit_req_zone 总结:
•limit_req_zone=req_zone:
•严格依照在limti_req_zone中配置的rate来处理请求
•超过rate处理能力范围的,直接drop
•表现为对收到的请求无延时

•limit_req zone=req_zone burst=5: 
•依照在limti_req_zone中配置的rate来处理请求
•同时设置了一个大小为5的缓冲队列,在缓冲队列中的请求会等待慢慢处理
•超过了burst缓冲队列长度和rate处理能力的请求被直接丢弃
•表现为对收到的请求有延时

•limit_req zone=req_zone burst=5 nodelay: 
•依照在limti_req_zone中配置的rate来处理请求
•同时设置了一个大小为5的缓冲队列,当请求到来时,会爆发出一个峰值处理能力,对于峰值处理数量之外的请求,直接丢弃
•在完成峰值请求之后,缓冲队列不能再放入请求。如果rate=10r/m,且这段时间内没有请求再到来,则每6 s 缓冲队列就能回复一个缓冲请求的能力,直到回复到能缓冲5个请求位置。

nginx location

当location冲突如何优先那个location
cat testserver.conf
server {
		listen	80;
		server_name module.oldboy.com;
		location / {  					根是第7优先级。通用匹配
		default_type text/hetml;
		return 200 “location =/”;
}
		location =/ {  					等于号的优先级是最高的。因为是完整的匹配
		default_type text/html;
		return 200 “location =/”;
}
		location ~ / {  				波浪号第二优先级。因为是模糊匹配
		default_type text/html;
		return 200 “location ~ /”
}
}

location字符优先级
1.	=		精确匹配,请求的资源必须是这个资源。没有这个资源直接转入通用匹配。例如 =/w 但是要请求/index.html
2.	^~		以某个字符串开头
3.	~		区分大小写的正则匹配
4.	~*		不区分大小写的正则匹配
5.	/		通用匹配,任何请求都会匹配到。如果以上所有都不匹配,那么会从通用匹配来搜寻。例如:/index.html

 	~ \.php$ 匹配以.php为结尾的的location。无论URL写成什么,都会匹配.php结尾的资源。
 	~ .*\.(jpg|gif|png|js|css)$	匹配所有以.(jpg|gif|png|js|css)为结尾的
 	=/error_html 精确匹配error_html文件./code/error_html
	root /code/
	
5.2 location优先级
5.3 location @   内部重定向

 error_page 404 403 401 @err;
 location @err {
          default_type text/html;
          return 200 '你可能是不小心走丢了。';
 }

LNMP

安装lnmp软件

linux
nginx
mysql或mariadb
php或python
selinx和firewalld一定要关闭
nginx结合PHP FastCGI运行原理
fastCGI是nginx和PHP服务器通信的一个协议。
1.用户通过HTTP协议发送请求,请求会先抵达LNMP架构中的nginx。
2.nginx会根据用户的请求进行location规则匹配。
3.location如果匹配到请求是静态,则由nginx读取本地直接返回。
4.location如果匹配到请求是动态,则由nginx将请求转发给fastCGI协议。
5.fastGI收到后会将请求交给PHP-fpm管理进程,php-fpm管理进程接收到后会调用具体的工作进程warrap。
6.warrap进程会调用php.ini程序进行解析,如果只是解析代码,php直接返回。
7.如果有查询数据库操作,则由php连接数据库(用户	密码	IP)发起查询的操作。
8.最终数据由MySQL—>php—>php-fpm—>fastcgi协议—>nginx—>http协议—>user。

Php-fpm.conf负责管理进程  php.ini负责解析代码

使用官方仓库安装nginx
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

安装nginx
yum	install	nginx -y
# 配置nginx和php进程运行用户
groupadd -g666 www &\
useradd -u666 -g666 www

移除 yum remove php-mysql-5.4 php php-fpm php-common
cat >/etc/yum.repos.d/php.repo<<EOF
[php]
name = php Repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0
EOF
yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb

# MySQL源
[mysql57-community]
name=MySQL 5.7 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql-connectors-community]
name=MySQL Connectors Community
baseurl=http://repo.mysql.com/yum/mysql-connectors-community/el/7/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql-tools-community]
name=MySQL Tools Community
baseurl=http://repo.mysql.com/yum/mysql-tools-community/el/7/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql-tools-preview]
name=MySQL Tools Preview
baseurl=http://repo.mysql.com/yum/mysql-tools-preview/el/7/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

#.配置PHP-FPM用户与nginx的运行用户保持一致
将nginx与PHP集成过程中,需要先了解fastcgi代理配置语法
#.设置fastcgi服务器的地址,该地址可以指定为域名或IP地址以及端口。
Syntax: fastcgi_pass address;
Default: -
Context: location, if in location
语法示例:
fastcgi_pass location:9000;
fastcgi_pass unix:/tmp/fastcgi.socket;

#.设置fastcgi默认的首页文件,需要结合fastcgi_param一起设置
Syntax: fastcgi_index name;
default: -
Context: http,server,location

#.通过fastcgi_param设置变量,并将设置的变量传递到后端的fastcgi服务器
Syntax: fastcgi_param parameter value [if_not_empty];
Default: -
Context: http, server, location
语法示例:
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /code$fastcgi_script_name;

#.通过图形方式展示fastcgi_index与fastcgi_param作用
root /code;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;	# 必须要写。
$document_root        				# 取决于root /code是什么。如果是/code那就是code。
$fastcgi_script_name  				# 如果请求的文件名称,index.php那就是index.php
SCRIPT_FILENAME= /code/index.php 	# php解析的真实路径


# 检查selinux和firewalld
# 检查服务是否启动nginx,mysql,php-fpm
# 检查网站配置文件以及对应的路径是否错误,书写名称是否正确
# 检查网站配置文件内容是否正确,是否有中文格式符号以及字母 nginx -t
# 修改配置文件,要重启服务。

nginx与php集成

vim /etc/php-fpm.d/www.conf	# 修改PHP进程用户

vim /etc/nginx/nginx.conf	# 修改nginx进程用户

systemctl restart/enable nginx
systemctl restart/enable php-fpm
# 源码目录必须授权。
[root@web01 conf.d]# vim php.conf 

server {
        listen 80;
        server_name php.caoxueming.com;
        location / {
        root /code;
        index index.php index.html;
}
        location ~ \.php$ {
        root /code;
        fastcgi_pass 127.0.0.1:9000;	# .php结尾的文件交给本地9000端口的进程执行。也就是PHP。
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;			# 传递的变量,一定要添加
}
}

vim /code/page.php
<?php

phpinfo();


# 浏览器输入 php.caoxueming.com/page.php

LNMP实现集成


# 查看yum安装的数据库临时密码
# 找不到密码的尝试123456
[root@web01 ~]# grep "temporary password" /var/log/mysqld.log

# yum安装数据库后,登入不进去。跳过检测表进去。
[root@web01 ~]# vim /etc/my.cnf
加入行
skip-grant-tables

# 重启数据库
systemctl restart mysqld

# 进入数据库后:
[root@web01 ~]# mysql
mysql> flush privileges;
mysql> set password for root@localhost = password('123456');

# php与mysql集成
启动数据库:
修改密码:
mysqladmin password '123456'
测试是否可连接状态:
如果无法读取文件,看下面是否有相同结尾的文件
vim /code/m.php
<?php
        $servername = "locahost";
        $username = "root";
        $password = "123456";


        $conn = mysqli_connect($servername,$username,$password);


        if (!$conn) {
        die("Connection failed: " . mysqli_connect_error());
        }

        echo "php连接MySQL数据库成功";

        ?>



# 博客网站配置文件
[root@localhost conf.d]# vim lnmp.caoxueming.conf
server {
        listen 80;								# 监听的端口
        server_name blog.caoxueming.com;		  
        root /code/wordpress;
        client_max_body_size 100m;				# 指定客户端上传大小
        location / {
        index index.php;						# .php结尾的nginx无法解析
        }
        location ~ \.php$ {						# 会被这个页面先捕捉文件
        fastcgi_pass 127.0.0.1:9000;			# 调用9000端口的服务解析
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        }
}

# 将wordpress解压到定义好的code下。
进入数据库创建库:
3306 [(none)]>create database wordpress charset utf8;
3306 [(none)]>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| school             |
| sys                |
| wordpress          |
| world              |
+--------------------+
3306 [(none)]>use wordpress;

# 设置wordpress页面
数据库名称  	  wordpress 
用户     	    root
密码			数据库密码
本地			127.0.0.1

# 如果无法浏览,注意文件权限是否正确。目录权限是否正确。

拆分数据库

由于单台服务器运行LNMP架构,会导致访问非常的缓慢。内存很容易吃满,容易出现oom。从而kill掉相关进程。导致架构无法正常运行。
1.web01服务端操作
# 备份数据库,一定要查看内容是否正确
[root@web01 yum.repos.d]# mysqldump -uroot -p123456 -A > test.sql

# 拷贝到要迁移的服务器
[root@web01 yum.repos.d]# scp test.sql root@172.16.1.51:~

# 关闭数据库
[root@web01 yum.repos.d]# systemctl stop mysqld

2.mysql服务端操作
安装数据库:
# 一定要选择和web相同的数据库版本,否则可能报错。
[root@mysql yum.repos.d]# yum install mariadb-server

# 查看yum安装的数据库零时密码
[root@mysql yum.repos.d]# grep "temporary password" /var/log/mysqld.log

# yum安装数据库后,登入不进去。跳过检测表进去。
[root@mysql yum.repos.d]# vim /etc/my.cnf
加入行
skip-grant-tables

# 重启数据库
systemctl restart mysqld

# 进入数据库后修改密码,修改后将配文件注释。
[root@web01 ~]# mysql
mysql> flush privileges;
mysql> set password for root@localhost = password('123456');

# 数据导入
[root@mysql yum.repos.d]# mysql -uroot -p123456 < /root/test.sql

# 进入数据库和表查看是否存在。
mysql> show databases;
mysql> use wordpress;
mysql> show tables;

3.修改程序连接远程数据库
# mysql服务区端,数据库添加用户,注意是mysql的用户
mysql>grant all privileges on *.* to lnmp@'10.0.0.%' identified by '123456';

# 查看权限
mysql> show grants for lnmp@'10.0.0.%';

# web01服务端操作
# 测试远程连接数据库服务器
[root@web01 yum.repos.d]# mysql -h10.0.0.51 -ulnmp -p

# 如果刚到公司不知道业务配置连接数据库的文件,可以查找出相关文件。
[root@web01 ~]# find /data/wordpress/ -type f|grep -R "123456" 

# 修改配置文件
[root@web01 ~]# vim /data/wordpress/wp-config.php 
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress');

/** MySQL数据库用户名 */
define('DB_USER', 'lnmp');		    # 修改成和创建的远程数据库用户。

/** MySQL数据库密码 */
define('DB_PASSWORD', '123456');	# 设置的密码

/** MySQL主机 */
define('DB_HOST', '10.0.0.51');		# 主机IP修改成设置的远程数据库服务器的IP,。

/** 创建数据表时默认的文字编码 */
define('DB_CHARSET', 'utf8mb4');

# 如果网站显示白页面,找到相关缓存目录cache清空缓存即可。
[root@web01 ~]# rm -rf /data/wordpress/cache/*


# 单个库导入
find /data/zhihu  -type f|xargs grep -R "123456"

1.web服务端操作
[root@web01 config]# mysqldump -uroot -p123456 zh > zhihu.sql
2.msyql服务端操作
[root@mysql ~]# mysql -uroot -p123456 
mysql> create database zh;
[root@mysql ~]# mysql -uroot -p123456 zh < zhihu.sql


http://wp.caoxueming.com/wp-content/uploads/2020/05/TIM图片20200413123443-1024x515.jpg
http://zh.caoxueming.com/uploads/article/20200501/57f9b80303055ce3ffbd81fdb005b0ff.jpg?838

扩展多台web服务


# 将web01的仓库拷贝到web02
# 扩展多台web应用服务
两台一样:
1.环境是不是应该一致
[root@web02 ~]# scp root@172.16.1.7:/etc/yum.repos.d/* /etc/yum.repos.d/
[root@web02 ~]# yum install nginx -y
[root@web02 ~]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb

2.nginx和php的配置文件一致
[root@web02 ~]# groupadd -g666 www
[root@web02 ~]# useradd -u666 -g666 www
[root@web02 ~]# scp -rp root@172.16.1.7:/etc/php-fpm.d/www.conf /etc/php-fpm.d/
[root@web02 ~]# scp -rp root@172.16.1.7:/etc/nginx/* /etc/nginx/
 
3.代码一致
# 先在web01上进行打包
[root@web01 ~]# tar czf data.tar.gz /code
# 推送给web02  tar czf data.tar.gz /code 
[root@web01 ~]# scp data.tar.gz root@172.16.1.8:~
# web02解压即可
[root@web02 ~]# tar xf data.tar.gz -C /
 
4.启动服务,并加入开机自启动
[root@web02 ~]# systemctl start nginx php-fpm
[root@web02 ~]# systemctl enable nginx php-fpm

5.解决不同节点数据对接问题

负载均衡

代理概述

用户请求 --> 代理服务器处理用户请求下发 --> web服务器 --> 找出资源返回给代理 --> 用户
客户无法直接访问服务端,因为服务器端是内网。
代理服务器有两个IP,一个是内网IP 一个是公网IP。当用户用公网IP访问时,代理服务器处理完毕后,会用内网IP发送给web服务器。

常见模式

正向代理:代理客户端访问网络资源。例如科学上网。
反向代理:客户发送请求,代理根据用户请求发送给web,web返回数据给代理,代理返回给用户。

区别:
正向代理对象是客户端。
反向代理对象是服务端。

nginx代理的协议

HTTP 		----->	代理超文本传输协议
HTTPS 		----->	代理http/https协议
TCP			----->	代理tcp/dup协议
websocket	----->	代理http1.1长连接通讯协议  http2.0支持并发;
GRPC		----->	代理go语言远程过程调用
POP/IMAP	----->	代理邮件收发协议
RTMP		----->	代理流媒体,直播,点播。

- 常用的协议:
HTTP 		----->	代理超文本传输协议
HTTPS 		----->	代理http/https协议
TCP			----->	代理tcp/dup协议
websocket	----->	代理http1.1长连接通讯协议
GRPC		----->	代理go语言远程过程调用

协议对应的模块

http/https   		ngx_http_proxy_module   	 --http 	server
http/https			ngx_http_fastcgi_module  	 --php 		server
http/https			ngx_http_uwcgi_module	 	 --python 	server	
websocket			ngx_http_proxy_module	 	 --socket
grpc	    		ngx_http_v2_module		 	 --grpc 	server

- 常用的模块:
http websocket https   nginx_http_proxy_module 
fastcgi				   ngx_http_fastcgi_module
uwcgi				   ngx_http_uwcgi_module
grpc				   ngx_http_v2_module

反向代理语法

# 确认selinux关闭
# 确认firewalld关闭
语法:
只能用在location层

操作:将8080端口代理成80端口
web服务端
[root@web01 conf.d]# vim web.caoxueming.com.conf
server {
        listen 8080;
        server_name web.caoxueming.com;
        location / {
        root /web;
        index index.html;
        }
}

proxy代理端,代理监听的端口永远在80.
[root@proxy conf.d]# vim  proxy.web.caoxueming.com.conf
server {
        listen 80;
        server_name web.caoxueming.com;
        location / {
        proxy_pass http://10.0.0.7:8080;
        }	
}

浏览器输入:web.caoxueming.com不用添加8080端口就可以访问了。

# 随机端口的占用
代理服务器的端口一般最多使用50000个左右
web服务器的端口一般最多使用2-30000个左右

# 当代理监听的端口和web端的网站配置文件监听的端口冲突时,web就会发送一个错误的页面返回给代理。
# 解决返回错误页面的问题。
proxy代理端
[root@proxy conf.d]# vim  proxy.web.caoxueming.com.conf
server {
        listen 80;
        server_name web.caoxueming.com;
        location / {
        proxy_pass http://10.0.0.7:80;			
        proxy_set_header Host $http_host;	添加头部信息变量,必须要访问这个页面。
	    }
}

# 让web服务端,显示真实的请求客户端地址。
[root@proxy conf.d]# vim  proxy.web.caoxueming.com.conf
server {
        listen 80;
        server_name web.caoxueming.com;
        location / {
        proxy_pass http://10.0.0.7:80;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 添加源IP透传变量。
	    }
}

# 将默认连接http1.0改成http1.1
[root@proxy conf.d]# vim  proxy.web.caoxueming.com.conf
server {
        listen 80;
        server_name web.caoxueming.com;
        location / {
        proxy_pass http://10.0.0.7:80;
        proxy_http_version 1.1;				添加http协议模块。
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

# 将web01公网IP停用。代理用172段内网IP访问web01,抓包数据无法抓到10.0.0.7的包。也不会显示代理服务器代理的谁。
[root@proxy conf.d]# vim  proxy.web.caoxueming.com.conf
server {
        listen 80;
        server_name web.caoxueming.com;
        location / {
        proxy_pass http://172.16.1.7:80;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

# 代理服务器与web服务器的连接时间。
proxy_connect_timeout 30;	连接后端的超时时间。
porxy_send_timeout 60;		后端把数据传送给代理的超时时间。
proxy_read_timeout 60;		代理等待后端服务器的响应时间。

proxy_buffering on;			缓冲区,一边收一边传。
proxy_buffer_size 32k;		保存用户的头信息大小32k。
proxy_buffers 4 128k;		缓冲区大小。

# 将以上的模块写成一个params文件。
vim /etc/nginx/proxy_params
写入完成后直接引用这个params
include proxy_params 

[root@proxy conf.d]# vim  proxy.web.caoxueming.com.conf
server {
        listen 80;
        server_name web.caoxueming.com;
        location / {
        proxy_pass http://172.16.1.7:80;
	    include proxy_params;
}
}

proxy_params

[root@WEB ~]# vim /etc/nginx/proxy_params
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

负载均衡

load balance
调度系统
海量用户的访问,调度节点将用户的请求转发给应用节点。
调度节点和应用节点,往往放在一个IDC机房里。加强调度节点和应用节点的通信实时性。

# 四层负载均衡
四层负载均衡指的是ISO七层模型中的传输层,nginx已经支持TCP/IP的控制。所以只需要对客户端的请求进行TCP/IP协议包进行转发,就实现了负载均衡。处理性能非常快,只需要底层进行应用处理。而不需要一些复杂的逻辑。四层协议只支持IP+端口。

# 七层负载均衡
七层负载均衡是在应用层,可以完成很多应用方面的协议请求。比如HTTP的信息改写,头信息改写,安全应用规则控制等等。NGINX就是一个典型的七层负载均衡SLB。

# 七层和四层的区别
四层负载均衡在底层进行分发。
七层负载均衡在最顶层进行分发。
由此可以看出七层的效率没有四层高。
但七层负载均衡更贴近于服务。比如上述七层对HTTP的各种改写。
#二者结合
可以将四层和七层结合使用。四层没有对端口数量的限制,它在内核就完成了工作。用户请求数据,四层解开头部信息,抛给七层,七层再解析四层没有解析完的数据包。这种一般大型互联网公司会用到。


# 负载均衡硬件(选择较少,一台往往几十万)
F5
radware

# 负载均衡软件
七层:nginx   HAProxy
四层:nginx   HAProxy	lvs(最厉害的四层负载,国人开发。)

# 云产品:
SLB lvs做四层  tengine七层
ULB haproxy做四层	haproxy nginx做七层

实现负载均衡

需要用到nginx的proxy_pass代理模块。
nginx代理仅代理一台服务器,而nginx负载均衡则是将客户端请求代理转发至一组upstream虚拟服务集群。

配置
只能用在http层
定义资源池,当访问location的时候,会跳转到定义的资源池,进行分别不同的处理。资源池的名称不可和以前的有重复。
upstream  backend {
}
server {
		location / {
		proxy_pass http://backend;
		}
}

实现
代理端操作
[root@proxy conf.d]# vim proxy.web.caoxueming.com.conf 
upstream web { 
        server 172.16.1.7:80;
        server 172.16.1.8:80;
}
server {
        listen 80;
        server_name web.caoxueming.com;
        location / {
        proxy_pass http://web;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

服务端
添加两个web页面配置即可。

作业
内容
知乎和博客实现负载均衡
1台负载均衡服务器  2台web服务端。
代理端
[root@proxy conf.d]# vim proxy.web.caoxueming.com.conf 
upstream web {
        server 10.0.0.7:80;
        server 10.0.0.8:80;
}
server {
        listen 80;
        server_name bolg.caoxueming.com;
        location / {
        proxy_pass http://web;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}
server {
        listen 80;
        server_name zhihu.caoxueming.com;
        location / {
        proxy_pass http://web;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

负载均衡调度算法

轮询 按照顺序逐一分配到不同的后端服务器
weight		加权轮询,weight值越大,分配到的访问几率越高。
ip_hash		每个请求按访问IP的hash结果分配,这样来自同一个IP的固定访问一个后端服务器。
url_hash	按照访问URL的hash结果来分配请求,是每个url定向到一个后端服务器。
least_conn	最少连接数,哪个机器链接数少就分发。

轮询

按照顺序逐一分配到不同的后端服务器
    upstream web {
        server 10.0.0.7:80;
        server 10.0.0.8:80;
    }

加权轮询

可在配置的server后面加个weight=number,number值越高,分配的概率越大。
upstream web {
        server 10.0.0.7:80 weight=10;
        server 10.0.0.8:80 weight=20;
    }

ip_hash

每个请求按访问IP的hash分配,这样来自同一IP固定访问一个后台服务器。
upstream lb_demo {
        ip_hash;
        server 10.0.0.7:80;
        server 10.0.0.8:80;
    }

least_hash

最少链接数,哪个机器连接数少就发分发给哪个机器。
upstream lb_demo {
        least_conn;
        server 10.0.0.7:80;
        server 10.0.0.8:80;
    }

url_hash

按访问的url的hash结果分配请求,是每个url定向到同一后端服务器上。
upstream web {
        web;
        server 10.0.0.7:80;
        server 10.0.0.8:80;
    }

后端信息

1.down		       当前的server暂时不参与负载均衡  相当于注释
2.backup		   预留的备份服务器
4.max_fails	   	   允许请求失败的次数
5.fail_timeout     经过max_fails失败后, 服务暂停时间
6.max_conns	       限制最大的接收连接数

down

down	当前的server暂时不参与负载均衡  相当于注释

upstream web {
         web;
         server 10.0.0.7:80 down; 无法轮询到这个IP。
         server 10.0.0.8:80;
    	}

backup

backup	 预留的备份服务器
upstream web {
         web;
         server 10.0.0.7:80 backup;  当10.0.0.8出现故障无法访问,会跳转到这个IP。
         server 10.0.0.8:80;
    	}

max_fails

max_fails	允许请求失败的次数
upstream web {
         web;
         server 10.0.0.7:80 max_fail=3 fail_timeout=10s;  如果十秒内请求失败三次那么踢出轮询。并10s内探测此IP是否可用。
         server 10.0.0.8:80;
    	}

fail_timeout

fail_timeout     经过max_fails失败后, 服务暂停时间
upstream web {
         web;
         server 10.0.0.7:80 max_fail=3 fail_timeout=10s;  如果十秒内请求失败三次那么踢出轮询。并10s内探测此IP是否可用。
         server 10.0.0.8:80;
    	}

max_conns

max_conns	限制最大的接收连接数
upstream web {
         web;
         server 10.0.0.7:80  max_conns=2000; 最多接受2000个请求。多余的全部连接失败。
         server 10.0.0.8:80  max_conns=2000;
    	}

后端长链接

upstream web {
         web;
         server 10.0.0.7:80  max_conns=2000; 最多接受2000个请求。多余的全部连接失败。
         server 10.0.0.8:80  max_conns=2000;
         keepalive	16;	最大的空闲连接数,如果超过一定的连接数,那么自动释放掉,保留16个空闲连接。好处就是:可以直接处理用户请求,就不用建立三次握手了。
         keepalive_timeout 100s;  空闲连接的超时时间。
    	}
    	
    	server {
		listen 80;
		server_name ip.caoxueming.com;
		location / {
		proxy_pass http://web;
		proxy_http_version 1.1;
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		}
}

生产环境中使用最多

	server 10.4.7.21:6443	max_fails=3 fail_timeout=30s;
	server 10.4.7.22:6443	max_fails=3 fail_timeout=30s;

企业案例

企业案例:使用nginx负载均衡时,如何将后端请求超时的服务器流量平滑的切换到另一台上。如果后台服务连接超时,Nginx是本身是有机制的,如果出现一个节点down掉的时候,Nginx会更据你具体负载均衡的设置,将请求转移到其他的节点上,但是,如果后台服务连接没有down掉,但是返回错误异常码了如:504、502、500,应该如何处理。
可以在负载均衡添加如下配置proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404;意思是,当其中一台返回错误码404,500...等错误时,可以分配到下一台服务器程序继续处理,提高平台访问成功率。

[root@proxy ~]# cat /etc/nginx/conf.d/proxy_blog.oldxu.com.conf
upstream blog {
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}
server {
	listen 80;
	server_name blog.oldxu.com;
	location / {
	proxy_pass http://blog;
	include proxy_params;
	proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
	}
}

七层负载均衡

基于代理透传

环境:
	10.0.0.5	proxy_node1
	10.0.0.6	proxy_node2
	10.0.0.7	proxy_node3
	10.0.0.8	webserver
	
域名:
	ip.caoxueming.com	解析	--> 10.0.0.5

proxy_node1

proxy_node1 Nginx配置如下:
[root@lb01 conf.d]# vim proxy_ip.caoxueming.com.conf 
server {
 listen 80;
 server_name ip.caoxueming.com;
 location / {
 proxy_pass http://10.0.0.6;
 proxy_http_version 1.1;
 proxy_set_header Host $http_host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }
}

proxy_node2

proxy_node2 Nginx配置如下:
[root@lb01 conf.d]# vim proxy_ip.caoxueming.com.conf 
server {
	listen 80;
	server_name ip.caoxueming.com;
	location / {
	proxy_pass http://10.0.0.7;
	proxy_http_version 1.1;
	proxy_set_header Host $http_host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

proxy_node3

proxy_node3 Nginx配置如下:
[root@lb01 conf.d]# cat proxy_ip.oldboy.com.conf 
server {
 listen 80;
 server_name ip.caoxueming.com;
 location / {
 proxy_pass http://10.0.0.8;
 proxy_http_version 1.1;
 proxy_set_header Host $http_host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }
}

  1. webserver

WebServer Nginx配置如下:
[root@web02 conf.d]# vim ip.caoxueming.com.conf 
server {
	listen 80;
	server_name ip.caoxueming.com;
	root /code;
	location / {
	index index.php index.html;
	}
	location ~ \.php$ {
	fastcgi_pass 127.0.0.1:9000;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	include fastcgi_params;
	}
}

test

测试方式一
	[root@web02 conf.d]# vim /code/index.php 
	<?php
		phpinfo();
	?>
	
	[root@web02 conf.d]# vim /code/index.php 
	<?php
		$ip = getenv("HTTP_X_FORWARDED_FOR");
		echo "这个是X_FORWARDED_FOR: $ip";    
	?>
	通过浏览器访问,搜索$_SERVER['HTTP_X_FORWARDED_FOR']

测试方式二
	1.proxy_node1代理的日志 10.0.0.5
	10.0.0.1 - - "GET /index.php HTTP/1.1" 200

	2.proxy_node2代理的日志 10.0.0.6
	10.0.0.5 - -  "GET /index.php HTTP/1.1" 200 "10.0.0.1"

	3.proxy_node3代理的日志 10.0.0.7
	10.0.0.6 - - "GET /index.php HTTP/1.1" 200 "10.0.0.1,10.0.0.5" 

	4.真实web的日志 10.0.0.8
	10.0.0.7 - - "GET /index.php HTTP/1.1" 200 "10.0.0.1,10.0.0.5,10.0.0.6"
	
# web服务端操作
# http,server,location层都可以添加。
使用nginx Realip_module获取多级代理下的客户端真实IP地址,需要在Web上配置(每个代理点都要配置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for)
server {
	listen 80;
	server_name ip.caoxueming.com;
	set_real_ip_from  10.0.0.5;
	set_real_ip_from  10.0.0.6;
	set_real_ip_from  10.0.0.7;
	real_ip_header    X-Forwarded-For;
	real_ip_recursive on;
	root /code;
	}

set_real_ip_from:真实服务器上一级代理的IP地址或者IP段,可以写多行(每个代理服务器的ip都要添加)

real_ip_header  X-Forwarded-For :从哪个header头检索出需要的IP地址(获取X-Forwarded-For地址信息)

real_ip_recursive on:(X-Forwarded-For - set_real_ip_from)递归排除set_real_ip_from里面出现的IP,其余没有出现的认为是用户真实IP
例如:  "10.0.0.1, 10.0.0.5, 10.0.0.6"

10.0.0.5,10.0.0.6都出现在set_real_ip_from中,仅仅10.0.0.1没出现,那么他就被认为是用户的ip地址,并且赋值到$remote_addr变量

负载均衡会话保持

概述

1.session由服务端程序生成,session_ID的编号。存储在服务端(没登录状态)。
2.应用程序Nginx通过的Header方式,会将程序生成的Session_ID 回传给浏览器。set-cookies
3.浏览器收到服务端的Session_ID,会将该Session_ID存储至Cookies中。
4.当我尝试登陆网站时,输入用户名称 + 用户密码 + Session_ID。
5.登陆成功,我们的服务端会存储该Session至本地,并将该sessionID与对应登陆的用户名称捆绑,标记已登陆。
6.当浏览器再起发送请求,还会携带cookies中的Session_ID,服务端校验Session_ID, 比对成功,则会话保持。

安装phpmyadmin

# nginx ip_hash(如果是NAT网络,会造成巨大负载)
# 基于浏览器的cookie(不安全)
# 基于服务端的session共享。将用户的session存储到redis缓存服务器。
1.下载phpmyadmin
wget https://files.phpmyadmin.net/phpMyAdmin/4.8.5/phpMyAdmin-4.8.5-all-languages.zip
unzip phpMyAdmin-4.8.5-all-languages.zip	
[root@web01 code]# vim /etc/nginx/conf.d/php.conf
server {
	listen 80;
	server_name php.caoxueming.com;
	root /data/phpmyadmin;
	location / {
	index index.php index.html;
	}
	location ~ \.php$ {
	fastcgi_pass 127.0.0.1:9000;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	include fastcgi_params;
	}
}

[root@web01 phpmyadmin]# cp config.sample.inc.php  config.inc.php
[root@web01 phpmyadmin]# vim config.inc.php 
/* Server parameters */
$cfg['Servers'][$i]['host'] = '172.16.1.51';

session目录授权
[root@web01 conf.d]# chown -R www.www /var/lib/php/

网站代码目录授权
[root@web01 conf.d]# chown -R www.www /data/

ip_hash

代理配置如下
用ip_hash实现了保持会话连接,无法共享session。会一直用访问同一个IP服务器,导致该web服务器负载高。无法实现负载均衡的特性。
[root@proxy conf.d]# vim proxy_php.oldboy.com.conf 
upstream php_pools {
	ip_hash
	server 10.0.0.7:80;
	server 10.0.0.8:80;
}
server {
	listen 80;
	server_name php.caoxueming.com;
	location / {
	proxy_pass http://php_pools;
	proxy_http_version 1.1;
	proxy_set_header Host $http_host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}
[root@proxy conf.d]# systemctl restart nginx

redis实现会话保持

# 解决session共享问题
# 使用Redis
proxy 10.0.0.5
web01 10.0.0.7
web02 10.0.0.8
redis 10.0.0.51
mysql 10.0.0.51

1.redis缓存服务器操作:
安装redis
[root@mysql ~]# yum install redis -y
[root@mysql ~]# sed -i 's#^bind.*#bind 10.0.0.51 127.0.0.1#g' /etc/redis.conf
[root@mysql ~]# systemctl restart  redis
[root@mysql ~]# systemctl enable   redis

2.配置应用服务器,连接redis,将session的信息存储至redis数据库中(7 8)  php->redis
[root@web01 ~]# vim /etc/php.ini 
session.save_handler = redis
;session.save_path = "/tmp" 下面添加
session.save_path = "tcp://172.16.1.51:6379" 
;session.save_path = "tcp://172.16.1.51:6379?auth=123456&weight=1&timeout=2.5"

[root@web01 ~]# vim /etc/php-fpm.d/www.conf	注释sessionID路径。
;php_value[session.save_handler] = files
;php_value[session.save_path]    = /var/lib/php/session

[root@web01 phpmyadmin]# cp config.sample.inc.php  config.inc.php
[root@web01 phpmyadmin]# vim config.inc.php 
/* Server parameters */
$cfg['Servers'][$i]['host'] = '172.16.1.51';

基于负载均衡实现不同设备调度到不同的资源池中

# web服务器操作
[root@web01 conf.d]# cat web.caoxueming.com.conf
server {
	listen 8080;
	server_name web.caoxueming.com;
	location / {
	root /web/pc;
	index index.html;
	}
}

server {
	listen 8081;
	server_name web.caoxueming.com;
	location / {
	root /web/ios;
	index index.html;
	}
}
server {
	listen 8082;
	server_name web.caoxueming.com;
	location / {
	root /web/ad;
	index index.html;
	}
}

[root@web01 conf.d]# mkdir -p /web/{pc,ios,ad}
[root@web01 conf.d]# echo pc..... >/web/pc/index.html
[root@web01 conf.d]# echo ios..... >/web/ios/index.html
[root@web01 conf.d]# echo ad..... >/web/ad/index.html
[root@web01 conf.d]# 

# 负载均衡客户端操作
[root@proxy conf.d]# vim web.caoxueming.com.conf 
upstream pc_pools {
	server 172.16.1.7:8080;
}

upstream ios_pools {
	server 172.16.1.7:8081;
}

upstream ad_pools {
	server 172.16.1.7:8082;
}

server {
	listen 80;
	server_name web.caoxueming.com;
	location / {
	proxy_pass http://pc_pools;	 已经定义了PC反馈。
	include proxy_params;
	if ($http_user_agent ~* "Iphone") {
	proxy_pass http://ios_pools;
	}

	if ($http_user_agent ~* "Android") {
	proxy_pass http://ad_pools;
	}

	if ($http_user_agent ~* "msie") {
	return 200 "Biche";
	}

	if ($http_user_agent ~* "rv") {
	return 200 "Biche";
	}
	}
}

基于负载均衡实现不同的url调度到不同资源池

[root@web01 conf.d]# vim url.caoxueming.conf 
server {
        listen 8080;
        server_name url.caoxueming.com;
        location / {
        root /url/images;
        index index.html;
        }
}

server {
        listen 8081;
        server_name url.caoxueming.com;
        location / {
        root /url/download;
        index index.html;
        }
}
server {
        listen 8082;
        server_name url.caoxueming.com;
        location / {
        root /url/user;
        index index.html;
        }
}

[root@web]# mkdir /url/{images,download,user} -p
[root@web]# echo "url_images page" > /url/images/index.html
[root@web]# echo "url_down page" > /url/download/index.html
[root@web]# echo "url_user page" > /url/user/index.html



负载的配置
[root@lb01 conf.d]# cat proxy_uri.caoxueming.com.conf 
upstream images_pools {
	server 172.16.1.7:8080;
}

upstream download_pools {
	server 172.16.1.7:8081;
}

upstream user_pools {
	server 172.16.1.7:8082;
}

server {
	listen 80;
	server_name url.caoxueming.com;
	location /images {
	proxy_pass http://images_pools/;
	include proxy_params;
	}
	location /download {
	proxy_pass http://download_pools/;
	include proxy_params;
	}
	location /user {
	proxy_pass http://user_pools/;
	include proxy_params;
	}
}

四层负载均衡

* 针对server层的网站层面,与http层属于同级层,用于操作网站网址;

* 针对ip分流和端口映射;

概述

# 什么是四层负载均衡
1.基于传输层 协议包来封装的 ( TCP/IP ), 七层负载均衡是 应用层协议,他组装在四层 负载均衡基础之上,无论是四层负载均衡还是 七层负载均衡 都指的是 OSI 网络模型。
2.传输层:tcp/udp协议,端口(基于ip+port的负载均衡 )ssh(22)mysql(3306) redis(6379)
3.应用层:请求的uri、Header修改、权限控制、访问规则等等

# 四层负载均衡的应用场景
1.实现端口转发
2.ssh、mysql等都是TCP协议请求,只能使用tcp方式 连接的服务,我们就可以使用四层负载均衡来调度。

# 四层结合七层实现大规模集群架构。
1.七层负载均衡能够接收连接数有限,需要配置多台七层负载均衡。
问题: 多台七层如何实现轮询?
解决: 在多台七层负载均衡前面接入四层负载均衡
2.四层可以保证七层负载均衡的高可用性。
注意:四层负载均衡 不识别域名,他仅识别端口,所以在四层结合七层的情况下,四层做端口转发,七层来实现域名的匹配,然后代理到后端web节点。

# 总结四层负载均衡:
1.四层负载均衡仅能转发TCP/IP协议、UDP协议,通常用来转发端口:如 tcp/80 tcp/443  tcp/3306 tcp/22 udp/53
2.四层负载均衡可以解决七层负载均衡高可用性的问题。( 多个七层负载均衡同时提供服务 )
3.四层负载均衡可以解决七层负载均衡端口数限制问题。(七层负载均衡最多能使用的端口是5w)
4.四层转发效率远比七层代理的效率高的多,但是他只能支持tcp/ip协议,所以他的功能较弱,虽然七层效率不高,但他持http/https这样的应用层协议。
5.四层是在传输层就对请求流量进行端口的转发。

stream

  • stream模块不能出现在http层;
  • 在配置层面与http层属于同一层;
  • /etc/nginx/conf.d/default必须 gzip 不然会影响stream层配置;
# 语法
stream {
    upstream backend {
    hash $remote_addr consistent;
    server backend1.example.com:12345 weight=5;    #权重为5;
    server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;    #请求3次不成功就暂停服务30秒再访问;
    server unix:/tmp/backend3;
    }
 server {
    listen 12345;
    proxy_connect_timeout 1s;   #连接超时时间;
    proxy_timeout 3s; #代理超时时间;
    proxy_pass backend;
    }
}
# 访问出现问题: tcpdump -i eth0 抓包;
# 开发要求连接mysql数据库, 但数据库在内网环境?	tcp  ip:port 	3306
# 开发要求连接redis数据库, 但数据库在内网环境?	tcp  ip:port 	6379
[root@lb01 ~]# vim /etc/nginx/nginx.conf
stream {
        upstream ssh_7 {
        server 172.16.1.7:22;
        }

        upstream mysql_51 {
        server 10.0.0.51:3306;
        }

        server {
                listen 6666;
        	    proxy_pass ssh_7;
        }

        server {
                listen 5555;
                proxy_pass mysql_51;
        }
	   }
	    
# 自定义配置
[root@proxy conf.d]# vim /etc/nginx/nginx.conf 
不能在http层添加
include /etc/nginx/conf.c/*.conf;
[root@proxy conf.d]# mkdir /etc/nginx/conf.c
[root@proxy conf.d]# vim /etc/nginx/conf.c/stream_mysql.conf
stream  {
        upstream ssh_7 {
        server 172.16.1.7:22;
        }

        upstream mysql_51 {
        server 10.0.0.51:3306;
        }

        server {
                listen 6666;
        	    proxy_pass ssh_7;
        }

        server {
                listen 5555;
                proxy_pass mysql_51;
        }
	    }

4+7跳转web

# 4+7跳转web
stream {
	upstream lb {
	server 10.0.0.5:80;
	#server 172.16.1.6:80 weight=3 max_fails=2 fail_timeout=10s;
	}
	server {
	listen 80;
	proxy_pass lb;
	proxy_connect_timeout 100s;
	proxy_timeout 100s;
	}

日志配置

# 日志配置
[root@lb01 ~]# vim /etc/nginx/conf.c/stream_mysql.conf 
stream  {
        log_format  proxy '$remote_addr - [$time_local]  $status $protocol'
                  		  '"$upstream_addr" "$upstream_bytes_sent" "$upstream_connect_time"' ;      #定义日志的格式
       		  
        access_log /var/log/nginx/tcp.log   proxy;       #调用日志   
        upstream ssh_7 {
        server 172.16.1.7:22;
        }

        upstream mysql_51 {
        server 10.0.0.51:3306;
        }

        server {
                listen 6666;
                proxy_pass ssh_7;
        }

        server {
                listen 5555;
                proxy_pass mysql_51;
        }
        }

4+7透传IP

  • 模块
Module ngx_stream_core_module

1.四层+7层+七层+web透传真实IP:

1.四层添加proxy_protocol协议[传递信息携带一个新的tcp头部(包含源IP、源端口、等等信息)]
2.七层需要支持proxy_protocol,在listen80添加proy_protocl协议。七层已经获取到了客户端的IP和四层负载均衡的IP
3.排除七层前面代理的IP地址set_real_ip_from 
4.同时将proxy_protocol协议提取真实IP地址复制给 $remote_addr变量通过x-forwarded-for携带到后端
5.第二七层负载均衡什么都不用 配置,只需要开启x-forwarded-for即可
6.web配置realip字段

2.四层配置:

[root@lb-4 conf]# vim nginx.conf
stream {
    upstream web {
    server 10.0.0.5:80;
    }
    server {
    listen 80;
    proxy_pass web;
    proxy_protocol on;  	#开启proxy_protocol协议
    }
}

3.七层 (如果有多个配置第一个七层即可):

[root@lb conf.d]# cat proxy_ip_oldxu.com.conf
upstream ip {
	server 10.0.0.7:80;
}
server {
    server_name ip.oldxu.com;
    listen 80 proxy_protocol;        #添加proxy_protocol头部信息(解度四层ip、端口头部信息)
    set_real_ip_from 10.0.0.0/24;  	 #添加七层负载前经过的代理IP地址(记录前面经过的代理ip)
    real_ip_header proxy_protocol;   #将proxy_protocol获取的IP赋值给$remote_addr(获取四层负载均衡服务器ip地址)
    location / {
    proxy_pass http://ip;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;	#将proxy_protocol真实客户端的IP地址赋值给X-Forwarded-For变量携带至后端(获取四层上级的web服务器真实ip地址)
    }
}

4.web

[root@web02 ~]# cat /etc/nginx/conf.d/ip.oldxu.com.conf
server {
	listen 80;
	server_name ip.oldxu.com;
	root  /php;
	#web前端所有的代理服务器地址,一个都不能少
	set_real_ip_from 10.0.0.5;
	set_real_ip_from 10.0.0.7;
	set_real_ip_from 10.0.0.4;
	real_ip_header X-Forwarded-For;	#从哪个herder检索出需要的IP地址。
	real_ip_recursive on;		    #递归排除上述的IP地址。获得真实访问IP。
	location /  {
	index index.php;
	}
	location ~ \.php$ {
	fastcgi_pass 127.0.0.1:9000;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	include  fastcgi_params;
	}
}

结果(第一个字段出现了真实的IP地址):
10.0.0.1 - - [29/Apr/2020:12:21:39 +0800] "GET / HTTP/1.0" 200 61 

综合实战

环境

环境:
10.0.0.31	NFS
10.0.0.41	RYSNC
10.0.0.51	数据库
10.0.0.4	L4
10.0.0.5	L7
10.0.0.7	WEB
10.0.0.8	WEB
10.0.0.9	L7

NFS

1.安装nfs 10.0.0.31
[root@nfs ~]# yum install nfs-utils -y

2.配置nfs
[root@nfs ~]# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)

3.创建目录
[root@nfs ~]# mkdir -p /data
	
4.创建用户
[root@nfs ~]# groupadd -g 666 www
[root@nfs ~]# useradd -u666 -g666 -M -s /sbin/nologin www
	
5.授权
[root@nfs ~]# chown -R www.www /data

6.重启nfs(restart)    下次开机自启 (enable)
[root@nfs ~]# systemctl restart nfs
[root@nfs ~]# systemctl enable nfs

7.检查是否真的启动了NFS服务,共享的目录是否正常
[root@nfs ~]# cat /var/lib/nfs/etab 

RSYNC

1.安装rsync 10.0.0.41
[root@backup ~]# yum install rsync -y

2.配置rsync
[root@backup ~]# vim /etc/rsyncd.conf
uid = www
gid = www
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[backup]
path = /backup

[data]
path = /data

创建虚拟用户以及虚拟用户的密码
[root@backup ~]# echo "rsync_backup:123456" > /etc/rsync.passwd
[root@backup ~]# chmod 600 /etc/rsync.passwd

创建用户
[root@backup ~]# groupadd -g 666 www
[root@backup ~]# useradd -u666 -g666 www

创建目录
[root@backup ~]# mkdir -p /data /backup
	
进行授权
[root@backup ~]# chown -R www.www /data/ /backup/
[root@backup ~]# ll -d /data/ /backup/
drwxr-xr-x. 7 www www 234 5月  23 10:47 /backup/
drwxr-xr-x. 2 www www   6 5月  23 10:47 /data/

3.重启rsync
[root@backup ~]# systemctl restart rsyncd

数据库安装

# MySQL源 10.0.0.51
[mysql57-community]
[mysql-connectors-community]
name=MySQL Connectors Community
baseurl=http://repo.mysql.com/yum/mysql-connectors-community/el/7/$basearch/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql-tools-community]
name=MySQL Tools Community
baseurl=http://repo.mysql.com/yum/mysql-tools-community/el/7/$basearch/
enabled=1
gpgcheck=0

[root@mysql yum.repos.d]# yum install mariadb-server
[root@mysql yum.repos.d]# msyqladmin password '123456'
3306 [(none)]>create database wordpress charset utf8;
3306 [(none)]>show databases;
mysql> grant all on *.* to lnmp@'10.0.0.%' identified by '123456';
mysql> show grants for lnmp@'10.0.0.%'
[root@web01 yum.repos.d]# mysql -h10.0.0.51 -ulnmp -p

WEB

[nginx-stable] 10.0.0.7 10.0.0.8
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

安装nginx
yum	install	nginx -y
# 配置nginx和php进程运行用户
groupadd -g666 www &\
useradd -u666 -g666 www

# 移除 yum remove php-mysql-5.4 php php-fpm php-common
cat >/etc/yum.repos.d/php.repo<<EOF
[php]
name = php Repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0
EOF
yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongo


[root@WEB-07 ~]# vim /etc/nginx/conf.d/wp.caoxueming.com.conf 
server {
        listen 80;
        server_name wp.caoxueming.com;
        root /data/wordpress;
        set_real_ip_from 10.0.0.4;
        set_real_ip_from 10.0.0.5;
        set_real_ip_from 10.0.0.9;
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        location / {
        index  index.php;
}
        location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
}
}

[root@WEB-07 ~]# vim /etc/nginx/conf.d/zh.caoxueming.com.conf 
server {
        listen 80;
        server_name zh.caoxueming.com;
        root /data/wecenter;
        set_real_ip_from 10.0.0.4;
        set_real_ip_from 10.0.0.5;
        set_real_ip_from 10.0.0.9;
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        location / {
        index index.php;
}
        location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params; 
            
}           
}   

L7

[nginx-stable] 10.0.0.7 10.0.0.8
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

安装nginx
yum	install	nginx -y

[root@proxy-05 ~]# vim /etc/nginx/conf.d/proxy_web.conf 
upstream web {
        server 10.0.0.7:80;
        server 10.0.0.8:80;
}
        server {
        listen 80 proxy_protocol;
        server_name zh.caoxueming.com;
        set_real_ip_from 10.0.0.0/24;
        real_ip_header proxy_protocol;
        location / {
        proxy_pass http://web;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
} 
        server {
        listen 80 proxy_protocol;
        server_name wp.caoxueming.com;
        set_real_ip_from 10.0.0.0/24; 
        real_ip_header proxy_protocol;
        location / {
        proxy_pass http://web; 
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}   
}  

L4

[nginx-stable] 10.0.0.7 10.0.0.8
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

安装nginx
yum	install	nginx -y

[root@proxy-04 ~]# vim /etc/nginx/conf.c/stream_web.conf 
stream {
log_format  proxy '$remote_addr - [$time_local]  $status $protocol'
                  '"$upstream_addr" "$upstream_bytes_sent" "$upstream_connect_time"';
access_log /var/log/nginx/tcp.log proxy;
        upstream web {
        server 10.0.0.5:80;
        server 10.0.0.9:80;
    }
        server {
        listen 80;
        proxy_pass web;
        proxy_protocol on;
    }
}

动静分离

  • nginx: 消耗CPU;
  • Tomcat: 消耗内存;

部署tomcat

1.tomcat默认8080端口,请注意端口是否被使用。

2.安装java
[root@WEB ~]# yum install java -y

3.下载tomcat
[root@WEB ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.34/bin/apache-tomcat-9.0.34.tar.gz

4.安装tomcat
[root@WEB ~]# mkdir /soft
[root@WEB ~]# tar xf  apache-tomcat-9.0.34.tar.gz -C /soft/
[root@WEB ~]# ln -s /soft/apache-tomcat-9.0.34/ /soft/apache

5.启动Tomcat
[root@WEB ~]# /soft/apache/bin/startup.sh

6.接入Nginx,启动nginx。
[root@WEB-07 images]# vim /etc/nginx/conf.d/tomcat.oldcao.com.conf 

server {
        listen 80;
        server_name tomcat.oldcao.com;
        location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
        location ~*\.(png|gif|jpg)$ {
        root /code/images;
}
}
**用访问tomcat.oldcao.com 默认返回/code/images下面的\.(png|gif|jpg)$文件给客户端;
**动态资源由location / 交给127.0.0.1:8080的tomcat解析并返回nginx再客户端;
7.复制图片到/code/images
[root@WEB apache]# find ./ -name "*.png"|xargs -i cp {} /code/images/
[root@WEB apache]# find ./ -name "*.gif"|xargs -i cp {} /code/images/
[root@WEB-07 apache]# find ./  -name "*.png" -o -name "*.jpg" -o -name "*.gif"|xargs -i cp {} /code/images/

8.授权
[root@WEB code]# chown -R nginx.nginx /code/*

动静分离演示

[root@WEB code]# rm  -rf  /soft/apache/webapps/ROOT/*
[root@WEB code]# vim /soft/apache/webapps/ROOT/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
<head>
<title>Nginx+Tomcat动静分离</title>
</head>
<body>
<%
  Random rand = new Random();
  out.println("<h2>动态资源</h2>");
  out.println(rand.nextInt(99)+100);
 %>
  <h2>静态图片</h2>
  <img src="nginx.png" />
  </body>
  </html>
[root@WEB ~]# /soft/apache/bin/shutdown.sh		#停止tomcat
[root@WEB ~]# /soft/apache/bin/startup.sh		#启动tomcat
[root@WEB ~]# mv /code/images/tomcat.png /code/images/nginx.png

实例演示

环境:
lb 	   10.0.0.5
tomcat 10.0.0.7  动态资源处理程序
nginx  10.0.0.8  静态资源处理程序

1.静态资源10.0.0.8
[root@web02 ~]# vim /etc/nginx/conf.d/ds.oldxu.com.conf
server  {
	listen 80;
	server_name ds.oldxu.com;
	root /code/images;
	location / {
	index index.html;	
	}
}
[root@web02 ~]# mkdir /code/images
[root@web02 ~]# cd /code/images/
[root@web02 images]# wget http://nginx.org/nginx.png
[root@web02 ~]# systemctl restart nginx

2动态资源  10.0.0.7
[root@web01 ~]# cat /soft/tomcat/webapps/ROOT/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
<head>
<title>Nginx+Tomcat动静分离</title>
</head>
<body>
<%
  Random rand = new Random();
  out.println("<h2>动态资源</h2>");
  out.println(rand.nextInt(99)+100);
%>
  <h2>静态图片</h2>
  <img src="nginx.png" />
  </body>
  </html>
  
[root@lb01 ~]# cat  /etc/nginx/conf.d/proxy_ds.oldxu.com.conf
upstream java {
	server 172.16.1.7:8080;
}

upstream static {
	server 172.16.1.8:80;
}

server {
	listen 80;
	server_name ds.oldxu.com;

	location ~*\.(png|gif|jpg)$ {
	proxy_pass http://static;
	include proxy_params;
	}

	location / {
	proxy_pass http://java;
	include proxy_params;
	}
	}
[root@lb01 ~]# systemctl restart nginx

LNDP

步骤一、安装 python3 的环境
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel \
sqlite-devel gcc gcc-c++  openssl-devel zlib zlib-devel python3 python3-devel -y

步骤二、安装 Django 框架、uwsgi
[root@web01 ~]# pip3 install -i https://mirrors.aliyun.com/pypi/simple/ --upgrade pip   #升级
[root@web01 ~]# pip3 install -i https://mirrors.aliyun.com/pypi/simple/ django==2.1.8   #安装django
[root@web01 ~]# pip3 install -i https://mirrors.aliyun.com/pypi/simple/ uwsgi	#uwsgi

步骤三、配置Django工程
[root@web02 ~]# cd /opt
[root@web02 opt]# django-admin.py startproject demosite



[root@web02 ~]# vim /opt/demosite/demosite/settings.py
修改
ALLOWED_HOSTS = ['*']

[root@web02 ~]# python3 /opt/demosite/manage.py runserver 0.0.0.0:9999


步骤四、配置uWSGI、配置Nginx
[root@web02 ~]# cat /opt/demosite/uwsgi.ini
[uwsgi]
#uwsgi监听的端口
socket = 127.0.0.1:9999
#uwsgi启动进程数
workers = 2
#最大接收的请求数
max-requests = 1000
#buffer缓冲区大小
buffer-size = 30000
#进程pid存放路径
pidfile = /run/uwsgi.pid
#uwsgi日志存储路径
daemonize = /var/log/uwsgi.log

[root@web02 ~]# uwsgi --ini /opt/demosite/uwsgi.ini
[uWSGI] getting INI configuration from /opt/demosite/uwsgi.ini
[root@web02 ~]# netstat -lntp|grep 9999
tcp        0      0 127.0.0.1:9999          0.0.0.0:*               LISTEN      32894/uwsgi


[root@web02 ~]# vim /etc/nginx/conf.d/djang.oldxu.com.conf
server {
	listen 80;
	server_name django.oldxu.com;

	location / {
		index  index.html;
		uwsgi_pass 127.0.0.1:9999;
		uwsgi_param UWSGI_CHDIR /opt/demosite;  #工程 所在的目录
		uwsgi_param UWSGI_SCRIPT demosite.wsgi; #demosite/wsgi接口文件 /opt/demosite/demosite/wsgi.py
		include uwsgi_params;
	}
}

---------django开发的博客:差劲

gitee.com搜索较好的开源项目


1.下载Django开发的博客
	[root@web02 ~]# wget http://cdn.xuliangwei.com/BBS.zip
	[root@web02 ~]# unzip BBS.zip  -d /code/

2.安装博客所依赖的模块( 开发会在写一个re......文件 )

	[root@web02 BBS]# pip3 install -i https://pypi.doubanio.com/simple/ -r /code/BBS/re.txt


3.安装数据库、导入项目的数据库文件

登陆51数据库
[root@db01 ~]# mysql -uroot -poldxu.com
MariaDB [(none)]> create database bbs charset utf8;
MariaDB [(none)]> use bbs;					#进入bbs库
MariaDB [bbs]> source  /root/bbs.sql				#导入/root/bbs.sql
MariaDB [bbs]> grant all privileges on *.* to 'all'@'%' identified by 'oldxu.com';		#授权远程连接的用户和密码



配置应用程序连接数据库的地址

[root@web02 BBS]# vim /code/BBS/BBS/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bbs',
        'HOST': "172.16.1.51",
        'USER': 'all',
        'PASSWORD': 'oldxu.com',
        'PORT': 3306,
    }
}


4.配置Django项目已uwsgi方式启动
[root@web02 ~]# cat /code/BBS/uwsgi.ini
[root@web02 ~]# cat  /code/BBS/uwsgi.ini
[uwsgi]
#uwsgi监听的端口
socket = 127.0.0.1:8899
#uwsgi启动进程数
workers = 2
#最大接收的请求数
max-requests = 1000
#buffer缓冲区大小
buffer-size = 30000
#进程pid存放路径
pidfile = /run/uwsgi-bbs.pid
#uwsgi日志存储路径
daemonize = /var/log/uwsgi-bbs.log


[root@web02 ~]# uwsgi --ini /code/BBS/uwsgi.ini

5.配置Nginx代理至Uwsgi服务

[root@web02 ~]# cat /etc/nginx/conf.d/bbs.oldxu.com.conf
server {
    listen 80;
    server_name bbs.oldxu.com;
    client_max_body_size 100M;

    location  /static {
        alias /code/BBS/static/;
	expires 1d;
    }

    location /media {
        alias /code/BBS/media/;
    }

    location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8899;
        uwsgi_param UWSGI_SCRIPT BBS.wsgi;
        uwsgi_param UWSGI_CHDIR /code/BBS;
    }
}


Rewrite跳转

介绍

rewrite和location的功能有点相像,都能实现跳转,主要区别在于rewrite常用于同一域名内更改获取资源的路径,而location是对一类路径做控制访问和反向代理,可以proxy_pass到其他服务器。

Nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。
rewrite只能放在server{},location{},if{}中,
并且只能对域名后边的除去传递的参数外的字符串起作用。
Rewrite主要的功能就是实现URL的重写,Nginx的Rewrite规则采用Pcre,perl兼容正则表达式的语法规则匹配,如果需要Nginx的Rewrite功能,在编译Nginx之前,需要编译安装PCRE库。
通过Rewrite规则,可以实现规范的URL、根据变量来做URL转向及选择配置。

相关指令

指令默认值适用范围作用
breaknoneif,server,location完成当前的规则集,不再处理rewrite指令,需要和last加以区分
if ( condition ) { … }noneserver , location用于检测一个条件是否符合,符合则执行大括号内的语句。不支持嵌套,不支持多个条件&&或处理
returnnoneserver , location用于结束规则的执行和返回状态码给客户端,状态码的值可以是:200 400 402 406 408 410 411 413 416 500 504,另外非标准状态码444,表示以不发送任何Header头来结束链接。

rewrite常用环境变量

变量说明
$args变量中存放了请求URL中的请求指令。argl=value1&arg2=value2
$content_length变量中存放了请求头中的content-length字段
$document_uri变量中存放了请求中当前的URL,不包括请求指令。
$host变量中存放了请求URL中的主机部分字段。
$http_user_agent变量中存放客户端的代理信息
$http_accept-language变量中存放了客户的请求语言信息
$http_cookie变量中存放客户端的cookie信息
$limit_rate变量中存放NGINX服务器对网络连接速率的限制,也就是Nginx配置中limit_rate指令的配置值
$remote_addr变量中存放了客户端的地址
$remote_port变量中存放了客户端与服务端建立连接的端口号
$remote_user变量中粗放了客户端的用户名
$request_body_file变量中存放了发给后端服务器的本地文件资源的名称
$request_method变量中存放了客户端的请求方式,比如GET POST
$request_filename变量中存放了当前请求的资源文件的路径名
$request_uri变量中存放了当前请求的URL,并且带请求指令
$query_string与变量$args含义相同
$scheme变量中存放了客户端请求使用的协议,比如 http https
$server_protocol变量中存放了客户端请求协议的版本,比如“HTTP/1.0”
$server_addr变量中存放了服务器的地址
$server_name变量中存放了客户端请求到达的服务器的名称
$server_port变量中存放了客户端请求到达的服务器的端口号
$uri与变量$document含义相同
$content_type变量中存放了针对当前请求的根路径
$document_uri变量中存放了针对当前请求额根路径
# 概述
rewrite主要实现URL地址重写,以及url地址跳转。
# 场景
用户访问www.caoxueming.com/class跳转class.caoxueming.com

# rewrite标记flag
last		本条规则匹配完成后,继续向下匹配新的location URI规则。
break		本条规则匹配完成后,停止匹配,不再匹配后面的规则。
redirect	返回302临时重定向,地址栏会显示跳转后的地址。
permanent	返回301永久重定向,地址栏会显示跳转后的地址。

last和break区别

break	匹配到规则,则会去本地路径中目录中寻找对应请求的文件。
last	匹配到规则,会对其所在的server{...}标签重新发起请求。

所以,在访问/break和/last请求时,虽然对应的请求目录/test都是不存在了,理论上都应该返回404,但是实际请求/last的时候,是会有后面localtion所匹配到的结果返回的,如果last匹配不到location的结果则在返回错误。


break:
1.如果规则被匹配到了,会先去查找本地是否存在该文件,不存在,则直接返回错误,404 403。存在, 存在则直接返回该页面的内容

last:
1.如果规则被匹配到了,会对当前的server{}重新发起请求,/last。rewrite.caoxueming.com/test/  --->  先进行location的匹配,如果匹配则走location。如果没有匹配,则查找本地目录下是否存在该文件,如果存在则返回,不存在则报错。

[root@testproxy conf.d]# vim rewrite.conf
server {
        listen 80;
        server_name rewrite.caoxueming.com;
        root /code;
        location ~ ^/break {			break 直接报错	真实路径 /code/test/
        rewrite ^/break /test/ break;
}
        location ~ ^/last {				last返回return 200 'ok';/code/test/
        rewrite ^/last /test/ last;
}
        location /test/ {
        default_type text/html;
        return 200 'ok';
}
}

redirect和permanent区别

redirect	临时跳转,每次请求时,都会询问服务器
	 
permanent	永久跳转,第一次请求时会循环,跳转后会记录跳转的状态在浏览器,当下次在请求时候,会通过浏览器的缓存直接跳转.

企业大多数使用的临时跳转
[root@testproxy conf.d]# vim rp.conf 
server {
        listen 80;
        server_name rp.caoxueming.com;
        root /code;
        location ~ ^/test/ {
        rewrite ^(.*)$ https://www.dinghuachong.com redirect;
        rewrite ^(.*)$ https://www.dinghuachong.com permanent;
}
}

1.当用户访问/code/test/index.html文件时,跳转/code/down/test/$1.html。
[root@testproxy conf.d]# vim break.conf 
server {
        listen 80;
        server_name break.caoxueming.com;
        root /code/;
        index index.html;
        location ~ ^/test {
        rewrite ^/test/(.*)\.html /down/test/$1.html break;
        }
}

2.用户访问course-11-22-33.html实际上真实访问是/course/11/22/33/course_33.html
3.用户访问course-44-55-66.html实际上真实访问是/course/44/55/66/course_66.html
[root@web01 conf.d]# mkdir /code/course/11/22/33/ -p
[root@web01 conf.d]# echo "course_11_22_33" > /code/course/11/22/33/course_33.html
[root@web01 conf.d]# mkdir /code/course/44/55/66/ -p
[root@web01 conf.d]# echo "course_44_55_66" > /code/course/44/55/66/course_66.html

location ~ ^/course {
	rewrite (.*)-(.*)-(.*)-(.*)\.html $1/$2/$3/$4/$1_$4.html break;
}

4.用户访问/test目录下任何内容, 实际上真实访问是http://www.xuliangwei.com
location /test {
        #rewrite ^(.*)$ https://www.xuliangwei.com redirect;
        return 302 https://www.dinghuachong.com;
}

5.将http请求,跳转至https
server {
        listen 80;
        server_name bgx.com;
        return 302 https://$server_name$request_uri;  http输入跟上什么后缀,跳转https就会跟上什么后缀
        }

rewrite优先级

1.Rewrite匹配优先级
1.先执行server块的rewrite指令
2.其次执行location匹配规则
3.最后执行location中的rewrite

server {
	listen 80;
	server_name test.oldboy.com;
	root /code;
	rewrite ^(.*)$ https://$server_name$1;
	
	location / {
		rewrite ^.*$ https://www.xuliangwei.com;
	}
	location /test {
		rewrite .* https://www.xuliangwei.com$1;
	}
}
test.oldboy.com/		-->  server 中的rewrite
test.oldboy.com/		--> location 匹配	location /  	在执行location中的rewrirte
test.oldboy.com/test	-->	location 匹配	location /test	在执行location中的rewrirte

2.Rewrite在匹配过程中会用到的一些Nginx全局变量
$server_name 当前用户请求的域名 test.oldboy.com --->$server_name = test.oldboy.com
test.oldboy.com/images/test.jpg	-->/code/images/test.jpg

$request_filename 	  判断文件是否存在  $request_filename request_filename 
$request_filename  	  当前请求的文件路径名(带网站的主目录/code/images/test.jpg)   
	
test.oldboy.com/images/test.jpg -->/images/test.jpg	  http ---跳转-->  https
$request_uri 当前请求的文件路径名(不带网站的主目录/images/test.jpg)

$scheme	用的协议,比如http或者https

rewrite 案例

需求1: 将用户请求url.oldxu.com.zh跳转至url.oldxu.com/zh
需求2: 将用户请求url.oldxu.com.jp跳转至url.oldxu.com/jp

[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
	listen 80;
	server_name url.oldxu.com.zh url.oldxu.com.jp;
	location / {
	#判断用户请求的域名是zh还是jp
	if ( $http_host ~* "zh" ) {
		set $language zh;
	}
	if ( $http_host ~* "jp" ) {
		set $language jp;
	}
	rewrite ^/$ http://url.oldxu.com/$language/ permanent;
	}
    }
server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;
	location / {
	index index.html;
	}
	}
	
[root@web01 ~]# mkdir /opt/zh -p
[root@web01 ~]# mkdir /opt/jp -p
[root@web01 ~]# echo "zh.." > /opt/zh/index.html
[root@web01 ~]# echo "jp.." > /opt/jp/index.html
[root@web01 ~]# nginx -t
[root@web01 ~]# systemctl reload nginx

需求3: 过滤 Nginx 请求中包含 a1=3526 的http请求到 10.16.3.5 的 8080 端口处理。
server {
     listen 80;
     server_name url.oldxu.com;
     root /opt;
     location / {
     index index.html;
     #如果用户请求的uri中a1=3256,我们通过反向代理代理到10.16.3.5:8080端口
     if ( $request_uri ~* 'a1=3256' ) {
     #proxy_pass http://10.16.3.5:8080;		#这个地址是不存在的
     return 200 'ok....!';				   #所以使用return来替代模拟 
     }
     }
     }

测试curl命令

测试的curl命令: curl -L -HHost:url.oldxu.com http://10.0.0.7?a1=3256
-L 跟随跳转
-H 指定Host头,具体要请求的域名是

return 案例

return:主要用来返回数据|返回字符串|返回url地址。

1.如果用户使用 IE 访问url.oldxu.com 则返回字符串(请更换您的浏览器)。chrome[返回数据]
server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;
	charset gbk,utf-8;
	location / {
	index index.html;
	default_type text/html;
	#判断用户使用的是否是 chrome浏览器,如果是则 返回一段话,如果不是则正常访问。
	if ( $http_user_agent ~* "chrome|MSIE" ) {
	return 200 'Please change Browser!!!';
	}
	}
	}

2.如果使用IE访问,直接报错 500.									[返回状态码]
server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;
	charset gbk,utf-8;
	location / {
	index index.html;
	default_type text/html;
	#判断用户使用的是否是 chrome浏览器,如果是则 返回一段话,如果不是则正常访问。
	if ( $http_user_agent ~* "chrome|MSIE|Gecko" ) {
	return 500;
	}
	}
	}

3.如果使用IE访问,直接跳转至浏览器下载页面。http://www.firefox.com.cn/[返回一个url地址]
server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;
	charset gbk,utf-8;
	location / {
	index index.html;
	default_type text/html;
	#判断用户使用的是否是 chrome浏览器,如果是则 返回一段话,如果不是则正常访问。
	if ( $http_user_agent ~* "chrome|MSIE" ) {
	return 302 http://www.firefox.com.cn;
	}
	}
	}

Rewrite Flag标记

rewrite主要是用来重写URL、或者说是用来做URL地址跳转的。
last:匹配成功,表示要停止继续匹配。
	请求的是1.HTML,最终的访问结果是a.html
	因为:在location{}内部,遇到last,本location{}内后续指令不在执行。
	匹配成功后,会重新像Server{}标签发起请求,从头到尾再匹配一遍规则,哪个匹配则执行哪个。

break:匹配成功,表示要停止继续匹配。
	请求的是1.HTML,最终的访问结果是2.html
	因为:在location {} 内部遇到了break,本location内以及后面的所有的location{}内的指令都不在执行。

break与last区别说明?
	当rewrite规则遇到break后,本location{}与其他location{}的所有rewrite/return规则都不再执行。
	当rewrite规则遇到last后,本location{}里后续rewrite/return规则不执行,但重写后的url再次从头开始执行所有规则,哪个匹配执行哪个。

[root@web01 ~]# cat   /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /code;
    location / {
    rewrite /1.html /2.html;
    rewrite /2.html /3.html last;
    }
    location /2.html {
    rewrite /2.html /a.html;
    }
    location /3.html {
    rewrite /3.html /b.html;
    }
    }
	
http--https场景下:
permanent:状态码301,永久跳转。新跳转的网站有排名,旧网站排名会被清空。1.html(排名会被清空)  2.html(有排名)
redirect: 状态码302,临时跳转。旧网站排名无影响,新网站没有排名。1.html(不影响)	2.html(没有排名)

[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /code;
    location / {
    rewrite /1.html /2.html permanent;
    }
    }

rewrite企业案例

需求1: 根据用户浏览器请求头中携带的语言调度到不同的页面。
中国人: zh
日本:   jp
[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	#判断浏览器语言
	if ($http_accept_language ~* "zh|zh-cn" ) {
	set $language /zh;
	}
	if ($http_accept_language ~* "jp|ja" ) {
	set $language /jp;
	}
	#rewrite跳转
	rewrite  ^/$ $language;
	location / {
	index index.html;
	}
	}

需求2: 用户通过手机设备访问 url.oldxu.com,跳转至url.oldxu.com/m
https://www.xhqb.com
https://www.xhqb.com/m/
[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	#判断是否是手机
	if ($http_user_agent ~* 'android|iphone|ipad') {
	rewrite ^/$ /m last;
	}
	location / {
	index  index.html;
	}
	}

需求3: 用户通过手机设备访问 url.oldxu.com 跳转至 m.oldxu.com
[root@web01 ~]# cat  /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	#判断是否是手机
	if ($http_user_agent ~* 'android|iphone|ipad') {
	rewrite ^/$ http://m.oldxu.com redirect;
	}
	location / {
	index  index.html;
	}
	}
server {
	listen 80;
	server_name m.oldxu.com;
	root  /opt/m;
	location / {
	index index.html;
	}
	}

需求4: 用户通过http协议请求,能自动跳转至https协议。
[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	#书写的方式很多
	#rewrite ^(.*)$ https://$server_name$1;
	return 302 https://$server_name$request_uri;
	}

需求5: 网站在维护过程中,希望用户访问所有网站重定向至一个维护页面。(在不变动nginx配置的情况下,进入维护页面。)
[root@web01 ~]# cat  /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	#维护状态
	rewrite ^(.*)$ /wh.html break;
	location / {
	index index.html;
	}
	}
	
需求6: 当服务器遇到 403 404 502 等错误时,自动转到临时维护的静态页。( 搜搜一些不存在的页面时,服务器会返回  孩子丢失的信息。 )
[root@web01 ~]# cat  /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	location / {
		index index.html;
	}
	error_page 403 404 502 = @tempdown;
	location @tempdown {
		rewrite ^(.*)$ /wh.html break;
	}
	}
[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	location / {
	index index.html;
	}
	#碰到403 404 502 -->tempdown,tempdown内部重定向
	error_page 403 404 502 = @tempdown;
	location @tempdown {
	root /opt/error_page;
	rewrite ^(.*)$ /index.html break;
	}
	}

需求7: 公司网站在停机维护时,指定的IP能够正常访问,其他的IP跳转到维护页。(学生)10.0.0.1 可以访问,除此以外所有人都不能访问。
[root@web01 error_page]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	#初始一个变量为0
	set $ip 0;
	#判断来源IP是自己公司的服务器地址,则将ip变量设定为1
	if ($remote_addr ~ "10.0.0.1|10.0.0.2") {
	set $ip 1;
	}
	#判断如果ip变量判断是0,我们直接进入维护页面。
	if ($ip = 0) {
	rewrite ^(.*)$ /wh.html  break;
	}
	location / {
	index index.html;
	}
	}

方式二
[root@web01 error_page]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	location / {
	index index.html;
	allow 10.0.0.7/32;
	deny all;
	}
	location /error_page {
	root /opt;
	}
	error_page 403 = @temp;
	location @temp {
	return 302 'http://url.oldxu.com/error_page/index.html';
	}
	}

需求8: 公司网站后台/admin,只允许公司的出口公网IP可以访问(10.0.0.1),其他的IP访问全部返回500,或直接跳转至首页。
[root@web01 error_page]# cat   /etc/nginx/conf.d/url.oldxu.com.conf
server {
  	listen 80;
    server_name url.oldxu.com;
    root /opt;
	location / {
	index index.html;
	}
	location /admin {
	index index.html;
	#设定一个初始变量,变量名为ip,变量的值为0
	set $ip 0;
	#判断来源的用户IP是多少,如果是10.0.0.7,则将变量名ip的值重置为1
	if ($remote_addr ~ "10.0.0.7") {
	set $ip 1;
	}
	#判断ip变量为0的,直接500拒绝。
	if ($ip = 0) {
	#return 500;
	return 302 'https://www.xuliangwei.com';
	}
	}
	}

https

如果不使用https协议,DNS可能会被劫持篡改。

HTTPS注意事项
Https	不支持续费,证书到期需重新申请新并进行替换。
Https	不支持三级域名解析,如 test.m.oldboy.com。
Https	显示绿色,说明整个网站的url都是https的,并且都是安全的。
Https	显示黄色,说明网站代码中有部分URL地址是http不安全协议的。
Https	显示红色,要么证书是假的,要么证书已经过期。

HTTPS加密模型

默认监听端口  443
对称加密:    相同的秘钥。
非对称加密:  一对秘钥,公钥加密,私钥解密。

SSL/TLS

ssl/TLS安全传输层协议,用于两个通信应用程序之间提供保密性和数据完整性。

我们首先需要申请证书,需要进行登记,登记我是谁,我是什么组织,我想做什么,到了登记机构在通过CSR发给CA,CA中心通过后,CA中心会生成一对公钥和私钥,那么公钥会在CA证书链中保存,公钥和私钥证书订阅人拿到后,会将其部署在WEB服务器上
1.当浏览器访问我们的https站点时,它会去请求我们的证书。
2.Nginx这样的web服务器会将我们的公钥证书发给浏览器。
3.浏览器会去验证我们的证书是否是合法和有效的。
4.CA机构会将过期的证书放置在CRL服务器,那么CRL服务的验证效率是非常差的,所以CA又推出了OCSP响应程序,OCSP响应程序。可以查询指定的一个证书是否过期,所以浏览器可以直接查询OCSP响应程序,但OCSP响应程序性能还不是很高。
5.Nginx会有一个OCSP的开关,当我们开启后,Nginx会主动上OCSP上查询,这样大量的客户端直接从Nginx获取,证书是否有效。

配置HTTPS证书

假的,真的要域名
[root@web01 ~]# mkdir /etc/nginx/ssl_key
[root@web01 ~]# cd /etc/nginx/ssl_key
[root@web01 ssl_key]# openssl genrsa -idea -out server.key 2048
[root@web01 ssl_key]# openssl req -days 36500 -x509 \
-sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt

配置Nginx

[root@web01 ssl_key]# cat  /etc/nginx/conf.d/s.oldxu.com.conf
server {
	listen 443 ssl;
	server_name s.oldxu.com;
	root  /code;
	ssl_certificate  ssl_key/server.crt;
	ssl_certificate_key ssl_key/server.key;
	ssl_protocols TLSv1.2;
	location / {
	index index.html;
	}
	}

# 访问时带上HTTPS,谷歌浏览器不支持。用IE或者火狐。

综合案例

当有用户请求http://s.oldxu.com 则强制跳转为https协议。
server {
	listen 80;
	server_name s.oldxu.com;
	return 302 https://$server_name$request_uri;
}
server {
	listen 443 ssl;
	server_name s.oldxu.com;
	root  /code;
	ssl_certificate  ssl_key/server.crt;
	ssl_certificate_key ssl_key/server.key;
	ssl_protocols TLSv1.2;
	location / {
	index index.html;
	}
	}

集群HTTPS

# 集群环境下发https证书。多台WEB或对配置文件都要配置fastcgi_param HTTPS on;模块。
[root@WEB-08 conf.d]# vim wp.caoxueming.com.conf 
server {
    listen 80;
    server_name wp.caoxueming.com;
    root /data/wordpress;
    location / {
    index index.php;
	}
    location ~\.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTPS on;	# HTTP永久跳转HTTPS必加参数。不然网站出现乱码,业务不显示等报错。
    include fastcgi_params;
	}
	}
	
[root@WEB-07 conf.d]# vim zh.caoxueming.com.conf 
server {
    listen 80;
    server_name zh.caoxueming.com;
    root /data/wecenter;
    location / {
    index index.php;
	}
    location ~\.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTPS on;	# HTTP永久跳转HTTPS必加参数。不然网站出现乱码,业务不显示等报错。
    include fastcgi_params;
	}
	}
	
# 负载均衡配置
[root@proxy-5 conf.d]# vim proxy_wp.conf 
upstream web {
    server 10.0.0.7:80;
    server 10.0.0.8:80;
}
    server {
    listen 443 ssl;
    server_name wp.caoxueming.com;
    ssl_certificate ssl_key/ca.pem;
    ssl_certificate_key ssl_key/ca-key.pem;
    location / {
    proxy_pass http://web;
    include proxy_params;
}
}
    server {
    listen 443 ssl;
    server_name wp.caoxueming.com;
    return 302 https://wp.caoxueming.com$request_uri;
}

[root@proxy-5 conf.d]# vim proxy_zh.conf 
    server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/ssl_key/ca.pem;
    ssl_certificate_key /etc/nginx/ssl_key/ca-key.pem;
    server_name zh.caoxueming.com;
    location / {
    proxy_pass http://web;
    include proxy_params;
}
}
	server {
	listen 80;
	server_name zh.caoxueming.com;
	return 302 https://$server_name$request_uri;
}

模拟场景

模拟银行场景:
1.主页http协议	http://yh.oldxu.com				(提供网页浏览)
2.模拟登陆		http://yh.oldxu.com/login		(相当于点击了登陆按钮)
3.新域名下,使用的是https协议。	https://star.oldxu.com  		(提供安全登陆)

配置

1.配置  https://star.oldxu.com
[root@web01 ~]# cat /etc/nginx/conf.d/star.oldxu.com.conf
server {
	listen 443 ssl;
	server_name start.oldxu.com;
	ssl_certificate ssl_key/server.crt;
	ssl_certificate_key ssl_key/server.key;
	root  /code/login;
	location / {
	index index.html;
	}
}
[root@web01 ~]# mkdir /code/login -p
[root@web01 ~]# echo "login...https" > /code/login/index.html

2.配置 http://yh.oldxu.com
[root@web01 ~]# cat  /etc/nginx/conf.d/yh.oldxu.com.conf
server {
	listen 80;
	server_name yh.oldxu.com;
	root /code;
	location / {
	index index.html;
	}
	location /login {
	return 302 https://start.oldxu.com;
	}
}

https优化:

减少CPU运算量
SSL的运行计算需要消耗额外的 CPU 资源,SSL通讯过程中『握手』阶段的运算最占用 CPU 资源,有两个方法可以减少每台客户端的运算量:
1.设置worker进程数设置为等于CPU处理器的核心数。 worker_processes auto;
2.启用 keepalive 长连接,一个连接发送更多个请求。
3.启用 SSL 会话缓存参数,避免进行多次 SSL『握手』。
server {
     listen  443 ssl;
     server_name    www.example.com;
	 keepalive_timeout   70;				#设置长连接
     ssl_certificate     www.example.com.crt;
     ssl_certificate_key www.example.com.key;
     ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
#在建立完ssl握手后如果断开连接,在session_timeout时间内再次连接,是不需要在次建立握手,可以复用之前的连接。
	 ssl_session_cache   shared:SSL:10m;		 # 1M缓存空间能存储 4000 个会话数量
	 ssl_session_timeout 1024m;			         # 配置会话超时时间 ( 默认5分钟 )
    }

优化实例

[root@proxy-5 conf.d]# vim proxy_zh.conf 
    server {
    listen 443 ssl;
    ssl_protocols	TLSv1.2;
    keepalive_timeout	70;
    ssl_certificate /etc/nginx/ssl_key/ca.pem;
    ssl_certificate_key /etc/nginx/ssl_key/ca-key.pem;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout	10m;
    server_name zh.caoxueming.com;
    location / {
    proxy_pass http://web;
    include proxy_params;
}
}
	server {
	listen 80;
	server_name zh.caoxueming.com;
	return 302 https://$server_name$request_uri;
}

真实域名下发证书

server {
        listen 80;
        server_name www.dinghuachong.com;
        return 302 https://$server_name$request_uri;
}
server {
        listen      443;
        server_name  www.dinghuachong.com;
        client_max_body_size 100m;
        ssl on;
        ssl_certificate /etc/nginx/cert/2316440_www.dinghuachong.com.pem;
        ssl_certificate_key /etc/nginx/cert/2316440_www.dinghuachong.com.key;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols  TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_timeout  5m;
        ssl_session_cache    shared:SSL:1m;
        index index.php index.html;
        root /code/wordpress;
	   }

NGINX四层下发

stream {
        server {
        listen              443 ssl;
        ssl_protocols       TLSv1.2;
        ssl_ciphers         AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
        ssl_certificate     /usr/local/nginx/conf/cert.pem;
        ssl_certificate_key /usr/local/nginx/conf/cert.key;
        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 10m;
        }

注意

只有nginx四层负载均衡支持。
LVS加入监听端口443即可。

keepalived高可用

  • 虚拟路由器:有一个master和多个backup 路由器组成;
1.高可用介绍
	1.1)什么是高可用
		简单理解:出现故障,自动恢复,对于用户而言无感知。
		专业理解:减少系统不能对外提供服务的时间。4个9 5个9。

	1.2)为什么要设计高可用?
2.高可用实现手段? 
	2.1)硬件
	2.2)软件 keepalived     基于VRRP协议来实现。VRRP虚拟路由冗余协议,主要用来解决单点故障问题。
3.vrrp虚拟路由冗余协议
	3.1)vrrp诞生过程
	3.2)vrrp实现原理

5.keepalived高可用使用场景?
6.keepalived高可用核心概念总结?
	1.如何确认谁是主谁是备节点?   优先级。 谁的优先级高谁就是master。
	2.master故障,然后恢复?     抢占式、非抢占式。

	业务不重要,需不需要高可用keepalived?

参数详解:

state:state指定instance(Initial)的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定,里如果这里设置为master,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为master

interface:实例绑定的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的

dont track primary:忽略VRRP的interface错误

track interface:跟踪接口,设置额外的监控,里面任意一块网卡出现问题,都会进入故障(FAULT)状态,例如,用nginx做均衡器的时候,内网必须正常工作,如果内网出问题了,这个均衡器也就无法运作了,所以必须对内外网同时做健康检查

mcast src ip:发送多播数据包时的源IP地址,这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址

garp master delay:在切换到master状态后,延迟进行免费的ARP(gratuitous ARP)请求

virtual router id:这里设置VRID,这里非常重要,相同的VRID为一个组,他将决定多播的MAC地址

priority 100:设置本节点的优先级,优先级高的为master

advert int:检查间隔,默认为1秒

virtual ipaddress:这里设置的就是VIP,也就是虚拟IP地址,他随着state的变化而增加删除,当state为master的时候就添加,当state为backup的时候删除,这里主要是有优先级来决定的,和state设置的值没有多大关系,这里可以设置多个IP地址

virtual routes:原理和virtual ipaddress一样,只不过这里是增加和删除路由

lvs sync daemon interface:lvs syncd绑定的网卡

authentication:这里设置认证

auth type:认证方式,可以是PASS或AH两种认证方式

auth pass:认证密码

nopreempt:设置不抢占,这里只能设置在state为backup的节点上,而且这个节点的优先级必须别另外的高。当主mysql恢复后不抢占资源

preempt delay:抢占延迟

debug:debug级别

notify master:和sync group这里设置的含义一样,可以单独设置,例如不同的实例通知不同的管理人员,http实例发给网站管理员,mysql的就发邮件给DBA




下面以第一种比较常用的方式来配详细解说一下

virtual_server 192.168.1.2 80 {                     #设置一个virtual server: VIP:Vport
delay_loop 3                                                  # service polling的delay时间,即服务轮询的时间间隔

lb_algo rr|wrr|lc|wlc|lblc|sh|dh                        #LVS调度算法
lb_kind NAT|DR|TUN                                      #LVS集群模式                      
persistence_timeout 120                                #会话保持时间(秒为单位),即以用户在120秒内被分配到同一个后端realserver
persistence_granularity <NETMASK>              #LVS会话保持粒度,ipvsadm中的-M参数,默认是0xffffffff,即每个客户端都做会话保持
protocol TCP                                                  #健康检查用的是TCP还是UDP
ha_suspend                                                   #suspendhealthchecker’s activity
virtualhost <string>                                       #HTTP_GET做健康检查时,检查的web服务器的虚拟主机(即host:头)

sorry_server <IPADDR> <PORT>                 #备用机,就是当所有后端realserver节点都不可用时,就用这里设置的,也就是临时把所有的请求都发送到这里啦

real_server <IPADDR> <PORT>                    #后端真实节点主机的权重等设置,主要,后端有几台这里就要设置几个
{
weight 1                                                         #给每台的权重,0表示失效(不知给他转发请求知道他恢复正常),默认是1
inhibit_on_failure                                            #表示在节点失败后,把他权重设置成0,而不是冲IPVS中删除

notify_up <STRING> | <QUOTED-STRING>  #检查服务器正常(UP)后,要执行的脚本
notify_down <STRING> | <QUOTED-STRING> #检查服务器失败(down)后,要执行的脚本

HTTP_GET                                                     #健康检查方式
{
url {                                                                #要坚持的URL,可以有多个
path /                                                             #具体路径
digest <STRING>                                            
status_code 200                                            #返回状态码
}
connect_port 80                                            #监控检查的端口

bindto <IPADD>                                             #健康检查的IP地址
connect_timeout   3                                       #连接超时时间
nb_get_retry 3                                               #重连次数
delay_before_retry 2                                      #重连间隔
} # END OF HTTP_GET|SSL_GET


#下面是常用的健康检查方式,健康检查方式一共有HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK这些
#TCP方式
TCP_CHECK {
connect_port 80
bindto 192.168.1.1
connect_timeout 4
} # TCP_CHECK

# SMTP方式,这个可以用来给邮件服务器做集群
SMTP_CHECK
host {
connect_ip <IP ADDRESS>
connect_port <PORT>                                     #默认检查25端口
14 KEEPALIVED
bindto <IP ADDRESS>
}
connect_timeout <INTEGER>
retry <INTEGER>
delay_before_retry <INTEGER>
# "smtp HELO"ž|·-ë꧌à"
helo_name <STRING>|<QUOTED-STRING>
} #SMTP_CHECK

#MISC方式,这个可以用来检查很多服务器只需要自己会些脚本即可
MISC_CHECK
{
misc_path <STRING>|<QUOTED-STRING> #外部程序或脚本
misc_timeout <INT>                                    #脚本或程序执行超时时间

misc_dynamic                                               #这个就很好用了,可以非常精确的来调整权重,是后端每天服务器的压力都能均衡调配,这个主要是通过执行的程序或脚本返回的状态代码来动态调整weight值,使权重根据真实的后端压力来适当调整,不过这需要有过硬的脚本功夫才行哦
#返回0:健康检查没问题,不修改权重
#返回1:健康检查失败,权重设置为0
#返回2-255:健康检查没问题,但是权重却要根据返回代码修改为返回码-2,例如如果程序或脚本执行后返回的代码为200,#那么权重这回被修改为 200-2
}
} # Realserver
} # Virtual Server

keepalived高可用安装与配置

安装:yum install keepalived -y
  • 配置: master (优先级) lb01 100:
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id lb01
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 50
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
}
    virtual_ipaddress {
        10.0.0.3
    }
}
  • backup (优先级) lb02 90
[root@lb02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id lb02
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}

启动

systemctl enable keepalived
systemctl start keepalived

8.keepalived高可用地址漂移测试:

方法一:
[root@lb01 ~]# ip addr | grep 10.0.0.3

尝试停止master的keeplaived
[root@lb01 ~]# systemctl stop keepalived

在slave上查看是否有对应的VIP
[root@lb02 ~]# ip addr|grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0


方法二:
向vrrp 224.0.0.18 发送组播数据报文:
	广播:比如我讲课,说一句话,所有人 都收到了。
	组播:是 一种特定的广播,只有特定的人群才可以收到。

9.keepalived高可用抢占式与非抢占式?

抢占(默认):

  • master故障,backup接管,master恢复后会抢占VIP。(发生2次切换) 默认就是抢占式。
    对于并发访问非常高的 站点,不建议配置抢占,因为会发生至少2次VIP地址漂移。

  • 什么情况用: master 和 backup 的 配置 不对等。 ( master性能高,backup性能弱。 )

非抢占:

  • master故障,backup接管,master恢复了不会抢占VIP,除非backup故障,master会再次接管VIP。
配置非抢占式步骤如下:
1、两个节点的state都必须配置为BACKUP(官方建议)
2、两个节点都在vrrp_instance中添加nopreempt参数
3、其中一个节点的优先级必须要高于另外一个节点的优先级。
两台服务器都角色状态启用nopreempt后,必须修改角色状态统一为BACKUP,唯一的区分就是优先级。

#Master
    vrrp_instance VI_1 {
        state BACKUP
        priority 150
        nopreempt
    }

#Backup
    vrrp_instance VI_1 {
        state BACKUP
        priority 100
        nopreempt
    }

10.keepalived高可用与Nginx集成

准备环境:
	10.0.0.5  已经配置好的负载均衡 ( blog、zh )
	10.0.0.6  
安装Nginx:
	1.拉取10.0.0.5 的配置;
	2.目的:确保10.0.0.5 与 10.0.0.6 配置一致,无论通过5 或者 6  都能正常访问  blog 和  zh
[root@lb02 ~]# scp root@172.16.1.5:/etc/yum.repos.d/nginx.repo /etc/yum.repos.d/
[root@lb02 ~]# yum install nginx -y
[root@lb02 ~]# scp -rp 172.16.1.5:/etc/nginx /etc/
[root@lb02 ~]# nginx -t
[root@lb02 ~]# systemctl enable nginx
[root@lb02 ~]# systemctl start nginx

配置高可用:
	1.提供的VIP是10.0.0.3 
	2.将域名解析指向到10.0.0.3 

		解析:10.0.0.3 blog.oldxu.com zh.oldxu.com

Nginx和Keepalived有什么关系? keepalived是如何实现nginx高可用的呢?

  • 没有关系。
  • Nginx仅借助了Keepalived的地址漂移技术,实现的高可用。

nginx停止了?那么VIP还会漂移吗?

  • 不会。
1.停止nginx
[root@lb01 ~]# systemctl stop nginx

2.检查vip,发现没有漂移。
[root@lb01 ~]# ip addr |grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

VIP在什么时候会漂移?

1.keepalived服务停止了,地址就会漂移。
2.服务器直接关机、重启了,地址会漂移。


希望Nginx如果故障停止了,那么希望VIP漂移到另外一台节点。
	写一个脚本:
		1.判断Nginx是否存活,
			如果存活则不处理。
			如果不存活,尝试1~3次,强制杀掉keeplaived。


[root@lb01 ~]# mkdir /server/scripts -p
[root@lb01 ~]# vim /server/scripts/check_web.sh
#!/bin/sh
nginxpid=$(ps -C nginx --no-header|wc -l)
#1.判断Nginx是否存活,如果不存活则尝试启动Nginx
if [ $nginxpid -eq 0 ];then
    systemctl start nginx
    sleep 3
    #2.等待3秒后再次获取一次Nginx状态
    nginxpid=$(ps -C nginx --no-header|wc -l) 
    #3.再次进行判断, 如Nginx还不存活则停止Keepalived,让地址进行漂移,并退出脚本  
    if [ $nginxpid -eq 0 ];then
        systemctl stop keepalived
   fi
fi

#给脚本增加执行权限
[root@lb01 ~]# chmod +x /server/scripts/check_web.sh

配置:
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id lb01
}

#定义脚本路径,定义脚本多久执行一次,定义名称check_web
vrrp_script check_web {
	script "/server/scripts/check_web.sh"
	interval 5
}

vrrp_instance VI_1 {
    state BACKUP
    priority 150
    nopreempt

    interface eth0
    virtual_router_id 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
}
    virtual_ipaddress {
        10.0.0.3
    }
	#调用脚本,并运行该脚本
	track_script {
		check_web
	}
}

keepalived如何投产?

  • 问题:虚拟的IP地址。是无法对外的,意味着 DNS 怎么解析到你的 VIP ?
NAT:
	SNAT  源地址转换		( 共享上网的 )
	DNAT 目标地址转换		 ( 端口映射 )

keepalived 脑裂?

	1.什么是脑裂?
		当两个节点同时认为自己是唯一处于活动状态的时候,从而出现了资源抢占,双方都在抢占资源的情况下,及为脑裂。
	2.脑裂的产生?
		1.网线松动
		2.开启了防火墙。
	3.脑裂影响的范围?
		1.对于无状态的服务,比如Nginx,不care脑裂不脑裂。
		2.对于有状态的服务,比如MySQL,就必须严格防止脑裂现象。
		对于MySQL来说,可能出现多种情况,比如无法正常访问、或者得不到正确的返回结果,但大部分是无法正常访问,直接没有响应;
		如果出现了脑裂,有多种办法可以规避,比如我们可以写一些监控性的脚本,同时监控2台服务器的地址配置情况,如果检测同时存在2个IP,就可以认定为脑裂,这		时软件解决办法,生产中用这种比较多;也有硬件解决办法,但不常用。
	4.网上很多解决keepalived脑裂的问题的文章。

编译安装

编译概述

公司线上业务已经有Nginx了,现在要新上一个业务,你给我把Nginx安装一下,按照之前的安装方式进行,怎么办?
1.先使用nginx -V 获取所有的编译参数。
2.按照所有的参数,在新的服务器上进行编译安装。

给Nginx安装一个第三方模块?
1.先使用nginx -V 获取所有的编译参数。
2.给nginx的源码导入第三方模块的补丁包。
3.按照之前的编译参数,+ 第三方模块的参数(使用add-module),在新的服务器上进行编译安装 。
4.验证模块是否有效,是否可用。( 三方模块官方站点获取对应的文档 )

安装依赖

yum install gcc redhat-rpm-config \
libxslt-devel gd-devel perl-ExtUtils-Embed \
geoip-devel gperftools-devel pcre-devel openssl-devel -y

下载源码包

[root@nfs ~]# useradd nginx
[root@nfs ~]# wget http://nginx.org/download/nginx-1.14.2.tar.gz
[root@nfs ~]# tar xf nginx-1.14.2.tar.gz
[root@nfs ~]# cd nginx-1.14.2/

编译

./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'

make

1.make
2.make install 

配置启动文件

[root@NFS-31 nginx-1.16.1]# vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target

# systemctl restart nginx

添加第三方模块

[root@nfs ~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip
[root@nfs ~]# unzip master.zip
[root@nfs ~]# cd nginx-1.14.2/
[root@nfs nginx-1.14.2]# patch -p1 <../nginx_upstream_check_module-master/check_1.14.0+.patch

编译

./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --add-module=/root/nginx_upstream_check_module-master --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'

make

make install

验证

[root@nfs nginx-1.14.2]# cat  /etc/nginx/conf.d/upstream_check.conf
upstream blog.oldxu.com {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    check interval=5000 rise=2 fall=3 timeout=1000 type=tcp;
    #interval检测间隔时间,单位为毫秒
    #rsie表示请求2次正常,标记此后端的状态为up
    #fall表示请求3次失败,标记此后端的状态为down
    #type  类型为tcp
    #timeout为超时时间,单位为毫秒
}
upstream webserver {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    check interval=5000 rise=2 fall=3 timeout=1000 type=tcp;
}
upstream php {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    check interval=5000 rise=2 fall=3 timeout=1000 type=tcp;
}
server {
    listen 8888;
    location / {
    proxy_pass http://blog.oldxu.com;
    }
    location /upstream_status {
    check_status;     #开启upstream状态页面
    }
}


[root@nfs nginx-1.14.2]# cat  /etc/nginx/conf.d/upstream_check.conf
upstream blog.oldxu.com {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    check interval=5000 rise=2 fall=3 timeout=1000 type=tcp;
}
upstream webserver {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    check interval=5000 rise=2 fall=3 timeout=1000 type=tcp;
}
upstream php {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    check interval=5000 rise=2 fall=3 timeout=1000 type=tcp;
}
server {
    listen 8888;
    location / {
    proxy_pass http://blog.oldxu.com;
    }
    location /upstream_status {
    check_status; 
    }
}

平滑升级

安装Nginx依赖

[root@nfs ~]# yum install gcc redhat-rpm-config \
libxslt-devel gd-devel perl-ExtUtils-Embed \
geoip-devel gperftools-devel pcre-devel openssl-devel -y

下载并编译

[root@nfs ~]# wget http://nginx.org/download/nginx-1.16.1.tar.gz
[root@nfs ~]# tar xf nginx-1.16.1.tar.gz
[root@nfs ~]# cd nginx-1.16.1/
[root@nfs ~]# rm -f /etc/nginx/conf.d/upstream_check.conf  不兼容该第三方模块

./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'

make

make  make即可,不需要make install

备份旧的二进制文件

[root@nfs nginx-1.16.1]# mv /usr/sbin/nginx /usr/sbin/nginx.old
[root@nfs nginx-1.16.1]# cp objs/nginx /usr/sbin/nginx

查看进程

[root@NFS-31 nginx-1.16.1]# ps -ef |grep nginx
root      83326      1  0 22:19 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83327  83326  0 22:19 ?        00:00:00 nginx: worker process
root      83357   1600  0 22:20 pts/0    00:00:00 grep --color=auto nginx

发送信号

[root@nfs nginx-1.16.1]# kill -WINCH 83326
# 查看进程,新的进程和旧的进程并存。
[root@NFS-31 nginx-1.16.1]# ps -ef|grep nginx
root      83326      1  0 22:19 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83327  83326  0 22:19 ?        00:00:00 nginx: worker process
root      83358  83326  0 22:20 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83359  83358  0 22:20 ?        00:00:00 nginx: worker proces

# 向旧的master进程发送QUIT信号,旧的master进程就退出了。
[root@NFS-31 nginx-1.16.1]# kill -WINCH 83326
[root@NFS-31 nginx-1.16.1]# ps -ef|grep nginx
root      83326      1  0 22:19 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
root      83358  83326  0 22:20 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83359  83358  0 22:20 ?        00:00:00 nginx: worker process

# 向旧的master进程发送QUIT信号,旧的master进程就退出了。
[root@NFS-31 nginx-1.16.1]# kill -QUIT 83326 
[root@NFS-31 nginx-1.16.1]# ps -ef|grep nginx
root      83358      1  0 22:20 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83359  83358  0 22:20 ?        00:00:00 nginx: worker process
root      83365   1600  0 22:22 pts/0    00:00:00 grep --color=auto nginx
[root@NFS-31 nginx-1.16.1]# ^C

信号

QUIT          优雅关闭、quit
HUP           优雅重启、reload
USR1          重新打开日志文件、reopen
USR2          平滑升级可执行的二进制程序。
WINCH         平滑关闭Worker进程。

回滚

替换二进制文件

# 替换二进制文件
[root@NFS-31 nginx-1.16.1]# mv /usr/sbin/nginx /usr/sbin/nginx-1.16
[root@NFS-31 nginx-1.16.1]# mv /usr/sbin/nginx-1.14 /usr/sbin/nginx  
[root@nfs nginx-1.16.1]# kill -WINCH 83326

操作步骤

# 查看进程,新的进程和旧的进程并存。
[root@NFS-31 nginx-1.16.1]# ps -ef|grep nginx
root      83326      1  0 22:19 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83327  83326  0 22:19 ?        00:00:00 nginx: worker process
root      83358  83326  0 22:20 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83359  83358  0 22:20 ?        00:00:00 nginx: worker proces

# 向旧的master进程发送QUIT信号,旧的master进程就退出了。
[root@NFS-31 nginx-1.16.1]# kill -WINCH 83326
[root@NFS-31 nginx-1.16.1]# ps -ef|grep nginx
root      83326      1  0 22:19 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
root      83358  83326  0 22:20 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83359  83358  0 22:20 ?        00:00:00 nginx: worker process

# 向旧的master进程发送QUIT信号,旧的master进程就退出了。
[root@NFS-31 nginx-1.16.1]# kill -QUIT 83326 
[root@NFS-31 nginx-1.16.1]# ps -ef|grep nginx
root      83358      1  0 22:20 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     83359  83358  0 22:20 ?        00:00:00 nginx: worker process
root      83365   1600  0 22:22 pts/0    00:00:00 grep --color=auto nginx
[root@NFS-31 nginx-1.16.1]# ^C
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值