本文档是一份全面且深入的Web集群管理实战指南。它系统性地阐述了构建和维护高可用、高性能、可扩展的Web服务集群所需的核心知识与技术栈。内容从HTTP协议基础与访问量指标分析入手,逐步深入到主流Web服务器Nginx的部署、配置、优化及模块化应用(如虚拟主机、日志、动静分离)。重点讲解了使用Nginx实现反向代理与负载均衡的架构,包括算法选择、会话保持和健康检查。为确保服务连续性,文档涵盖了基于Keepalived的高可用方案。此外,还扩展了Java应用容器Tomcat的集群部署、监控与优化,并最终以Linux iptables防火墙的安全配置收尾。本指南融合了理论、配置范例与生产环境经验,旨在为运维工程师和架构师提供从单点服务到分布式集群的完整知识体系和实操参考。
一、web集群-http协议
1.http协议概述
- 默认端口是80.
- HTTP超文本传输协议:数据请求与响应
sh
#request 请求
---request begin---
GET / HTTP/1.1
User-Agent: Wget/1.14 (linux-gnu)
Accept: */*
Host: www.baidu.com
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
#response 响应
---response begin---
HTTP/1.1 200 OK
Content-Length: 2381
Content-Type: text/html
Server: bfe
Date: Thu, 30 Mar 2023 03:32:23 GMT
---response end---
2.http协议版本
| http1.0 | http1.1 | http2.0 | http3.0 | |
|---|---|---|---|---|
| 特点 | 短连接,每次请求都需要重复建立断开连接 | 加入长连接功能 | 增加并发,访问速度更快 | 基于upd更快,应用于流媒体 |
| 占用服务端资源 | keepalive功能(网站响应后不会立刻断开,保留下这个链接) | |||
| 是否加密 | http 不加密 https 加密 | 默认基于https | ||
| 基于tcp/udp | tcp | tcp | tcp | udp |
目前现状:
大部分企业还在使用http1.1, 一部分使用http2.0
目前http3.0(QUIC ) 流媒体直播在使用.
HTTP1.1 vs 2.0 速度对比: HTTP1.1/HTTP2 加载对比 (sinacloud.com)
3.http协议详解
- http 请求报文
- http 响应
3.1 http 请求
01 概述
sh
wget --debug www.baidu.com
---request begin---
GET / HTTP/1.1
User-Agent: Wget/1.14 (linux-gnu)
Accept: */*
Host: www.baidu.com
Connection: Keep-Alive
---request end---
02 请求报文起始行
- 请求方法: 用于指定客户端如何访问服务端(下载,上传,查看服务端信息)
| 常见的请求方法 | 说明 |
|---|---|
| GET | 下载(大部分请求) |
| POST | 上传 |
| HEAD | 类似于GET,仅仅输出响应的头部信心。(查看服务端的信息,一般用于检查) |
- 资源的位置(URI): 这个资源在网站站点目录的哪个地方,叫什么名字. URI(资源标识符)
温馨提示:
GET /liux.mp4 HTTP/1.1 这里的/不是根,是网站站点目录,未来可以在
web服务中进行配置.
/app/code/www/ 站点目录
访问/liux.mp4 /app/code/www/liux.mp4
- 协议与版本 HTTP/1.0 HTTP/1.1
03 请求头
| 字段 | 含义 |
|---|---|
| User-Agent | 客户端代理(用什么工具访问网站) |
| Host | 表示访问的目标网站:域名或ip |
3.2 http 响应报文
-
curl -v www.baidu.com
-
状态码与服务端信息
01 响应报文起始行
-
协议与版本 HTTP/1.1
-
状态码:数字3位,用于描述服务端是否能找到或处理用户的请求.(类似于命令行错误提示) 200 ok. 404
-
状态码描述:
02 响应头
| 响应头字段 | |
|---|---|
| Server | 显示服务端使用的web服务器及版本 |
| Content-Type | 媒体类型(文件类型) |
| Content-Length | 大小 |
| Location | 跳转之后的新的位置(未来讲解rewrite 301/302),跳转的时候才有 |
3.3 http协议状态码
- 状态码: 错误提示,反映出服务端是否能够正常的处理用户请求.
| 状态码 | 含义 |
|---|---|
| 2xx | 正常 |
| 3xx | 需要进行跳转,正x常 |
| 4xx | 异常,客户端问题 |
| 5xx | 异常,服务端错误问题 |
| 详细的状态码 | 含义 |
|---|---|
| 200 ok | 访问正常 |
| 301 Moved Permanently | 永久跳转 |
| 302 Found | 临时跳转 |
| 304 Not Modified | 浏览器缓存 |
| 403 Forbidden | 权限拒绝(拒绝访问) 🅰️权限问题 🅱️首页文件问题 |
| 404 Not Found | 文件找不到,一般辅助错误日志排查 |
| 500 Internal Error | 内部错误,SELinux开启,其他原因一般辅助错误日志排查 |
| 502 Bad Gateway | 网关错误,一般发生在负载中(类似场景下),请求发送到后面,无人处理,提示502. |
| 503 service temporarily unavailable | 服务临时不可用,后端负载异常等情况,人为设置(升级) |
| 504 Gateway Time-out | 网关超时 |
3.4 HTTP协议小结
-
HTTP: 用户的请求与响应被后格式与定义
-
HTTP请求报文:
- 请求起始行: GET / (uri) HTTP/1.
- 请求头(head): User-Agent: 客户端代理(浏览器) Host: 域名
- 空行
- 请求报文主体(body): POST
-
HTTP响应报文:
- 响应报文的起始行: HTTP/1.1 状态码
- 响应头: Server(web服务器)
- 空行
- 响应报文的主体(body): 文件内容
二、web集群-衡量系统访问量指标
1.概述
| 指标 | 说明 |
|---|---|
| IP | 访问网站的独立IP数量,公网IP |
| PV | 每个页面访问量Page view (打开一个页面或访问一个页面,称为1个pv) |
| UV | 独立访问数量,接近于用户数量 Unique Vistor 独立的设备,一个设备表示一个pv(一台电脑访问表示一个uv) |
| DAV | 每天的活跃用户的数量:日活跃用户 |
| MAU | 月活(月活跃用户) |
2.统计
- IP,PV,UV 三剑客进行过滤,第三方统计插件(百度统计,...网站页面加入代码),ELK
- DAU,MAU 第3方工具,数据库统计用户登录情况.
三、web集群-Nginx
1.web服务
- WEB服务,网站服务:网站
- WEB中间件: 等同于WEB服务
- 中间件:范围更加广泛,指的负载均衡之后的服务.
- 数据库中间件:数据库缓存,消息对列 ...
2.常见网站服务
| 网站服务 | 说明 | 官网 |
|---|---|---|
| Nginx | 大部分使用nginx | nginx documentation |
| Tengine | 基于Nginx二开,淘宝开源,更多内置模块 | |
| Openresty | 基于Nginx二开,加强Lua功能与模块 | |
| Tomcat/Jboss/Jetty/Weblogic | 运行java环境的,web服务 | |
| PHP | 运行php环境,需要nginx(LNMP) |
3.Nginx极速上手指南
- 常用服务的版本:1.22.0
- nginx安装方式
- 1.源码编译=>Nginx (1.版本随意 2.安装复杂 3.升级繁琐 4.规范 5.便于管理)
- 2.epel仓库=>Nginx (1.版本较低 2.安装简单 3.配置不易读)
- 3.官方仓库=>Nginx (1.版本较新 2.安装简单 3.配置易读) nginx.org
3.1 配置yum源与安装nginx
sh
#配置nginx官网yum源 https://nginx.org/en/linux_packages.html#instructions
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1 # 检查下载nginx的完整性
enabled=1 # 是否开启此仓库 1为开启 0为关闭
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
#安装nginx-1.22.0-1.el7.ngx.x86_64 版本
yum -y install nginx-1.22.0-1.el7.ngx.x86_64
#启动
systemctl enable nginx
systemctl start nginx
systemctl status nginx
#检查
ps -ef|grep nginx
netstat -lntup|grep 80
3.2 检查安装
sh
[root@web01 ~]# rpm -qa nginx
nginx-1.22.0-1.el7.ngx.x86_64
[root@web01 ~]# rpm -ql nginx
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
/etc/nginx/fastcgi_params
/etc/nginx/mime.types
/etc/nginx/modules
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
/usr/lib64/nginx
/usr/lib64/nginx/modules
/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade
/usr/sbin/nginx
/usr/sbin/nginx-debug
/usr/share/doc/nginx-1.22.0
/usr/share/doc/nginx-1.22.0/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
/var/cache/nginx
/var/log/nginx
3.3 目录结构
Nginx不同的安装方法:目录,文件会有所区别.
| 目录结构 | 说明 |
|---|---|
| /etc/nginx | nginx各种配的目录 |
| /etc/nginx/nginx.conf | 主配置文件 |
| /etc/nginx/conf.d | 子配置文件(网站) |
| /etc/nginx/conf.d/default.conf | 默认的子配置文件 |
| /usr/sbin/nginx | ngx命令 |
| /usr/share/nginx/html/ | ngx默认的站点目录,网站的根目录 |
| /var/log/nginx/ | ngx日志:访问日志,错误日志 |
| 其他目录和文件 | 说明 |
|---|---|
| /etc/logrotate.d/nginx | 日志切割 |
| /etc/nginx/mime.types | 媒体类型 |
| /etc/nginx/fastcgi_params | ngx+php |
| /etc/nginx/uwsgi_params | ngx+python |
| /usr/lib/systemd/system/nginx.service | systemctl配置文件 |
| /var/cache/nginx/ | 缓存目录 |
3.4日常启动与管理
sh
#检查80端口有没有占用
ss -lntup |grep 80
#设置开机自启动与启动
systemctl enable nginx
systemctl start nginx
#查看进程
ps -ef |grep nginx

- 访问
sh
http://10.0.0.7/
#命令行访问
curl 10.0.0.7
curl -v 10.0.0.7
4.Ngx核心配置文件
- /etc/nginx/nginx.conf
4.1 主配置文件⭐️⭐️⭐️⭐️⭐️
sh
[root@web01 nginx]# cat /etc/nginx/nginx.conf
[核心区块]
user nginx; # 虚拟用户 可以自定义
worker_processes auto; # worker子进程的数量 CPU核心数有几个 这个就是几
error_log /var/log/nginx/error.log notice; # 错误日志存放的路径
pid /var/run/nginx.pid; # 运行后的PID号的路径
events { # 事件模块
worker_connections 25000; # 每个进程最大的并发连接数
}
# 注意 最大连接数量和文件描述符有关(打开文件最大数量)
http {
include /etc/nginx/mime.types; # 支持的媒体类型
default_type application/octet-stream; # 如果找不到对应的类型 默认下载方式打开
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; # 长连接的超时时间
#gzip on; # 是否开启压缩
include /etc/nginx/conf.d/*.conf; #子配置文件目录
}

熟练掌握的指令:
include 文件包含,引用其他地方的ngx配置文件.
user指定ngx用户.
error_log错误日志
access_log 访问日志
4.2 子配置文件
- conf.d/*.conf

| 网站中常用必会指令 | 说明 |
|---|---|
| listen | 指定监听端口 |
| server_name | 指定域名,多个通过空格分割. |
| location(区域) | 匹配请求中的uri(资源地址) |
| root | 指定站点目录(网站的根目录) |
| index | 指定站点的首页文件. 用户访问的时候不加上任何的文件,展示首页文件 |
| error_log | 指定错误状态码与对应的错误页面 |
ngx:必会问题:
如果删除首页文件,进行(不指定文件)访问会发生什么?
403首页文件不存在.
5. 部署一个网站
| 网站要求 | 说明 |
|---|---|
| 域名 | liux.cn |
| 站点目录 | /app/code/game |
| 代码来源 | bird.zip |
5.1 配置文件
sh
server {
listen 80
server_name linux.cn
root /app/code/game;
location / {
index index.html;
}
}
[root@web01 /etc/nginx/conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax
is ok
nginx: configuration file /etc/nginx/nginx.conf test is
successful
[root@web01 /etc/nginx/conf.d]# systemctl reload nginx
5.2 其他
sh
创建目录
mkdir -p /app/code/game/
上传代码
unzip bird.zip
mv bird/* /app/code/game/
配置linux和windows hosts解析
#win: C:\Windows\System32\drivers\etc\hosts
#linux: /etc/hosts
10.0.0.7 linux.cn
6.虚拟主机
- 虚拟主机:相当于是1个网站,在ngx中通过server{}实现
6.1概述
| 虚拟主机的分类 | 说明 | 应用场景 |
|---|---|---|
| 基于域名的虚拟主机 | 不同域名访问不同的网站 | 最常用 |
| 基于端口的虚拟主机 | 不同端口访问不同的网站 | 保护,设置特殊端口 8888 18888 |
| 基于ip的虚拟主机 | 不同ip访问不同的网站 | 保护,用户只能通过某个ip连接进来。用来限制网站 只能通过指定的ip进行访问内网ip,vpn ip |
6.2 基于域名的虚拟主机
sh
mkdir -p /app/code/live/
echo live.liux.cn web01 >/app/code/live/index.html
[root@web01 /etc/nginx/conf.d]# cat live.liux.cn.conf
server {
listen 80;
server_name live.liux.cn;
root /app/code/live;
location / {
index index.html;
}
}
[root@web01 /etc/nginx/conf.d]# cat game.liux.cn.conf
server {
listen 80;
server_name game.liux.cn;
root /app/code/game;
location / {
index index.html;
}
}
[root@web01 /etc/nginx/conf.d]# cat default.conf
server {
listen 80 default_server;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
#测试:
curl -H Host:game.liux.cn http://10.0.0.7:80
curl -H Host:live.liux.cn http://10.0.0.7:80
curl http://10.0.0.7:80
6.3 基于端口的虚拟主机
sh
#修改live.liux.cn端口为81.
erver {
listen 81;
server_name live.liux.cn;
root /app/code/live;
location / {
index index.html;
}
}
6.4 基于ip的虚拟主机
sh
#修改配置文件.
erver {
listen 172.16.1.7:81;
server_name live.liux.cn;
root /app/code/live;
location / {
index index.html;
}
}
#测试
[root@web01 /etc/nginx/conf.d]# curl -H Host:live.liux.cn http://10.0.0.7:81
curl: (7) Failed connect to 10.0.0.7:81; Connection
refused
[root@web01 /etc/nginx/conf.d]# curl -H Host:live.liux.cn http://172.16.1.7:81
live.liux.cn web01
7. Ngx日志
7.1概述
| 日志 | 使用建议 | 定义 | 使用 |
|---|---|---|---|
| 错误日志 | 发生错误的时候可以查看,4xx、5xx | 通过错误级别定义 | error_log |
| 访问日志 | 记录着用户什么时候访问网站哪些页面,客户端信息 | 通过log_format定义访问日志的格式 | access_log |
7.2 错误日志
- 指定错误日志的位置和错误级别(日志级别)
| error_log 指令 |
|---|
| error_log 文件名 级别 |
| 放在哪::main,http,mail,stream,server,location |
错误级别:从左往后,越来越粗糙.
debug,info,notice,warn,error,crit,alert,or emerg
error
notice
debug:用于调试使用,短时间开启,网站访问量较大别开
- 生产建议(设置错误日志)
sh
[root@web01 /etc/nginx/conf.d]# cat game.liux.cn.conf
server {
listen 80;
server_name game.liux.cn;
error_log /var/log/nginx/game.liux.cn-error.log notice;
root /app/code/game;
location / {
index index.html;
}
}.
#需要把nginx.conf里面的error_log注释
7.3 访问日志
- 辅助我们进行分析,网站访问量,ip,pv.
- log_format****指定访问日志的格式
- log_format 格式名字格式...;
- 放在哪里: http
| Ngx访问日志格式(ngx内置变量) | 说明 |
|---|---|
| remote_addr | 客户端ip地址 |
| remote_user | 用户名(空,进行认证用户 |
| time_local | 时间 30/Aug/2022:14:44:27 +0800 |
| request | 请求报文的起始行(请求方法 URI HTTP/1.1) |
| status | http状态码 |
| body_bytes_sent | 响应报文的主体大小(文件大小) 单位字节 |
| http_referer | 从哪里跳转,访问到这个网站的. 网站运营分析 |
| http_user_agent | 客户端代理(浏览器) |
| http_x_forwarded_for | 负载中使用,记录用户真实的ip地址. |
更多ngx内置变量:http://nginx.org/en/docs/varindex.html
access_log指定日志,使用对应格式
access_log****指定访问日志access_log 日志位置格式
放在哪:http,server,location,if in location,limit_except
sh
Nginx日志常用参数详解:
$http_x_real_ip:真实访问得ip地址
$remote_addr:记录访问网站的客户端地址
$remote_user:远程客户端用户名称
$time_local:记录访问时间与时区
$request:表示request请求头的行
$status:http状态码,记录请求返回的状态,例如:200、404、301等
$body_bytes_sent:服务器发送给客户端的响应body字节数
$http_referer:记录此次请求是从哪个链接访问过来的,可以根据refer进行防盗链设置
$http_user_agent:记录客户端访问信息,例如:浏览器,手机客户端等
$http_x_forwarded_for:当前端有代理服务器时,设置Web节点记录客户端地址的配置,此参数生效的前提是代理服务器上也进行了相关的http_x_forwarded_for设置
$ssl_protocol:SSL协议版本
$ssl_cipher:交换数据中的算法
$upstream_status:upstream状态
$upstream_addr:当ngnix做负载均衡时,可以查看后台提供真实服务的设备
$upstream_response_time:请求过程中,upstream响应时间
$request_time:整个请求的总时间
$args:这个变量等于请求行中的参数,同$query_string
$content_length:请求头中的Content-length字段。
$content_type:请求头中的Content-Type字段。
$document_root:当前请求在root指令中指定的值。
$host:请求主机头字段,否则为服务器名称。
$http_user_agent:客户端agent信息
$http_cookie:客户端cookie信息
$limit_rate:这个变量可以限制连接速率。
$request_method:客户端请求的动作,通常为GET或POST。
$remote_addr:客户端的IP地址。
$remote_port:客户端的端口。
$remote_user:已经经过Auth Basic Module验证的用户名。
$request_filename:当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme:HTTP方法(如http,https)。
$server_protocol:请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr:服务器地址,在完成一次系统调用后可以确定这个值。
$server_name:服务器名称。
$server_port:请求到达服务器的端口号。
$request_uri:包含请求参数的原始URI,不包含主机名,如:"/foo/bar.php?arg=baz"。
$uri:不带请求参数的当前URI,$uri不包含主机名,如"/foo/bar.html"。
$document_uri:与$uri相同。
- 生产环境(添加访问日志)
sh
[root@web01 /etc/nginx/conf.d]# cat game.liux.cn.conf
server {
listen 80;
server_name game.liux.cn;
error_log /var/log/nginx/game.liux.cn-error.log notice;
access_log /var/log/nginx/game.liux.cn-access.log main;
root /app/code/game;
location / {
index index.html;
}
}.
#需要把nginx.conf里面的access_log注释
- 访问日志其他选项access_log
| access.log | |
|---|---|
| 进行压缩 | gzip 需要通过zcat/zless/zgrep查看 |
| 进行缓存 | buffer=32k 先把日志写入到内存中,定期写入到磁盘 |
| 定义刷新时间 | flush=10s |
sh
access_log /var/log/nginx/game.liux.cn-access.log main buffer=32k flush=10s ;
8.Location规则
- location在ngx中用于匹配用户请求中的uri。类似于对uri进行判断。
- location规则也叫路由规则
URI vs URL
http://www.baidu.com/liux/liux.avi
URI: /liux/liux.avi 域名后面的内容
URL: http://www.baidu.com/liux/liux.avi 网址
URI: / 域名后面的内容
URL: http://www.baidu.com 网址
| location规则 | ||
|---|---|---|
| ⭐️location / {xxxx} | 默认(保底)规则,location在进行匹配的时候,其他的规则都失败了,这时候匹配默认的规则 | |
| ⭐️location /image/{} | 用于匹配请求的uri(路径) | |
| ⭐️location ~ .(jpg | jpeg)$ {} | 支持正则,区分大小写 | |
| ⭐️ location ~* .(jpg | jpeg)$ {} | 支持正则,区分大小写 | |
| location ^~ /liux/ | 不支持正则,仅仅匹配普通字符,很少使用 | |
| location = /50x.html | 精确匹配,使用较少. | |
| location @名字 {} | 命名的location一般用于return/error_log 跳转. |
- location匹配的时候优先级(需要背)
| 优先级 | 符号 |
|---|---|
| 1 | = 精确匹配 |
| 2 | ^~ 以某个字符开头 |
| 3 | ~ ~* ~区分大小写 ~* 不区分大小写 |
| 4 | /image/ |
| 5 | / 通用匹配,任何请求都会匹配到 |
9.Ngx 搭建下载站
9.1 部署
-
搭建网站,用户可以直接流量站点目录,单击文件进行下载.
-
自动索引功能(列表站点目录的内容),首页文件不存在 autoindex模块
- autoindex on; 开启目录索引功能(列表)
- autoindex_localtime on; 显示本地时间.
- autoindex_exact_size off; 是否显示精确的文件的大小. off表示以人类可读形式显示大小
sh
[root@web01 conf.d]# vim dl.liux.cn.conf
server {
listen 80;
server_name dl.liux.cn;
root /app/code/dl;
error_log /var/log/nginx/dl-error.log notice;
access_log /var/log/nginx/dl-access.log main;
autoindex on;
charset utf-8;
autoindex_localtime on;
autoindex_exact_size off;
location / {
index index.html;
}
}
touch /app/code/dl/4k-cc-wuma-{01..10}.txt
#检查语法功能
nginx -t
#重启nginx
systemctl reload nginx

9.2 增加vip认证功能
- 增加认证功能
- auth_basic 模块
- auth_basic "请输入密码:"; #输出提示,根据不同浏览器,可能不显示
- auth_basic_user_file conf/htpasswd; #指定用户名,密码文件
- 要求
- 只要用户访问包含vip资源,提示输入密码
- 创建密码文件
sh
#创建密码文件,并创建用户密码 -c创建文件,文件存在就不需要加-c
htpasswd -bc /etc/nginx/passwd liux 12366
#修改权限
chown nginx.nginx /etc/nginx/passwd
chmod 600 /etc/nginx/passwd
- 符合要求的配置
sh
server {
listen 80;
server_name dl.liux.cn;
root /app/code/dl;
error_log /var/log/nginx/dl-error.log notice;
access_log /var/log/nginx/dl-access.log main;
autoindex on;
charset utf-8;
autoindex_localtime on;
autoindex_exact_size off;
location / {
index index.html;
}
location ~* /.*vip.*/ {
auth_basic "input password";
auth_basic_user_file /etc/nginx/passwd;
}
}
9.3 黑白名单功能
- 黑名单: 屏蔽指定的ip或网段,默认是可以进入. 逛公园.
- 白名单: 默认是拒绝,电影院,在名单中的ip可以访问.
01 黑名单
- deny 拒绝
sh
#######安全功能-黑名单########
deny 10.0.0.1;
#######安全功能-黑名单########

生产建议:
通过定时任务+日志分析,分析出401,异常的ip,次数过多,就加入到这个黑名单中.
可以创建独立的黑名单文件,通过include包含进来即可.
02 白名单
- 默认是拒绝,在名单中的可以访问.
sh
#######安全功能-白名单########
allow 10.0.0.1;
deny all;
#######安全功能-白名单########

03 小结
| 访问控制功能 | 说明 | 应用场景 |
|---|---|---|
| 黑名单 | 通过ngx,deny屏蔽指定的ip/网段 | 分析日志后屏蔽异常访问的ip地址. |
| 白名单 | 通过ngx,allow+deny all;实现指定ip/网段进行访问. | 用于控制访问,保护内部地址. |
9.4 状态检查模块-增加统计功能(stub_status)⭐️⭐️⭐️⭐️⭐️
- 显示ngx当前状态(显示ngx状态信息),未来用于监控ngx.
- 熟练使用状态模块.
- stub_status模块/指令.
sh
#在/etc/nginx/conf.d/dl.liux.cn.conf 添加如下行
location /status/ {
stub_status;
}
#浏览器运行
http://dl.liux.cn/status/
Active connections: 1
server accepts handled requests
36 36 125
Reading: 0 Writing: 1 Waiting: 0
| ngx状态模块中的指标说明 | 说明 | |
|---|---|---|
| Active connections | 当前已经建立的连接数(est)和等待数量 | ngx并发 |
| server accepts | 已经接收到客户端的连接总数. | |
| handled | 服务端已经处理的连接. | |
| requests | 客户端发出请求的总数. | |
| reading | 正在读取的请求头连接数量 | |
| writing | 正在进行的响应的连接数量 | |
| waiting | 排队数量 | 排队情况. |
9.5 nginx访问限制
limit_conn_module连接频率限制tcp
sh
http{ #http层,设置
# Limit settings
limit_conn_zone $remote_addr zone=conn_zone:10m;
server{ #server层调用
#连接限制,限制同时最高1个连接
limit_conn conn_zone 1;
}
}
limit_req_module请求频率限制
sh
# http标签段定义请求限制, rate限制速率,限制一秒钟最多一个IP请求
http {
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
}
server {
listen 80;
server_name module.oldboy.com;
# 1r/s只接收一个请求,其余请求拒绝处理并返回错误码给客户端
#limit_req zone=req_zone;
# 请求超过1r/s,剩下的将被延迟处理,请求数超过burst定义的数量, 多余的请求返回503
limit_req zone=req_zone burst=3 nodelay;
location / {
root /code;
index index.html;
}
}
9.6 模块小结
| 模块 | 说明 | 重要程度 |
|---|---|---|
| 目录索引模块 | autoindex on; | 💔 |
| 认证功能模块 | auth_basic_user_file; | ❤️ |
| 访问控制模块 | allow,deny | ❤️❤️❤️ |
| 状态模块 | 用于监控ngx, stub_status | ❤️❤️❤️❤️❤️ |
| ngx核心模块 | root,location,...,error_log | ❤️❤️❤️❤️❤️ |
| ngx日志模块 | access_log,log_format | ❤️❤️❤️ |
10.动态网站架构
10.1 概述
| 网站架构 | 说明 | 性能 | 说明 |
|---|---|---|---|
| 静态网站 | 网站仅仅包含html ,css样式,js脚本,图片,视频 ngx可以直接处理的静态资源 | 只需要web服务器即可,nginx可以承受较高的访问量。不支持动态的功能,注册,评论。静态网站功能单一 | 浏览器端解析(客户端解析),服务端仅仅负责发送 |
| 动态网站 | 动态网站通过开发语言实现:Java,php,python,golang... | 动态资源页面需要服务器进行处理nginx+php/tomcat+数据库 处理后把结果返回给用户。 | 动态请求需要服务端进行处理与解析,把结果给用户。 |
- 通过url简单/初步判断,网站的类型
- url中包含&或?一般都是动态网站.
10.2 常见的动态网站架构
-
PHP: LNMP, LAMP, WNMP/WAMP
-
Java: LNMT(Tomcat,Jetty,Weblogic,Jboss)
-
Python: LNMP(Python,uwsgi)
-
Golang: LNMG(Golang)
-
C/C++: LNM?..
LNM?
Linux 系统
Nginx Web服务
MySQL/MariaDB 数据库
LAMP A==> apache 目前很少使用.WNMP/WAMP W==>Windows 一般开发使用.
10.3 部署LNP项目
-
kodexplorer
-
1️⃣准备好对应的环境:nginx和PHP
-
2️⃣测试下环境是否可用.
-
3️⃣部署代码与安装代码.
01 部署服务
-
安装ngx ✅
-
安装php
sh
#版本 php 7.x
#生产环境选择,根据开发书写代码环境准备即可.
#配置php源
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
#给php配置yum源
vim /etc/yum.repos.d/php.repo
[webtatic-php]
name = php Repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64
enabled = 1
gpgcheck = 0
#安装php
yum install -y php72w php72w-cli php72w-common php72w-devel php72w-embedded php72w-gd php72w-mcrypt php72w-mbstring php72w-pdo php72w-xml php72w-fpm php72w-mysqlnd php72w-opcache php72w-pecl-memcached php72w-pecl-redis php72w-pecl-mongodb
#查看php并统计
rpm -qa |grep php |wc -l
02 服务配置
- 启动服务nginx,php-fpm
sh
systemctl enable nginx php-fpm
systemctl start nginx php-fpm
- 检查php端口与进程
sh
[root@web01 dl]# ss -lntup |grep php
tcp LISTEN 0 128 127.0.0.1:9000 *:* users:(("php-fpm",pid=3734,fd=9),("php-fpm",pid=3733,fd=9),("php-fpm",pid=3732,fd=9),("php-fpm",pid=3731,fd=9),("php-fpm",pid=3730,fd=9),("php-fpm",pid=3729,fd=7))
[root@web01 dl]# ps -ef |grep php
root 3729 1 0 22:55 ? 00:00:00 php-fpm: master process (/etc/php-fpm.conf)
apache 3730 3729 0 22:55 ? 00:00:00 php-fpm: pool www
apache 3731 3729 0 22:55 ? 00:00:00 php-fpm: pool www
apache 3732 3729 0 22:55 ? 00:00:00 php-fpm: pool www
apache 3733 3729 0 22:55 ? 00:00:00 php-fpm: pool www
apache 3734 3729 0 22:55 ? 00:00:00 php-fpm: pool www
root 3748 2207 0 22:56 pts/1 00:00:00 grep --color=auto php
php用户与nginx统一: 统一为nginx
- 统一nginx与php用户,需要修改php配置文件
sh
vim /etc/php-fpm.d/www.conf
egrep -n '^user|^group' /etc/php-fpm/www.conf
8:user = nginx
10:group = nginx
#修改完重启php
systemctl restart php-fpm
- nginx与php配合
sh
[root@web01 kodexp]# vim /etc/nginx/conf.d/kodexp.liux.cn.conf
server{
listen 80;
server_name kodexp.liux.cn;
error_log /var/log/nginx/kodexp-error.log notice;
access_log /var/log/nginx/kodexp-access.log main;
root /app/code/kodexp;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /app/code/kodexp/$fastcgi_script_name;
fastcgi_param SCIRPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
- 测试ngx是否能够处理静态资源
sh
echo kodexp.liux.cn web01 >/app/code/kodexp/liux.html
- 测试ngx能否把动态交给php,php能否处理动态资源
sh
[root@web01 kodexp]# vim info.php
<?php
phpinfo();
?>

03 部署代码
sh
wget https://static.kodcloud.com/update/download/kodexplorer4.50.zip
wget https://static.kodcloud.com/update/download/kodexplorer4.49.zip
ll -h kodexplorer4.49.zip
unzip -t kodexplorer4.49.zip #查看压缩包有没有包含kodexplorer目录
unzip kodexplorer4.49.zip -d /app/code/kodexp/
chown -R nginx.nginx /app/code/kodexp/
11.同台网站架构-LNMP项目部署
LNMP是一套技术的组合,L=Linux、N=Nginx、M=MySQL、P~=PHP
11.1 wordpress博客项目部署
01 配置数据库
- db01数据库服务器, 10.0.0.51/172.16.1.51
- mariadb
sh
#mariadb-server 服务端
#mariadb 客户端
yum -y install mariadb-server
#启动
systemctl enable mariadb
systemctl start mariadb
#检查服务与端口
ss -lntup |grep mysql
ps -ef |grep mysql

- 数据库安全配置(SQL语句实现,现在他通过脚本命令实现)
sh
mysql_secure_installation
用于设置root密码,清理用户和清理临时库.
Enter current password for root (enter for none):回车
Set root password? [Y/n] Y设置密码
New password: 输入密码
Re-enter new password: 再次输入
Password updated successfully!
Reloading privilege tables...
... Success!
Remove anonymous users? [Y/n] Y 删除数据库中的匿名用户(没有用户名的用户,容易导致安全问题)
Disallow root login remotely? [Y/n] Y 是否禁止root远程登录
Remove test database and access to it? [Y/n] Y 是否删除test测试用的数据库
Reload privilege tables now? [Y/n] Y 是否更新权限信息表
Linux系统的root与数据库的root
2个独立的用户.
Linux的root用户用于进入和管理整个Linux系统.
数据库的root用户仅仅用于管理MySQL数据库.
- 进入数据库内部
sh
[root@db01 ~]# mysql -uroot -p1
#创建数据库
create database liux;
#创建用户(会用,会改) 未来通过用户管理数据库.
grant all on liux.* to 'liux'@'localhost' identified by '1';
grant 所有权限 on 数据库.* to '用户名'@'白名单'
数据库白名单说明:
白名单表示用户可以从哪里进行登录与使用数据库.
一般localhost表示只能在数据库本地使用.
可以通过172.16.1.% 进行授权局域网访问. 其他局域网机器可以访问数据库.
只给个%表示所有人可以访问(不安全). %不包含localhost.
- 删除(极其危险)
sh
#删除数据库
drop database liux;
#删除用户
drop user 'liux'@'localhost' ;
- 创建博客用户名和密码
sh
create database wordpress;
grant all on wordpress.* to 'wordpress'@'localhost' identified by '1';
grant all on wordpress.* to 'wordpress'@'172.16.1.%' identified by '1';
#连接测试
mysql -uwordpress -p1 -h 172.16.1.51
02 php
sh
ss -lntup |grep php-fpm
ps -ef |grep php
03 ngx
- 配置文件
- 站点目录
sh
server {
listen 80;
server_name wordpress.liux.cn;
root /app/code/wordpress;
error_log /var/log/nginx/wordpress-error.log notice;
access_log /var/log/nginx/wordpress-access.log main;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
04 调试
-
测试ngx静态页面
-
测试ngx+php动态
-
测试php+mysql
sh
vim mysqli.php
<?php
//数据库地址
$db_host='172.16.1.51';
//数据库用户名
$db_user='wordpress';
$db_pass='1';
$link_id=mysqli_connect($db_host,$db_user,$db_pass);
if($link_id){
echo "mysql successful by liux";
}else{
echo "connection failed!\n";
}
?>

05 部署代码
sh
wget https://cn.wordpress.org/latest-zh_CN.tar.gz
tar -tf latest-zh_CN.tar.gz #查看压缩包
tar -xf latest-zh_CN.tar.gz #解压
mv wordpress/* /app/code/wordpress/
chown -R nginx.nginx /app/code/wordpress/

12.LNMP架构搭建全流程
1.安装nginx(web01)、php(web01)、mysql(51)
sh
第一步: 安装Nginx
配置官网YUM仓库:
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
第二步: 创建虚拟用户
[root@web01 ~]# groupadd -g666 www
[root@web01 ~]# useradd -u666 -g666 -M -s /sbin/nologin www
第三步: 配置Nginx启动用户为www
[root@web01 ~]# head -4 /etc/nginx/nginx.conf
user www;
worker_processes auto;
第四步: 启动Nginx加入开机自动运行
[root@web01 ~]# systemctl start nginx
[root@web01 ~]# systemctl enable nginx
安装PHP服务
第一步: 配置PHP仓库
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
第二步: 安装PHP服务
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 --nogpgcheck
注意: 如果网络慢可以通过本地rpm方式安装(需要上传rpm包)
第三步: 修改php的启动用户为www
[root@web01 ~]# head -10 /etc/php-fpm.d/www.conf
user = www
; RPM: Keep a group allowed to write in log dir.
group = www
第四步: 启动PHP 加入开机自动运行
[root@web01 ~]# systemctl start php-fpm
[root@web01 ~]# systemctl enable php-fpm
第五步: 查看PHP默认端口号9000
[root@web01 ~]# netstat -tnulp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 6951/php-fpm: maste
51
安装数据库mariadb-server
第一步: 安装服务
[root@web01 ~]# yum -y install mariadb-server
第二步: 启动数据库
[root@web01 ~]# systemctl start mariadb
[root@web01 ~]# systemctl enable mariadb
[root@web01 ~]# netstat -tnulp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 6951/php-fpm: maste
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 7273/mysqld
第三步: 配置登录密码 默认用户root
[root@web01 ~]# mysqladmin password 'lzy123.com'
测试登录:
[root@web01 ~]# mysql -uroot -p'lzy123.com'
MariaDB [(none)]>
MariaDB [(none)]> show databases; # 查看当前有哪些库
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
MariaDB [(none)]>
MariaDB [(none)]> create database hehe; # 创建hehe库
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> drop database hehe; # 删除hehe库
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> quit # 退出
2.Nginx连接PHP-MySQL
sh
[root@web01 conf.d]# cat php.conf
server {
listen 80;
server_name php.liux.com;
location / {
root /code;
index index.php index.html;
}
location ~ \.php$ {
root /code;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@web01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web01 conf.d]# systemctl restart nginx
测试连接mysql:
cat /code/mysql.php
[root@web01 conf.d]# cat /code/mysql.php
<?php
$servername = "localhost";
$username = "root";
$password = "lzy123.com";
// 创建连接
$conn = mysqli_connect($servername, $username, $password);
// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "小哥哥,php可以连接MySQL...";
?>
3.部署wordpress服务
sh
第一步: 创建nginx server
[root@web01 conf.d]# cat blog.conf
server {
listen 80;
server_name blog.liux.com;
location / {
root /code/wordpress;
index index.php index.html;
}
location ~ \.php$ {
root /code/blog/wordpress;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@web01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web01 conf.d]# systemctl restart nginx
创建blog目录
[root@web01 conf.d]# mkdir /code/blog
第二步: 下载wordpress代码到/code/blog中
wordpress官网地址: https://cn.wordpress.org/download/
[root@web01 conf.d]# cd /code/blog/
[root@web01 blog]# wget https://cn.wordpress.org/latest-zh_CN.tar.gz
第三步: 解压代码
[root@web01 blog]# tar xf latest-zh_CN.tar.gz
[root@web01 blog]# ll
total 4
drwxr-xr-x 5 1006 1006 4096 Mar 30 03:02 wordpress
第四步: 访问blog.oldboy.com(windows做hosts解析)
第五步: 创建数据库
[root@web01 wordpress]# mysql -uroot -plzy123.com -e "create database wordpress"
[root@web01 wordpress]# mysql -uroot -plzy123.com -e "show databases"
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| wordpress |
+--------------------+
第六步: 修改目录权限
[root@web01 wordpress]# chown -R www.www /code/blog/wordpress/
[root@web01 wordpress]# ll -d /code/blog/wordpress/
drwxr-xr-x 5 www www 4096 Mar 30 03:02 /code/blog/wordpress/
4.部署知乎服务
sh
1.配置nginx server
[root@web01 conf.d]# cat zh.conf
server {
listen 80;
server_name zh.liux.com;
root /code/zh;
index index.php index.html;
location ~ \.php$ {
root /code/zh;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@web01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web01 conf.d]# systemctl restart nginx
第二步: 创建目录并下载代码
[root@web01 conf.d]# mkdir /code/zh
[root@web01 conf.d]# cd /code/zh
将wecenter上传到代码目录解压
[root@web01 zh]# unzip WeCenter_V3.6.2.zip
修改权限:
[root@web01 zh]# ll -d /code/zh
drwxr-xr-x 14 root root 4096 Apr 4 12:05 /code/zh
[root@web01 zh]# chown -R www.www /code/zh
[root@web01 zh]# ll -d /code/zh
drwxr-xr-x 14 www www 4096 Apr 4 12:05 /code/zh
第三步: 浏览器访问zh.liux.com(hosts解析)
第四步: 创建zh库
[root@web01 zh]# mysql -uroot -plzy123.com -e "create database zh;"
[root@web01 zh]# mysql -uroot -plzy123.com -e "show databases"
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| wordpress |
| zh |
5.拆分静态数据到NFS
sh
1.10.0.0.31安装NFS服务
[root@nfs ~]# yum -y install nfs-utils
2.创建匿名压缩用户www
[root@nfs ~]# groupadd -g666 www
[root@nfs ~]# useradd -u666 -g666 -M -s /sbin/nologin www
3.修改配置文件
[root@nfs ~]# cat /etc/exports
/data/wordpress 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
/data/zh 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
4.创建必要的数据文件
[root@nfs ~]# mkdir -p /data/wordpress
[root@nfs ~]# mkdir -p /data/zh
[root@nfs ~]# chown www.www /data/*
[root@nfs ~]# ll /data/
total 0
drwxr-xr-x 2 www www 6 Apr 6 10:03 wordpress
drwxr-xr-x 2 www www 6 Apr 6 10:03 zh
5.启动NFS
[root@nfs ~]# systemctl start nfs
[root@nfs ~]# systemctl enable nfs
6.查找wordpress上传图片的目录位置
右键复制图片链接地址: 找到上传目录uploads
http://blog.oldboy.com/wp-content/uploads/2023/04/1.jpg
1)将2023目录拷贝到31的/data/wordpress/
[root@web01 ~]# scp -r /code/blog/wordpress/wp-content/uploads/* 172.16.1.
31:/data/wordpress/
NFS重新授权下下面的目录权限
[root@nfs ~]# chown -R www.www /data/wordpress/
[root@nfs ~]# ll /data/wordpress/
total 0
drwxr-xr-x 3 www www 16 Apr 6 10:11 2023
2)将31/data/wordpress挂载到uploads目录
WEB01:
一.安装nfs-utils
[root@web01 ~]# yum -y install nfs-utils
二.查看共享的目录
[root@web01 ~]# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data/zh 172.16.1.0/24
/data/wordpress 172.16.1.0/24
三.挂载NFS共享目录/data/wordpress
[root@web01 ~]# mount -t nfs 172.16.1.31:/data/wordpress /code/blog/wordpress/wp-content/uploads/
[root@web01 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 476M 0 476M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 14M 473M 3% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/sda3 19G 2.4G 17G 13% /
/dev/sda1 197M 110M 88M 56% /boot
tmpfs 98M 0 98M 0% /run/user/0
172.16.1.31:/data/wordpress 19G 2.0G 17G 11% /code/blog/wordpress/wp-content/uploads
6.快速扩展一台web02服务器
sh
1.安装Nginx
[root@web02 ~]# scp 172.16.1.7:/etc/yum.repos.d/nginx.repo /etc/yum.repos.d/
[root@web02 ~]# yum -y install nginx
2.安装PHP
批量删除PHP软件:
[root@web02 ~]# rpm -qa|grep php|xargs yum -y remove
安装PHP软件
[root@web02 ~]# tar xf php71.tar.gz
安装:
[root@web02 ~]# yum -y localinstall *.rpm
3.安装nfs-utils
[root@web02 ~]# yum -y install nfs-utils
4.创建虚拟用户www
[root@web02 ~]# groupadd -g666 www
[root@web02 ~]# useradd -u666 -g666 -M -s /sbin/nologin www
5.同步服务的配置文件到web02
同步Nginx配置:
[root@web02 ~]# rsync -avz --delete 172.16.1.7:/etc/nginx/ /etc/nginx/
同步PHP配置:
[root@web02 ~]# rsync -avz --delete 172.16.1.7:/etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf
6.同步代码文件到web02
打包code然后拷贝到web02 进行解压到/目录
.....
[root@web02 ~]# tar xf code.tar.gz -C /
[root@web02 ~]# ll /code/
total 4
drwxr-xr-x 3 root root 23 Apr 4 11:27 blog
drwxr-xr-x 14 www www 4096 Apr 4 12:05 zh
[root@web02 ~]# ll /code/blog/
total 4
drwxr-xr-x 5 www www 4096 Apr 6 09:20 wordpress
启动服务:
[root@web02 ~]# systemctl start nginx php-fpm
[root@web02 ~]# systemctl enable nginx php-fpm
挂载NFS到本地上传目录
[root@web02 ~]# mount -t nfs 172.16.1.31:/data/wordpress /code/blog/wordpress/wp-content/uploads/
[root@web02 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 476M 0 476M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.6M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/sda3 19G 2.3G 17G 12% /
/dev/sda1 197M 110M 88M 56% /boot
tmpfs 98M 0 98M 0% /run/user/0
172.16.1.31:/data/wordpress 19G 2.0G 17G 11% /code/blog/wordpress/wp-content/uploads
13.网站自动化部署全流程
12.1 整个流程
(https://www.processon.com/view/link/625cbb740e3e74074ac09405)
| 流程 | 说明 |
|---|---|
| 规划与分组 | 列表,分组,主机名 |
| 基础优化与配置 | 密钥认证,常用软件,定时任务 |
| 书写每个服务的剧本 | 根据服务使用流程,书写剧本。(优先部署不依赖其他服务的服务) |
| 客户端 | 调用了哪些服务端 |
12.2 分组
| 角色 | 主机名 | 外网ip | 内网ip |
|---|---|---|---|
| web服务器 | web02 | 10.0.0.8 | 172.16.1.8 |
| 数据库服务器 | db02 | 10.0.0.52 | 172.16.1.52 |
| 备份服务器 | backup02 | 10.0.0.42 | 172.16.1.42 |
| 存储服务器 | nfs02 | 10.0.0.32 | 172.16.1.32 |
| 批量管理服务器 | m02 | 10.0.0.62 | 172.16.1.62 |
使用虚拟机模拟环境:
- 添加普通用户,设置sudo权限 NOPASSWD: ALL
- 修改ssh端口号,禁止root远程登录
12.3 环境配置
01 在管理主机m02上面创建密钥并分发
sh
#安装密码提供工具
yum -y install sshpass
#编写脚本密钥生成和分发脚本
[root@m02 ~]# vim /server/scripts/fenfa.sh
#!/bin/bash
#author:liux
#desc:自动话创建密钥与分发密钥
#0.变量
ips="8 32 42 52"
#1.创建密钥对(未来可以加入判断)
echo "创建密钥对"
ssh-keygen -f /root/.ssh/id_rsa -P ''
#2.分发公钥
echo "分发公钥"
for ip in $ips
do
sshpass -p12366 ssh-copy-id -i /root/.ssh/id_rsa.pub -oStrictHostKeyChecking=no 10.0.0.$ip
done
#3.检查
echo "检查密钥认证"
for ip in $ips
do
ssh 10.0.0.$ip hostname -I
done
02 安装ansible和优化配置文件
sh
yum -y install ansible
#1. 添加普通用户,设置sudo权限 NOPASSWD: ALL
#添加普通用户
ansible all -m user -a 'name=ans shell=/bin/bash home=/home/ans state=present'
#设置密码
ansible all -m shell -a 'echo 12366 |passwd --stdin ans'
#远程主机
ansible all -m shell -a 'echo "ans ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers'
#2. 禁止root远程登录
ansible all -a "sed -i.bak 's@#PermitRootLogin yes@PermitRootLogin no@g' /etc/ssh/sshd_config"
ansible all -a "systemctl restart sshd"
#修改配置文件
[root@m02 ~]# vim /etc/ansible/ansible.cfg
[root@m02 ~]# egrep -v '^$|#' /etc/ansible/ansible.cfg
[defaults]
forks = 5
sudo_user = ans
remote_user = ans #被管理端使用的用户,不指定默认是当前用户/root
remote_port = 22
host_key_checking = False
log_path = /var/log/ansible.log
[inventory]
[privilege_escalation]
become=True
become_method=sudo
become_user=root
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
注意:如果修改之后连接不上,需要重新分发一下密钥
03 服务剧本-存储nfs
- 存储nfs
- 服务端: nfs02机器上,部署,配置,启动/重启 /wp-uploads/ www
- 客户端: web服务端上,部署,挂载 /app/code/blog/wp-content/uploads/ www
- nfs 服务端
sh
#服务端: nfs02机器上,部署,配置,启动/重启 /wp-uploads/ www
#/server/scripts/roles
[root@m02 roles]# vim nfs-server/tasks/main.yml
- name: 01 部署
yum:
name:
- rpcbind
- nfs-utils
state: installed
- name: 02 添加用户,指定uid
user:
name: "{{ web_user }}"
uid: "{{ web_user_uid }}"
shell: "/sbin/nologin"
create_home: false
state: present
- name: 02 准备共享目录
file:
path: "{{ nfs_wp_dir }}"
owner: "{{ web_user}}"
group: "{{ web_user}}"
state: directory
- name: 03 配置 加入触发器
template:
src: exports.j2
dest: /etc/exports
backup: yes
notify:
- restart nfs server
- name: 04 启动
systemd:
name: "{{ item }}"
enabled: yes
state: started
loop:
- rpcbind
- nfs
sh
#触发器
[root@m02 roles]# vim nfs-server/handlers/main.yml
- name: restart nfs server
systemd:
name: nfs
state: reloaded
sh
#变量
[root@m02 roles]# vim group_vars/all/main.yml
#common vars
web_user: "www"
web_user_uid: 1999
lan_net: "172.16.1.0/24"
#nfs_vars
nfs_wp_dir: "/wp-uploads/"
#web_vars
web_wp_upload_dir: "/app/code/wordpress/wp-content/uploads"
#rsync_vars
rsync_user: "rsync"
rsync_server: "backup02"
#db_vars
db_host: "db02"
db_user: "wordpress"
db_name: "wordpress"
db_pass: "12366"
sh
#nfs配置
[root@m02 roles]# vim nfs-server/templates/exports.j2
{{ nfs_wp_dir }} 172.16.1.0/24(rw,all_squash,anonuid={{ web_user_uid }},anongid={{ web_user_uid}})
sh
#top
[root@m02 roles]# vim top.yml
[root@m02 roles]# vim top.yml
- hosts: nfs
gather_facts: false
roles:
- role: nfs-server
- hosts: web
gather_facts: false
roles:
- role: nfs-client
- hosts: backup
gather_facts: false
roles:
- role: rsync-server
- hosts: all
gather_facts: false
roles:
- role: rsync-client
- hosts: db
roles:
- role: db
- hosts: web
roles:
- role: web
- role: code-wordpress
测试
sh
ansible-playbook -i hosts top.yml

- nfs客户端
sh
[root@m02 roles]# vim nfs-client/tasks/main.yml
- name: 01. 安装nfs
yum:
name:
- nfs-utils
state: installed
- name: 02 添加用户,指定uid
user:
name: "{{ web_user }}"
uid: "{{ web_user_uid }}"
shell: "/sbin/nologin"
create_home: false
state: present
- name: 02. 创建挂载点
file:
path: "{{ web_wp_upload_dir }}"
owner: "{{ web_user }}"
group: "{{web_user }}"
state: directory
- name: 03. 挂载
mount:
src: "nfs02:{{ nfs_wp_dir }}"
path: "{{ web_wp_upload_dir }}"
fstype: nfs
state: mounted
测试:
sh
ansible-playbook -i hosts top.yml

04 服务剧本-rsync
- 服务端: backup,配置文件,用户,目录,重启(加入触发器)
sh
[root@m02 roles]# vim rsync-server/tasks/main.yml
- name: 01. 分发配置文件
template:
src: rsyncd.conf.j2
dest: /etc/rsyncd.conf
backup: yes
- name: 02. 用户
user:
name: "{{ rsync_user }}"
shell: "/sbin/nologin"
create_home: false
state: present
- name: 03. 目录
file:
path: "{{ item }}"
owner: "{{rsync_user}}"
group: "{{rsync_user}}"
state: directory
loop:
- /backup
- /nfsbackup
- name: 04. 密码文件
lineinfile:
path: /etc/rsync.password
create: true
mode: 0600
line: "rsync_backup:12366"
state: present
- name: 05. 重启服务
systemd:
name: rsyncd
state: restarted
rsyncd.conf.j2 配置
sh
[root@m02 roles]# vim rsync-server/templates/rsyncd.conf.j2
#created by liux
##rsyncd.conf start##
fake super=yes
uid=rsync
gid=rsync
use chroot=no
max connections=2000
timeout=600
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsync.lock
log file=/var/log/rsyncd.log
ignore errors
read only=false
list=false
hosts allow={{lan_net}}
#hosts deny=0.0.0.0/32
auth users=rsync_backup
secrets file=/etc/rsync.password
#####################################
[backup]
comment=backup by liux
path=/backup/
[nfsbackup]
comment = nfs实时备份
path = /nfsbackup
######################
#{% for name in ["backup","nfsbackup"] %}
#[{{name}}]
#comment = {{name}} 的备份
#path = /{{name}}
#{% endfor %}
测试:
sh
ansible-playbook -i hosts top.yml
#同步文件到backup02看是否成功
rsync -avz /etc/hostname rsync_backup@backup02::backup
- 客户端: all,密码文件,脚本,定时任务
sh
[root@m02 roles]# vim rsync-client/tasks/main.yml
- name: 01. 密码文件
lineinfile:
path: /etc/client.rsync
create: true
line: 12366
mode: 0600
- name: 02. 创建脚本目录
file:
path: /server/scripts
state: directory
- name: 02. 分发脚本
template:
src: bak_conf.sh.j2
dest: /server/scripts/bak_conf.sh
- name: 03. 定时任务
cron:
name: "backup everyday by liux"
minute: 00
hour: 00
job: "sh /server/scripts/bak_conf.sh &>/dev/null"
state: present
rsyncd.conf.j2 配置文件
sh
[root@m02 roles]# vim rsync-server/templates/rsyncd.conf.j2
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsync.lock
log file=/var/log/rsyncd.log
ignore errors
read only=false
list=false
hosts allow={{lan_net}}
#hosts deny=0.0.0.0/32
auth users=rsync_backup
secrets file=/etc/rsync.password
#####################################
[backup]
comment=backup by liux
path=/backup/
[nfsbackup]
comment = nfs实时备份
path = /nfsbackup
######################
#{% for name in ["backup","nfsbackup"] %}
#[{{name}}]
#comment = {{name}} 的备份
#path = /{{name}}
#{% endfor %}
测试
sh
#运行脚本
ansible-playbook -i hosts top.yml
#在客户端查看是时候有定时任务
crontab -l
#在备份服务器上查看是否有备份
ll /backup/


05 服务剧本-数据库
sh
[root@m02 roles]# vim db/tasks/main.yml
[root@m02 roles]# cat db/tasks/main.yml
- name: 01. 安装软件
yum:
name:
- mariadb
- mariadb-server
- MySQL-python
- name: 02. 启动服务
systemd:
name: mariadb
enabled: true
state: started
- name: 03. 删除空用户
mysql_user:
name: ''
host: "{{ item }}"
state: absent
loop:
- "localhost"
- "{{ansible_hostname}}"
ignore_errors: true
- name: 04. 设置root密码
mysql_user:
user: root
host: "localhost"
password: "12366"
ignore_errors: true
- name: 05. 添加数据库
mysql_db:
name: wordpress
login_user: root
login_password: "12366"
- name: 06. 添加用户
mysql_user:
login_user: root
login_password: "12366"
name: wordpress
host: '172.16.1.%'
password: '12366'
priv: 'wordpress.*:ALL'
06 服务剧本-php+nginx
- 部署ngx
- 部署php
- 分发配置文件-ngx
- 分发配置文件-php
- 启动服务
剧本主配置文件 web/tasks/main.yml
sh
#php+nginx
[root@m02 roles]# vim web/tasks/main.yml
- name: 01. 配置ngx源
copy:
src: nginx.repo
dest: /etc/yum.repos.d/nginx.repo
- name: 02. 安装ngx
yum:
name: nginx
state: installed
- name: 03. 分发php安装包
unarchive:
src: php.zip
dest: /tmp/
- name: 04. 安装软件包
shell: yum localinstall -y /tmp/*.rpm
- name: 05. 分发ngx、php配置文件(触发器)
template:
src: "{{ item.s }}"
dest: "{{ item.d }}"
loop:
- {s: "nginx.conf.j2",d: "/etc/nginx/nginx.conf"}
- {s: "www.conf.j2",d: "/etc/php-fpm.d/www.conf"}
- name: 05. 分发ngx、php配置文件
copy:
src: "{{ item }}"
dest: /etc/nginx/conf.d/
loop:
- default.conf
- wordpress.liux.cn.conf
- name: 06. 启动
systemd:
name: "{{ item }}"
enabled: true
state: restarted
loop:
- php-fpm
- nginx
- 其他配置文件
sh
[root@m02 roles]# cat web/files/nginx.repo
[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
[root@m02 roles]# cat web/files/default.conf
server {
listen 80 default_server;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
[root@m02 roles]# cat web/files/wordpress.liux.cn.conf
server {
listen 80;
server_name wordpress.liux.cn;
root /app/code/wordpress;
error_log /var/log/nginx/wordpress-error.log notice;
access_log /var/log/nginx/wordpress-access.log main;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@m02 roles]# cat web/templates/nginx.conf.j2
user {{web_user}};
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
[root@m02 roles]# cat web/templates/www.conf.j2
[www]
user = {{web_user}}
group = {{web_user}}
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
07 部署代码
- 分发代码
- 分发代码里面的数据库配置文件
sh
#部署代码
[root@m02 roles]# vim code-wordpress/tasks/main.yml
- name: 01. 分发压缩包
unarchive:
src: wordpress.tar.gz
dest: /app/code/wordpress
owner: "{{ web_user }}"
group: "{{ web_user }}"
- name: 02. 分发数据库连接文件
template:
src: wp-config.php.j2
dest: /app/code/wordpress/wp-config.php
- 数据库配置文件
sh
[root@m02 templates]# cat wp-config.php.j2
<?php
define( 'DB_NAME', '{{db_name}}' );
/** Database username */
define( 'DB_USER', '{{db_user}}' );
/** Database password */
define( 'DB_PASSWORD', '{{db_pass}}' );
/** Database hostname */
define( 'DB_HOST', '{{db_host}}' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
define( 'AUTH_KEY', 'l]w]CBdnMUU{K1*Q)HPE``NaKbeZ~O$Jn$>W3p_TR!<3*j4Saj,o+sZW<*,CK(jC' );
define( 'SECURE_AUTH_KEY', 'sB~B{/YgrGHgv;*+_RK<;Eu^lK-2SD~SNtmpe9/uCrZPeDn?o15CF7+9!9VIC*eh' );
define( 'LOGGED_IN_KEY', '.jc+E()h@{`:k(d][$!NtO[S]-(%#gu*a%+:t286Z]Tb<vq;&r]MSUGulW)xQ@*B' );
define( 'NONCE_KEY', 'vKB]lX+m7xaz2bP>BI@qi5_w#STB]uzf{00H$>*79svsmL`jb:6fRhxst~z6,kKg' );
define( 'AUTH_SALT', '5,LSYLPL_ &7zPQ,V;BYazdFCkbgY{_|<Fs$eB:6.m6T-]0VM9B[GFM3Yx~S9qN[' );
define( 'SECURE_AUTH_SALT', 'yPQR|-:}{Q=V,YAICC:/A@Bz}_ju`YHRbGL2=E2 dB~/1wzH!H|ILn;b( /iGdtL' );
define( 'LOGGED_IN_SALT', 'BBX0RXuQaR2o=-/6niN[Lmv<o`GWA~h$xam{n93(KoP,$Z^Z|:Esn?#bgf*mB7Ot' );
define( 'NONCE_SALT', 'JB!}yHMfgc~+^KmR$C8<<cp#SQYu<IyuT_wPH*.`JcO%>9lVuP<AjjN~zPS^xX#c' );
$table_prefix = 'wp_';
define( 'WP_DEBUG', false );
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';
- 测试
sh
#运行脚本
ansible-playbook -i hosts top.yml
四、web集群-NGX-代理与负载
- proxy代理模块 和upstream负载均衡模块
1.代理
1.1 代理概述
- 代理:外卖/中介/中间商。用户无法直接做某些事,通过中介进行处理,这个中介就是代理。
1.2代理分类
| 代理方向 | 方向 | 应用 |
|---|---|---|
| 正向代理 | 用户(服务器)-->代理-->(外部)某网站 | 服务器通过代理实现共享上网/访问某个网站 |
| 反向代理 | 用户(app/浏览器)-->代理-->网站服务器(web) | 给网站设置统一入口。网站集群可以使用(负载均衡)功能 |
1.3.代理-环境
01 环境概述
| 角色 | ip | 主机名 |
|---|---|---|
| 代理 | 10.0.0.5/172.16.1.5 | lb01 |
| web | 10.0.0.7/172.16.1.7 | web01 |
建议开启db01和nfs01
- 配置ngx yum源并安装、检查、开启
sh
scp nginx.repo 172.16.1.5:/etc/yum.repos.d
yum -y install nginx
rpm -qa nginx
systemctl enable nginx
systemctl start nginx
ngx启动后默认是web服务器
需要使用对应的模块:proxy(代理),upstream(负载均衡模块)
02 环境准备
| 域名 | 站点目录 | 首页文件 |
|---|---|---|
| proxy.liux.cn | /app/code/proxy | index.html |
a) web服务器
sh
#注释所有ngx子配置文件
cd /etc/nginx/conf.d/
gzip *.conf
#配置代理使用的子配置文件
[root@web01 conf.d]# cat proxy.liux.cn.conf
server {
listen 80;
server_name proxy.liux.cn;
root /app/code/proxy;
error_log /var/log/nginx/proxy_error.log notice;
access_log /var/log/nginx/proxy_access.log main;
location / {
index index.html;
}
}
#proxy站点目录
mkdir -p /app/code/proxy
echo proxy.liux.cn web01 >/app/code/proxy/index.html
#检查语法、重启ngx、测试
nginx -t
systemctl reload nginx
curl -H Host:proxy.liux.cn 10.0.0.7
b) lb01代理服务器
- 通过ngx的proxy模块中的proxy_pass指令实现代理功能
不需要配置站点目录
仅仅需要配置转发proxy_pass
sh
[root@lb01 ~]# cd /etc/nginx/conf.d/
[root@lb01 conf.d]# vim /etc/nginx/conf.d/proxy.liux.cn.conf
#lb 代理服务器的ngx配置
server {
listen 80;
server_name proxy.liux.cn;
error_log /var/log/nginx/proxy_error.log notice;
access_log /var/log/nginx/proxy_access.log main;
location / {
proxy_pass http://10.0.0.7:80 ;
}
}
nginx -t
systemctl reload nginx
#命令行测试访问的是web01服务器的html页面
curl -H Host:proxy.liux.cn http://10.0.0.5
c) 测试
- 命令行测试
sh
[root@lb01 conf.d]# curl -H Host:proxy.liux.cn http://10.0.0.5
proxy.liux.cn web01
- 浏览器测试 hosts配置 10.0.0.5 proxy.liux.cn

d)web有多个虚拟主机故障案例
解压上面注释掉的conf
root@web01 conf.d\]# gzip -d \*.gz
- 故障现象:
- web服务器有多个虚拟主机的时候,通过代理访问web出现异常.访问的不是我们想要的虚拟主机.
- 原因:
- 代理向后端web节点发出请求的时候,请求头中的Host,被修改成ip地址形式了。
- 相当于代理通过ip地址访问web服务器,只显示默认虚拟主机.
- 解决:
- 方向:修改代理ՎՎʖweb的请求头。
- proxy_set_header Host $http_host;
sh
#lb 代理服务器的ngx配置
server {
listen 80;
server_name proxy.liux.cn;
error_log /var/log/nginx/proxy_error.log notice;
access_log /var/log/nginx/proxy_access.log main;
location / {
proxy_pass http://10.0.0.7:80 ;
#代理 --> 节点发出请求,修改请求头
proxy_set_header Host $http_host;
}
}
e)web记录用户真实ip地址
- **KaTeX parse error: Double subscript at position 12: proxy_add_x_̲forwarded_for**...remote_addr 客户ip地址.
- 多层代理的时候,会记录每个代理的ip地址.相当于记录了多个$remote_addr
sh
[root@lb01 conf.d]# vim proxy.liux.cn.conf
#lb 代理服务器的ngx配置
server {
listen 80;
server_name proxy.liux.cn;
error_log /var/log/nginx/proxy_error.log notice;
access_log /var/log/nginx/proxy_access.log main;
location / {
proxy_pass http://10.0.0.7:80 ;
#代理 --> 节点发出请求,修改请求头
proxy_set_header Host $http_host;
#proxy_set_header X-Forwarded-For 取出客户端ip的地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
XFF头的内容需要通过$http_x_forwarded_for变量获取并写入到日志中.
root@web01 conf.d\]# tail -f /var/log/nginx/proxy_access.log
2.负载均衡
2.1 负载均衡概述
-
用户访问网站的时候后端节点只有1台,抗住不了.
-
假设每台web能够抗住10w访问量.
-
需要使用多台web服务器形成web集群,这个集群前面需要1台负载均衡进行调度.
-
优势:可以让网站集群承受更高的访问量.
-
缺点:访问量较小不推荐使用.
2.2 负载均衡选型
| 选型 | 选择 |
|---|---|
| 硬件 | F5,A10 |
| 软件 | Nginx,Tengine,Openresty(内置lua),Haproxy(专业负载),LVS(高性能) |
| 公有云服务 | SLB,CLB... |
2.3 环境
| 角色 | ip | |
|---|---|---|
| lb01 负载均衡 | 10.0.0.5/172.16.1.5 | lb.liux.cn |
| web01 | 10.0.0.7/172.16.1.7 | lb.liux.cn /app/code/lb |
| web02 | 10.0.0.8/172.16.1.8 | lb.liux.cn /app/code/lb |
首页文件内容 lb.liux.cn 主机名
- web服务器 配置 web01和02都需要配置
sh
root@web01 conf.d]# vim lb.liux.cn.conf
server {
listen 80;
server_name lb.liux.cn;
root /app/code/lb;
error_log /var/log/nginx/lb_error.log notice;
access_log /var/log/nginx/lb_access.log main;
location / {
index index.html;
}
}
[root@web01 conf.d]# mkdir -p /app/code/lb
[root@web01 conf.d]# echo lb.liux.cn `hostname` >/app/code/lb/index.html
[root@web01 conf.d]# cat /app/code/lb/index.html
lb.liux.cn web01
- 测试
sh
[root@web02 conf.d]# curl -H Host:lb.liux.cn http://10.0.0.7
lb.liux.cn web01
[root@web02 conf.d]# curl -H Host:lb.liux.cn http://10.0.0.8
lb.liux.cn web02
- 书写负载均衡配置文件
- 通过upstream指令创建分组 lb_pools
- proxy_pass http://lb_pools;
sh
[root@lb01 conf.d]# vim lb.liux.cn.conf
upstream lb_pools {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
server {
listen 80;
server_name lb.liux.cn;
root /app/code/lb;
error_log /var/log/nginx/lb_error.log notice;
access_log /var/log/nginx/lb_access.log main;
location / {
proxy_pass http://lb_pools;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- 命令行测试
sh
[root@lb01 conf.d]# curl -H Host:lb.liux.cn 10.0.0.5
lb.liux.cn web01
[root@lb01 conf.d]# curl -H Host:lb.liux.cn 10.0.0.5
lb.liux.cn web02
3. 总结
- upstream模块,upstream指令实现负载均衡.创建分组/池塘,proxy_pass中使用即可
4 负载均衡 vs 反向代理
- 一般出现在面试中,如果不是一般认为这两个是一致的.
| 内容 | 共同点 | 区别 | 服务 |
|---|---|---|---|
| 负载均衡 | 用户的请求分发到后端节点上 | 用户-->lb-->web lb负载 均衡做的是数据转发,不会产生新的请求。一个请求一个响应 | lvs |
| 反向代理 | 用户的请求分发到后端节点上 | 中间有个中介,用户-->中介-->web 2个请求两个响应 代替用户去找web服务器 | ngx/tegine/openresty/haproxy |
反向代理:代理 替用户进行访问,找到数据后发送给用户。
负载均衡:转发 把用户的请求转发给后端节点。
5.负载均衡模块的选项
- upstream模块 server指令支持的选项
| server后面可以加的选项 | 说明 | 应用场景 |
|---|---|---|
| weight | 权重,根据ngx权重分配请求 | 如果web服务端配置不同,可以给配置好的服务端较高的权重 |
| max_fails | ngx具备一些健康检查功能,指定失败的次数,超过这个次数就认为节点挂了 | 一般情况下可以设置为1-3即可 |
| fail_timeout | 认为节点挂了后间隔多久再次检查健康情况,默认10s | 根据要求设置时间即可,一般30/60s |
| backup | 备胎服务器,其他所有服务器都挂了的时候才启用 | 使用的时候需要考虑雪崩的情况 |
- 在配置中添加 weight=1 max_fails=3 fail_timeout=30s
sh
[root@lb01 conf.d]# vim lb.liux.cn.conf
upstream lb_pools {
server 10.0.0.7:80 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.8:80 weight=1 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name lb.liux.cn;
root /app/code/lb;
error_log /var/log/nginx/lb_error.log notice;
access_log /var/log/nginx/lb_access.log main;
location / {
proxy_pass http://lb_pools;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- 使用命令循环调用测试
sh
[root@lb01 conf.d]# for n in {1..1000} ; do curl -H Host:lb.liux.cn 10.0.0.5;date +%F_%T; sleep 1 ; done
[root@web01 conf.d]# pkill nginx

6.wordpress接入负载均衡
- nfs01挂载
- db数据库、用户
- web01、web02 部署环境ngx+php,测试,部署代码,挂载nfs
- 接入负载
6.1 nfs01存储
sh
[root@nfs01 ~]# vim /etc/exports
[root@nfs01 ~]# tail -1 /etc/exports
/wp-uploads/ 172.16.1.0/24(rw,all_squash)
[root@nfs01 ~]# mkdir -p /wp-uploads
[root@nfs01 ~]# chown -R nfsnobody /wp-uploads/
#重启服务、查看
[root@nfs01 ~]# systemctl reload nfs
[root@nfs01 ~]# showmount -e
Export list for nfs01:
/wp-uploads 172.16.1.0/24
/backup-nfs 172.16.1.0/24
/nfsdata 172.16.1.0/24
/data 172.16.1.0/24
6.2 检查数据库(db)
sh
root@db01 ~]# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| wordpress |
+--------------------+
4 rows in set (0.01 sec)
MariaDB [(none)]> select user,host from mysql.user;
+-----------+------------+
| user | host |
+-----------+------------+
| root | 127.0.0.1 |
| wordpress | 172.16.1.% |
| root | ::1 |
| root | localhost |
| wordpress | localhost |
+-----------+------------+
5 rows in set (0.00 sec)
6.3 web01
- 测试是否可用
- 挂载存储(挂载之前先备份)
sh
mv /app/code/wordpress/wp-content/uploads/* /tmp/
mount -t nfs 172.16.1.31:/wp-uploads/ /app/code/wordpress/wp-content/uploads/
mv /tmp/2023/ /app/code/wordpress/wp-content/uploads/
6.4 web02
sh
#将web01的配置文件和代码拷贝到web02服务器
scp /etc/nginx/nginx.conf web02:/etc/nginx/
scp /etc/nginx/conf.d/wordpress.liux.cn.conf web02:/etc/nginx/conf.d/
scp /etc/php-fpm.d/www.conf web02:/etc/php-fpm.d/
scp -r /app/code/wordpress/ web02:/app/code/
#挂载
mount -t nfs 172.16.1.31:/wp-uploads/ /app/code/wordpress/wp-content/uploads/
6.5 接入负载均衡
sh
#编写负载均衡配置文件
[root@lb01 conf.d]# vim wordpress.liux.cn.conf
upstream wordpress_pools {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
server {
listen 80;
server_name wordpress.liux.cn;
location / {
proxy_pass http://wordpress_pools;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
#检查语法与重启
[root@lb01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb01 conf.d]# systemctl reload nginx
6.6 排错流程
-
浏览器看看错误提示
-
辅助浏览器F12调试功能,网络,状态码
-
命令行进行curl
-
直接请求web,检查web是否OK.
-
如果直接访问lb,有问题,访问web没有问题,lb问题
-
如果直接访问lb,有问题,访问web也有问题,web问题
-
web问题,info.php(ngx+php) mysqli.php(php+数据库),代码
7. 网站的高并发优化之动静分离
-
网站代码分为
- 动态部分(php,java,python,Golang)
- 静态部分(html,css,js,图片,视频)
-
目标:把网站的动态资源和静态资源分来,通过不同服务器进行存放与提供用户访问.
- 动态资源与静态资源分开
- 静态资源只需要运行ngx即可.
- 动态资源ngx+动态语言即可.
-
lb配置文件
sh
upstream blog_default {
server 10.0.0.7:80 weight=1 max_fails=3 fail_timeout=30s;
}
upstream blog_static {
server 10.0.0.8:80 weight=1 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name blog.liux.cn;
error_log /var/log/nginx/blog-error.log notice;
access_log /var/log/nginx/blog-access.log main;
location / {
proxy_pass http://blog_default;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* \.(html|css|js|jpg|jpeg|png|bmp|gif)$ {
proxy_pass http://blog_static;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- web静态-只保留ngx(关闭php服务)
sh
[root@web02 ~]# vim /etc/nginx/conf.d/blog.liux.cn.conf
server {
listen 80;
server_name blog.liux.cn;
root /app/code/blog;
error_log /var/log/nginx/blog-error.log notice;
access_log /var/log/nginx/blog-access.log main;
location / {
index index.html;
}
}
8.会话保持
8.1 概述
- 用户的请求,登录的请求,经过负载均衡后落到后面的web服务器上,登录的状态/信息也会记录在web服务器上,就会导致不同的web服务器上,登录状态不统一,造成用户频繁需要登录.
- 会话: 用户的登录状态,购物车状态
- 目标: 如何实现会话保持/会话共享.
8.2 cookie vs session
- 开发中核心概念,知晓cookie和session含义,大致区别即可
| 技术点 | 共同点 | 区别 | 其他 |
|---|---|---|---|
| cookie | 存放用户的信息、登录信息 | 存放在客户端浏览器 | 服务器给客户端响应,进行设置set-cookie,未来再次访问携带者cookie访问服务端 |
| session | 存放用户的信息、登录信息 | 存放服务端(文件、数据库...) | 浏览器cookie与服务端的session对应 |
8.3会话保持方案
- 存粹cookie
- cookie+session方式+统一存放session服务器(会话保持服务器)
- ip_hash方法(讲解负载均衡轮询算法)
- 通过redis实现phpmyadmin/kodbox会话共享
phpMyAdmin : web页面版本的数据库管理工具. SQL语句. PHP代码
-
流程
-
db: phpmyadmin用户,权限大一些.
-
web: 部署代码,传输到另外一个web上
-
准备redis环境(db01)
-
修改php配置
-
接入负载均衡.访问与测试
-
a)db准备phpmyadmin的用户
sh
grant all on *.* to 'phpmyadmin'@'172.16.1.%' identified by '1';
b)部署代码
sh
#添加配置文件
[root@web01 conf.d]# cp wordpress.liux.cn.conf phpmyadmin.liux.cn.conf
[root@web01 conf.d]# sed -i.bak 's#wordpress#phpmyadmin#g' phpmyadmin.liux.cn.conf
wget --no-check-certificate https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.tar.xz
tar xf phpMyAdmin-5.2.1-all-languages.tar.xz
mv phpMyAdmin-5.2.1-all-languages/* /app/code/phpmyadmin/
chown -R nginx /app/code/phpmyadmin/
#创建数据库配置文件
[root@web01 phpmyadmin]# cp config.sample.inc.php config.inc.php
[root@web01 phpmyadmin]# vim config.inc.php
[root@web01 phpmyadmin]# grep -n host config.inc.php
30:$cfg['Servers'][$i]['host'] = '172.16.1.51';
#修改session文件所有者权限为nginx
[root@web01 phpmyadmin]# grep session /etc/php-fpm.d/www.conf
; (error_log, sessions.save_path, ...).
; Set session path to a directory owned by process user
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
[root@web01 phpmyadmin]# ll -d /var/lib/php/session
drwxrwx--- 2 root apache 6 Oct 1 2020 /var/lib/php/session
[root@web01 phpmyadmin]# chown -R nginx.nginx /var/lib/php/session

- 将web01代码拷贝到web02
sh
#web01拷贝代码
scp -r /app/code/phpmyadmin/ web02:/app/code/
scp /etc/nginx/conf.d/phpmyadmin.liux.cn.conf web02:/etc/nginx/conf.d/
#web02修改session配置权限
chown -R nginx.nginx /var/lib/php/session
c)部署redis服务
sh
yum -y install redis
#172.16.1.51 本地网卡的ip
vim /etc/redis.conf
bind 127.0.0.1 172.16.1.51
#开启自启动和开启,查看端口6379
systemctl enable redis
systemctl start redis
ss -lntup |grep redis
d)接入负载均衡(lb01)
sh
[root@lb01 conf.d]# cat phpmyadmin.liux.cn.conf
upstream phpmyadmin_pools {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
server {
listen 80;
server_name phpmyadmin.liux.cn;
location / {
proxy_pass http://phpmyadmin_pools;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
e)php配置文件指定会话存放位置(web01和web02都需要修改)
通知php指定会话保存位置:redis tcp://172.16.1.51:6379
修改/etc/php-fpm.d/www.conf
sh
#1.修改/etc/php.ini文件
[root@web ~]# vim /etc/php.ini
session.save_handler = redis
session.save_path = "tcp://172.16.1.51:6379"
;session.save_path = "tcp://172.16.1.51:6379?auth=123" #如果redis存在密码,则使用该方式
#2.注释/etc/php-fpm.d/www.conf里面的两条内容,否则session内容会一直写入/var/lib/php/session目录中
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
systemctl restart php-fpm
9.负载均衡-轮询算法(面试题)
负载均衡的调度算法:
rr轮询 按时间顺序逐一分配到不同的后端服务器(默认)
weight 加权轮询,weight值越大,分配到的访问几率越高
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器
url_hash 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器
least_conn 最少链接数,那个机器链接数少就分发
- 决定负载均衡如何把请求分发给后端节点,这种分发的方式就是轮询算法.
| 负载 | 说明 |
|---|---|
| rr轮询 | round robin 轮询,默认的循环访问 |
| wrr | 加权轮询,在轮询的基础上增加权重功能. server中 weight就是加权轮询 |
| ip_hash | ip哈希, 只要客户端ip一样,就会一直访问同一个后端节点 (用户请求与web服务器绑定.) 解决会话保持/会话共享 可能导致负载不均. |
| xxx_hash | url_hash 只要用户访问的url相同/uri相同,就访问相同的web服务器 缓存服务器: 静态资源缓存 |
| least_conn | 最小连接数,lc算法. 也可以配合上权重 weight, wlc权重的最小连接数 |
- ip_hash
sh
upstream lb_pools {
ip_hash;
server 10.0.0.7:80 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.8:80 weight=1 max_fails=3 fail_timeout=30s;
}
-
url_hash
hash $request_uri;
10.对负载均衡进行状态检查
-
负载均衡状态检查模块 upstream check模块,web展示
-
默认ngx没有安装,是一个第三方的模块,需要编译安装ngx添加这个模块即可.生成ngx命令
-
步骤:
- 找一台db01(无ngx即可)
- 编译安装tengine,生成ngx命令,替代lb上ngx的命令即可.
-
下载tengine代码和解压
sh
wget http://tengine.taobao.org/download/tengine-2.3.3.tar.gz
tar xf tengine-2.3.3.tar.gz
- 编译安装
sh
安装依赖
./configure 配置(生成Makefile)
make 编译(根据Makefile进行编译安装生成对应的命令)
make install 创建目录,复制文件
#安装依赖
yum install -y pcre-devel openssl-devel
Nginx负载均衡健康检查
在Nginx官方模块提供的模块中,没有对负载均衡后端节点的健康检查模块,但可以使用第三方模块。
nginx_upstream_check_module来检测后端服务的健康状态。nginx_upstream_check_module 是一个非常实用的 Nginx 第三方模块,它可以为我们提供主动的健康检查功能,有效地提高后端服务器的可用性和稳定性
sh
Nginx编译安装
安装编译命令: yum install -y gcc glibc gcc-c++ pcre-devel openssl-devel patch
第一种情况:
服务器没有安装Nginx的时候可以直接编译安装
1.下载源码包
[root@lb01 conf.d]# nginx -v
nginx version: nginx/1.24.0
[root@lb01 ~]# wget http://nginx.org/download/nginx-1.24.0.tar.gz
解压nginx
[root@lb01 ~]# tar xf nginx-1.24.0.tar.gz
2.配置参数(安装路径 安装模块 参数....)
[root@lb01 ~]# cd nginx-1.24.0/
[root@lb01 nginx-1.24.0]#
./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-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_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 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
3.make
4.make install
--------------------------------------------
第二种情况: 已经安装了nginx服务 在进行编译安装(添加模块)
添加模块编译方法:
1.下载源码包 和上面相同
2.下载模块包 wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip
[root@lb01 ~]# ll -h
total 1.3M
-rw-------. 1 root root 1.5K Feb 22 16:41 anaconda-ks.cfg
-rw-r--r-- 1 root root 173K Apr 7 10:58 master.zip
解压模块:
[root@lb01 ~]# unzip master.zip
[root@lb01 ~]# ll
drwxr-xr-x 6 root root 4096 Nov 6 12:37 nginx_upstream_check_module-master
3.将新的模块配置到nginx模块中
[root@lb01 ~]# cd nginx-1.24.0/
打补丁: 添加新的模块到nginx中
[root@lb01 nginx-1.24.0]# patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch
4.配置参数:
./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-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_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 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
./configure --prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--with-http_ssl_module \
--add-module=/root/nginx_upstream_check_module-master
--prefix 指定nginx 的安装目录
5.编译安装
make && make install
在已有的负载均衡上增加健康检查的功能
[root@lb01 conf.d]# cat proxy_web.conf
upstream webs {
server 172.16.1.7:80 max_fails=2 fail_timeout=10s;
server 172.16.1.8:80 max_fails=2 fail_timeout=10s;
check interval=3000 rise=2 fall=3 timeout=1000 type=tcp;
#interval 检测间隔时间,单位为毫秒
#rise 表示请求2次正常,标记此后端的状态为up
#fall 表示请求3次失败,标记此后端的状态为down
#type 类型为tcp
#timeout 超时时间,单位为毫秒
check_http_send "HEAD /api/tTag/queryTag HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
#check_http_send 定义了发送给后端服务器的检查请求。
#check_http_expect_alive 指定哪些 HTTP 状态码会被认为是"存活"的。
}
server {
listen 80;
server_name blog.liux.com;
location / {
proxy_pass http://webs;
include proxy_params; #请求时携带的参数配置
}
location /upstream_check {
check_status;
}
}
[root@lb01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb01 conf.d]# systemctl restart nginx
访问: blog.liux.com/upstream_check 会监测到两台服务器的健康状态情况,如其中一台down掉,会自动剔除。恢复正常后也会加入
curl http://172.16.130.56/api/tTag/queryTag

11.升级案例
- 平滑升级步骤
- 1️⃣准备好新的nginx命令(已经测试的)
- 2️⃣把当前环境的nginx的命令备份,使用新的替换.
- 3️⃣通过kill命令向当前运行ngx发出信号,准备被替代 USR2 (把当前运行ngx的pid文件改个名使用新的nginx命令启动ngx进程)
- 4️⃣测试调试,关闭旧的ngx的进程即可.(kill即可)
sh
#检查的当前环境
[root@lb01 conf.d]# nginx -V
nginx version: nginx/1.22.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --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-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_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 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
#启动ngx
[root@lb01 /etc/nginx/conf.d]# systemctl start nginx
[root@lb01 /etc/nginx/conf.d]# ps -ef |grep nginx
root 7404 1 0 15:32 ? 00:00:00 nginx:
master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 7405 7404 0 15:32 ? 00:00:00 nginx:
worker process
root 7407 3011 0 15:32 pts/1 00:00:00 grep Վʔ
color=auto nginx
#查看pid
[root@lb01 /etc/nginx/conf.d]# ll /var/run/nginx.pid
-rw-rՎʔrՎʔ 1 root root 5 Sep 7 15:32 /var/run/nginx.pid
[root@lb01 /etc/nginx/conf.d]# ll /var/run/nginx.pid*
-rw-rՎʔrՎʔ 1 root root 5 Sep 7 15:32 /var/run/nginx.pid
[root@lb01 /etc/nginx/conf.d]# cat /var/run/nginx.pid*
7404
#准备升级,备份ngx命令,替代ngx命令
mv /sbin/nginx /sbin/nginx-v1.22.0
mv nginx-tengine-2.3.3 /sbin/nginx
#检查替换后结果
nginx -V
#准备新老交替
[root@lb01 ~]# kill -USR2 `cat /var/run/nginx.pid`
#生成1新的pid文件和重命名一个pid文件
[root@lb01 ~]# ll /var/run/nginx.pid*
-rw-rՎʔrՎʔ 1 root root 5 Sep 7 15:34 /var/run/nginx.pid
-rw-rՎʔrՎʔ 1 root root 5 Sep 7 15:32
/var/run/nginx.pid.oldbin
[root@lb01 ~]# cat /var/run/nginx.pid.oldbin
7404
[root@lb01 ~]# ps -ef |grep nginx
[root@lb01 ~]# kill 7404
[root@lb01 ~]# ps -ef |grep nginx
root 7442 1 0 15:34 ? 00:00:00 nginx:
master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 7443 7442 0 15:34 ? 00:00:00 nginx:
worker process
root 7483 3011 0 15:37 pts/1 00:00:00 grep Վʔ
color=auto nginx
[root@lb01 ~]# ss -lntup |grep 80
tcp LISTEN 0 128 *:80
*:* users:(("nginx",pid=7443,fd=10),("nginx",pid=7442,fd=10))
12.ngx-rewrite功能
12.1 ngx重定向概述
- 重定向:也叫url重定向,也叫url改写
- 网站是http(80)-->https(443) URL重定向
- 根据客户端访问类型进行跳转 www.liux.cn 如果用户使用的移动端则访问m.liux.cn URL重定向
- 新老域名跳转: www.360buy.com --> jd.com
12.2 模块与指令
| 指令 | 说明 |
|---|---|
| return | 实现对url的改写,一般与ngx变量一起使用,返回指定的状态码 |
| rewrite | 实现对url的改写,使用正则匹配uri,进行改写,还有各种标记 |
| set | 创建或修改ngx变量 |
| if | 判断 |
01 return指令
- 格式1:return code URL;返回状态码+新的url地址
- 格式2:return code;返回指定的状态码
- 放哪:server,location,if
sh
#如果用户访问/admin/页面返回403
[root@web01 ~]# cat /etc/nginx/conf.d/rewrite.liux.cn.conf
server {
listen 80;
server_name rewrite.liux.cn;
root /app/code/rewrite;
location / {
index index.html;
}
location /admin/ {
return 403;
}
}
这里书写return 403;所有人禁止访问/admin/页面.
如果你的客户端ip是10.0.0.这种,可以访问.
案例:域名间跳转
sh
server {
listen 80;
server_name rewrite.liux.cn;
return 301 http://www.baidu.com$request_uri;
}
案例:http跳转https
sh
server {
listen 80;
server_name rewrite.liux.cn;
return 302 https://rewrite.liux.cn$request_uri;
}
server {
listen 443 ssl; #ssl;开启https功能
server_name rewrite.liux.cn;
root /app/code/rewrite/;
location / {
index index.html;
}
}
02 set
- 用于自己创建ngx变量
sh
set $liux 666;
ngx变量,进行赋值与进行使用都需要加上$符号.
sh
server {
listen 80;
server_name rewrite.liux.cn;
set $oldboy $http_host$request_uri;
return 200 $oldboy;
}
案例:设置网站是否为维护状态,维护状态返回503,其他正常访问
- 流程:
- 设置标记$flag 默认是0,放在文件中。
- 判断$flag是1,则网站返回503
sh
#编写rewrite.liux.cn.conf
[root@web01 /etc/nginx/conf.d]# vim rewrite.liux.cn.conf
server {
listen 80;
server_name rewrite.liux.cn;
root /app/code/rewrite;
include conf.d/rewrite-status.flag;
if ( $flag = 1 ) {
return 503;
}
location / {
index index.html;
}
}
#编写rewrite-status.flag
[root@web01 /etc/nginx/conf.d]# vim rewrite-status.flag
set $flag 1;
#检查语法,重启ngx
nginx -t
systemctl reload nginx
#测试
[root@web01 /etc/nginx/conf.d]# crul -H Host:rewrite.liux.cn 10.0.0.7
<html>
<head><title>503 Service Temporarily Unavailable</title>
</head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1>
</center>
<hr><center>nginx/1.22.0</center>
</body>
</html>
13.rewrite
- rewrite主要实现url地址重写,以及重定向,就是把传入
web的请求重定向到其他url的过程。
13.1 rewrite指令
- 命令的格式与sed 's###g' 类似,实现替换功能,rewrite替换url内容
- 格式:rewrite 找什么(具体内容/正则/保护分组) 替换成什么(具体内容,后向引用) [标记]; 标记可以省略,默认使用redirect标记(302)
- 放在哪里:server,location,if
- ⚠️rewrite匹配的内容,匹配uri
rewrite:
redirect 302 临时
permanent 301 永久跳转
13.2 应用案例
- 域名跳转
sh
#访问rewrite.liux.cn跳转到百度
server {
listen 80;
server_name rewrite.liux.cn;
#return 301 http://www.baidu.com$request_uri;
#http://rewrite.liux.cn/images/1.img
#http://rewrite.liux.cn
rewrite ^(.*)$ http://www.baidu.com$1 ; #^(.*)$表示 /images/1.img
}
- http -->https
sh
server {
listen 80;
server_name rewrite.liux.cn;
#return 302
https://rewrite.liux.cn$request_uri;
rewrite ^(.*)$ https://rewrite.liux.cn$1 ; #302
}
server {
listen 443 ssl;
server_name rewrite.liux.cn;
root /app/code/rewrite/;
location / {
index index.html;
}
}
13.3 rewrite各种标记
| 标记 | 说明 | 补充 |
|---|---|---|
| redirect | 302 临时 用户访问的时候,收到302提示以及新的位置location(响应头),用户根据新的位置进行访问(让用户重新发出http请求) | 新旧地址都可以用 |
| permanent | 301 永久 用户访问的时候,收到301提示及新的位置location(响应头),用户根据新的位置进行访问 | 旧的地址排名取消,就地址不用了,只用新的网站 |
| break | 用户的请求匹配到break,则终止运行 | |
| last | 用户请求匹配到last标记的rewrite规则后,停止继续运行,ngx重新发出内部请求,请求与location规则进行匹配 | 开启ngx rewrite_log才能看到 |
sh
server {
listen 80;
server_name flag.liux.cn;
root /app/code/flag;
error_log /var/log/nginx/flag-error.log notice;
rewrite_log on; #需要错误日志debug ... notice
location / {
rewrite /1.html /2.html ;
rewrite /2.html /3.html ;
}
location /2.html {
rewrite /2.html /3.html ;
}
location /3.html {
rewrite /3.html /a.html ;
}
}
echo 1.html url >/app/code/flag/1.html
echo 2.html url >/app/code/flag/2.html
echo 3.html url >/app/code/flag/3.html
echo a.html url >/app/code/flag/a.html
echo b.html url >/app/code/flag/b.html
#1.访问/1.html显示a.html内容
[root@web01 /etc/nginx/conf.d]# curl -H Host:flag.liux.cn 10.0.0.7/1.html
a.html url
#2.访问/2.html显示a.html内容
[root@web01 /etc/nginx/conf.d]# curl -H Host:flag.liux.cn 10.0.0.7/2.html
a.html url
#3. 在rewrite /1.html /2.html的时候加上标记break标记.
rewrite /1.html /2.html break; #执行完成rewrite后直接结束.
13.4 四层负载均衡
- 对端口进行负载均衡
| 环境准备 | |
|---|---|
| web01 | nc -kl 9999 |
| web02 | nc -kl 9998 |
| lb01 | 配置4层负载均衡 开放端口12306 |
开启4层负载均衡模块 stream模块
sh
vim /etc/nginx/nginx.conf
stream {
upstream nc_pools {
server 10.0.0.7:9999;
server 10.0.0.8:9998;
}
server {
listen 12306;
proxy_pass nc_pools;
}
}
ss -lntup |grep 12306
web01 web02
sh
nc -kl 9999
nc -kl 9998
测试命令
sh
telnet 10.0.0.5 12306
五、web集群-NGX优化
- 通用优化
sh
[root@nginx ~]# cat nginx.conf
user www; # nginx进程启动用户
worker_processes auto; #与cpu核心一致即可
worker_cpu_affinity auto; # 自动绑定CPU核心
#中等流量Web应用 65536-262144 可应对数千并发
# worker_rlimit_nofile > worker_connections
# 需小于系统file-max值 cat /proc/sys/fs/file-max
worker_rlimit_nofile 100000; # 每个worker可打开文件数
error_log /var/log/nginx/error.log warn; # 错误日志
pid /run/nginx.pid;
events {
worker_connections 10240; # 限制每个进程能处理多少个连接,10240x[cpu核心]
use epoll; # 使用epoll高效网络模型 默认
multi_accept on; # 一次性接受所有新连接
}
http {
include mime.types;
default_type application/octet-stream;
charset utf-8; # 统一使用utf-8字符集
# 定义日志格式
log_format main '$http_x_real_ip | $remote_addr | $remote_user | [$time_iso8601] | "$request" | $status | $body_bytes_sent | $request_time | $upstream_addr | $upstream_status | $upstream_response_time | "$http_referer" | "$http_user_agent" | "$http_x_forwarded_for"';
#定义json日志格式
log_format json_access '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"status":"$status"}';
access_log /var/log/nginx/access.log main; # 访问日志
server_tokens off; # 禁止浏览器显示nginx版本号
client_max_body_size 200m; # 文件上传大小限制调整
# 文件高效传输,静态资源服务器建议打开
sendfile on; #开启高效传输模式
tcp_nopush on; #开启tcp连接的非阻塞模式 ,配合 sendfile 提高网络效率
tcp_nodelay on; # 降低延迟
# 文件实时传输,动态资源服务建议打开,需要打开keepalive
keepalive_timeout 65; #设置http请求连接超时时间
# Gzip 压缩
gzip on;
gzip_disable "MSIE [1-6]\."; #针对IE浏览器不进行压缩
gzip_http_version 1.1;
gzip_comp_level 6; #压缩级别
gzip_buffers 16 8k; #压缩的缓冲区
gzip_min_length 1024; #文件大于1kb才进行压缩
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg;
include /etc/nginx/conf.d/*.conf;
}
-
web服务
-
负载均衡
-
性能优化/安全优化
-
nginx优化总结
-
CPU亲和、worker进程数、调整每个worker进程打开的文件数
-
使用额pool网络模型、调整每个worker进程的最大连接数
-
文件的高效读取sendfile、no铺设
-
文件的传输实时性、nodealy
-
开启tcp长连接,以及长连接超时时间keepalived
-
开启文件传输压缩gzip
-
开启静态文件expires缓存
-
隐藏nginx版本号
-
禁止通过ip地址访问,禁止恶意域名解析,只允许域名访问
-
配置防盗链、以及跨域访问
-
防DDOS、cc攻击,限制单IP并发连接,以及http请求
-
优雅限制nginx错误页面
-
nginx加密传输https优化
-
nginx proxy_cache、fastcgi_cache、uwsgi_cache 缓存,第三方工具(squid、varnish)
-
六、web集群-高可用服务
- 高可用服务(HA)-keepalived
1.概述
Keepalived是Linux下的一个轻量级的高可用解决方案,通过虚拟链路冗余协议来实现服务或网络高可用。
Keepalived的功能:
- 管理LVS负载均衡软件
- 实现LVS集群节点的健康检查
- 作为系统网络服务的高可用性
一般是指2台机器启动着完全相同的业务系统,当有一台机器down机了,另外一台服务器就能快速的接管,对于访问的用户是无感知的。
| 选型 | |
|---|---|
| keepalived | 活着 高可用软件,负载使用,一般不涉及数据服务 |
| heartbeat | 心跳 涉及数据库,存储数据相关可使用 heartbeat+drbd |
| 商业高可用软件 |
2.原理
- keepalived 是基于VRRP协议实现高可用
- VRRP虚拟路由器冗余协议,最开始是给网络设备实现高可用。 目前通过keepalive实现vrrp协议,通过vrrp实现高可用
- 分为主、备,一般是两个节点。主备之间通过vrrp协议发送数据包沟通
- 主给备定期发送数据包,备收到数据包表示主还活着;备无法收到数据包,表示主挂了,备胎转正了,接管用户请求流量
- VRRP协议使用组播的ip 224.xx.xx.xx
3.环境部署
| 高可用环境准备 | 需要安装的服务 |
|---|---|
| lb01 | nginx+keepalived |
| lb02 | nginx+keepalived |
- /etc/keepalived/keepalived.conf 配置文件结构
- global_defs 全局定义部分
- vrrp_instance vrrp协议配置,vip,主备,网卡...经常改动部分
- virtual_server lvs相关配置
sh
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
#全局定义部分
global_defs {
router_id lb01 #每一个keepalived的名字,当前网络中唯一
}
#vrrp实例配置部分 用于配置VIP virtual_ipaddres
vrrp_instance vip_3 { #vip_3 设置一对主备之间使用的名字,注意同一对主备之间这个名字要一致
state MASTER #主/备 MASTER主 BACKUP 备
interface eth0 #指定网卡
virtual_router_id 51 #在一对主备之间设置的一个id号 主备之间id号同一即可
priority 100 #优先级 数字越大优先级越高 设置建议:主>备 100 50
advert_int 1 #心跳间隔 多久发送一次vrrp数据包 1秒 监测间隔时间
authentication { #授权与认证,保持默认即可 对数据包加密
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { #设置vip
10.0.0.3 dev eth0 label eth0:0 #label设置别名 虚拟的VIP地址10.0.0.3
}
}

sh
#测试
systemctl enable keepalived.service
systemctl start keepalived.service
[root@lb01 ~]# ip a |grep 10.0.0.3
inet 10.0.0.3/32 scope global eth0:0
#关掉lb01的keepalived
[root@lb01 ~]# pkill keepalived
#lb02
[root@lb02 ~]# ip a |grep 10.0.0.3
inet 10.0.0.3/32 scope global eth0:0
4.问题⭐️⭐️⭐️
4.1故障
脑裂概述:由于某些原因,导致两台keepalived高可用服务器在指定时间内,无法检测到对方的心跳,各自去的资源及服务的所有权,而此时的两台高可用服务器又都还活着
- 脑裂
- 现象:主备都有VIP
- 原因:
- 备认为主挂了,接管资源生成VIP。实际上主并没有挂,仍有VIP
- 有很多原因可以导致脑裂,开启防火墙、selinux,配置,物理线路
- 解决:
- 监控(备节点监控),只要备节点有VIP就告警
- 远程控制主节点,只要备节点认为主挂了,那就让他真的挂了
4.2keepalived基于主机高可用软件
-
keepalived只会在主机挂了,网络断开后,
-
默认情况下keepalived不会监控某个服务
-
项目目标:某个服务关闭了,keepalived就进行主备切换。
-
项目步骤:
- 书写脚本,过滤服务进程数,端口数量
- 通过keepalived调用这个脚本
-
书写脚本
sh
#书写脚本
#!/bin/bash
#author :liux
#desc:监控nginx端口数量
port_cnt=`ss -lntup |grep nginx|wc -l`
if [ $port_cnt -eq 0 ];then
systemctl stop keepalived
fi
#给脚本授予执行权限
chmod +x /server/scripts/keep_lb.sh
- 书写keepalived配置文件
sh
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lb01
}
#定义监控的脚本
vrrp_script keep_lb {
script /server/scripts/keep_lb.sh
interval 2
weight 1
user root
}
vrrp_instance vip_3 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3 dev eth0 label eth0:0
}
#vrrp实例使用keep_lb.sh脚本
track_script {
keep_lb
}
- 测试
sh
#kill掉nginx
[root@lb01 ~]# pkill nginx
#主VIP没有了
[root@lb01 ~]# ip a |grep 10.0.0.3
[root@lb01 ~]#
[root@lb02 ~]# ip a |grep 10.0.0.3
inet 10.0.0.3/32 scope global eth0:0
5.进阶用法
5.1非抢占模式
- keepalived 主备默认是抢占式,主挂了,备接管。主恢复,就重新抢回资源
- 配置非抢占模式
- 2个节点都是备 BACKUP
- 两个节点配置nopreempt

5.2双主模式
- 应对高并并发的时候设置的双主模式

七、https证书
1 概述
- 为什么需要使用HTTPS,因为HTTP不安全,当我们使用http网站时,会遭到劫持和篡改,如果采用https协议,那么数据在传输过程中是加密的,所以黑客无法窃取或者篡改数据报文信息,同时也避免网站传输时信息泄露。
- 那么我们在实现https时,需要了解ssl协议,但我们现在使用的更多的是TLS加密协议。
- 那么TLS是怎么保证明文消息被加密的呢?在OSI七层模型中,应用层是http协议,那么在应用层协议之下,我们的表示层,是ssl协议所发挥作用的一层,他通过(握手、交换秘钥、告警、加密)等方式,是应用层http协议没有感知的情况下做到了数据的安全加密
2.https访问流程
1、浏览器发起往服务器的443端口发起请求,请求携带了浏览器支持的加密算法和哈希算法。
2、服务器收到请求,选择浏览器支持的加密算法和哈希算法。
3、服务器下将数字证书返回给浏览器,这里的数字证书可以是向某个可靠机构申请的,也可以是自制的。
4、浏览器进入数字证书认证环节,这一部分是浏览器内置的TLS完成的:
4.1 首先浏览器会从内置的证书列表中索引,找到服务器下发证书对应的机构,如果没有找到,此时就会提示用户该证书是不是由 权威机构颁发,是不可信任的。如果查到了对应的机构,则取出该机构颁发的公钥。
4.2 用机构的证书公钥解密得到证书的内容和证书签名,内容包括网站的网址、网站的公钥、证书的有效期等。浏览器会先验证证书签名的合法性(验证过程类似上面Bob和Susan的通信)。签名通过后,浏览器验证证书记录的网址是否和当前网址是一致的,不一致会提示用户。如果网址一致会检查证书有效期,证书过期了也会提示用户。这些都通过认证时,浏览器就可以安全使用证书中的网站公钥了。
4.3 浏览器生成一个随机数R,并使用网站公钥对R进行加密。
5、浏览器将加密的R传送给服务器。
6、服务器用自己的私钥解密得到R。
7、服务器以R为密钥使用了对称加密算法加密网页内容并传输给浏览器。
8、浏览器以R为密钥使用之前约定好的解密算法获取网页内容。
3.生成证书
sh
[root@lb01 ~]# mkdir -p /etc/nginx/ssl_key
[root@lb01 ~]# cd /etc/nginx/ssl_key
###使用openssl命令充当CA权威机构创建证书(生产不使用此方式生成证书,不被互联网认可的黑户证书)###
[root@lb01 ssl_key]# openssl genrsa -idea -out server.key 2048
Generating RSA private key, 2048 bit long modulus
............................................................................+++
.....+++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:
[root@lb01 ssl_key]# ll
total 4
-rw-r--r-- 1 root root 1739 Jul 9 18:55 server.key
###生成自签证书,同时去掉私钥的密码###
[root@lb01 ssl_key]# openssl req -days 36500 -x509 \
> -sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt
Generating a 2048 bit RSA private key
.........................................................................................+++
....................................+++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:CN
Locality Name (eg, city) [Default City]:CHINA
Organization Name (eg, company) [Default Company Ltd]:cq
Organizational Unit Name (eg, section) []:spb
Common Name (eg, your name or your server's hostname) []:liux.com
Email Address []:123@qq.com
[root@lb01 ssl_key]# ll
total 8
-rw-r--r-- 1 root root 1354 Jul 9 18:56 server.crt
-rw-r--r-- 1 root root 1704 Jul 9 18:56 server.key
# req --> 用于创建新的证书
# new --> 表示创建的是新证书
# x509 --> 表示定义证书的格式为标准格式
# key --> 表示调用的私钥文件信息
# out --> 表示输出证书文件信息
# days --> 表示证书的有效期
4.wordpress配置https
sh
1.负载均衡配置lb01
[root@lb01 conf.d]# cat proxy.conf
upstream node {
server 172.16.1.7:80 max_fails=2 fail_timeout=10s;
server 172.16.1.8:80 max_fails=2 fail_timeout=10s;
check interval=3000 rise=2 fall=3 timeout=1000 type=tcp;
#interval 检测间隔时间,单位为毫秒
#rise 表示请求2次正常,标记此后端的状态为up
#fall 表示请求3次失败,标记此后端的状态为down
#type 类型为tcp
#timeout 超时时间,单位为毫秒
}
server {
listen 80;
server_name blog.liux.com;
return 302 https://$server_name$request_uri;
}
server {
listen 443;
server_name blog.liux.com;
ssl on;
ssl_certificate ssl_key/server.crt;
ssl_certificate_key ssl_key/server.key;
location / {
proxy_pass http://node;
include proxy_params;
}
}
2.web01、web02配置
[root@web01 conf.d]# cat blog.conf
server {
listen 80;
server_name blog.liux.com;
location / {
root /code/wordpress;
index index.php index.html;
}
location ~ \.php$ {
root /code/wordpress;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
##负载访问使用的https后端web使用的是http,对于PHP来说他并不知道用的到底是什么所以会出现错误;
#告诉PHP我前置的负载使用的是https协议
fastcgi_param HTTPS on;
include fastcgi_params;
}
}
八、web集群-tomcat集群
1.内容
- Java容器
- jvm,jre,jdk
- 部署Java环境,tomcat
- 目录结构
- 配置使用
- 常用部署Java代码方式
- ngx+tomcat
- 远程监控功能
- tomcat故障案例
- tomcat优化
2.Java容器
- 用于存放与运行Java代码的环境
| Java容器 | |
|---|---|
| Tomcat | 最常用,较重要,功能完善 |
| Jetty | 轻量,功能较少 |
| Weblogic | 用于oracle数据库环境使用 |
| 东方通 | 国产Java容器 |
3.JVM-JRE-JDK
- 1份代码处处运行与使用 代码的可移植性
- JVM:Java 虚拟机中,运行Java代码的地方
- JRE:Java运行环境。 提供jvm环境,Java命令
- JDK:Java开发环境,jvm+jre+额外功能
4.环境部署
4.1 环境准备
| 环境 | |
|---|---|
| web03 | 10.0.0.9/172.16.1.9 |
| web04 | 10.0.0.10/172.16.1.10 |
| db01 | 10.0.0.51/172.16.1.51 |
4.2 部署jdk
- jdk jdk-8u361
sh
#解压到指定目录
[root@web03 ~]# mkdir -p /app/tools
[root@web03 ~]# tar xf jdk-8u361-linux-x64.tar.gz -C /app/tools/
#创建软链接
[root@web03 ~]# ln -s /app/tools/jdk1.8.0_361/ /app/tools/jdk
[root@web03 ~]# ll /app/tools/
total 0
lrwxrwxrwx 1 root root 24 Apr 12 13:31 jdk -> /app/tools/jdk1.8.0_361/
drwxr-xr-x 8 root root 294 Apr 12 13:30 jdk1.8.0_361
#配置Java环境变量,一般是二进制安装需要配置
cat >>/etc/profile<<'EOF'
export JAVA_HOME=/app/tools/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
EOF
#使配置生效
source /etc/profile
4.3 部署tomcat
- tomcat
sh
#解压到指定目录并创建软链接
tar -xf apache-tomcat-9.0.73.tar.gz -C /app/tools/
ln -s /app/tools/apache-tomcat-9.0.73/ /app/tools/tomcat
#检查jdk、tomcat信息
[root@web03 ~]# /app/tools/tomcat/bin/version.sh
4.4 tomcat目录结构
| 目录 | |
|---|---|
| bin | 存放tomcat管理命令 |
| conf | tomcat配置文件 |
| lib | 依赖与库文件,插件文件 |
| logs | 日志目录 |
| webapps | 站点目录 |
| work | tomcat运行Java代码的存放代码的目录 |
- bin****目录
| bin目录 | |
|---|---|
| startup.sh | 启动 |
| shutdown.sh | 关闭 |
| catalina.sh | 核心脚本,配置tomcat优化,jvm优化 |
- conf
| conf配置文件 | 说明 |
|---|---|
| server.xml | tomcat配置文件 |
| web.xml | 配置文件,辅助配置 |
- logs
| logs日志目录 | |
|---|---|
| catalina.out | tomcat应用日志,启动过程,关闭,错误信息 核心找:startup启动用时,错误提示:error,failed,exception |
| catalina.2023-04-12.log | catalina.out的切割日志,每天切割 |
| localhost_access_log.2023-04-12.txt | 访问日志,可以重新定义文字和内容 |
4.5tomcat日常管理与维护
- 书写systemctl管理配置文件进行管理
- 服务管理指令存放位置:/usr/lib/systemd/system/xxxx.service
| systemctl配置文件的结构 | |
|---|---|
| [Unit] | 指定注释信息,依赖(先后顺序) |
| Description | 说明与注释 |
| After | 在这里指定的服务之后运行. network.target |
| [Service] | 用于指定服务开启命令,关闭命令,重启命令. |
| Type=notify | 指定类型 simple 或forking即可 |
| ExecStart | 服务启动命令 |
| ExecStop | 服务关闭命令 |
| ExecReload | 重启命令 |
| EnvironmentFile | 配置环境变量的文件(一般对于编译安装,二进制安装需要加上) |
| [Install] | 内容固定,用于指定运行级别 |
| WantedBy=multi-user.target | 运行级别 |
- tomcat systemctl 配置
sh
#systemctl 配置文件编写
root@web03 logs]# vim /usr/lib/systemd/system/tomcat.service
[Unit]
Description=Tomcat java web container
After=network.target
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/tomcat
ExecStart=/app/tools/tomcat/bin/startup.sh
ExecStop=/app/tools/tomcat/bin/shutdown.sh
ExecReload=/app/tools/tomcat/bin/shutdown.sh && sleep 1 && /app/tools/tomcat/bin/startup.sh
[Install]
WantedBy=multi-user.target
#配置环境变量的文件
[root@web03 logs]# vim /etc/sysconfig/tomcat
JAVA_HOME=/app/tools/jdk
PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:/usr/bin/:/usr/sbin/:/usr/local/bin/:/usr/local/sbin
CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
#重新加载systemctl
systemctl daemon-reload
#启动tomcat
systemctl start tomcat
5.tomcat集群 -配置文件
- server.xml
sh
#8005端口 shutdown端口,连接这个端口输入shutdown字符,就可以关闭Tomcat
<Server port="8005" shutdown="SHUTDOWN">
#配置管理端认证功能
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
#用户处理http请求用的端口 8080
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
#这里的8443是用于处理 https请求
#engine部分,指定默认的虚拟主机localhost
<Engine name="Catalina" defaultHost="localhost">
#Host部分,虚拟主机的配置部分
#name指定域名
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
- tomcat 与ngx配置文件对比
| 名称 | tomcat | ngx |
|---|---|---|
| 虚拟主机 | host部分 | server {} |
| 域名 | name="域名" | server_name 域名; |
| 端口 | <Connector port="8080" | listen 80; |
| 站点目录 | appBase="webapps" | root /app/code/test; |
| 自动解压 | unpackWARs="true" | |
| 自动部署 | autoDeploy="true" 加载到jvm中 | |
| 日志目录 | directory="logs" | access_log /var/log/nginx/access.log main; |
| 日志名称 | prefix="localhost_access_log" suffix=".txt" | access_log /var/log/nginx/access.log main; |
| 日志格式 | pattern="%h %l %u %t "%r" %s %b" | log_format main ...; |
- 端口:8005,8080,8443, 8009(从8.5开始隐藏,与apache连接)
6.规范tomcat访问日志模式
| 说明 | tomcat | nginx |
|---|---|---|
| 定义访问日志的格式 | Host部分的pattern定义 | http区域 log_format部分 |
| 客户端ip地址 | %h | $remote_addr |
| 访问的时间 | %t | $local_time |
| 请求起始行 | %r | $request |
| 状态码 | %s | $status |
| 大小 | %b | $body_bytes_sent |
| 从哪里跳转来的 | %{Referer}i | $http_referer |
| 客户端类型,浏览器 | %{User-Agent}i | $http_user_agent |
| XFF头记录 | %{X-Forwarded-For}i | $http_x_forwarded_for |
" '"'表示双引号
sh
pattern="%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" "%{X-Forwarded-For}i""
7.tomcat多实例
- 在同一台linux主机上运行多个tomcat实例
- 原因:充分利用服务器资源
- 步骤:
- 多个tomcat目录
- 配置文件端口8080,8005
- 启动
8.监控功能
-
通过各种监控工具(Zabbix/Grafana/Prometheus/...),监控
-
Tomcat/java 需要我们开启java远程监控功能(JMX )
-
步骤
- tomcat配置中修改tomcat启动的选项.开启jmx远程监控功能.
- 交给zbx就可以了(使用windows jdk连接tomcat)
sh
#catalina.sh 文件中125行 后面
#CATALINA_OPTS java环境变量,指定java启动的时候的选项
CATALINA_OPTS="$CATALINA_OPTS \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=10.0.0.9"
| 开启远程监控功能选项 | |
|---|---|
| -Dcom.sun.management.jmxremote \ | 开启远程监控功能 |
| -Dcom.sun.management.jmxremote.port=12345 \ | 指定端口 |
| -Dcom.sun.management.jmxremote.authenticate=false \ | 关闭认证功能 |
| -Dcom.sun.management.jmxremote.ssl=false \ | 关闭ssl加密功能 |
| -Djava.rmi.server.hostname=10.0.0.9 | 写上本地网卡的ip,监听的地址 |
sh
#修改后java进程中增加了上面添加的那些选项.
/app/tools/jdk/bin/java
-Djava.util.logging.config.file=/app/tools/tomcat/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
-Dcom.sun.management.jmxremote
-Dcom.sun.-management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=10.0.0.9
-Dignore.endorsed.dirs= -classpath /app/tools/tomcat/bin/bootstrap.jar:/app/tools/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/app/tools/tomcat -Dcatalina.home=/app/tools/tomcat
-Djava.io.tmpdir=/app/tools/tomcat/temp org.apache.catalina.startup.Bootstrap start
- 在windows下,通过jdk连接tomcat(模拟监控软件连接)

9.Java故障案例
9.1命令 jps jstack jmap
- jps
sh
#只显示Java进程信息
jps -lvm
- jstack 查看Java进程内部信息,线程信息
sh
#2325 Java进程的pid 通过jps -jvm可以查看到
jstack 2325 |grep -i state
- jmap 查看或导出jvm内存信息
sh
#查看
#2325 Java进程的pid 通过jps -jvm可以查看到
jmap -heap 2325
#导出jvm内存镜像文件
[root@web03 tomcat]# jmap -dump:format=b,file=8080.hprof 2325
Dumping heap to /app/tools/apache-tomcat-9.0.73/8080.hprof ...
Heap dump file created
jvm内存镜像文件,在windows系统下通过MemoryAnalyzer查看 (MA/MAT)
1.需要jdk环境
2.解压即可使用
3.将jvm内存镜像文件导入MA软件中
9.2 Java应用负载高故障案例
10.Java会话共享方案
| 会话共享方案 | 说明 | 备注 |
|---|---|---|
| 1️⃣单机 | 如果单个应用,tomcat不用考虑会话共享的问题 | |
| 2️⃣session复制功能 | tomcat配置后,可以把session信息复制给其他节点 | 只适用于集群节点较少的情况 |
| 3️⃣通过插件实现会话共享,存放在redis中 | tomcat通过插件,将用户会话保存在指定的服务器中(redis) tomcat-cluster-session-manager | 需要插件,进行配置,代码支持 |
| 4️⃣通过代码直接指定session位置 | 修改代码与增加功能 | |
| 5️⃣使用其他方式替代会话 | oauth认证,token认证 | 代码级别 |
11.tomcat配置https
- 下载tomcat证书
- 修改配置文件(配置跳转)
修改tomcat配置文件 server.xml
sh
<Connector port="8443"
protocol="HTTP/1.1"
SSLEnabled="true"
scheme="https"
secure="true"
keystoreFile="/app/tools/tomcat/cert/ssl.liux.cn.pfx"
keystoreType="PKCS12"
keystorePass="AGrnHD9j"
clientAuth="false"
SSLProtocol="TLSv1.1+TLSv1.2+TLSv1.3"
ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256" />
配置http →https
sh
#在web.xml的文件中 </welcome-file-list>后添加以下内容
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area </realm-name>
</login-config>
<security-constraint>
<web-resource-collection >
<web-resource-name>ssl </web-resource-name>
<url-pattern>/* </url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL </transport-guarantee>
</user-data-constraint>
</security-constraint>
12.tomcat优化(面试必备)
- 安全优化
- 性能优化
- jvm优化
12.1 安全优化
| 条目 | 配置 | 备注 |
|---|---|---|
| tomcat shutdown端口的保护8005 | 改为其他特殊的端口 | |
| ajp连接端口禁用 | tomcat8.5开始默认就注释了 | 8009端口,用于与apache联俄籍 |
| 禁用管理端 | 把管理端相关配置,文件,目录都清理掉 webapps下面的docs example host-manager manager | 开启较为危险 |
| 降权启动 | 通过普通用户运行与管理 比如 tomcat用户 | 端口大于1024,1024以内的端口为特权端口,只能root使用 |
| 文件列表访问控制 | 类似于nginx autoindex,是否会默认列表站点目录的内容,默认关闭 | |
| tomcat版本信息隐藏 | 遇到4xx,5xx错误的时候显示指定的页面,不包含服务器版本信息 | |
| tomcat web服务隐藏 | http响应头里面的内容 connector 8080 部分增加头部信息Server信息 | |
| 访问限制 | 类似于ngx,使用allow和deny | 一般推荐使用ngx限制 |
| 脚本权限回收 | tomcat/bin目录,脚本设置为700/500 ,从tomcat 8.5开始默认750 | 权限最小化 |
| 访问日志格式规范 | tomcat server.xml中配置访问日志的格式,参考ngx |
12.2 性能优化
-
io模型优化
-
线程数量,压缩的配置
01 io模型优化
- 类似于nginx同步,异步模型.
- 决定了tomcat如何处理数据
| io模型 | 说明 |
|---|---|
| BIO | Blocked IO,阻塞,同步模型. tomcat7及之前版本默认是BIO |
| NIO(NIO1 NIO2) | New IO,非阻塞,异步模型. tomcat8开始默认就是nio |
| APR | 应对高并发场景 |
应用建议:一般使用默认的即可
02 tomcat Java线程数
sh
#在connector中加
maxThreads="500" 最大的线程数量 200-400之间,具体的数值需要进行压力测试.
acceptCount="500" 当达到最大线程数量的时候,队列长度acceptCount一般与maxThreads 一致
acceptorThreadCount="2" 请求分成几队伍进行,数值上与cpu核心总数一致或2倍默认是1
minSpareThreads="10" 空闲时候最小的线程数量,不忙的时候,最少留几服务员,值班的线程数量设置数值的建议,搭建好环境,部署应用,通过测试软件测试,监控状态.
测试软件:ab,压力测试工具loadrunner....,jmeter
03 DNS 压缩
sh
#禁用DNS反向解析功能,加速访问. 域名 →ip ip→域名
#类型与ngx gzip压缩(推荐在ngx配置)
compression="on" 开启tomcat压缩功能 静态文本资源 html js css
compressionMinSize="2048" 大于2048字节的文件才会被压缩
compressableMimeType="text/html,text/plain,text/css,application/javascript,application/json,application/x-fontttf,application/x-font-otf"
12.3 jvm优化
修改catalina.sh文件中的内容
- 设置jvm内存大小
- 配置gc日志(垃圾回收)
- 配置自动dump功能
01设置jvm内存大小
- 设置 jvm初始内存大小 (默认物理内存1/64) jvm最大内存大小(默认物理内存的1/4 )
sh
#修改 catalina.sh文件
JAVA_OPTS='-Xms1024m -Xmx1024m -Xloggc:/var/log/tomcat_gc.log'
#-Xms jvm jvm初始内存大小
#-Xmx max jvm最大内存
方案01: 一般 -Xmx 是 -Xms 2倍.
方法02: -Xmx 与-Xms 一致,防止重复gc垃圾回收.
gc garbage collect 垃圾回收 定期清理 jvm内存.
-Xloggc:/var/log/tomcat_gc.log 垃圾回收的日志
02设置jvm内存大小
sh
-Xloggc:/var/log/tomcat_gc.log
03 配置自动dump功能
- jvm发生异常,自动导出jvm内存镜像
sh
-XX:+HeapDumpOnOutOfMemoryError #OOM故障
-XX:HeapDumpPath=/app/tools/tomcat/temp/oom.hprof
-XX:+HeapDumpOnOutOfMemoryError #开启导出jvm镜像功能,用于java/tomcat加载应用故障,内存不足oom out of memory 内存不足.
-XX:HeapDumpPath=/app/tools/tomcat/temp/oom.hprof #用于指定jvm内存镜像导出到哪里.
13.Java前后端项目
13.1项目环境概述
| 主机 | 环境 |
|---|---|
| web03 | 前端(ngx)+后端(jdk) |
| db02 | 数据库 mysql 8.0 二进制方法安装 /app/tools/mysql/ 数据目录/app/data/3306/ |
13.2数据库准备
- 环境以及配置
sh
mkdir -p /app/tools/ /app/data/3306
tar xf mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz -C /app/tools
ln -s mysql-8.0.27-linux-glibc2.12-x86_64 mysql
yum install ncurses ncurses-devel libaio-devel openssl openssl-devel -y
#创建用户
useradd -s /sbin/nologin -M mysql
#添加配置文件
cat>/etc/my.cnf<<'EOF'
#by liux weixin:liux
[mysqld]
#用户
user=mysql
#安装目录
basedir=/app/tools/mysql/
#数据目录
datadir=/app/data/3306/
port=3306
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
EOF
#给配置文件和目录授权
chown mysql.mysql /etc/my.cnf
chown -R mysql.mysql /app/data/3306
#配置PATH环境变量
echo 'export PATH=/app/tools/mysql/bin:$PATH'>>/etc/profile
- 初始化数据库
sh
mysqld --initialize-insecure --user=mysql --basedir=/app/tools/mysql/ --datadir=/app/data/3306/
#检查上面一句执行有没有成功
echo $?
- 启动数据库
sh
#拷贝已经准备好的启动管理文件
cp /app/tools/mysql/support-files/mysql.server /etc/init.d/mysqld
systemctl enable mysqld
systemctl start mysqld
#登录
mysql
- 创建数据库、添加用户
sh
create database exam charset utf8mb4;
create user exam@'172.16.1.%' identified with mysql_native_password by '1';
#授权
grant all on exam.* to exam@'172.16.1.%' ;
#测试
mysql -uexam -p1 -h 172.16.1.52
#导入数据
mysql exam <xzs-mysql.sql
13.3 部署后端
sh
mkdir -p /app/code/exam/{front,backend}
unzip online-exam-backend.zip
#运行代码
java -Duser.timezone=Asia/Shanghai -jar -Dspring.profiles.active=prod xzs-3.8.0.jar
#-Dspring.profiles.active=prod jar包目录同层的 application-prod.yml application.yml
#测试 student/123456 admin/123456
http://10.0.0.9:8000
13.4部署前端
sh
#配置nginx配置文件
vim /etc/nginx/conf.d/exam.liux.cn.conf
server{
listen 80;
server_name exam.liux.cn;
location /{
root /app/code/exam/front/;
index index.html;
}
location /api/ {
proxy_pass http://localhost:8000;
}
}
#配置host 调试
http://exam.liux.cn/admin
九、iptables 防火墙
-
目标:
-
封端口,封ip
-
实现NAT功能
-
共享上网
-
端口映射(端口转发),ip映射
-
9.1防火墙的种类及使用说明
- 硬件: 整个企业入口
- 三层路由: H3C 华为 Cisco(思科)
- 防火墙: 深信服,绿盟...
- 软件: 开源软件 网站内部 封ip 封ip
- iptables 写入到Linux内核中 以后服务docker 工作在 4层(大部分)
- firewalld c7
- nftables c8
- ufw (ubuntu firewall) Ubuntu
- 云防火墙(公有云)
- 安全组 (封ip,封端口)
- NAT网关(共享上网,端口映射...)
- waf应用防火墙
- waf防火墙(应用防火墙,处理7层的攻击) SQL注入,等攻击
- 书写规则(描述攻击过程,关键提示,关键操作.)
企业选型建议:
中小企业: 使用公有云,安全组,waf防火墙,态势感知.
访问量巨大: 使用硬件防火墙,waf防火墙,硬件服务器+云服务器
9.2iptables 执行过程
-
工作流程:
- 防火墙是层层过滤 的,实际是按照配置规则的顺序从上到下,从前到后进行过滤
的。
2. 如果匹配成功 规则,即明确表示是拒绝****(DROP)还是接收(ACCEPT) ,数据包就不再向下匹配新的规则。
3. 如果规则中没有明确表明是阻止还是通过的,也就是没有匹配规则,向下进行匹配,直到匹配默认规则得到明确的阻止还是通过。
4. 防火墙的默认规则 是所有规则都匹配完才会匹配的。
9.3 表与链
- 表(table)是对功能的分类,防火墙功能(filter表),共享上网,端口转发(na表)
- 链对数据流进行处理,需要使用不同的链(数据流入(INPUT),数据流出(OUTPUT))
- iptables 是4****表伍链
- 4表: filter 表 nat****表 raw表 mangle表
- 伍链: INPUT OUTPUT FORWARD PREROUTING POSTROUTING
9.4 实战环境准备
- 在m01上面安装iptables以及添加配置
sh
yum -y install iptables-services
#配置文件
[root@m01 ~]# rpm -ql iptables-services
/etc/sysconfig/ip6tables
/etc/sysconfig/iptables #防火墙的配置文件
/usr/lib/systemd/system/ip6tables.service
/usr/lib/systemd/system/iptables.service #防火墙服务配置命令 systemctl start iptables
/usr/libexec/initscripts/legacy-actions/ip6tables
/usr/libexec/initscripts/legacy-actions/ip6tables/panic
/usr/libexec/initscripts/legacy-actions/ip6tables/save
/usr/libexec/initscripts/legacy-actions/iptables
/usr/libexec/initscripts/legacy-actions/iptables/panic
/usr/libexec/initscripts/legacy-actions/iptables/save
/usr/libexec/iptables
/usr/libexec/iptables/ip6tables.init
/usr/libexec/iptables/iptables.init
[root@m01 ~]# rpm -ql iptables
/usr/sbin/iptables #iptables 命令 添加/删除/查看规则(4表伍链)
/usr/sbin/iptables-restore # 恢复
/usr/sbin/iptables-save #iptables规则 输出(保存)
#防火墙相关模块 加载到内核中
#写入到开机自启动.
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
#永久生效
cat >>/etc/rc.local<<EOF
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
EOF
#查看是否成功
lsmod |egrep 'filter|nat|ipt'
#启动
systemctl start iptables.service
systemctl enable iptables.service
#查看filter表中的规则 ,默认查看的是filter表
iptables -nL
9.5 iptables命令参数
| 参数 | 含义 |
|---|---|
| -L | 显示表中的所有规则 |
| -n | 不要把ip或端口反向解析为名字 |
| -t | 指定表,不指定默认为filter |
| -A | append 追加把规则写入到链的末尾.加入准许类规则 |
| -I | insert 把规则加在链的第1条 拒绝类规则放在所有规则最上面 拒绝类 -I |
| -D | delete 删除 -D INPUT 1 |
| -p | 指定协议 protocal tcp/udp/icmp/all |
| --dport | 目标端口 dest destination ⚠ 指定端口的时候加上协议 -p tcp |
| --sport | 源端口 source 源 |
| -s | --source 源ip 如果只屏蔽/准许ip,网段,不用加上协议 |
| -d | --destination 目标ip |
| -m | 指定模块 multiport |
| -i | input 输入的时候 从哪个网卡进来 |
| -o | ouput 输出的时候 从哪个网卡出去 |
| -j | 满足条件后的动作 : DROP(拒绝 )/ACCEPT(准许)/REJECT(拒绝) |
| DROP REJECT拒绝 DROP 把数据丢掉 不会返回信息给用户 REJECT 拒绝 返回拒绝信息 | |
| -F flush | 清除指定表中所有的规则,备份. |
| -X | 删除用户自定义的链 |
| -Z zero | 链的计数器清零(数据包计数器与数据包字节计数器) |
| -v | 显示数据包,数据量 |
9.6配置filter表规则
- 正式配置之前 先备份, 清空规则
sh
iptables -F
iptables -X
iptables -Z
9.7禁止访问22端口
sh
#拒绝用户访问22端口
iptables -t filter -A INPUT -p tcp --dport 22 -j DROP
#查看规则并加上序号
iptables -t filter -nL --line-number
#删除规则
iptables -t filter -D INPUT 1 #根据序号删除
9.8测试案例
- 禁止10.0.0.0/24网段访问8888端口
sh
iptables -I INPUT -s 10.0.0.0/24 -p tcp --dport 8080 -j DROP
- 指定多个端口
sh
iptables -A INPUT -m multiport -p tcp --dport 80,443-j ACCEPT
- ICMP(Internet Control Message Protocol)Internet控制报文协议ping
- 通过防火墙规则 控制是否可以****ping
sh
iptables -t filter -I INPUT -p icmp --icmp-type 8 -j DROP
- 通过内核参数,禁止被ping
sh
[root@m01 ~]# cat /etc/sysctl.conf
#/proc/sys/net/ipv4/icmp_echo_ignore_all
#net网络 ipv4协议 icmp协议忽略所有
net.ipv4.icmp_echo_ignore_all = 1
#生效
sysctl -p
9.9防火墙规则的保存与恢复
- iptables-save 进行备份,默认输出到屏幕
- iptables-restore 进行恢复,加上文件
- 写入到/etc/sysconfig/iptables
sh
iptables-save>/etc/sysconfig/iptables
iptables-restore</etc/sysconfig/iptables
9.10实际生产用法
- ssh可以连接进来
sh
iptables -F
iptables -X
iptables -Z
iptables -nL
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
-
设置允许本机lo通讯规则
允许本机回环lo接口数据流量流出与流入
sh
# -i 数据进入的时候
iptables -A INPUT -i lo -j ACCEPT
# -o 数据流出的时候
iptables -A OUTPUT -o lo -j ACCEPT
- 配置默认规则及 放行 80 443端口
sh
iptables -A INPUT -m multiport -p tcp --dport 443,80 -j ACCEPT
- 允许网段访问
sh
iptables -A INPUT -s 10.0.0.0/24 -j ACCEPT
iptables -A INPUT -s 172.16.1.0/24 -j ACCEPT
- 修改默认的规则为拒绝INPUT
sh
iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
9.11nat实现共享上网
- 172.16.1.7 内网服务器实现通过iptables实现共享上网原理详解
sh
iptables -t nat -A POSTROUTING -s 172.16.1.7 -j SNAT --to-source 10.0.0.61
指定nat表,配置POSTROUTING链
源ip是172.16.1.7这台主机进行共享上网,如果是多台(-s172.16.1.0/24)
指定使用SNAT功能,源地址转换.
通过SNAT功能把数据包中的源ip地址改为防火墙公网的ip地址.(10.0.0.61)
-
环境准备
- web01 172.16.1.7 (只保留这个网卡), eth0网卡关闭(ONBOOT=no)
- m01 配置共享上网的规则
(1)防火墙配置(m01)
sh
#配置防火墙规则,改为默认是准许. 清空其他规则. 配置防火墙共享上网规则
iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j SNAT --to-source 10.0.0.61
#防火墙上开启ip_forward功能(内核转发功能)
echo 'net.ipv4.ip_forward = 1' >>/etc/sysctl.conf
#配置生效
sysctl -p
(2)web配置(web01)
- 关闭eth0网卡.仅开启eth1网卡,配置网关指向m01(172.16.1.61)
sh
vim /etc/sysconfig/network-scripts/ifcfg-eth0
ONBOOT=no
vim /etc/sysconfig/network-scripts/ifcfg-eth1
GATEWAY=172.16.1.61
systemctl restart network
ssh 172.16.1.7
ip a
(3)测试
sh
ping baidu.com
ip r
route -n
共享上网流程:
防火墙添加规则 SNAT\规则 nat表 POSTROUTING
防火墙服务器 开启ip转发功能
后端节点,配置网卡,让网卡网关指向防火墙
后端节点的网卡中配置DNS1=223.5.5.5 ,DNS2=223.6.6.6
9.12nat实现端口转发
- 端口映射为了解决用户进来的问题. 外部的用户访问内网的某个服务器,端口
sh
iptables -t nat -A PREROUTING -d 10.0.0.61 -p tcp --dport 9000 -j DNAT --to-destination 172.16.1.7:22
- 测试
sh
#本地shell中
[d:\~]$ ssh root@10.0.0.61 9000
十、总结
通过本文档的系统学习,我们可以建立起一套完整的Web集群管理知识体系。从最底层的HTTP通信协议理解,到核心Web服务器Nginx的精细化配置与性能调优;从实现流量分发和业务扩展的负载均衡架构,到保障服务无间断运行的高可用方案;从动态应用(如PHP、Java)运行环境的搭建与优化,到网络边界的基础安全防护。整个流程体现了现代Web服务从单体部署走向分布式、高可用集群的核心路径。
核心要点:
- 基础与度量:深刻理解HTTP协议是优化和排错的基础,而IP、PV、UV等指标是衡量服务规模和健康状况的关键。
- Nginx为核心:Nginx凭借其高性能、高并发和模块化特性,成为Web集群中的核心组件,既可作为静态资源服务器、动态请求代理,也可作为负载均衡器。
- 架构是关键:通过"代理+负载均衡"将流量智能分发至后端多台应用服务器,是实现水平扩展、提升并发处理能力和容灾能力的核心架构。
- 可用性保障:利用Keepalived实现虚拟IP(VIP)的故障自动切换,是构建无单点故障高可用集群的经典模式,需警惕并解决"脑裂"问题。
- 全栈能力:完整的集群管理需涵盖不同技术栈,包括LNMP动态网站部署、Tomcat Java应用集群的会话管理及JVM优化。
- 安全与优化:安全(如iptables防火墙规则、HTTPS)与性能优化(如Nginx/Tomcat参数调优)贯穿于架构设计、部署和运维的全生命周期,是保障服务稳定、高效、安全运行的必要条件。
本指南所呈现的内容,是一套经过实践检验的、可落地的Web集群构建与运维方案,适用于从创业公司到大型互联网企业的多种业务场景,为构建稳健的线上服务提供了坚实的技术支撑。