Web集群管理实战指南:从架构到运维

本文档是一份全面且深入的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 响应报文
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

Nginx配置文件详解-CSDN博客

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 网址

http://www.baidu.com

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

  1. 2个独立的用户.

  2. Linux的root用户用于进入和管理整个Linux系统.

  3. 数据库的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

使用虚拟机模拟环境:

  1. 添加普通用户,设置sudo权限 NOPASSWD: ALL
  2. 修改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
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服务器上,登录状态不统一,造成用户频繁需要登录.
  • 会话: 用户的登录状态,购物车状态
  • 目标: 如何实现会话保持/会话共享.
  • 开发中核心概念,知晓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重定向概述
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 &quot;%r&quot; %s %b" />

</Host>
  • tomcatngx配置文件对比
名称 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

" '&quot'表示双引号

sh 复制代码
pattern="%h %l %u %t &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;"

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 执行过程

  • 工作流程:

    1. 防火墙是层层过滤 的,实际是按照配置规则的顺序从上到下,从前到后进行过滤

    的。
    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
  1. 指定nat表,配置POSTROUTING链

  2. 源ip是172.16.1.7这台主机进行共享上网,如果是多台(-s172.16.1.0/24)

  3. 指定使用SNAT功能,源地址转换.

  4. 通过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

共享上网流程:

  1. 防火墙添加规则 SNAT\规则 nat表 POSTROUTING

  2. 防火墙服务器 开启ip转发功能

  3. 后端节点,配置网卡,让网卡网关指向防火墙

  4. 后端节点的网卡中配置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服务从单体部署走向分布式、高可用集群的核心路径。

核心要点:

  1. 基础与度量:深刻理解HTTP协议是优化和排错的基础,而IP、PV、UV等指标是衡量服务规模和健康状况的关键。
  2. Nginx为核心:Nginx凭借其高性能、高并发和模块化特性,成为Web集群中的核心组件,既可作为静态资源服务器、动态请求代理,也可作为负载均衡器。
  3. 架构是关键:通过"代理+负载均衡"将流量智能分发至后端多台应用服务器,是实现水平扩展、提升并发处理能力和容灾能力的核心架构。
  4. 可用性保障:利用Keepalived实现虚拟IP(VIP)的故障自动切换,是构建无单点故障高可用集群的经典模式,需警惕并解决"脑裂"问题。
  5. 全栈能力:完整的集群管理需涵盖不同技术栈,包括LNMP动态网站部署、Tomcat Java应用集群的会话管理及JVM优化。
  6. 安全与优化:安全(如iptables防火墙规则、HTTPS)与性能优化(如Nginx/Tomcat参数调优)贯穿于架构设计、部署和运维的全生命周期,是保障服务稳定、高效、安全运行的必要条件。

本指南所呈现的内容,是一套经过实践检验的、可落地的Web集群构建与运维方案,适用于从创业公司到大型互联网企业的多种业务场景,为构建稳健的线上服务提供了坚实的技术支撑。

相关推荐
石小千2 小时前
Linux清除缓存
linux·运维
weixin_516023072 小时前
VESTA在Linux下的安装
linux·运维·服务器
有味道的男人2 小时前
平衡接入京东关键词API利弊的核心策略
大数据·运维
江湖有缘2 小时前
从零开始:基于 Docker Compose部署高可用 Miniflux RSS阅读器
运维·docker·容器
沛沛老爹2 小时前
Web转AI架构篇 Agent Skills vs MCP:工具箱与标准接口的本质区别
java·开发语言·前端·人工智能·架构·企业开发
ZKNOW甄知科技2 小时前
IT自动分派单据:让企业服务流程更智能、更高效的关键技术
大数据·运维·数据库·人工智能·低代码·自动化
运维有小邓@2 小时前
Log360 的可扩展架构实践:常见场景
运维·网络·架构
小光学长2 小时前
基于Web的长江游轮公共服务系统j225o57w(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库
热心市民R先生2 小时前
IGH EtherCAT 主站核心文件体系全解析:构成、区别与运维实践
运维·服务器·网络