二阶段测试

news2024/11/16 2:19:48

二阶段测试

在这里插入图片描述

1、部署框架前准备工作

服务器类型部署组件ip地址
DR1调度服务器 主(ha01)Keepalived+LVS-DR192.168.168.21
DR2调度服务器 备 (ha02)Keepalived+LVS-DR192.168.168.22
web1节点服务器 (slave01)Nginx+Tomcat+MySQL 备+MHA manager+MHA node192.168.168.12
web2节点服务器 (slave02)Nginx+Tomcat +MySQL 备+MHA node192.168.168.13
NFS存储服务器(master01)MySQL 主+NFS+MHA node192.168.168.11
vip虚拟ip192.168.168.100
1、实验思路---服务器架构

ha01  192.168.168.21  keepalive+lvs-DR

ha02 192.168.168.22  keepalive+lvs-DR

master01 192.168.168.11  mysql+NFS+mha+node

slave01 192.168.168.12  nginx+tomcat+mysql+mha+node+manager

slave02 192.168.168.13  nginx+tomcat+mysql+mha+node

三台数据库均以mysql8.0版本安装好

虚拟地址vip:192.168.168.100

2、关闭防护墙、修改主机名

[root@localhost ~]# systemctl stop firewalld.service && setenforce 0
[root@localhost ~]# hostnamectl set-hostname ha01
[root@localhost ~]# hostnamectl set-hostname ha02
[root@localhost ~]# hostnamectl set-hostname slave01
[root@localhost ~]# hostnamectl set-hostname slave02
[root@localhost ~]# hostnamectl set-hostname master01

[root@localhost ~]# su

----------以下两台调度器同时配置---------------

3、部署LVS-DR

[root@ha01 ~]# modprobe ip_vs
[root@ha01 ~]# cat /proc/net/ip_vs

## 加载ip_vs模块,并查看版本信息

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port Forward Weight ActiveConn InActConn

[root@ha01 ~]# yum install -y ipvsadm

4、配置虚拟地址

配置虚拟ip地址(IPADDR=192.168.168.100)
[root@ha01 ~]# cd /etc/sysconfig/network-scripts/
[root@ha01 network-scripts]# ls
ifcfg-ens33  ifdown-ipv6    ifdown-TeamPort  ifup-ippp   ifup-routes       network-functions
ifcfg-lo     ifdown-isdn    ifdown-tunnel    ifup-ipv6   ifup-sit          network-functions-ipv6
ifdown       ifdown-post    ifup             ifup-isdn   ifup-Team
ifdown-bnep  ifdown-ppp     ifup-aliases     ifup-plip   ifup-TeamPort
ifdown-eth   ifdown-routes  ifup-bnep        ifup-plusb  ifup-tunnel
ifdown-ib    ifdown-sit     ifup-eth         ifup-post   ifup-wireless
ifdown-ippp  ifdown-Team    ifup-ib          ifup-ppp    init.ipv6-global
[root@ha01 network-scripts]# cp ifcfg-ens33 ifcfg-ens33:0
[root@ha01 network-scripts]# vim ifcfg-ens33:0

DEVICE=ens33:0
ONBOOT=yes
IPADDR=192.168.168.100
NETMASK=255.255.255.255
[root@ha02 network-scripts]# ifup ifcfg-ens33:0
ERROR     : [/etc/sysconfig/network-scripts/ifup-eth] Error, some other host (00:0C:29:1F:FB:2F) already uses address 20.0.0.10.
[root@ha02 network-scripts]# systemctl restart network
[root@ha02 network-scripts]# ifup ifcfg-ens33:0



[root@ha01 network-scripts]# ifup ifcfg-ens33:0 

[root@ha01 network-scripts]# ifconfig 

在这里插入图片描述

在这里插入图片描述

[root@ha01 ~]#route add -host 192.168.168.100 dev ens33:0

[root@ha01 ~]# vim /etc/rc.local


/usr/sbin/route add -host 192.168.168.100 dev ens33:0

3、配置ARP内核响应参数防止更新VIP中的MAC地址,避免发生冲突

[root@ha01 network-scripts]# vim /etc/sysctl.conf 

net.ipv4.ip_forward = 0
#proc响应关闭重定向功能
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens33.send_redirects = 0
[root@ha01 network-scripts]# sysctl -p

##加载配置文件生效

net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens33.send_redirects = 0

4、配置负载均衡分配策略

[root@ha01 network-scripts]# ipvsadm-save > /etc/sysconfig/ipvsadm

## 保持策略

[root@ha01 network-scripts]# systemctl start ipvsadm.service

## 开启ipvsadm服务

[root@ha01 network-scripts]# ipvsadm -C

## 情况策略,添加虚拟ip地址,指定负载均衡算法给两台web节点服务器

[root@ha01 network-scripts]# ipvsadm -A -t 192.168.168.100:80 -s rr
[root@ha01 network-scripts]# ipvsadm -a -t  192.168.168.100:80 -r 192.168.168.12:80 -g
[root@ha01 network-scripts]# ipvsadm -a -t 192.168.168.100:80 -r 192.168.168.13:80 -g
[root@ha01 network-scripts]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  ha01:http rr
  -> 192.168.168.12:http              Route   1      0          0         
  -> 192.168.168.12:http              Route   1      0          0         

5、配置web节点服务器(两台slave同时部署 192.168.168.12、192.168.168.13)

1、配置虚拟ip地址(VIP:192.168.168.100)

[root@slave01 ~]# cd /etc/sysconfig/network-scripts/
[root@slave01 network-scripts]# ls
ifcfg-ens33  ifdown-ipv6    ifdown-TeamPort  ifup-ippp   ifup-routes       network-functions
ifcfg-lo     ifdown-isdn    ifdown-tunnel    ifup-ipv6   ifup-sit          network-functions-ipv6
ifdown       ifdown-post    ifup             ifup-isdn   ifup-Team
ifdown-bnep  ifdown-ppp     ifup-aliases     ifup-plip   ifup-TeamPort
ifdown-eth   ifdown-routes  ifup-bnep        ifup-plusb  ifup-tunnel
ifdown-ib    ifdown-sit     ifup-eth         ifup-post   ifup-wireless
ifdown-ippp  ifdown-Team    ifup-ib          ifup-ppp    init.ipv6-global
[root@slave01 network-scripts]# cp ifcfg-ens33 ifcfg-lo:0
[root@slave01 network-scripts]# vim ifcfg-lo:0

DEVICE=lo:0
ONBOOT=yes
IPADDR=192.168.168.100
NETMASK=255.255.255.255

[root@slave01 network-scripts]# ifup ifcfg-lo:0

## 开启虚拟网卡

[root@slave01 network-scripts]# ifconfig

## 查看网卡
[root@slave01 network-scripts]# route add -host 192.168.168.100 dev lo:0
[root@slave01 network-scripts]# vim /etc/rc.local 

## 配置永久添加路由

route add -host 192.168.168.100 dev lo:0
2、配置ARP内核响应参数防止更新VIP中的MAC地址,避免发生冲突
[root@slave01 network-scripts]# vim /etc/sysctl.conf 

net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

[root@slave01 network-scripts]# sysctl -p
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

6、部署NFS存储服务器(NFS共享存储ip地址:192.168.168.11)

[root@master01 ~]# rpm -q rpcbind nfs-utils 

## 检查是否有安装nfs

rpcbind-0.2.0-42.el7.x86_64
nfs-utils-1.3.0-0.48.el7.x86_64

[root@master01 ~]# systemctl start nfs
[root@master01 ~]# systemctl start rpcbind
##开启服务

[root@master01 ~]# systemctl enable nfs

## 设置开机自启

Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
[root@master01 ~]# systemctl enable rpcbind

[root@master01 ~]# mkdir /opt/web1 /opt/web2

## 创建web目录

[root@master01 web1]# echo '<h1>This is node web1</h1>' >  /opt/web1/index.html
[root@master01 web1]# echo '<h1>This is node web2</h1>' >  /opt/web2/index.html

## 添加网页内容
[root@master01 ~]# vim /etc/exports
/opt/web1 192.168.168.0/24(ro)
/opt/web2 192.168.168.0/24(ro)
[root@master01 ~]# exportfs -rv

## 发布共享

exporting 20.0.0.0/24:/opt/web2
exporting 20.0.0.0/24:/opt/web1

7、节点服务器安装web服务(Nginx)并挂载共享目录

1、安装Nginx

将安装包拖入/opt/目录下

【安装 Nginx 服务】
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
1、安装依赖包
yum -y install pcre-devel zlib-devel gcc gcc-c++ make

2、创建运行用户
useradd -M -s /sbin/nologin nginx

3、编译安装
cd /opt
tar zxvf nginx-1.22.0.tar.gz -C /opt/

cd nginx-1.22.0/
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module

make && make install

4、优化路径
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/

5、添加 Nginx 系统服务
vim /lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target

[Unit]:这个部分定义了服务单元的元数据。
Description: 描述该服务单元的信息,描述为"nginx"。
After: 定义服务单元所依赖的其他单元,这里表示服务需要在网络加载完成之后启动。

[Service]:这个部分定义了服务的运行配置。
Type: 指定服务的类型,这里是forking,表示服务是一个后台进程(通常是fork出子进程)。
PIDFile: 指定保存主进程ID的文件路径,Nginx将会把主进程ID写入这个文件,以便Systemd可以追踪和管理进程。
ExecStart: 指定启动服务的命令。这里是启动Nginx的命令/usr/local/nginx/sbin/nginx。
ExecReload: 指定重新加载配置的命令。当执行此命令时,Systemd将发送HUP信号给主进程,Nginx将重新加载配置文件。
ExecStop: 指定停止服务的命令。当执行此命令时,Systemd将发送QUIT信号给主进程,Nginx将优雅地停止服务。
PrivateTmp: 将此项设置为true,表示为服务提供独立的临时目录。

[Install]:这个部分定义了服务的安装配置。
WantedBy: 指定服务所属的目标(target),这里是multi-user.target,表示服务在多用户模式下启动。

chmod 754 /lib/systemd/system/nginx.service
systemctl start nginx.service
systemctl enable nginx.service

2、节点服务器挂载共享目录 (slave1 slave2分别挂载/opt/web1 /opt/web2)

[root@slave01 sbin]# cd 
[root@slave01 ~]# showmount -e 192.168.168.11
Export list for 192.168.168.11:
/opt/web2 192.168.168.0/24
/opt/web1192.168.168.0/24
[root@slave01 ~]# mount.nfs 192.168.168.11:/opt/web1 /usr/local/nginx/html/
[root@slave01 ~]# cd /usr/local/nginx/html/
[root@slave01 html]# ls
index.html
[root@slave01 html]# cat index.html 

<h1>This is node web1</h1>


8、部署Nginx+Tomcat的动静分离

1、安装Tomcat作为后端服务器

将tomcat和jdk安装包放入/opt/目录下

[root@slave01 html]# cd /opt/
[root@slave01 opt]# ls
apache-tomcat-9.0.20.tar.gz  jdk-8u201-linux-x64.rpm  nginx-1.12.2  nginx-1.12.2.tar.gz  rh


[root@slave01 opt]# cd 
[root@slave01 ~]# vim tomcat.sh


#!/bin/bash
 #安装部署tomcat

systemctl stop firewalld
systemctl disable firewalld
setenforce 0

#安装JDK
cd /opt
rpm -ivh jdk-8u201-linux-x64.rpm &> /dev/null
java -version    
      
#设置JDK环境变量
cat > /etc/profile.d/java.sh <<EOF
export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar                      
export PATH=$JAVA_HOME/bin:$PATH
EOF
source /etc/profile.d/java.sh

if [ $? -eq 0 ];then
echo -e  "\033[34;1m JDK安装完成! \033[0m"
fi
java -version

#安装启动Tomcat
cd /opt
tar zxvf apache-tomcat-9.0.16.tar.gz &> /dev/null
mv apache-tomcat-9.0.16 /usr/local/tomcat
##启动tomcat 
/usr/local/tomcat/bin/startup.sh

if [ $? -eq 0 ];then
echo -e  "\033[34;1m tomcat安装完成! \033[0m"
fi
[root@slave01 ~]# chmod +x tomcat.sh 
[root@slave01 ~]# ./tomcat.sh 

2、动静分离Tomcat server配置(192.168.168.12、192.168.168.13)

配置Tomcat的动态网页显示内容

slave01 192.168.168.12

[root@slave01 opt]# mkdir /usr/local/tomcat/webapps/test

## 创建目录

[root@slave01 opt]# cd /usr/local/tomcat/webapps/
[root@slave01 webapps]# ls
docs  examples  host-manager  manager  ROOT  test
[root@slave01 webapps]# cd test/
[root@slave01 test]# vim /usr/local/tomcat/webapps/test/index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<html>

<head>
<title>tomcat1</title>
</head>

<body>
<% out.println("This is tomcat1 server");%>

<div>动态页面1</div><br/>

</body>
</html>

[root@slave01 test]# ls
index.jsp

slave01 192.168.168.13

[root@slave01 opt]# mkdir /usr/local/tomcat/webapps/test

## 创建目录

[root@slave01 opt]# cd /usr/local/tomcat/webapps/
[root@slave01 webapps]# ls
docs  examples  host-manager  manager  ROOT  test
[root@slave01 webapps]# cd test/
[root@slave01 test]# vim /usr/local/tomcat/webapps/test/index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<html>

<head>
<title>tomcat2</title>
</head>

<body>
<% out.println("This is tomcat2 server");%>

<div>动态页面2</div><br/>

</body>
</html>

[root@slave01 test]# ls
index.jsp

3、Tomcat实例主配置删除前面的 Host配置,增添新的Host配置

两个web节点服务器配置相同

[root@slave01 test]# cd /usr/local/tomcat/conf/
[root@slave01 conf]# ls
catalina.policy      context.xml           jaspic-providers.xsd  server.xml        tomcat-users.xsd
catalina.properties  jaspic-providers.xml  logging.properties    tomcat-users.xml  web.xml

[root@slave01 conf]# cp server.xml{,.bak}

## 备份配置文件

[root@slave01 conf]# vim server.xml



 <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
      <Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true" />

​    </Host>
   <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
          <Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true" />
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
     <!--   <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>
    </Engine>

  </Service>
</Server>
[root@slave01 conf]# /usr/local/tomcat/bin/shutdown.sh 

[root@slave01 conf]# /usr/local/tomcat/bin/startup.sh 

[root@slave01 conf]# netstat -natp | grep 8080

## 查看端口是否打开

tcp6       0      0 :::8080                 :::*                    LISTEN      45514/java          
4、 Nginx server 配置( 192.168.168.12、 192.168.168.13)两者配置相同
#### 

```
[root@slave01 conf]# cd /usr/local/nginx/conf/

[root@slave01 conf]# ls
fastcgi.conf            koi-utf             nginx.conf           uwsgi_params
fastcgi.conf.default    koi-win             nginx.conf.default   uwsgi_params.default
fastcgi_params          mime.types          scgi_params          win-utf
fastcgi_params.default  mime.types.default  scgi_params.default
[root@slave01 conf]# cp nginx.conf{,.bak}
[root@slave01 conf]# vim nginx.conf
##复制备份修改配置文件

  upstream tomcat {
   server 192.168.168.12:8080 weight=1;
   server 192.168.168.13:8080 weight=1;
}

server {
    listen       80;
    server_name  localhost;
    server_name  www.web1.com;
     charset utf-8;

​     location ~ .*.jsp$ {
​         proxy_pass http://tomcat;
​         proxy_set_header HOST $host;
​         proxy_set_header X-Real-IP $remote_addr;
​          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
​     }

​     location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
​         root /usr/local/nginx/html;
​         expires 10d;
​     }
```

[root@slave02 conf]# cd /usr/local/nginx/sbin/
[root@slave01 sbin]# nginx -s reload

9、 配置keeplived(主(ha01)、备(ha02)DR 服务器都需要配置)

主 DR服务器 ha01:192.168.168.21

[root@ha01 ~]# yum install ipvsadm keepalived -y
[root@ha01 ~]# cd /etc/keepalived/
[root@ha01 keepalived]# ls
keepalived.conf
[root@ha01 keepalived]# cp keepalived.conf{,.bak}
[root@ha01 keepalived]# vim keepalived.conf

## 按图修改配置文件

vim keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_01
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_iptables
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 120
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.168.100
    }
}

virtual_server 192.168.168.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 0
    protocol TCP

    real_server 192.168.168.12 80 {
        weight 1
        TCP_CHECK {
                connect_port 80
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 4
        }
    }
 real_server 192.168.168.13 80 {
         weight 1
         TCP_CHECK {
                 connect_port 80
                connect_timeout 3
                 nb_get_retry 3
                 delay_before_retry 4
         }
     }
}
      
[root@ha01 keepalived]# systemctl start keepalived.service 
[root@ha01 keepalived]# ip addr show dev ens33
[root@ha01 keepalived]# scp keepalived.conf  192.168.168.21:/etc/keepalived/

## 注意备ha02调度服务器要先下载 yum install ipvsadm keepalived -y ,在scp传输keepalived.conf文件

备 DR服务器 ha02:192.168.168.22

[root@ha01 ~]# yum install ipvsadm keepalived -y
[root@ha02 network-scripts]# cd /etc/keepalived/
[root@ha02 keepalived]# systemctl start keepalived.service 
[root@ha02 keepalived]# vim keepalived.conf 


! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_02
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
   vrrp_iptables
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.168.100
    }
}

virtual_server 192.168.168.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 0
    protocol TCP

   real_server 192.168.168.12 80 {
        weight 1
        TCP_CHECK {
                connect_port 80
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 4
        }
    }
 real_server 192.168.168.13 80 {
         weight 1
         TCP_CHECK {
                 connect_port 80
                connect_timeout 3
                 nb_get_retry 3
                 delay_before_retry 4
         }
     }
}

[root@ha01 keepalived]# systemctl start keepalived.service 
[root@ha01 keepalived]# ip addr show dev ens33                          
测试keepalived是否能主备切换成功

关闭主DR服务器ha01中的keepaliverd服务
主DR服务器ha01

10、部署MySQL集群MHA高可用

1、安装MySQL(slave01,slave02,master同时配置)
1.1、编译及安装MySQL

安装mysql8.0

[root@ha01 keepalived]# systemctl stop keepalived.service 
[root@ha01 keepalived]# ip addr





mysql8.0.30安装:
安装过程:
[root@mysql1 opt]# tar -xf mysql-8.0.30-el7-x86_64.tar.gz 

[root@mysql1 opt]# mv mysql-8.0.30-el7-x86_64 mysql

[root@mysql1 opt]# mv mysql /usr/local/

#创建程序用户管理
useradd -s /sbin/nologin mysql

#修改mysql目录和配置文件的权限
[root@mysql1 mysql]# chown -R mysql:mysql /usr/local/mysql/
[root@mysql1 mysql]# chown mysql:mysql /etc/my.cnf

#修改配置文件
[root@mysql1 bin]# vim /etc/my.cnf
[client]
port = 3306
socket=/usr/local/mysql/mysql.sock

[mysqld]
user = mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port = 3306
character-set-server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket=/usr/local/mysql/mysql.sock
bind-address = 0.0.0.0
skip-name-resolve
max_connections=2048
default-storage-engine=INNODB
max_allowed_packet=16M
server-id = 1
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION



#设置环境变量,申明/宣告mysql命令便于系统识别
[root@mysql1 mysql]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@mysql1 mysql]# source /etc/profile

#初始化数据库:
[root@mysql1 mysql]# cd /usr/local/mysql/bin/
cd /usr/local/mysql/bin/
./mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data

#设置系统识别,进行操作:
[root@mysql1 bin]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@mysql1 bin]# chmod +x /etc/init.d/mysqld
[root@mysql1 bin]# systemctl daemon-reload
[root@mysql1 bin]# systemctl restart mysqld

#初始化数据库密码:
[root@mysql1 bin]# mysqladmin -u root -p password "123456"
直接回车即可

#进入数据库:
[root@mysql1 bin]# mysql -u root -p123456
#创建用户并设置密码:
mysql> CREATE USER 'root'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec)

#赋予远程连接的权限
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
Query OK, 0 rows affected (0.00 sec)

#刷新生效
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

#修改加密方式,可以进行远程连接
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

三台数据库服务器

systemctl stop firewalld
setenforce 0

1、Master、Slave1、Slave2 节点上安装 mysql8.0

yum -y install ntp

##同步时间工具

date

##同步时间

2.修改 Master、Slave1、Slave2 节点的主机名

hostnamectl set-hostname Master01
hostnamectl set-hostname Slave01
hostnamectl set-hostname Slave02

hostnamectl set-hostname master01
su

hostnamectl set-hostname slave01
su

hostnamectl set-hostname slave02
su
##本地映射

vim /etc/hosts
192.168.168.11 master01
192.168.168.12 slave01
192.168.168.13 slave02

3.修改 Master、Slave1、Slave2 节点的 Mysql主配置文件/etc/my.cnf


##Master01 节点##
vim /etc/my.cnf
[mysqld]
server-id = 1
log_bin = master-bin
log-slave-updates = true

relay_log_recovery=1





log_bin = master-bin:
用于记录主服务器上的更改操作的日志文件。
这个配置用于主服务器,将生成的二进制日志文件保存为"master-bin"(可以是其他自定义的名称)。

log-slave-updates = true:
从服务器是否要记录它自己执行的更改操作到自己的二进制日志文件中。
设置为"true"表示从服务器会记录自己执行的更改操作,将其写入从服务器的二进制日志文件中。

relay_log_recovery=1

##配置从服务器在启动时是否执行二进制日志的恢复操作(和主库同步),1开启开启。


systemctl restart mysqld





##Slave01 节点##
vim /etc/my.cnf
server-id = 2 						#三台服务器的 server-id 不能一样
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index



log_bin = master-bin:
指定主服务器(master)的二进制日志文件名称,用于记录主服务器上的更改操作的日志文件。

relay-log = relay-log-bin:
指定从服务器的中继日志文件名称,即用于记录主服务器的二进制日志在从服务器上执行的中继日志。
从服务器会读取主服务器的二进制日志并将其记录到中继日志中。这个配置用于从服务器。

relay-log-index = slave-relay-bin.index:
指定从服务器的中继日志索引文件的名称,该索引文件用于跟踪中继日志文件的位置和顺序。
通过这个索引文件,从服务器知道哪个中继日志文件是下一个要读取和执行的。这个配置用于从服务器。

systemctl restart mysqld





###Slave02 节点##
vim /etc/my.cnf						#三台服务器的 server-id 不能一样
server-id = 3 
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index

#slave2不用设置master,指定主的备服务器为slave1即可。

systemctl restart mysqld

4.在 Master01、Slave01、Slave02 节点上都创建两个软链接

ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/

5.配置 mysql 一主两从

(1)所有数据库节点进行 mysql 授权
mysql -uroot -p123456

#从数据库同步使用
CREATE USER 'myslave'@'192.168.168.%' IDENTIFIED WITH mysql_native_password BY '123456';

GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.168.%';			
	
#manager 使用
CREATE USER 'mha'@'192.168.168.%' IDENTIFIED WITH mysql_native_password BY 'manager';
GRANT ALL PRIVILEGES ON *.* TO 'mha'@'192.168.168.%' WITH GRANT OPTION;
		

#防止从库通过主机名连接不上主库
CREATE USER 'mha'@'master01' IDENTIFIED WITH mysql_native_password BY 'manager';
GRANT ALL PRIVILEGES ON *.* TO 'mha'@'master01';

CREATE USER 'mha'@'slave01' IDENTIFIED WITH mysql_native_password BY 'manager';
GRANT ALL PRIVILEGES ON *.* TO 'mha'@'slave01';

CREATE USER 'mha'@'slave02' IDENTIFIED WITH mysql_native_password BY 'manager';
GRANT ALL PRIVILEGES ON *.* TO 'mha'@'slave02';

flush privileges;


(2)在 Master 节点查看二进制文件和同步点

show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |    1747  |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+

(3)在 Slave1、Slave2 节点执行同步操作

change master to master_host='192.168.168.11',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=1747; 

start slave;

(4)在 Slave01、Slave02 节点查看数据同步结果

show slave status\G;
//确保 IO 和 SQL 线程都是 Yes,代表同步正常。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

​ (5)两个从库必须设置为只读模式:

set global read_only=1;##set global read_only=0;关闭只读

(6)插入数据测试数据库同步
##在 Master 主库插入条数据,测试是否同步##

create database test_db;
use test_db;
create table test(id int);
insert into test(id) values (1);

底行模式:set paste 文本复制模式

mysql>set global read_only=1;一般设置为从数据库为只读

mysql>set global read_only=0;关闭数据库为只读

----------------------------------------以上主从数据库配置完成--------------------------------------------------

二、安装MHA所有组件

6.安装 MHA 软件
(1)所有服务器上都安装 MHA 依赖的环境,首先安装 epel 源

yum install epel-release --nogpgcheck -y

yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN

(2)安装 MHA 软件包,先在所有服务器上必须先安装 node 组件
对于每个操作系统版本不一样,这里 CentOS7.6选择 0.57 版本。
在所有服务器上必须先安装 node 组件,最后在 MHA-manager 节点上安装 manager 组件,
因为 manager 依赖 node 组件。

cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install

(3)在 MHA manager 节点上安装 manager 组件

cd /opt
tar zxvf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install

#manager 组件安装后在/usr/local/bin 下面会生成几个工具,主要包括以下几个:
masterha_check_ssh 检查 MHA 的 SSH 配置状况
masterha_check_repl 检查 MySQL 复制状况
masterha_manger 启动 manager的脚本
masterha_check_status 检测当前 MHA 运行状态
masterha_master_monitor 检测 master 是否宕机
masterha_master_switch 控制故障转移(自动或者 手动)
masterha_conf_host 添加或删除配置的 server 信息
masterha_stop 关闭manager

#node 组件安装后也会在/usr/local/bin 下面会生成几个脚本
(这些工具通常由 MHAManager 的脚本触发,无需人为操作)主要如下:

save_binary_logs 保存和复制 master 的二进制日志

apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的 slave

filter_mysqlbinlog 去除不必要的 ROLLBACK 事件(MHA 已不再使用这个工具)

purge_relay_logs 清除中继日志(不会阻塞 SQL 线程)

7.在所有服务器上配置无密码认证

(1)在 manager 节点上配置到所有数据库节点的无密码认证
ssh-keygen -t rsa 				#一路按回车键
ssh-copy-id 192.168.168.11
ssh-copy-id 192.168.168.12
ssh-copy-id 192.168.168.13

(2)在 master 上配置到数据库节点 slave1 和 slave2 的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.168.12
ssh-copy-id 192.168.168.13

(3)在 slave1 上配置到数据库节点 master 和 slave2 的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.168.11
ssh-copy-id 192.168.168.13

(4)在 slave2 上配置到数据库节点 master 和 slave1 的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.168.11
ssh-copy-id 192.168.168.12

8.在 manager 节点上配置 MHA
(1)在 manager 节点上复制相关脚本到/usr/local/bin 目录

cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin

//拷贝后会有四个执行文件

ll /usr/local/bin/scripts/

在这里插入图片描述

master_ip_failover #自动切换时 VIP 管理的脚本
master_ip_online_change #在线切换时 vip 的管理
power_manager #故障发生后关闭主机的脚本

send_report #因故障切换后发送报警的脚本

(2)复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录,
这里使用master_ip_failover脚本来管理 VIP 和故障切换

cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin

(3)修改内容如下:(删除原有内容,直接复制并修改vip相关参数)
vim /usr/local/bin/master_ip_failover

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';

use Getopt::Long;

my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
#############################添加内容部分#########################################
my $vip = '192.168.168.110';									#指定vip的地址
my $brdc = '192.168.168.255';								#指定vip的广播地址
my $ifdev = 'ens33';										#指定vip绑定的网卡
my $key = '1';												#指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";		#代表此变量值为ifconfig ens33:1 192.168.168.110
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";		#代表此变量值为ifconfig ens33:1 192.168.168.110 down
my $exit_code = 0;											#指定退出状态码为0
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
##################################################################################
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);

exit &main();

sub main {

print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

if ( $command eq "stop" || $command eq "stopssh" ) {

my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {

my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}

A simple system call that disable the VIP on the old_master

sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}

sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";

}

管理 MySQL 主从复制设置中的虚拟 IP 故障切换而设计的,可能用于主服务器需要切换到另一台服务器的情景。

它使用 SSH 在远程服务器上执行命令来控制虚拟 IP 地址

(4)创建 MHA 软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理 mysql 节点服务器

mkdir /etc/masterha
cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha

vim /etc/masterha/app1.cnf						#删除原有内容,直接复制并修改节点服务器的IP地址



[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
password=manager
ping_interval=1
remote_workdir=/tmp
repl_password=123456
repl_user=myslave
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.168.12 -s 192.168.168.13 
#从对主监听
shutdown_script=""
ssh_user=root
user=mha

[server1]
hostname=192.168.168.11 
#主服务器
port=3306

[server2]
candidate_master=1   
check_repl_delay=0
hostname=192.168.168.12  
#备用主服务器
port=3306

[server3]
hostname=192.168.168.13  
#从服务器2
port=3306

----------------------------------------------------------------------------------------------------------


[server default]
manager_log=/var/log/masterha/app1/manager.log      #manager日志
manager_workdir=/var/log/masterha/app1         #manager工作目录
master_binlog_dir=/usr/local/mysql/data/         #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便MHA能找到
master_ip_failover_script=/usr/local/bin/master_ip_failover  #设置自动failover时候的切换脚本,也就是上面的那个脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change  #设置手动切换时候的切换脚本
password=manager #设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
ping_interval=1 #设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
remote_workdir=/tmp #设置远端mysql在发生切换时binlog的保存位置
repl_password=123 #设置复制用户的密码
repl_user=myslave #设置复制用户的用户
report_script=/usr/local/send_report     #设置发生切换后发送的报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.168.12 -s 192.168.168.13 #指定检查的从服务器IP地址
shutdown_script=“” #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root #设置ssh的登录用户名
user=mha #设置监控用户root

[server1]
hostname=192.168.168.11
port=3306

[server2]
hostname=192.168.168.12
port=3306
candidate_master=1
#设置为候选master,设置该参数以后,发生主从切换以后将会将此从库提升为主库,
即使这个从库不是集群中最新的slave

check_repl_delay=0
#默认情况下如果一个slave落后master 超过100M的relay logs的话,MHA将不会选择该slave作为一个新的master,
因为对于这个slave的恢复需要花费很长时间;通过设置check_repl_delay=0,
MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,
因为这个候选主在切换的过程中一定是新的master

[server3]
hostname=192.168.168.13

port=3306

9.第一次配置需要在 Master 节点上手动开启虚拟IP

/sbin/ifconfig ens33:1 192.168.168.110/24

10.在 manager 节点上测试 ssh 无密码认证,如果正常最后会输出 successfully,如下所示。

masterha_check_ssh -conf=/etc/masterha/app1.cnf

在这里插入图片描述

Tue Nov 26 23:09:45 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Nov 26 23:09:45 2020 - [info] Reading application default configuration from /etc/masterha/app1.cnf…
Tue Nov 26 23:09:45 2020 - [info] Reading server configuration from /etc/masterha/app1.cnf…
Tue Nov 26 23:09:45 2020 - [info] Starting SSH connection tests…
Tue Nov 26 23:09:46 2020 - [debug]
Tue Nov 26 23:09:45 2020 - [debug] Connecting via SSH from root@192.168.80.11(192.168.80.11:22) to root@192.168.80.12(192.168.80.12:22)…
Tue Nov 26 23:09:46 2020 - [debug] ok.
Tue Nov 26 23:09:47 2020 - [debug]
Tue Nov 26 23:09:46 2020 - [debug] Connecting via SSH from root@192.168.80.12(192.168.80.12:22) to root@192.168.80.11(192.168.80.11:22)…
Tue Nov 26 23:09:47 2020 - [debug] ok.
Tue Nov 26 23:09:47 2020 - [info] All SSH connection tests passed successfully.

11.在 manager 节点上测试 mysql 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常。如下所示。
masterha_check_repl -conf=/etc/masterha/app1.cnf

在这里插入图片描述

Tue Nov 26 23:10:29 2020 - [info] Slaves settings check done.
Tue Nov 26 23:10:29 2020 - [info]
192.168.80.11(192.168.80.11:3306) (current master)
±-192.168.80.12(192.168.80.12:3306)

Tue Nov 26 23:10:29 2020 - [info] Checking replication health on 192.168.80.12…
Tue Nov 26 23:10:29 2020 - [info] ok.
Tue Nov 26 23:10:29 2020 - [info] Checking master_ip_failover_script status:
Tue Nov 26 23:10:29 2020 - [info] /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.80.11 --orig_master_ip=192.168.80.11 --orig_master_port=3306

IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.80.200===

Checking the Status of the script… OK
Tue Nov 26 23:10:29 2020 - [info] OK.
Tue Nov 26 23:10:29 2020 - [warning] shutdown_script is not defined.
Tue Nov 26 23:10:29 2020 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

12.在 manager 节点上启动 MHA

nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

#生产中java 服务启动的方式
nohup java -jar 微服务名称-( war jar)&

nohup java -jar test.jar &
tail -f nohup.out
#生产中启动jar包的方式

#限制资源启动:
nohup java -Xmx512m -Xms256m -Xss256k -XX:+UseParallelGC -jar test.jar &

-Xmx512m: 设置 Java 虚拟机最大堆内存为 512 MB。
-Xms256m: 设置 Java 虚拟机初始堆内存为 256 MB。
-Xss256k: 设置线程堆栈大小为 256 KB。
-XX:+UseParallelGC: 启用并行垃圾回收器。


–remove_dead_master_conf:该参数代表当发生主从切换后,老的主库的 ip 将会从配置文件中移除。
–manger_log:日志存放位置。
–ignore_last_failover:在缺省情况下,如果 MHA 检测到连续发生宕机,
且两次宕机间隔不足 8 小时的话,则不会进行 Failover,
之所以这样限制是为了避免 ping-pong 效应。
该参数代表忽略上次 MHA 触发切换产生的文件,
默认情况下,MHA 发生切换后会在日志记录,
也就是上面设置的日志app1.failover.complete文件,
下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,

除非在第一次切换后收到删除该文件,为了方便,这里设置为–ignore_last_failover。

13.查看 MHA 状态,可以看到当前的 master 是 master 节点。

masterha_check_status --conf=/etc/masterha/app1.cnf

app1 (pid:17761) is running(0:PING_OK), master:192.168.168.11
  1. 查看 MHA 日志,也以看到当前的 master 是 192.168.233.21,如下所示。

    cat /var/log/masterha/app1/manager.log | grep "current master"
    

    在这里插入图片描述

  2. 查看master 的 VIP 地址 192.168.233.100 是否存在,这个 VIP 地址不会因为 manager 节点停止 MHA 服务而消失。

    ifconfig  ##查看vip
    

    //若要关闭 manager 服务,可以使用如下命令。

masterha_stop --conf=/etc/masterha/app1.cnf

nore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &


#生产中java 服务启动的方式
nohup  java -jar  微服务名称-( war jar)&   

nohup java -jar test.jar &
tail -f nohup.out
#生产中启动jar包的方式

#限制资源启动:
nohup java -Xmx512m -Xms256m -Xss256k -XX:+UseParallelGC -jar test.jar &

-Xmx512m: 设置 Java 虚拟机最大堆内存为 512 MB。
-Xms256m: 设置 Java 虚拟机初始堆内存为 256 MB。
-Xss256k: 设置线程堆栈大小为 256 KB。
-XX:+UseParallelGC: 启用并行垃圾回收器。


----------------------------------------------------------------------------------------------------------

--remove_dead_master_conf:该参数代表当发生主从切换后,老的主库的 ip 将会从配置文件中移除。
--manger_log:日志存放位置。
--ignore_last_failover:在缺省情况下,如果 MHA 检测到连续发生宕机,
且两次宕机间隔不足 8 小时的话,则不会进行 Failover, 
之所以这样限制是为了避免 ping-pong 效应。
该参数代表忽略上次 MHA 触发切换产生的文件,
默认情况下,MHA 发生切换后会在日志记录,
也就是上面设置的日志app1.failover.complete文件,
下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,

除非在第一次切换后收到删除该文件,为了方便,这里设置为--ignore_last_failover。

13.查看 MHA 状态,可以看到当前的 master 是 master 节点。



masterha_check_status --conf=/etc/masterha/app1.cnf

app1 (pid:17761) is running(0:PING_OK), master:192.168.168.11


14. 查看 MHA 日志,也以看到当前的 master 是 192.168.233.21,如下所示。

    ```
    cat /var/log/masterha/app1/manager.log | grep "current master"
    ```

    [外链图片转存中...(img-PRajN5kQ-1722178621595)]

15. 查看master 的 VIP 地址 192.168.233.100 是否存在,这个 VIP 地址不会因为 manager 节点停止 MHA 服务而消失。

    ```
    ifconfig  ##查看vip
    ```

    //若要关闭 manager 服务,可以使用如下命令。

masterha_stop --conf=/etc/masterha/app1.cnf


或者可以直接采用 kill 进程 ID 的方式关闭。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1956565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【OpenCV C++20 学习笔记】图片融合

图片融合 原理实现结果展示完整代码 原理 关于OpenCV的配置和基础用法&#xff0c;请参阅本专栏的其他文章&#xff1a;垚武田的OpenCV合集 这里采用的图片熔合的算法来自Richard Szeliski的书《Computer Vision: Algorithms and Applications》&#xff08;《计算机视觉&#…

【C++】循环结构-for循环

for 循环语法格式&#xff1a; for(起始表达式;条件表达式;末尾循环体) {循环语句} 注意&#xff1a;括号内的三者也可以写出来写在循环语句里&#xff0c;但使用for循环就是为了使循环更加简洁明了&#xff0c;因此不仅以这么做 下面是一个实例 #include<iostream> …

ROS安装key NO_PUBKEY F42ED6FBAB17C654

解决方案 可以手工添加。 ROS1云课→18一键配置_linux ros1配置-CSDN博客 下载ros.key&#xff0c;然后手工添加到对应位置。 ros2407.key master zhangrelay / ros_book GitCode 问题描述 ros2ros2-20l1a001cd:~$ sudo apt update Hit:1 http://ftp.sjtu.edu.cn/ubunt…

010 仿muduo实现高性能服务器组件_Http协议模块

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;仿muduo &#x1f4d2;代码仓库&#xff1a; 项目代码 &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言Util模块设计意义整体设计代码如下 HttpRequest模块代码如下…

初始K8s

K8S 基本概念: K8S 的全称为 Kubernetes (K12345678S)&#xff0c;PS&#xff1a;“嘛&#xff0c;写全称也太累了吧&#xff0c;不如整个缩写”。 作用&#xff1a; 用于自动部署、扩展和管理“容器化&#xff08;containerized&#xff09;应用程序”的开源系统。 可以理解成…

web自动化6-pytest③实践测试用例-回归用例web自动化

# -*- coding: utf-8 -*- """ lemut_select - 业务受理 Author: duxiaowei Date: 2024/7/17 """ import timeimport allure import pytest from selenium.webdriver.common.by import By# 业务受理 allure.feature("业务受理") class …

SQL Date Functions | SQL Time Functions 概述

SQL Date Functions | SQL Time Functions 在SQL中&#xff0c;日期和时间函数是用于处理日期和时间数据的重要工具。 SQL Date Functions | SQL Time Functions函数可以从日期时间数据中提取特定的部分、执行日期计算、格式化日期时间等操作。 No.FunctionDescription描述1…

sql注入详解【从数据库架构分析】

文章目录 简介数据库的架构sql注入概念正常语句正常回显页面在页面中使用sql语句 跨库查询sql文件读写影响条件复现读写的路径的问题 sql注入请求分类sql注入请求类型sql注入请求方式&#xff1a;sql注入数据请求格式 数据库的增删改查数据库查询数据库添加数据库删除数据库修改…

【TS】TypeScript中的接口(Interface):对象类型的强大工具

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 TypeScript中的接口(Interface):对象类型的强大工具引言1. 接口的基本概念1.1 什…

MybatisPlus核心用法

MybatisPlus核心用法 目录 MybatisPlus核心用法1.使用MybatisPlus的基本步骤&#xff1a;2.MybatisPlus是如何获取实现CRUD的数据库表信息的&#xff1f;3.MybatisPlus的常用注解有哪些&#xff1f;如果表名称和实体类名称不符合约定该怎么做&#xff1f;IdType的常见类型有哪些…

IOS微软语音转文本,lame压缩音频

在IOS开发中&#xff0c;用微软进行语音转文本操作&#xff0c;并将录音文件压缩后返回 项目中遇到了利用微软SDK进行实时录音转文本操作&#xff0c;如果操作失败&#xff0c;那么就利用原始音频文件通过网络请求操作&#xff0c;最终这份文件上传到阿里云保存&#xff0c;考…

监控服务器状态,夜莺( nightingale)方案介绍

前提 选择一台服务器&#xff0c;部署一个监控服务端&#xff0c;然后在各个windows或者linux中部署数据采集节点。 类似如下结构 目前我这边采用的技术是 https://flashcat.cloud/product/nightingale/ Nightingale 的解决方案 1 部署内容 服务端&#xff08;服务端为 c…

centos7安装思源黑体

centos7安装思源黑体 下载思源字体centos7查看目前字体查看所有字体查看所有中文字体 进入字体目录将新加的字体目录添加到fonts.conf配置文件刷新字体缓存查看效果 下载思源字体 下载地址: https://github.com/adobe-fonts/source-han-sans/releases centos7查看目前字体 查…

【MyBatis】基础操作

准备工作 准备数据库表创建 springboot工程&#xff0c;选择引入对应的起步依赖&#xff08;mybatis、mysql驱动、lombok&#xff09;application.properties中引入数据库连接信息创建对应的实体类 Emp&#xff08;实体类属性采用驼峰命名&#xff09;准备Mapper接口 EmpMappe…

排序系列 之 希尔排序

&#xff01;&#xff01;&#xff01;排序仅针对于数组哦本次排序是按照升序来的哦 介绍 英文名为ShellSort&#xff0c;又称“缩小增量排序”是直接插入排序算法的一种更高效的改进版本希尔排序是把记录按下标的指定步长分组&#xff0c;然后按照每组使用直接插入排序&#…

idea一直update indexing 卡死

打开IDEA存储应用程序的本地数据文件夹&#xff0c;关闭IDEA&#xff0c;删除caches和index文件夹下的文件&#xff0c;重新打开。

数据加密技术在数据安全中起到什么样的作用?

把数据以及一个密钥&#xff0c;通过相关的加密算法&#xff0c;进行一系列的加密算法计算处理&#xff0c;使这个数据变成密文&#xff0c;保护数据的机密性。数据加密技术是一种将原始数据&#xff08;明文&#xff09;通过算法转换成只有授权用户才能解读的格式&#xff08;…

C++客户端Qt开发——系统相关(多媒体音频)

3.多媒体&#xff08;音频、视频&#xff09; 播放声音需要引入multimedia模块 使用QSound类 仅支持的音频文件格式为.wav&#xff0c;同样使用qrc文件管理外部的资源 &#xff08;使用的.wav文件不宜过大&#xff0c;尽量在几秒内&#xff0c;否则会构建时间过长&#xff…

拓维思树障分析Tovos PowerLine 4.0.19 航线规划Tovos SmartPlan 2.0.0 下载License电力应用软件使用

Tovos PowerLine 是功能强大的输电线路智能巡检系统&#xff01;这是一个专业且智能的软件&#xff0c;能够更准确的进行巡检和对线路设备进行精确的测量&#xff0c;通过获取高精度的点云来获取精准的三维路线的地形地貌、设备设施、途径的各种物体等来精确您的三维空间信息和…