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
源码编译,
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 -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.
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代表一个网站,简称虚拟主机。
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
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
}
模块
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;
}
}
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;
}
创建用户和密码并结合访问控制:
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;
}
}
[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;
}
}
状态模块
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
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";
}
}
当处理速度,达不到请求的速度,则会讲请求放置缓存,如果缓存被占满。多余的请求将被丢弃。
设置共享内存区域和请求的最大突发大小,过多的请求被延迟,直到它们的数量超过最大的限制,在这种情况下请求以错误终止。
测试:
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;
}
}
配置:
[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连接;
配置:
[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----->+剩下
配置:
[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=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个请求位置。
当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 '你可能是不小心走丢了。';
}
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<
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
# 查看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
# 博客网站配置文件
[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 [email protected]:~
# 关闭数据库
[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
# 将web01的仓库拷贝到web02
# 扩展多台web应用服务
两台一样:
1.环境是不是应该一致
[root@web02 ~]# scp [email protected]:/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 [email protected]:/etc/php-fpm.d/www.conf /etc/php-fpm.d/
[root@web02 ~]# scp -rp [email protected]:/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 [email protected]:~
# 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返回数据给代理,代理返回给用户。
区别:
正向代理对象是客户端。
反向代理对象是服务端。
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;
}
}
[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固定访问一个后台服务器。
upstream lb_demo {
ip_hash;
server 10.0.0.7:80;
server 10.0.0.8:80;
}
最少链接数,哪个机器连接数少就发分发给哪个机器。
upstream lb_demo {
least_conn;
server 10.0.0.7:80;
server 10.0.0.8:80;
}
按访问的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;
}
}
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
[root@web02 conf.d]# vim /code/index.php
通过浏览器访问,搜索$_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, 比对成功,则会话保持。
# 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
# 解决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";
}
}
}
[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 {
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
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;
}
}
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
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
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
[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<
[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;
}
}
[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;
}
}
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"%>
Nginx+Tomcat动静分离
<%
Random rand = new Random();
out.println("动态资源
");
out.println(rand.nextInt(99)+100);
%>
静态图片
[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"%>
Nginx+Tomcat动静分离
<%
Random rand = new Random();
out.println("动态资源
");
out.println(rand.nextInt(99)+100);
%>
静态图片
[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
步骤一、安装 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和location的功能有点相像,都能实现跳转,主要区别在于rewrite常用于同一域名内更改获取资源的路径,而location是对一类路径做控制访问和反向代理,可以proxy_pass到其他服务器。
Nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。
rewrite只能放在server{},location{},if{}中,
并且只能对域名后边的除去传递的参数外的字符串起作用。
Rewrite主要的功能就是实现URL的重写,Nginx的Rewrite规则采用Pcre,perl兼容正则表达式的语法规则匹配,如果需要Nginx的Rewrite功能,在编译Nginx之前,需要编译安装PCRE库。
通过Rewrite规则,可以实现规范的URL、根据变量来做URL转向及选择配置。
指令 | 默认值 | 适用范围 | 作用 |
---|---|---|---|
break | none | if,server,location | 完成当前的规则集,不再处理rewrite指令,需要和last加以区分 |
if ( condition ) { … } | none | server , location | 用于检测一个条件是否符合,符合则执行大括号内的语句。不支持嵌套,不支持多个条件&&或处理 |
return | none | server , location | 用于结束规则的执行和返回状态码给客户端,状态码的值可以是:200 400 402 406 408 410 411 413 416 500 504,另外非标准状态码444,表示以不发送任何Header头来结束链接。 |
变量 | 说明 |
---|---|
$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永久重定向,地址栏会显示跳转后的地址。
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 永久跳转,第一次请求时会循环,跳转后会记录跳转的状态在浏览器,当下次在请求时候,会通过浏览器的缓存直接跳转.
企业大多数使用的临时跳转
[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就会跟上什么后缀
}
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
需求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 -L -HHost:url.oldxu.com http://10.0.0.7?a1=3256
-L 跟随跳转
-H 指定Host头,具体要请求的域名是
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主要是用来重写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;
}
}
需求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协议,DNS可能会被劫持篡改。
HTTPS注意事项
Https 不支持续费,证书到期需重新申请新并进行替换。
Https 不支持三级域名解析,如 test.m.oldboy.com。
Https 显示绿色,说明整个网站的url都是https的,并且都是安全的。
Https 显示黄色,说明网站代码中有部分URL地址是http不安全协议的。
Https 显示红色,要么证书是假的,要么证书已经过期。
默认监听端口 443
对称加密: 相同的秘钥。
非对称加密: 一对秘钥,公钥加密,私钥解密。
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获取,证书是否有效。
假的,真的要域名
[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
[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;
}
}
减少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;
}
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即可。
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 #LVS会话保持粒度,ipvsadm中的-M参数,默认是0xffffffff,即每个客户端都做会话保持
protocol TCP #健康检查用的是TCP还是UDP
ha_suspend #suspendhealthchecker’s activity
virtualhost #HTTP_GET做健康检查时,检查的web服务器的虚拟主机(即host:头)
sorry_server #备用机,就是当所有后端realserver节点都不可用时,就用这里设置的,也就是临时把所有的请求都发送到这里啦
real_server #后端真实节点主机的权重等设置,主要,后端有几台这里就要设置几个
{
weight 1 #给每台的权重,0表示失效(不知给他转发请求知道他恢复正常),默认是1
inhibit_on_failure #表示在节点失败后,把他权重设置成0,而不是冲IPVS中删除
notify_up | #检查服务器正常(UP)后,要执行的脚本
notify_down | #检查服务器失败(down)后,要执行的脚本
HTTP_GET #健康检查方式
{
url { #要坚持的URL,可以有多个
path / #具体路径
digest
status_code 200 #返回状态码
}
connect_port 80 #监控检查的端口
bindto #健康检查的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
connect_port #默认检查25端口
14 KEEPALIVED
bindto
}
connect_timeout
retry
delay_before_retry
# "smtp HELO"ž|·-ë꧌à"
helo_name |
} #SMTP_CHECK
#MISC方式,这个可以用来检查很多服务器只需要自己会些脚本即可
MISC_CHECK
{
misc_path | #外部程序或脚本
misc_timeout #脚本或程序执行超时时间
misc_dynamic #这个就很好用了,可以非常精确的来调整权重,是后端每天服务器的压力都能均衡调配,这个主要是通过执行的程序或脚本返回的状态代码来动态调整weight值,使权重根据真实的后端压力来适当调整,不过这需要有过硬的脚本功夫才行哦
#返回0:健康检查没问题,不修改权重
#返回1:健康检查失败,权重设置为0
#返回2-255:健康检查没问题,但是权重却要根据返回代码修改为返回码-2,例如如果程序或脚本执行后返回的代码为200,#那么权重这回被修改为 200-2
}
} # Realserver
} # Virtual Server
keepalived高可用安装与配置
安装:yum install keepalived -y
[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
}
}
[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性能弱。 )
非抢占:
配置非抢占式步骤如下:
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 [email protected]:/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停止了?那么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如何投产?
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