当前位置: 首页 > news >正文

web集群

项目名称

基于keepalived+nginx构建一个高可用、高性能的web集群

项目架构图

项目描述

基本描述

构建一个基于 Nginx 的 7 层负载均衡的 Web 集群系统,模拟企业级业务环境,实现高并发和高可用性的 Web 集群。通过压力测试验证集群性能,找出瓶颈并进行优化。

详细描述

项目名称

基于 Keepalived + Nginx 环境构建一个高可用、高性能的 Web 集群项目

项目环境

Linux服务器9台(centos 7.9)、nginx-1.25.2 、ab 2.3 、nfs4 、Prometheus 2.34.0 、node_exporter-1.4.0、grafana 10.0.0 、keepalived 2.1.5 、anislbe 2.9.27、bind

serverip
web-1192.168.0.11
web-2192.168.0.12
web-3192.168.0.13
LB-1192.168.0.100
LB-2192.168.0.200
dns192.168.0.20
nfs192.168.0.21
Prometheus192.168.0.22
ansible192.168.0.23

项目步骤

1、搭建 Ansible 服务器。建立 SSH 免密通道。编写 Playbook,通过一键脚本快速部署 Nginx 集群。
2、部署负载均衡器。部署 2 台 Linux 服务器作为负载均衡器。使用 Nginx 的 7 层负载均衡功能实现调度算法,采用加权轮询策略
3、搭建 NFS 服务器。保障 Nginx 集群的数据一致性。设置提供服务的后端 real-server 开机自动挂载。
4、搭建 DNS 服务器。给整个 Web 集群做域名解析。通过 DNS 域名解析将两个 VIP 绑定到一个域名,用户访问时流量被导向不同的负载均衡器上。
5、部署 Prometheus + Grafana。监控整个 Web 集群的性能。
6、安装 Keepalived 软件。在负载均衡器上安装 Keepalived。配置 2 个 VRRP 实例,互为主备,防止单点故障,实现双 VIP 的高可用功能。
7、使用压力测试工具 ab 进行压力测试。对 Web 集群进行压力测试,评估其性能。
8、优化整个 Web 集群。尝试优化集群性能,提升整体表现。包括对内核参数、Nginx 参数等进行调优。

项目中遇到的困难

1.在配置双VIP架构时,发现虚拟IP(VIP)无法正常工作,导致负载均衡器无法正常切换或提供服务。

1、可能原因:
	虚拟路由ID冲突:在Keepalived配置中,虚拟路由ID(virtual_router_id)必须在同一个网络中唯一。如果两个负载均衡器的虚拟路由ID相同,会导致冲突,VIP无法正常分配。优先级配置错误:主备负载均衡器的优先级(priority)配置不正确,可能导致两个节点都认为自己是主节点,或者无法正确切换。认证配置错误:VRRP的认证类型(auth_type)和认证密码(auth_pass)配置不一致,导致节点间无法正常通信
2、解决方法
	检查虚拟路由ID:确保每个VRRP实例的virtual_router_id在同一个网络中唯一。调整优先级:主节点的优先级应高于备节点,确保主节点能够优先获取VIP。验证认证配置:确保所有节点的认证类型和密码一致,避免通信问题。
3、结论
	在配置双VIP架构时,我遇到了VIP无法正常工作的问题。经过排查,发现是由于虚拟路由ID冲突导致的。我们立即检查了Keepalived的配置文件,发现两个负载均衡器的virtual_router_id配置相同,导致冲突。我们将其中一个实例的virtual_router_id修改为不同的值,并重新加载配置,问题得以解决。此外,我还验证了优先级和认证配置,确保主备节点能够正常切换。

2.在配置NFS时,web设置了开机自动挂载,但发现Web服务器在开机时无法正常启动。

1、可能原因:
可能原因:NFS服务器未启动:NFS服务器在Web服务器启动前未启动,导致挂载失败。挂载配置错误:/etc/fstab中的挂载配置不正确,导致系统在启动时尝试挂载失败。网络问题:网络未完全初始化,导致NFS挂载失败。
2、解决方法
解决方法:检查NFS服务器状态:确保NFS服务器在Web服务器启动前已经启动。调整挂载配置:在/etc/fstab中添加noauto选项,避免系统在启动时自动挂载。手动挂载:在系统启动后手动执行mount命令挂载NFS共享目录。
3、结论
	在配置NFS时,我们设置了开机自动挂载,但发现Web服务器在开机时无法正常启动。经过排查,发现是由于NFS服务器未启动导致的。我们立即进入单用户模式,注释掉/etc/fstab中的挂载配置,然后手动启动NFS服务器并挂载共享目录。为了避免类似问题,我们在/etc/fstab中添加了noauto选项,确保系统在启动时不会自动挂载NFS共享目录,而是通过脚本在系统启动后手动挂载。

3.在将域名绑定到VIP后,发现访问域名时无法正常解析到VIP,导致无法访问负载均衡器。

1、可能原因:
可能原因:DNS配置错误:DNS服务器的配置文件中,域名解析记录未正确配置。防火墙规则:防火墙规则阻止了VIP的流量。VRRP配置问题:Keepalived的配置文件中,vrrp_strict未注释,导致产生了一条防火墙规则,阻止了VIP的流量。
2、解决方法
解决方法:检查DNS配置:确保DNS服务器的配置文件中,域名解析记录正确无误。调整防火墙规则:确保防火墙允许VIP的流量通过。注释vrrp_strict:在Keepalived配置文件中,注释掉vrrp_strict,避免产生不必要的防火墙规则。
3、结论
	在将域名绑定到VIP后,发现访问域名时无法正常解析到VIP。经过排查,发现是由于Keepalived配置文件中的vrrp_strict未注释,导致产生了一条防火墙规则,阻止了VIP的流量。我们立即注释掉vrrp_strict,并重新加载Keepalived配置,问题得以解决。此外,我们还检查了DNS服务器的配置文件,确保域名解析记录正确无误,并调整了防火墙规则,确保VIP的流量能够正常通过。

项目心得

逐渐理解了集群的概念,对高可用高性能以及系统性能指标有了一定的认识,学习了脑裂现象的原因和解决方案,对一键安装部署与ansible的使用更加清晰。
掌握了压力测试,尝试进行系统优化和参数调整,以此来提升性能。
基础功能的软件配合搭建有了一定的了解,对今后大规模的集群打下基础,提升了整体规划与troublshooting的能力。

项目步骤

一、前期准备工作

1、关闭selinux和firewalld

# 防火墙并且设置防火墙开启不启动
service firewalld stop && systemctl disable firewalld# 临时关闭seLinux
setenforce 0# 永久关闭seLinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

2、配置静态ip地址

cd /etc/sysconfig/network-scripts/
vim  ifcfg-ens33TYPE="Ethernet"
BOOTPROTO="none"
DEVICE="ens33"
NAME="ens33"
ONBOOT="yes"
IPADDR="192.168.0.11"
PREFIX=24
GATEWAY="192.168.0.1"
DNS1=114.114.114.114# 其他服务器按照规划好的IP地址配置静态ip

3、修改主机名

hostnamectl set-hostname web-1
hostnamectl set-hostname web-2
hostnamectl set-hostname web-3hostnamectl set-hostname LB-1
hostnamectl set-hostname LB-2hostnamectl set-hostname nfs
hostnamectl set-hostname ansible
hostnamectl set-hostname Prometheus
hostnamectl set-hostname dns

二、搭建ansible服务器,建立ssh免密通道,编写playbook通过一键安装nginx的脚本快速部署nginx集群。

1、编写一键安装nginx脚本

[root@ansible ~]# cat onekey_install_nginx.sh 
#!/bin/bash#新建一个文件夹用来存放下载的nginx源码包
mkdir -p /nginx
cd /nginx#新建用户
useradd hanwei -s /sbin/nologin#下载nginx源码包
yum install wget -y
wget http://nginx.org/download/nginx-1.25.2.tar.gz#解压nginx源码包
tar xf  nginx-1.25.2.tar.gz#解决依赖关系
yum -y install  openssl openssl-devel pcre pcre-devel gcc autoconf automake make#编译前的配置
./configure  --prefix=/usr/local/scnginx99  --user=hanwei  --with-threads  --with-http_ssl_module  --with-http_v2_module --with-http_stub_status_module --with-stream#编译,开启2个进程同时编译,速度会快些
make -j 2#安装
make install#启动nginx
/usr/local/scnginx99/sbin/nginx#修改PATH变量
PATH=$PATH:/usr/local/scnginx99/sbin/
echo "PATH=$PATH:/usr/local/scnginx99/sbin/" >>/root/.bashrc#设置nginx开机启动
echo "/usr/local/scnginx99/sbin/nginx" >>/etc/rc.local
chmod +x /etc/rc.d/rc.local#关闭seLinux和firewalld
systemctl stop firewalld
#设置firewalld开机不启动
systemctl disable firewalld#临时关闭seLinux
setenforce 0
#永久关闭seLinux
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config

2、部署ansible服务器

1.下载ansible软件
[root@ansible ~]# yum install epel-release -y
[root@ansible ~]# yum install ansible -y2.建立ssh免密通道,在ansible服务器上生成密钥对,指定生成的密钥类型为 RSA。RSA 是一种非对称加密算法,广泛用于 SSH 认证。
[root@ansible .ssh]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:RwPsvRYZ/cRdqUv2JVlFKQovTUsDb+3B+27izeinC8c root@ansible
The key's randomart image is:
+---[RSA 2048]----+
|       ..... . oO|
|        .oo++.ooo|
|       . .O=+*oo |
|        .o=*.+* .|
|        S ooooo..|
|         .o .... |
|         . . E . |
|            o.=o |
|            o**+ |
+----[SHA256]-----+
[root@ansible .ssh]# ls
id_rsa  id_rsa.pub
3.上传公钥到整个web集群服务器的root用户家目录下,以实现免密码SSH登录
ssh-copy-id  -i id_rsa.pub root@192.168.0.11
ssh-copy-id  -i id_rsa.pub root@192.168.0.12
ssh-copy-id  -i id_rsa.pub root@192.168.0.13
ssh-copy-id  -i id_rsa.pub root@192.168.0.100
ssh-copy-id  -i id_rsa.pub root@192.168.0.200
ssh-copy-id  -i id_rsa.pub root@192.168.0.20
ssh-copy-id  -i id_rsa.pub root@192.168.0.21
ssh-copy-id  -i id_rsa.pub root@192.168.0.22
4.验证是否实现免密码密钥认证(远程登陆)
[root@ansible .ssh]# ssh root@192.168.0.11
[root@master ~]# exit
登出
Connection to 192.168.0.11 closed.
[root@ansible .ssh]# ssh root@192.168.0.12
[root@slave-1 ~]# exit
登出
Connection to 192.168.0.12 closed.
[root@ansible .ssh]# ssh root@192.168.0.13
[root@slave-2 ~]# exit
登出
Connection to 192.168.0.13 closed.
5.编写主机清单
[root@ansible .ssh]# cd /etc/ansible
[root@ansible ansible]# ls
ansible.cfg  hosts  roles
[root@ansible ansible]# vim hosts 
[web]
192.168.0.11
192.168.0.12
192.168.0.13
[LB]
192.168.0.100
192.168.0.200
[dns]
192.168.0.20
[nfs]
192.168.0.21
[Prometheus]
192.168.0.22
测试,这条命令尝试对名为web的主机或主机组执行ip addr命令
[root@ansible ~]# ansible  web  -m shell -a "ip add"

3、编写playbook

Playbook 的主要目的是在两个不同的主机组(web 和 LB)上自动化部署 Nginx 服务器。

创建目录:在目标服务器上创建一个指定的目录(在这个例子中是 /web),这是为了存放后续需要上传的安装脚本。
复制安装脚本:将位于 Ansible 控制节点(即运行此 Playbook 的机器)上的 Nginx 一键安装脚本 (onekey_install_nginx.sh) 复制到目标服务器上的指定目录(/web)中。
执行安装脚本:通过运行之前上传的一键安装脚本来安装 Nginx。这一步假设该脚本包含了所有必要的命令来正确地安装和配置 Nginx 服务。
#编写playbook
[root@ansible ~]# cat nginx.yaml 
- hosts: webremote_user: roottasks:- name: mkdir /webfile: path=/web state=directory- name: cp onekey_install_nginx.sh to hostscopy: src=/root/onekey_install_nginx.sh  dest=/web/onekey_install_nginx.sh  - name: install nginx shell: bash  /web/onekey_install_nginx.sh  - hosts: LBremote_user: roottasks:- name: mkdir /webfile: path=/web state=directory- name: cp onekey_install_nginx.sh to hostscopy: src=/root/onekey_install_nginx.sh  dest=/web/onekey_install_nginx.sh  - name: install nginx shell: bash  /web/onekey_install_nginx.sh  #检查playbook的语法
[root@ansible ~]# ansible-playbook --syntax-check nginx.yaml playbook: nginx.yaml#执行playbook
[root@ansible ~]# ansible-playbook nginx.yaml 

三、部署2台Linux服务器做负载均衡器,使用nginx的7/4层负载均衡功能实现,调度算法使用加权轮询。

1.负载均衡器上的配置(7层负载均衡)

vim nginx.confhttp {upstream  nginx_web {server  192.168.0.11 weight=1;server  192.168.0.12 weight=2;server  192.168.0.13 weight=5;}   server {listen   80;location / {proxy_pass http://nginx_web;}}
}[root@LB-1 conf]# nginx -t
nginx: the configuration file /usr/local/scnginx99/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/scnginx88/conf/nginx.conf test is successful[root@LB-1 conf]# nginx  -s reload[root@LB-2 conf]# nginx -t
nginx: the configuration file /usr/local/scnginx99/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/scnginx88/conf/nginx.conf test is successful[root@LB-2 conf]# nginx  -s reload

2.负载均衡器上的配置(4层负载均衡)

[root@LB-1 conf]# cat nginx.confworker_processes  2;events {worker_connections  1024;
}stream {upstream web_servers {server 192.168.0.11:80 weight=1;server 192.168.0.12:80 weight=2;server 192.168.0.13:80 weight=5;}server {listen   80  ;proxy_pass web_servers;}
}

四、搭建nfs服务器,保障nginx集群的数据一致性,并在real server中设置开机自动挂载。

1、搭建nfs服务器

1.下载nfs-utils软件
[root@nfs ~]# yum install nfs-utils -y2.新建共享目录和index.html
[root@nfs ~]# mkdir /nginx
[root@nfs ~]# cd /nginx
[root@nfs nginx]# echo "hello world" >index.html
[root@nfs nginx]# ls
index.html3.配置 NFS 导出目录
[root@nfs ~]# vim /etc/exports
[root@nfs ~]# cat /etc/exports
/nginx   192.168.0.0/24(ro,no_root_squash,sync)4.刷新nfs或者重新输出共享目录
[root@nfs ~]# exportfs -r   #输出所有共享目录
[root@nfs ~]# exportfs -v   #显示输出的共享目录
/nginx            192.168.0.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,ro,secure,no_root_squash,no_all_squash)5.重启nfs服务并且设置nfs开机自启
[root@nfs web]# systemctl restart nfs && systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.6.测试能否挂载nfs服务器共享的目录
[root@web-1 ~]# mount 192.168.0.21:/nginx   /usr/local/scnginx99/html# 验证挂载
[root@web-1 ~]# df -Th|grep nfs
192.168.0.21:/nginx      nfs4       17G  1.5G   16G    9% /usr/local/scnginx99/html#安装 NFS 客户端工具
[root@web-1 ~]# yum install nfs-utils -y[root@web-1 ~]# service nfs restart
Redirecting to /bin/systemctl restart nfs.service[root@web-1 ~]# ps aux |grep nfs
root      87368  0.0  0.0      0     0 ?        S<   16:49   0:00 [nfsd4_callbacks]
root      87374  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      87375  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      87376  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      87377  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      87378  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      87379  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      87380  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      87381  0.0  0.0      0     0 ?        S    16:49   0:00 [nfsd]
root      96648  0.0  0.0 112824   988 pts/0    S+   17:02   0:00 grep --color=auto nfs# 在另外的web-2和web-3,进行挂载
[root@web-2 ~]# mount 192.168.0.21:/nginx   /usr/local/scnginx99/html[root@web-3 ~]# mount 192.168.0.21:/nginx   /usr/local/scnginx99/html

2、设置开机自动挂载nfs文件系统

# web-1、web-2、web-3上操作vim /etc/fstab192.168.0.21:/nginx   /usr/local/scnginx99/html  nfs    defaults  0 0# 测试配置
mount -a

五、搭建dns服务器,给整个web集群做域名解析,通过dns域名解析负载均衡器将2个vip绑定到一个域名给用户访问,实现将流量导入到不同的负载均衡器上。

1.安装软件bind
yum install bind* -y2.设置named服务开机启动,启动DNS服务
systemctl enable named && systemctl start named 3.查看进程和端口号
ps aux|grep namednetstat -anplut|grep named4.修改/etc/named.conf配置文件,重启服务允许其他电脑能过来查询dns域名
[root@dns ~]# vim /etc/named.conf
options {listen-on port 53 { any; };  # 修改,允许监听所有 IP 地址的 53 端口listen-on-v6 port 53 { any; }; # 修改,允许监听 IPv6 的 53 端口directory       "/var/named";dump-file       "/var/named/data/cache_dump.db";statistics-file "/var/named/data/named_stats.txt";memstatistics-file "/var/named/data/named_mem_stats.txt";recursing-file  "/var/named/data/named.recursing";secroots-file   "/var/named/data/named.secroots";allow-query     { any; }; # 修改,允许所有客户端查询 DNS重启named服务
[root@dns ~]# service named restart 
Redirecting to /bin/systemctl restart named.service5.修改配置文件,告诉 DNS 服务器为 sc.com 域名提供解析服务,指定域名解析数据文件为 sc.com.zone
[root@dns named]# vim /etc/named.rfc1912.zones zone "sc.com" IN {type master;file "sc.com.zone";allow-update { none; };
};6.创建sc.com.zone的数据文件
[root@dns named]# pwd
/var/named[root@dns named]# ls
chroot  chroot_sdb  data  dynamic  dyndb-ldap  named.ca  named.empty  named.localhost  named.loopback  [root@dns named]# cp -a  named.localhost sc.com.zone
[root@dns named]# ls
chroot  chroot_sdb  data  dynamic  dyndb-ldap  named.ca  named.empty  named.localhost  named.loopback  sc.com.zone  7.编写sc.com.zone,定义 sc.com 域名的解析规则
[root@dns named]# cat sc.com.zone 
$TTL 1D #设置默认的 TTL(Time to Live)为 1 天
@ IN SOA  @ rname.invalid. (0 ; serial1D  ; refresh1H  ; retry1W  ; expire3H )  ; minimumNS  @A 127.0.0.1AAAA  ::1
www   A   192.168.0.188  # 将 www.sc.com 解析到 192.168.0.188
www   A   192.168.0.189  # 将 www.sc.com 解析到 192.168.0.189[root@dns named]# named-checkzone sc.com  /var/named/sc.com.zone
zone sc.com/IN: loaded serial 0
OK[root@dns named]# service named restart8.所有机器上将dns服务器指向我们搭建的dns服务器
cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 192.168.0.209.使用host查看是否能进行域名解析,测试 www.sc.com 是否能正确解析到 192.168.0.188 和 192.168.0.189
[root@dns named]# host www.sc.com
www.sc.com has address 192.168.0.188
www.sc.com has address 192.168.0.189

六、部署Prometheus+grafana来监控整个web集群的性能

1、部署Prometheus服务器

1.下载源码包
yum install wget -ywget https://github.com/prometheus/prometheus/releases/download/v2.44.0/prometheus-2.44.0.linux-amd64.tar.gz2.解压
[root@Prometheus prom]# tar xf prometheus-2.34.0.linux-amd64.tar.gz [root@Prometheus prom]# ls
prometheus-2.34.0.linux-amd64  prometheus-2.34.0.linux-amd64.tar.gz[root@Prometheus prom]# cd prometheus-2.34.0.linux-amd64[root@Prometheus prometheus-2.34.0.linux-amd64]# ls
console_libraries  consoles  LICENSE  NOTICE  prometheus  prometheus.yml  promtool3.修改环境变量
[root@Prometheus prom]# PATH=/prom:$PATH[root@Prometheus prom]# which prometheus
/prom/prometheus4.启动
#以后台模式启动 Prometheus 监控服务,并使用指定的配置文件 (/prom/prometheus.yml),同时保证即使用户登出或关闭终端,Prometheus 服务也会持续运行。输出和错误信息会被重定向到 nohup.out 文件中。
[root@Prometheus prom]# nohup prometheus --config.file=/prom/prometheus.yml &
[1] 54097
[root@Prometheus prom]# nohup: 忽略输入并把输出追加到"nohup.out"[root@Prometheus prom]# netstat -anplut|grep prom
tcp6       0      0 :::9090                 :::*                    LISTEN      54097/prometheus    
tcp6       0      0 ::1:9090                ::1:40076               ESTABLISHED 54097/prometheus    
tcp6       0      0 ::1:40076               ::1:9090                ESTABLISHED 54097/prometheus  

2、被监控主机安装node_exporter

[root@web-1 ~]# mkdir -p /node_exporter
[root@web-1 ~]# cd /node_exporter/
[root@web-1 node_exporter]# ls
node_exporter-1.4.0-rc.0.linux-amd64.tar.gz[root@web-1 node_exporter]# tar xf node_exporter-1.4.0-rc.0.linux-amd64.tar.gz [root@web-1 node_exporter]# ls
node_exporter-1.4.0-rc.0.linux-amd64.tar.gz node_exporter-1.4.0-rc.0.linux-amd64[root@web-1 node_exporter]# cd node_exporter-1.4.0-rc.0.linux-amd64[root@web-1 node_exporter-1.4.0-rc.0.linux-amd64]# PATH=/node_exporter/node_exporter-1.4.0-rc.0.linux-amd64:$PATH[root@web-1 node_exporter-1.4.0-rc.0.linux-amd64]# which node_exporter 
/node_exporter/node_exporter-1.4.0-rc.0.linux-amd64/node_exporter[root@web-1 node_exporter-1.4.0-rc.0.linux-amd64]# node_exporter --help  #查看使用手册[root@web-1 node_exporter-1.4.0-rc.0.linux-amd64]# nohup node_exporter --web.listen-address='0.0.0.0:9100' &

3、在Prometheus server里添加被监控主机

[root@Prometheus prom]# cat prometheus.yml # 添加需要监控的服务器的信息
- job_name: web-1scrape_interval: 5s  # 定义 Prometheus 抓取目标数据的时间间隔。static_configs:- targets:- 192.168.0.11:9100 # 指定要监控的目标列表- job_name: web-2scrape_interval: 5sstatic_configs:- targets:- 192.168.0.12:9100- job_name: web-3scrape_interval: 5sstatic_configs:- targets:- 192.168.0.13:9100- job_name: LB-1scrape_interval: 5sstatic_configs:- targets:- 192.168.0.100:9100- job_name: LB-2scrape_interval: 5sstatic_configs:- targets:- 192.168.0.200:9100- job_name: nfsscrape_interval: 5sstatic_configs:- targets:- 192.168.0.21:9100- job_name: dnsscrape_interval: 5sstatic_configs:- targets:- 192.168.0.20:9100- job_name: ansiblescrape_interval: 5sstatic_configs:- targets:- 192.168.0.23:9100

4、安装 grafana

yum install -y https://dl.grafana.com/enterprise/release/grafana-enterprise-10.0.0-1.x86_64.rpm#让Linux系统的systemd进程指定grafana
[root@Prometheus prom]# systemctl daemon-reload  # 启动grafana并且设置开启自启
[root@Prometheus prom]# systemctl start grafana-server && systemctl enable grafana-server# 访问192.168.0.22:3000进入Grafana界面,在grafana中配置prometheus的数据源

七、 配置Keepalived与双VIP提高负载均衡器的高可用性,防止单点故障。

定义:双 VIP 架构(Dual VIP Architecture)是一种高可用性(High Availability, HA)的网络架构设计,主要用于确保服务在出现故障时能够快速恢复,从而最大限度地减少停机时间。VIP(Virtual IP):虚拟 IP 地址,是一个逻辑 IP 地址,不与特定的物理设备绑定,而是可以动态分配给不同的服务器。
双 VIP:在系统中配置两个 VIP,使用两个或多个虚拟IP地址来提供服务。主 VIP(Primary VIP):用于对外提供服务。通常绑定到主节点(Master)
备 VIP(Secondary VIP):用于故障切换或负载均衡。当主节点故障时,备 VIP 可以接管服务

双VIP的作用
增加冗余和高可用性
防止单点故障:通过使用双VIP,即使其中一个服务器出现故障,另一个服务器可以立即接管其VIP,从而避免服务中断。
快速故障恢复:一旦检测到故障,系统可以迅速切换到备用服务器,减少停机时间,提高系统的整体可用性。
支持多种服务:如果你的环境中运行了多个独立的服务,可以通过不同的VIP来区分这些服务。例如,一个VIP用于前端Web服务,另一个VIP用于后端数据库服务。这样做的好处是可以更灵活地管理和分配资源。
负载分担:虽然Keepalived主要用于实现高可用性而不是负载均衡,但在某些场景下,你可以利用多个VIP来实现基本的负载分担。比如,将不同类型的流量导向不同的VIP,间接实现流量的初步分配。
故障隔离:如果一个VIP所在的网络出现问题,另一个VIP仍然可以正常工作,从而限制了故障的影响范围。

1、安装keepalived软件

1.安装keepalived软件,在两台负载均衡器上都安装
[root@LB-1 conf]# yum install keepalived -y
[root@LB-2 conf]# yum install keepalived -y2.修改配置文件
[root@LB-1 conf]# cd /etc/keepalived/
[root@LB-1 keepalived]# ls
keepalived.conf
[root@LB-1 keepalived]# cat keepalived.conf 
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1		# SMTP服务器地址,用于发送通知邮件smtp_connect_timeout 30		# SMTP连接超时时间router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strict					# 如果启用,则会启用严格的VRRP协议规范,可能会限制一些功能vrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_1 {	# 定义一个VRRP实例,名为VI_1state MASTER	 # 设置此实例的状态为主(master)interface ens33		# 绑定到网络接口ens33virtual_router_id 58	# 虚拟路由器ID,必须在同一虚拟路由器中的所有实例之间唯一priority 120		# 优先级,数值越大优先级越高,主节点应比备节点优先级高advert_int 1		# VRRP通告间隔,默认1秒authentication {auth_type PASS		# 认证类型为简单密码认证auth_pass 1111		# 认证密码}virtual_ipaddress {		# 虚拟IP地址列表192.168.0.188		# 分配给这个VRRP实例的虚拟IP地址}
}vrrp_instance VI_2 {		# 另一个VRRP实例,名为VI_2state BACKUP		# 设置此实例状态为备份(backup)interface ens33virtual_router_id 59priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.0.189		# 另一个虚拟IP地址}
}
[root@LB-2 keepalived]# cat keepalived.conf 
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_1 {state BACKUP		# 注意这里的状态是BACKUPinterface ens33virtual_router_id 58priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.0.188}
}vrrp_instance VI_2 {state MASTER	# 注意这里的状态是MASTER	interface ens33virtual_router_id 59priority 120advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.0.189}
}
[root@LB-1 keepalived]# service keepalived restart
Redirecting to /bin/systemctl restart keepalived.service[root@LB-22 keepalived]# service keepalived restart
Redirecting to /bin/systemctl restart keepalived.service[root@LB-2 keepalived]# ps aux|grep keepa
root       1708  0.0  0.0 123020  2032 ?        Ss   16:14   0:00 /usr/sbin/keepalived -D
root       1709  0.0  0.1 133992  7892 ?        S    16:14   0:00 /usr/sbin/keepalived -D
root       1712  0.0  0.1 133860  6160 ?        S    16:14   0:00 /usr/sbin/keepalived -D
root       1719  0.0  0.0 112832  2392 pts/0    S+   16:14   0:00 grep --color=auto keepa查看vip
[root@LB-1 keepalived]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:37:fb:39 brd ff:ff:ff:ff:ff:ffinet 192.168.0.100/24 brd 192.168.0.255 scope global noprefixroute dynamic ens33valid_lft 1075sec preferred_lft 1075secinet 192.168.0.188/32 scope global ens33valid_lft forever preferred_lft forever[root@LB-2 keepalived]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:37:fb:39 brd ff:ff:ff:ff:ff:ffinet 192.168.0.200/24 brd 192.168.0.255 scope global noprefixroute dynamic ens33valid_lft 1075sec preferred_lft 1075secinet 192.168.0.189/32 scope global ens33valid_lft forever preferred_lft forever

2、监控nginx

如果负载均衡器上的nginx程序出现问题(例如:nginx没启动),就会导致访问web集群出现问题

解决思路:如果检查到nginx进程关闭,将优先级降低30,停止它的master身份,让位给其他的机器;或者关闭keepalived服务。

第1步:编写脚本
[root@LB-1 web]# pwd
/web
[root@LB-1 web]# ls
check_nginx.sh  halt_keepalived.sh[root@LB-1 web]# cat check_nginx.sh 
#!/bin/bash#检测nginx是否正常运行
if  /usr/sbin/pidof  nginx  ;thenexit 0		# 如果找到Nginx进程,返回状态码0,表示正常
elseexit 1		# 如果没有找到Nginx进程,返回状态码1,表示异常
fi
[root@LB-1 web]# chmod +x check_nginx.sh 
#当本机成为backup的时候,立马执行下面的脚本
[root@LB-1 web]# cat halt_keepalived.sh 
#!/bin/bashservice  keepalived  stop[root@LB-1 web]# chmod +x halt_keepalived.sh
第2步:在keepalived里定义监控脚本
#Keepalived配置文件中的新增部分
#定义监控脚本chk_nginx
vrrp_script chk_nginx {
#当脚本/web/check_nginx.sh脚本执行返回值为0的时候,不执行下面的weight  -30的操作,只有脚本执行失败,返回值非0的时候,就执行执行权重值减30的操作,意味着如果Nginx服务不可用,该节点的优先级会减少30,使得其他节点有更高的机会成为主服务器
script "/web/check_nginx.sh"	# 执行的检查脚本路径
interval 1		# 每隔1秒执行一次检查
weight -30		# 如果检查失败(即Nginx未运行),降低优先级30点
}
[root@lb-1 keepalived]# cat keepalived.conf 
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 0vrrp_gna_interval 0
}#定义监控脚本chk_nginx
vrrp_script chk_nginx {
#当脚本/web/check_nginx.sh脚本执行返回值为0的时候,不执行下面的weight  -30的操作,只有脚本执行失败,返回值非0的时候,就执行执行权重值减30的操作,意味着如果Nginx服务不可用,该节点的优先级会减少30,使得其他节点有更高的机会成为主服务器
script "/web/check_nginx.sh"
interval 1
weight -30
}vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 58priority 120advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.0.188}
#调用监控脚本
track_script {
chk_nginx
}#当本机成为backup的时候,立马执行下面的脚本
notify_backup  "/web/halt_keepalived.sh"}
vrrp_instance VI_2 {state BACKUPinterface ens33virtual_router_id 59priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.0.189}
}

八、使用压力测试软件ab对web集群进行压力测试。

使用 Apache HTTP 服务器自带的基准测试工具 ApacheBench (ab) 对LB-1 进行压力测试
-c 1000:表示并发级别(concurrency level)为 1000,即同时发起 1000 个请求。
-n 20000:表示总共要发送的请求数量(requests)为 20000 次。
http://192.168.0.100/:这是目标 URL,指定了要进行压力测试的服务器地址和路径
1.下载ab软件
[root@scmaster ~]# yum install ab -y2.进行压力测试
[root@scmaster ~]# ab -c 1000  -n 20000  http://192.168.0.100/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.0.100 (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
Completed 18000 requests
Completed 20000 requests
Finished 20000 requestsServer Software:        nginx/1.25.2
Server Hostname:        192.168.0.100
Server Port:            80Document Path:          /
Document Length:        620 bytesConcurrency Level:      1000
Time taken for tests:   8.049 seconds
Complete requests:      20000
Failed requests:        2535(Connect: 0, Receive: 0, Length: 2535, Exceptions: 0)
Write errors:           0
Non-2xx responses:      35
Total transferred:      17039510 bytes
HTML transferred:       12381995 bytes
Requests per second:    2484.72 [#/sec] (mean)   # 目前测试的最大并发数(吞吐量)
Time per request:       402.460 [ms] (mean)
Time per request:       0.402 [ms] (mean, across all concurrent requests)
Transfer rate:          2067.30 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0  198 482.9     46    7035
Processing:    20  165 156.7    118    1822
Waiting:        3  151 152.9    104    1797
Total:         31  363 502.2    183    7194Percentage of the requests served within a certain time (ms)50%    18366%    25475%    31580%    39590%   112495%   120998%   149899%   3120100%   7194 

测试概述

并发级别:1000(同时发起的请求数)
总请求次数:20000
目标服务器:Nginx 1.25.2,运行在 192.168.0.100,端口 80
文档路径:根目录 /
文档长度:620 字节总耗时:完成所有请求花费了大约 8.049 秒。请求完成情况:
成功完成的请求总数为 20000。
失败的请求总数为 2535吞吐量
平均每秒处理的请求数(Requests per second)为 2484.72 次,这表明服务器在高并发情况下仍能保持较高的处理速度。响应时间:
平均每个请求的响应时间为 402.460 毫秒(包括连接时间和处理时间)。结论
尽管存在一定的失败请求和非2xx响应,但整体来看,服务器能够处理高达 1000 并发用户的访问,平均每秒处理近 2500 次请求,显示出较强的负载能力。

九、尝试去优化整个web集群,提升性能(内核参数、nginx参数的调优)

1、内核参数调优

[root@web-1 ~]# ulimit -n  100001   [root@web-1 ~]# ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 14826
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 100001	#设置将允许单个进程最多打开 100001 个文件或网络连接。
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 14826
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

2、nginx参数调优

[root@web-1 conf]# cat nginx.conf# 根据cpu核心的数量去修改(我的cpu核心数量是2),这里设置为2,意味着Nginx将使用2个工作进程。
worker_processes  2;# 并发数量,同时可以允许多少人同时访问nginx, 每个工作进程可以处理的最大并发连接数为2048。
events {worker_connections  2048; 
}http { # 65秒后nginx会主动断开连接,指定了客户端与Nginx之间的Keep-Alive连接保持的时间,超过这个时间后Nginx会主动断开连接以释放资源keepalive_timeout  65;}

3、参考云服务器的参数调优

[root@aliyun ~]# sysctl -p
vm.swappiness = 0  # 减少交换分区的使用,尽量避免内存页被换出到磁盘。
kernel.sysrq = 1   # 启用Magic SysRq键,有助于在系统崩溃时进行调试。
net.ipv4.neigh.default.gc_stale_time = 120  # ARP缓存条目的过期时间设为120秒。
net.ipv4.conf.all.rp_filter = 0  # 关闭反向路径过滤,这可能在某些特定网络配置下需要禁用。
net.ipv4.conf.default.rp_filter = 0  # 默认接口上也禁用反向路径过滤。
net.ipv4.conf.default.arp_announce = 2  # 在发送ARP请求时,尽量使用最佳本地地址。
net.ipv4.conf.lo.arp_announce = 2  # 对回环接口应用同样的ARP策略。
net.ipv4.conf.all.arp_announce = 2  # 对所有接口应用同样的ARP策略。
net.ipv4.tcp_max_tw_buckets = 5000  # 设置TCP TIME_WAIT状态的最大套接字数量。
net.ipv4.tcp_syncookies = 1  # 启用SYN Cookies,帮助防御SYN Flood攻击。
net.ipv4.tcp_max_syn_backlog = 1024  # 增加SYN队列长度,允许更多的未完成连接。
net.ipv4.tcp_synack_retries = 2  # 减少SYN/ACK重试次数,加快连接建立过程。
net.ipv4.tcp_slow_start_after_idle = 0  # 禁用TCP慢启动算法在空闲后的重新启动,提高性能。

脚本

1、初始化脚本init_env.sh

set -e
#!/bin/bash#第1步:下载阿里云的centos-7.reop文件
cd  /etc/yum.repos.dcurl  -O http://mirrors.aliyun.com/repo/Centos-7.repo
#新建存放centos官方提供的repo文件,因为官方不提供服务了
mkdir  backup
mv  CentOS-*  backup#第2步:修改主机名
hostnamectl  set-hostname  $1#第3步:配置静态ip地址
cat  >/etc/sysconfig/network-scripts/ifcfg-ens33 <<EOF
BOOTPROTO="none"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=$2
PREFIX=24
GATEWAY=$3
DNS1=114.114.114.114
DNS2=222.246.129.80
EOF#启动网络服务
service  network  restart#第4步: 关闭selinux和firewalld防火墙服务
systemctl stop  firewalld
systemctl disable firewalld#修改/etc/selinux/config文件里的enforcing为disabled
sed  -i  '/SELINUX=/  s/enforcing/disabled/'  /etc/selinux/config 
#重启服务器
reboot

2、linux安装mysql,onekey_install_mysql_binary_v3.sh

#!/bin/bash#解决软件的依赖关系并且安装需要工具
yum  install cmake ncurses-devel gcc  gcc-c++  vim libaio lsof bzip2 openssl-devel ncurses-compat-libs net-tools -y#解压mysql二进制安装包
tar  xf  mysql-5.7.37-linux-glibc2.12-x86_64.tar.gz#移动mysql解压后的文件到/usr/local下改名叫mysql
#/usr/local/mysql 是mysql的安装目录 --》门店
mv mysql-5.7.37-linux-glibc2.12-x86_64 /usr/local/mysql#新建组和用户 mysql
groupadd mysql
#mysql这个用户的shell 是/bin/false 属于mysql组 
useradd -r -g mysql -s /bin/false mysql#关闭firewalld防火墙服务,并且设置开机不要启动
service firewalld stop
systemctl  disable  firewalld#临时关闭selinux
setenforce 0
#永久关闭selinux
sed -i '/^SELINUX=/ s/enforcing/disabled/'  /etc/selinux/config#新建存放数据的目录 --》仓库
mkdir  /data/mysql -p
#修改/data/mysql目录的权限归mysql用户和mysql组所有,这样mysql用户启动的mysql进程可以对这个文件夹进行读写了
chown mysql:mysql /data/mysql/
#只是允许mysql这个用户和mysql组可以访问,其他人都不能访问
chmod 750 /data/mysql/#进入/usr/local/mysql/bin目录
cd /usr/local/mysql/bin/#初始化mysql
./mysqld  --initialize --user=mysql --basedir=/usr/local/mysql/  --datadir=/data/mysql  &>passwd.txt#让mysql支持ssl方式登录的设置
./mysql_ssl_rsa_setup --datadir=/data/mysql/#获得临时密码
tem_passwd=$(cat passwd.txt |grep "temporary"|awk '{print $NF}')#$NF表示最后一个字段# abc=$(命令)  优先执行命令,然后将结果赋值给abc # 修改PATH变量,加入mysql bin目录的路径
#临时修改PATH变量的值
export PATH=/usr/local/mysql/bin/:$PATH
#重新启动linux系统后也生效,永久修改
echo  'PATH=/usr/local/mysql/bin:$PATH' >>/root/.bashrc#复制support-files里的mysql.server文件到/etc/init.d/目录下叫mysqld
cp  ../support-files/mysql.server   /etc/init.d/mysqld#修改/etc/init.d/mysqld脚本文件里的datadir目录的值
sed  -i '70c  datadir=/data/mysql'  /etc/init.d/mysqld#生成/etc/my.cnf配置文件
cat  >/etc/my.cnf  <<EOF
[mysqld_safe][client]
socket=/data/mysql/mysql.sock[mysqld]
socket=/data/mysql/mysql.sock
port = 3306
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8[mysql]
auto-rehash
prompt=\\u@\\d \\R:\\m  mysql>
EOF#修改内核的open file的数量
ulimit -n 1000000
#设置开机启动的时候也配置生效
echo "ulimit -n 1000000" >>/etc/rc.local
chmod +x /etc/rc.d/rc.local#将mysqld添加到linux系统里服务管理名单里
/sbin/chkconfig --add mysqld
#设置mysqld服务开机启动
/sbin/chkconfig mysqld on#启动mysqld进程
service mysqld start#初次修改密码需要使用--connect-expired-password 选项
#-e 后面接的表示是在mysql里需要执行命令  execute 执行
#set password='Sanchuang123#';  修改root用户的密码为Sanchuang123#
mysql -uroot -p$tem_passwd --connect-expired-password   -e  "set password='Sanchuang123#';"#检验上一步修改密码是否成功,如果有输出能看到mysql里的数据库,说明成功。
mysql -uroot -p'Sanchuang123#'  -e "show databases;"

3、在其他机器上安装node_exporter的脚本,install_node_exporter.sh

#!/bin/bashtar xf /root/node_exporter-1.4.0-rc.0.linux-amd64.tar.gz  -C /
cd  /
mv node_exporter-1.4.0-rc.0.linux-amd64/ node_exporter
cd /node_exporter/
echo 'PATH=/node_exporter/:$PATH' >>/etc/profile#生成nodeexporter.service文件
cat >/usr/lib/systemd/system/node_exporter.service  <<EOF
[Unit]
Description=node_exporter
[Service]
ExecStart=/node_exporter/node_exporter --web.listen-address 0.0.0.0:9090 
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF#让systemd进程识别node_exporter服务
systemctl daemon-reload
#设置开机启动
systemctl  enable node_exporter
#启动node_exporter
systemctl  start node_exporter

4、ansible备份脚本,backup_file.sh

set -e
#!/bin/bash#/etc/passwd   /etc/shadow  /var/log
mkdir  -p /backup
tar czf  /backup/$(date +%Y%m%d)_passwd_shadow_log.tar.gz  /etc/passwd  /etc/shadow  /var/log[root@ansible-prome ansible]#
先在所有的节点服务器上创建/backup目录
[root@ansible-prome ansible]#   ansible all -m shell -a "mkdir -p /backup"
[root@ansible-prome ansible]# ansible all -m copy -a "src=/etc/ansible/backup_file.sh  dest=/backup"
每天的2:30执行
[root@ansible-prome ansible]# ansible all -m cron  -a "minute=30 hour=2 job='bash /backup/backup_file.sh' name=backup_file "

5、使用playbook完成任务

0.卸载nginx
1.yum安装nginx
2.修改nginx的配置的端口号9900sed命令--》shell手工修改配置里的端口号
3.将配置文件下发到所有的node节点服务器
4.启动nginx
5.卸载tree命令软件
6.在所有的node节点服务器上新建/scbackup目录
7.编写一个脚本backup_file.sh 实现备份/etc/passwd和/etc/shadow文件到/backup下,文件名里包含当天的日期,例如2019-7-10-passwd_shadow.tar.gz 添加一个计划任务,每天的5:30去执行,在所有的node节点服务器上实施。
install_nginx.yaml[root@ansible-prome ansible]# cd /playbook/
[root@ansible-prome playbook]# ls
192.168.205.133  redis.conf  redis_first.yaml  redis_second.yaml  redis_third.yaml
[root@ansible-prome playbook]#
先准备一个nginx.conf配置文件
[root@ansible-prome playbook]# yum  install  nginx -y
[root@ansible-prome playbook]# cp /etc/nginx/nginx.conf  /playbook/
[root@ansible-prome playbook]# vim  /playbook/nginx.conflisten       9900;  #将80修改为9900listen       [::]:9900;  #将80修改为9900
[root@ansible-prome playbook]# vim install_nginx.yaml 
[root@ansible-prome playbook]# cat install_nginx.yaml 
- hosts: webremote_user: roottasks:- name: remove nginxyum: name=nginx state=removed- name: install nginxyum: name=nginx state=installed- name: copy nginx.conf filecopy: src=/playbook/nginx.conf  dest=/etc/nginx/nginx.conf
#  - name: use sed modify nginx.conf
#   shell: sed -i '/listen/ s/80/9900/'  /etc/nginx/nginx.conf- name: start nginxservice:  name=nginx  state=started- name: remove treeyum: name=tree  state=removed- name: mkdir /scbackupshell: mkdir -p /scbackup- name: crontab cron: minute=30 hour=5 job='bash /backup/backup_file.sh' name=backup_file3
[root@ansible-prome playbook]# ansible-playbook --syntax-check install_nginx.yaml playbook: install_nginx.yaml
[root@ansible-prome playbook]# 
执行playbook脚本
[root@ansible-prome playbook]# ansible-playbook install_nginx.yaml 

相关文章:

web集群

项目名称 基于keepalivednginx构建一个高可用、高性能的web集群 项目架构图 项目描述 基本描述 构建一个基于 Nginx 的 7 层负载均衡的 Web 集群系统&#xff0c;模拟企业级业务环境&#xff0c;实现高并发和高可用性的 Web 集群。通过压力测试验证集群性能&#xff0c;找…...

HTMLCSS :下雪了

这段代码创建了一个动态的雪花飘落加载动画&#xff0c;通过 CSS 技术实现了雪花的下落和消失效果&#xff0c;为页面添加了视觉吸引力和动态感。 大家复制代码时&#xff0c;可能会因格式转换出现错乱&#xff0c;导致样式失效。建议先少量复制代码进行测试&#xff0c;若未能…...

Kafka SSL(TLS)安全协议

文章目录 Kafka SSL&#xff08;TLS&#xff09;安全协议1. Kafka SSL 的作用1.1 数据加密1.2 身份认证1.3 数据完整性1.4 防止中间人攻击1.5 确保安全的分布式环境1.6 防止拒绝服务&#xff08;DoS&#xff09;攻击 2. Kafka SSL 配置步骤&#xff08;1&#xff09;创建 SSL 证…...

WebForms SortedList 深度解析

WebForms SortedList 深度解析 引言 在Web开发领域,对于数据结构的理解与应用至关重要。其中,SortedList类在WebForms中是一个常用的数据结构,它能够帮助开发者高效地管理有序数据集合。本文将深入解析SortedList类在WebForms中的应用,包括其基本概念、常用方法、性能特点…...

项目集成Spring Security认证部分

一、需求分析 在本项目中&#xff0c;使用了Spring Security框架来进行认证和授权管理。由于是前后端分离的项目&#xff0c;所有认证的请求需要通过Token来验证身份&#xff0c;系统中包括了用户登录、角色授权以及资源访问控制等功能。 系统中的资源控制&#xff1a; 白名单…...

【PyTorch】7.自动微分模块:开启神经网络 “进化之门” 的魔法钥匙

目录 1. 梯度基本计算 2. 控制梯度计算 3. 梯度计算注意 4. 小节 个人主页&#xff1a;Icomi 专栏地址&#xff1a;PyTorch入门 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活…...

【算法】回溯算法专题① ——子集型回溯 python

目录 引入变形实战演练总结 引入 子集 https://leetcode.cn/problems/subsets/description/ 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 …...

Nginx 安装配置指南

Nginx 安装配置指南 引言 Nginx 是一款高性能的 HTTP 和反向代理服务器&#xff0c;同时也可以作为 IMAP/POP3/SMTP 代理服务器。由于其稳定性、丰富的功能集以及低资源消耗而被广泛应用于各种场景。本文将为您详细介绍 Nginx 的安装与配置过程。 系统要求 在安装 Nginx 之…...

深度学习 DAY3:NLP发展史

NLP发展史 NLP发展脉络简要梳理如下&#xff1a; (远古模型&#xff0c;上图没有但也可以算NLP&#xff09; 1940 - BOW&#xff08;无序统计模型&#xff09; 1950 - n-gram&#xff08;基于词序的模型&#xff09; (近代模型&#xff09; 2001 - Neural language models&am…...

Spring Data JPA 实战:构建高性能数据访问层

1 简介 1.1 Spring Data JPA 概述 1.1.1 什么是 Spring Data JPA? Spring Data JPA 是 Spring Data 项目的一部分,旨在简化对基于 JPA 的数据库访问操作。它通过提供一致的编程模型和接口,使得开发者可以更轻松地与关系型数据库进行交互,同时减少了样板代码的编写。Spri…...

全程Kali linux---CTFshow misc入门(25-37)

第二十五题&#xff1a; 提示&#xff1a;flag在图片下面。 直接检查CRC&#xff0c;检测到错误&#xff0c;就直接暴力破解。 暴力破解CRC的python代码。 import binascii import struct def brute_force_ihdr_crc(filename): # 读取文件二进制数据 with open(filen…...

【Elasticsearch】match_bool_prefix 查询 vs match_phrase_prefix 查询

Match Bool Prefix Query vs. Match Phrase Prefix Query 在 Elasticsearch 中&#xff0c;match_bool_prefix 查询和 match_phrase_prefix 查询虽然都支持前缀匹配&#xff0c;但它们的行为和用途有所不同。以下是它们之间的主要区别&#xff1a; 1. match_bool_prefix 查询…...

被裁与人生的意义--春节随想

还有两个月就要被迫离开工作了十多年的公司了&#xff0c;不过有幸安安稳稳的过了一个春节&#xff0c;很知足! 我是最后一批要离开的&#xff0c;一百多号同事都没“活到”蛇年。看着一批批仁人志士被“秋后斩首”&#xff0c;马上轮到我们十来个&#xff0c;个中滋味很难言清…...

DNS缓存详解(DNS Cache Detailed Explanation)

DNS缓存详解 清空DNS缓存可以让网页访问更快捷。本文将从什么是DNS缓存、为什么清空DNS缓存、如何清空DNS缓存、清空DNS缓存存在的问题四个方面详细阐述DNS缓存清空的相关知识。 一、什么是DNS缓存 1、DNS缓存的定义&#xff1a; DNS缓存是域名系统服务在遇到DNS查询时自动…...

深度学习之“线性代数”

线性代数在深度学习中是解决多维数学对象计算问题的核心工具。这些数学对象包括标量、向量、矩阵和张量&#xff0c;借助它们可以高效地对数据进行操作和建模。以下将详细介绍这些数学对象及其在深度学习中的典型用途。 数学对象概述 标量 标量是最简单的数学对象&#xff0…...

【论文阅读】RAG-Reward: Optimizing RAG with Reward Modeling and RLHF

研究背景 研究问题&#xff1a;这篇文章要解决的问题是如何优化检索增强生成&#xff08;RAG&#xff09;系统&#xff0c;特别是通过奖励建模和人类反馈强化学习&#xff08;RLHF&#xff09;来提高大型语言模型&#xff08;LLMs&#xff09;在RAG任务中的效果。研究难点&…...

新一代搜索引擎,是 ES 的15倍?

Manticore Search介绍 Manticore Search 是一个使用 C 开发的高性能搜索引擎&#xff0c;创建于 2017 年&#xff0c;其前身是 Sphinx Search 。Manticore Search 充分利用了 Sphinx&#xff0c;显着改进了它的功能&#xff0c;修复了数百个错误&#xff0c;几乎完全重写了代码…...

鸿蒙物流项目之实现广告页

目录&#xff1a; 1、广告页布局2、倒计时的实现 1、广告页布局 鸿蒙官方有提供实现广告页的方法&#xff0c;这里我们不使用&#xff0c;使用自定义广告页。 2、倒计时的实现 在页面加载时实现倒计时功能&#xff0c;在页面倒计时为0时跳转其他页面后销毁页面后同时也要销毁定…...

自制虚拟机(C/C++)(二、分析引导扇区,虚拟机读二进制文件img软盘)

先修复上一次的bug&#xff0c;添加新指令&#xff0c;并增加图形界面 #include <graphics.h> #include <conio.h> #include <windows.h> #include <commdlg.h> #include <iostream> #include <fstream> #include <sstream> #inclu…...

S4 HANA给科目分配允许记账的税码

本文主要介绍在S4 HANA OP中给科目分配允许记账的税码相关设置。具体请参照如下内容&#xff1a; 1. 给科目分配允许记账的税码 以上配置定义了总账科目可以使用什么税码进行记账。通常在科目主数据中会明确总账科目的“Tax Category”来请明确总账科目可以使用什么类型的税码…...

【LeetCode 刷题】回溯算法-组合问题

此博客为《代码随想录》二叉树章节的学习笔记&#xff0c;主要内容为回溯算法组合问题相关的题目解析。 文章目录 77. 组合216.组合总和III17.电话号码的字母组合39. 组合总和40. 组合总和 II 77. 组合 题目链接 class Solution:def combinationSum3(self, k: int, n: int) …...

Automatic Prefix Caching

APC技术&#xff0c;遇到新prompt和老prompt前缀完全相等的&#xff0c;则复用老prompt的KV cache&#xff0c;避免重新计算。 VLLM代码实例&#xff1a; # set enable_prefix_cachingTrue to enable APC llm LLM(modellmsys/longchat-13b-16k,enable_prefix_cachingTrue ) 应…...

DDD - 领域事件_解耦微服务的关键

文章目录 Pre领域事件的核心概念领域事件的作用领域事件的识别领域事件的技术实现领域事件的运行机制案例领域事件驱动的优势 Pre DDD - 微服务设计与领域驱动设计实战(中)_ 解决微服务拆分难题 EDA - Spring Boot构建基于事件驱动的消息系统 领域事件的核心概念 领域事件&a…...

吴晓波 历代经济变革得失@简明“中国经济史” - 读书笔记

目录 《历代经济变革得失》读书笔记一、核心观点二、主要内容&#xff08;一&#xff09;导论&#xff08;二&#xff09;春秋战国时期&#xff08;三&#xff09;汉代&#xff08;四&#xff09;北宋&#xff08;五&#xff09;明清时期&#xff08;六&#xff09;近现代&…...

Ubuntu下的Doxygen+VScode实现C/C++接口文档自动生成

Ubuntu下的DoxygenVScode实现C/C接口文档自动生成 Chapter1 Ubuntu下的DoxygenVScode实现C/C接口文档自动生成1、 Doxygen简介1. 安装Doxygen1&#xff09;方法一&#xff1a;2&#xff09;方法二&#xff1a;2. doxygen注释自动生成插件3. doxygen注释基本语法4. doxygen的生成…...

论文阅读:Realistic Noise Synthesis with Diffusion Models

这篇文章是 2025 AAAI 的一篇工作&#xff0c;主要介绍的是用扩散模型实现对真实噪声的仿真模拟 Abstract 深度去噪模型需要大量来自现实世界的训练数据&#xff0c;而获取这些数据颇具挑战性。当前的噪声合成技术难以准确模拟复杂的噪声分布。我们提出一种新颖的逼真噪声合成…...

【Linux系统】计算机世界的基石:冯诺依曼架构与操作系统设计

文章目录 一.冯诺依曼体系结构1.1 为什么体系结构中要存在内存&#xff1f;1.2 冯诺依曼瓶颈 二.操作系统2.1 设计目的2.2 系统调用与库函数 一.冯诺依曼体系结构 冯诺依曼体系结构&#xff08;Von Neumann Architecture&#xff09;是计算机的基本设计理念之一&#xff0c;由…...

p1044 栈

两种递推细节不同 1,将1和n在序列末尾的情况单独放出来处理&#xff0c;因为dp[0]0&#xff1b; 2,将所有情况统一处理&#xff0c;这种情况就要要求dp[1]1; 这里的n在解题中可以看做是元素数量 思路是&#xff0c;根据出栈最后一个元素,统计它前面的元素数量的输出序列数和…...

x86-64数据传输指令

关于汇编语言一些基础概念的更详细的介绍&#xff0c;可移步MIPS指令集&#xff08;一&#xff09;基本操作_mips指令 sw-CSDN博客 该指令集中一个字2字节。 该架构有16个64位寄存器&#xff0c;名字都以%r开头&#xff0c;每个寄存器的最低位字节&#xff0c;低1~2位字节&…...

C++11新特性之lambda表达式

1.介绍 C11引入了lambda表达式。lambda表达式提供一种简洁的方式来定义匿名函数对象&#xff0c;使得在需要临时定义一个函数时非常方便。 2.lambda表达式用法 lambda表达式的基本用法为&#xff1a; [捕获列表]&#xff08;参数列表&#xff09;->返回类型 { 函数体 …...

51单片机密码锁代码

基于液晶屏外设写的. main.c #include <REGX52.H> #include "LCD1602.h" #include "MatrixKey.h" #include "Sleep.h" long password1234; long resNum0; int status0,res0,k1500; long birth2005; void main(){LCD_Init();LCD_ShowStr…...

如何使用C#的using语句释放资源?什么是IDisposable接口?与垃圾回收有什么关系?

在 C# 中,using语句用于自动释放实现了IDisposable接口的对象所占用的非托管资源,如文件句柄、数据库连接、图形句柄等。其使用方式如下: 基础用法 声明并初始化资源对象:在using关键字后的括号内声明并初始化一个实现了IDisposable接口的对象。使用资源:在using语句块内…...

【Unity3D】实现横版2D游戏——单向平台(简易版)

目录 问题 项目Demo直接使用免费资源&#xff1a;Hero Knight - Pixel Art &#xff08;Asset Store搜索&#xff09; 打开Demo场景&#xff0c;进行如下修改&#xff0c;注意Tag是自定义标签SingleDirCollider using System.Collections; using System.Collections.Generic;…...

BW AO/工作簿权限配置

场景&#xff1a; 按事业部配置工作簿权限&#xff1b; 1、创建用户 事务码&#xff1a;SU01&#xff0c;用户主数据的维护&#xff0c;可以创建、修改、删除、锁定、解锁、修改密码等 用户设置详情页 2、创建权限角色 用户的权限菜单是通过权限角色分配来实现的 2.1、自定…...

TensorFlow 示例摄氏度到华氏度的转换(一)

TensorFlow 实现神经网络模型来进行摄氏度到华氏度的转换&#xff0c;可以将其作为一个回归问题来处理。我们可以通过神经网络来拟合这个简单的转换公式。 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与预测 7. 保存与加载模型 …...

一文讲解JVM中的G1垃圾收集器

接上一篇博文&#xff0c;这篇博文讲下JVM中的G1垃圾收集器 G1在JDK1.7时引入&#xff0c;在JDK9时取代了CMS成为默认的垃圾收集器&#xff1b; G1把Java堆划分为多个大小相等的独立区域Region&#xff0c;每个区域都可以扮演新生代&#xff08;Eden和Survivor&#xff09;或老…...

图书管理系统 Axios 源码__获取图书列表

目录 核心功能 源码介绍 1. 获取图书列表 技术要点 适用人群 本项目是一个基于 HTML Bootstrap JavaScript Axios 开发的图书管理系统&#xff0c;可用于 添加、编辑、删除和管理图书信息&#xff0c;适合前端开发者学习 前端交互设计、Axios 数据请求 以及 Bootstrap 样…...

mac和linux传输文件

1、使用scp命令传输 # 上传 wenqiangwq ~ % scp -pr -P 22 nginx.yaml root192.168.1.15:/tmp/ root192.168.1.15s password: nginx.yaml 100% 1736 332.4KB/s 00:00# 下载 wenqiangwq ~ % scp -pr -P 22 root192.168.1.15:/tmp/ngin…...

[CVPR 2024] AnyDoor: Zero-shot Object-level Image Customization

github.com/ali-vilab/AnyDoor.写在前面&#xff1a; 【论文速读】按照#论文十问#提炼出论文核心知识点&#xff0c;方便相关科研工作者快速掌握论文内容。过程中并不对论文相关内容进行翻译。博主认为翻译难免会损坏论文的原本含义&#xff0c;也鼓励诸位入门级科研人员阅读文…...

(动态规划路径基础 最小路径和)leetcode 64

视频教程 1.初始化dp数组&#xff0c;初始化边界 2、从[1行到n-1行][1列到m-1列]依次赋值 #include<vector> #include<algorithm> #include <iostream>using namespace std; int main() {vector<vector<int>> grid { {1,3,1},{1,5,1},{4,2,1}…...

跨组织环境下 MQTT 桥接架构的评估

论文标题 中文标题&#xff1a; 跨组织环境下 MQTT 桥接架构的评估 英文标题&#xff1a; Evaluation of MQTT Bridge Architectures in a Cross-Organizational Context 作者信息 Keila Lima, Tosin Daniel Oyetoyan, Rogardt Heldal, Wilhelm Hasselbring Western Norway …...

2025年1月22日(网络编程 udp)

系统信息&#xff1a; ubuntu 16.04LTS Raspberry Pi Zero 2W 系统版本&#xff1a; 2024-10-22-raspios-bullseye-armhf Python 版本&#xff1a;Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习…...

基于 STM32 的智能电梯控制系统

1. 引言 随着城市化进程的加速&#xff0c;高层建筑日益增多&#xff0c;电梯作为垂直交通工具的重要性愈发凸显。传统电梯控制系统在运行效率、安全性和智能化程度上已难以满足现代需求。智能电梯控制系统能够实时监测电梯的运行状态、乘客需求&#xff0c;并根据这些信息优化…...

使用 Docker(Podman) 部署 MongoDB 数据库及使用详解

在现代开发环境中&#xff0c;容器化技术&#xff08;如 Docker 和 Podman&#xff09;已成为部署和管理应用程序的标准方式。本文将详细介绍如何使用 Podman/Docker 部署 MongoDB 数据库&#xff0c;并确保其他应用程序容器能够通过 Docker 网络成功连接到 MongoDB。我们将逐步…...

npm 和 pip 安装中常见问题总结

安装路径的疑惑&#xff1a;NPM 和 PIP 的安装机制 NPM 安装路径规则&#xff1a; 依赖安装在项目目录下&#xff1a; 当你运行 npm install --save-dev jest&#xff0c;它会在当前目录&#xff08;例如 F:\&#xff09;下创建一个 node_modules 文件夹&#xff0c;把 jest 安…...

golang面试题

目录 go版本新增功能 Go 1.11 Go 1.18 Go 1.5 go关键字 &#xff1a; 1. 用于声明的关键字 2. 控制流关键字 3. 包相关关键字 4. 并发相关关键字 5. 异常处理关键字 6. 接口和类型断言关键字 go数据类型&#xff1a; 复合数据类型 引用数据类型 接口类型 GC垃…...

基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 3.核心程序 .…...

Install Python

目录 1.Install Python 1.安装Python 3 2.在Windows上安装Python 3.在Mac上安装Python 4.在Linux上安装Python 5.运行Python 2.Python解释器 1.CPython 2.IPython 3.PyPy 4.Jython 5.IronPython 6.小结 1.Install Python 因为Python是跨平台的&#xff0c;它可以…...

云计算部署模式全面解析

目录 引言公有云私有云混合云三种部署模式的对比选择建议未来趋势结语 1. 引言 随着云计算技术的快速发展,企业在选择云部署模式时面临着多种选择。本文将深入探讨云计算的三种主要部署模式:公有云、私有云和混合云,帮助读者全面了解它们的特点、优势及适用场景。 © iv…...

tomcat核心组件及原理概述

目录 1. tomcat概述 1.1 概念 1.2 官网地址 2. 基本使用 2.1下载 3. 整体架构 3.1 核心组件 3.2 从web.xml配置和模块对应角度 3.3 如何处理请求 4. 配置JVM参数 5. 附录 1. tomcat概述 1.1 概念 什么是tomcat Tomcat是一个开源、免费、轻量级的Web服务器。 Tomca…...