【详细教程】MySQL 高可用架构代码实现

news2025/5/26 6:26:05

前言

对于 MySQL 数据库作为各个业务系统的存储介质,在系统中承担着非常重要的职责,如果数据库崩了,那么对于读和写数据库的操作都会受到影响。如果不能迅速恢复,对业务的影响是非常大的。之前 B 站不是出过一次事故么,2 小时才恢复过来,详细可以看之前写的文章。

B 站崩了,总结下「高可用」和「异地多活」

上次折腾完 ELK 日志检索平台后,开发环境可以正常查询日志了。近在做系统高可用相关的工作,这次我来分享下 MySQL 双主 + Keepalived 的高可用落地和踩坑之路。

一文带你搭建一套 ELK Stack 日志平台

一、方案选择

对于 MySQL 的高可用,主要分为两步,配置 MySQL 主主模式和 keepalived 软件。拓扑图如下所示:

MySQL 数据库的主主模式

两个数据库分别部署在两台服务器上,相互同步数据,但是只有一个提供给外部访问,当一个宕机后,另外一个可以继续提供服务,在没有 keepalived 软件的帮助下,只能手动切换

keepalived 监测、自动重启、流量切换
  • 检测和重启:两台服务器上都部署 keepalived 软件,定时检测 MySQL 服务是否正常,如果一个数据库服务崩了,keepalived 会用脚本尝试重启 mysql 服务。

  • 备份:两个 keepalived 服务都提供了虚拟 IP 供客户端使用,但是流量只会转到一台 MySQL 服务上。

  • 虚拟 IP:keepalived 配置好了后,会有一个 虚拟 IP,对于客户端来说,不关心连接的是哪台 MySQL,访问虚拟 IP 就可以了。

  • 流量切换:如果客户端正在访问的 MySQL 服务崩了后,keepalived 会用我们写的脚本自动重启 MySQL,如果重启失败,脚本主动停掉 keepalived,客户端的流量就不会访问到这台服务器上的 MySQL 服务,后续访问的流量都会切到另外一台 MySQL 服务。

检测和重启的原理如下所示:

需要配置的内容如下:

  • 两台 Ubuntu 服务器上启动 MySQL 容器。

  • 配置 MySQL 主从复制架构。

  • 将 MySQL 主从改为主主复制架构。

  • 两台服务器搭建 keepalived 环境监控 MySQL 和自动重启 MySQL。

二、主主复制的原理

对于 MySQL 的主主架构,其实原理就是两台服务器互为主从,双向复制。而复制的原理如下:

主从复制主要有以下流程:

  1. 主库将数据的改变记录到 binlog 中;

  2. 从库会在一定时间间隔内对master 的 binlog 进行检查,如果发生改变,则开始一个 I/O Thread 请求读取 master 中 binlog ;

  3. 同时主库为每个 I/O 线程启动一个 dump 线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从库将启动 SQL 线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒;

大白话就是:

从库会生成两个线程,一个 I/O 线程,一个 SQL 线程;

I/O 线程会去请求主库的 binlog,并将得到的 binlog 写到本地的 relay-log (中继日志)文件中;

主库会生成一个 dump 线程,用来给从库 I/O 线程传 binlog;

SQL 线程,会读取 relay log 文件中的日志,并解析成 SQL 语句逐一执行;

接下来我们先把 MySQL 的基础环境在两台 Ubuntu 服务器上搭建好,后续操作都是基于这个来做的。

三、配置 MySQL 环境

作为演示,我在本机启动了两台 Ubuntu 虚拟机,安装有 docker。因为我们的测试和生产环境是用 Docker 跑的,所以我将环境的镜像打包后,还原到我的虚拟机上面。

3.1 备份和还原 mysql 镜像

保存测试环境的 mysql 镜像

sudo docker save -o mysql.tar  hcr:5000/hschub/hscmysql:0.0.2

sudo chmod 777 mysql.tar

两台机器导入镜像

sudo docker load -i mysql.tar

启动容器,需要注意的是需要映射本地文件夹。

sudo docker run -p 3306:3306 --name mysql \
-v /home/hss/mysql/data:/var/lib/mysql \
-v /home/hss/mysql/etc/mysql:/etc/mysql \
-e MYSQL_ROOT_PASSWORD='123456' \
-d 46b

-v 代表映射的文件夹,-d 表示后台运行,46b 代表镜像 id。

进入容器,连接 mysql,node1的mysql 密码是 123456,node2 是 123456

# 查询容器 id
docker ps

# 进入 mysql 容器
docker exec -it <容器 id> /bin/bash

# 连接 mysql
mysql -u root -p

接下来我们配置 MySQL 的主从架构,需要注意的是后续搭建的主主架构是基于主从架构来的,区别就是修改了一部分配置。

四、配置 MySQL 的主从架构

拓扑结构:

  • 192.168.56.11 node1,主节点

  • 192.168.56.12 node2,从节点

4.1 修改主节点配置文件

修改 /home/hss/mysql/etc/mysql/my.cnf 文件

server_id = 11
log_bin = /var/lib/mysql/log/mysql-bin
binlog-ignore-db=mysql
binlog_format= mixed
sync_binlog=100
log_slave_updates = 1
binlog_cache_size=32m
max_binlog_cache_size=64m
max_binlog_size=512m
relay_log = /var/lib/mysql/log/relay-bin
relay_log_index = /var/lib/mysql/log/relay-bin.index
master_info_repository=TABLE
relay-log-info-repository=TABLE
relay-log-recovery

创建 /home/hss/mysql/data/log/mysql-bin 文件夹

创建 /home/hss/mysql/data/log/relay-bin  文件夹

给两个文件夹加上 777 权限,然后重启 MySQL 容器。

4.2 修改从节点配置文件

和主节点配置类似,需要修改 server_id = 12

4.3 添加主节点 mysql 账户信息

CREATE USER 'vagrant'@'192.168.56.12' IDENTIFIED BY 'vagrant';

ALTER USER 'vagrant'@'192.168.56.12' IDENTIFIED WITH mysql_native_password BY 'vagrant'; 

GRANT REPLICATION SLAVE ON *.* TO 'vagrant'@'192.168.56.12';

FLUSH PRIVILEGES;

4.4 锁主库的表

FLUSH TABLES WITH READ LOCK;

4.5 查看二进制日志文件的位置

记住 File 和 Position,后面会用到。这里 File = mysql-bin.000008,Position = 1020。

4.6 备份数据库,导出为脚本文件

cd /var/lib/mysql

mkdir backup

mysqldump -uroot -P3306 --all-databases --triggers --routines --events > /var/lib/mysql/backup/all_databases.sql

查看挂载目录下是否有生成 all_databases.sql 文件,如下图所示:

4.7 解除锁定表

UNLOCK TABLES

4.8 从节点还原数据库

mysql -uroot -p -hlocalhost -P3306 < /var/lib/mysql/backup/all_databases.sql

4.9 设置同步信息

在 MySQL 命令行窗口中执行以下命令设置同步信息。这里就是配置主数据库的 IP 地址、Port、用户名、密码,二进制文件名,偏移量。

CHANGE MASTER TO MASTER_HOST='192.168.56.11',
MASTER_PORT=3306,
MASTER_USER='vagrant',
MASTER_PASSWORD='vagrant',
MASTER_LOG_FILE='mysql-bin.000008',
MASTER_LOG_POS=1020;

4.10 启动从数据库的复制线程

在 MySQL 命令行窗口中执行以下命令启动从数据库的复制线程。

START salve;

4.11 查看从数据库的同步状态

SHOW slave status \G

如果 Slave_IO_Running 和 Slave_SQL_Running 显示 Yes,就表示启动同步成功。如下图所示:

在主库上执行以下命令显示当前连接过来的从库线程。

SHOW PROCESSLIST

如下所示,Slave has read all relay log; wating for more updates,说明从库已经同步完了。

使用上面的两个命令,我们可以判断当前的复制情况。

4.12 验证同步功能

下面验证下主从节点之间是否能正常同步数据。

主节点创建 testdb 数据库和 member 表。

刷新下从节点,发现从节点自动创建了 member 表。如下图所示。

然后在主节点插入一条数据,刷新从节点后,发现从节点也自动创建了一条数据。

五、配置主主架构

5.1 步骤

配置主主架构就是在主从架构中交换下配置信息。步骤如下:

  • 在节点 node2 上创建复制账户。

  • 查看二进制日志文件和位置信息。

  • 在节点 node1 上设置主从复制的信息,包括 ip,port,用户名,密码,二进制日志文件和位置信息。

  • node1 开启主从复制,查看主从复制状态

5.2 node2 节点上的操作

5.2.1 停止同步

STOP slave

5.2.2 添加主节点 mysql 账户信息
CREATE USER 'vagrant'@'192.168.56.11' IDENTIFIED BY 'vagrant';

ALTER USER 'vagrant'@'192.168.56.11' IDENTIFIED WITH mysql_native_password BY 'vagrant'; 

GRANT REPLICATION SLAVE ON *.* TO 'vagrant'@'192.168.56.11';

FLUSH PRIVILEGES;
5.2.3 查看二进制日志文件和位置信息

SHOW MASTER STATUS

5.2.4 开启主从复制

start slave

5.2.5 查看同步状态

5.3 node 1 节点上的操作

5.3.1 设置同步信息
CHANGE MASTER TO MASTER_HOST='192.168.56.12',
MASTER_PORT=3306,
MASTER_USER='vagrant',
MASTER_PASSWORD='vagrant',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=2453;
5.3.2 启动从数据库的复制线程

START salve

5.3.3 查看从数据库的同步状态

SHOW slave status \G

5.4 测试主主同步

node2 的 member 表增加一条数据 (2,zzz),node1 上同步成功

node 1 的 member 表增加一条数据(3,aaa),node2 上同步成功

六、搭建 keepalived 环境

6.1 Keepalived 的应用场景

Keepalived 软件在主主架构中,可以配置成两种应用场景:

  • ① 当这台服务器上的 keepalived 发现 MySQL 服务崩了后,立刻停掉这台服务器上 keepalived 自己,这样流量就会自动切到另外一台 keepalived 服务器。

  • ② 当这台服务器上的 keepalived 发现 MySQL 服务崩了后,立刻尝试重启 MySQL 服务,如果重启失败,则停掉 keepalived 自己。和种方案的区别是会尝试重启 MySQL 服务。

这里我配置成第二种功能场景,保障 MySQL 服务的高可用。另外可以配置 MySQL 服务异常时,发送邮件给运维或开发人员,由他们检查服务器的状态。

6.2 使用 Keepalived 的原理

Keepalived 提供了一个虚拟 IP (简称 VIP),对外提供访问。当客户端连接这个虚拟 IP 后,只会访问其中一个 MySQL。MySQL 节点故障后,keepalived 执行脚本进行重启,如果重启失败,脚本自动停掉 keepalived,备用节点自动切换为主节点。

keepalived 检测和重启的流程图如下:

6.3 安装 keepalived 软件

安装依赖、获取 keepalived 安装包、解压安装包、删除安装包。

# 安装依赖
sudo apt-get install -y libssl-dev
sudo apt-get install -y openssl 
sudo apt-get install -y libpopt-dev
sudo apt-get install -y libnl-dev
sudo apt-get install -y libnl-3-dev
sudo apt-get install -y libnl-genl-3.dev
sudo apt-get install daemon
sudo apt-get install libc-dev
sudo apt-get install libnfnetlink-dev
sudo apt-get install gcc

# 获取 keepalived 安装包
cd /usr/local
sudo su
sudo wget https://www.keepalived.org/software/keepalived-2.2.2.tar.gz

# 解压安装包
sudo tar -zxvf keepalived-2.2.2.tar.gz 

# 删除安装包
mv keepalived-2.2.2 keepalived

配置 keepalived 软件

cd keepalived

./configure --prefix=/usr/local/keepalived --disable-dependency-tracking

执行结果如下所示:

编译 keepalived 软件

sudo make && make install

执行结果如下所示:

对于 Ubuntu ,需要做一点特别的改动,创建链接

mkdir -p  /etc/rc.d/init.d
ln -s /lib/lsb/init-functions /etc/rc.d/init.d/functions

拷贝配置文件

sudo mkdir /etc/sysconfig
sudo cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
sudo cp /usr/local/keepalived/keepalived/etc/init.d/keepalived /etc/init.d/
sudo cp /usr/local/keepalived/sbin/keepalived /sbin/
sudo mkdir /etc/keepalived
sudo cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/

修改配置文件 /etc/keepalived/keepalived.conf

daemon keepalived ${KEEPALIVED_OPTIONS}

改为

daemon -- keepalived ${KEEPALIVED_OPTIONS}

6.4 添加虚拟 IP

先用 ifconfig 查看当前的网卡,比如我的服务器上是 enp0s8。

ip addr del 192.168.56.88 dev enp0s8:1

ifconfig enp0s8:1 192.168.56.88 broadcast 192.168.56.255 netmask 255.255.255.0 up
route add -host 192.168.56.88 dev enp0s8:1

将命令写到 /usr/local/script/vip.sh*文件中。好将 /usr/local/script/vip.sh*文件添加到服务器的开机启动项中,将 Keepalived 服务设置为开机自启动(未写)。

6.5 修改配置文件

备份配置文件

sudo mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.backup

修改配置文件

sudo vim /etc/keepalived/keepalived.conf

配置文件的内容如下:

global_defs {
   router_id MYSQL_HA  #当前节点名
}
vrrp_script restart_mysql {
   script "/usr/local/keepalived/restart_mysql.sh"  #重启 mysql 容器
   interval 2
   weight 2
}
vrrp_instance VI_1 {    
    state BACKUP         #两台配置节点均为BACKUP
    interface enp0s8       #绑定虚拟IP的网络接口
    virtual_router_id 51 #VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组
    priority 101         #节点的优先级,另一台优先级改低一点
    advert_int 1         #组播信息发送间隔,两个节点设置必须一样
    nopreempt            #不抢占,只在优先级高的机器上设置即可,优先级低的机器不设置
    authentication {      #设置验证信息,两个节点必须一致
        auth_type PASS
        auth_pass 123456
    }
    track_script {
        restart_mysql  #检测 mysql 状态,如果失败,则重启 mysql 容器
    }
    virtual_ipaddress {   #指定虚拟IP,两个节点设置必须一样
        192.168.56.88
    }
}
virtual_server 192.168.56.88 3306 {   #linux虚拟服务器(LVS)配置 
    delay_loop 2     #每个2秒检查一次real_server状态
    lb_algo wrr      #LVS调度算法,rr|wrr|lc|wlc|lblc|sh|dh
    lb_kind DR      #LVS集群模式 ,NAT|DR|TUN
    persistence_timeout 60    #会话保持时间
    protocol TCP    #使用的协议是TCP还是UDP

    real_server 192.168.56.11 3306 {
        weight 3   #权重
        TCP_CHECK {
            connect_timeout 10   #连接超时时间
            nb_get_retry 3      #重连次数
            delay_before_retry 3 #重连间隔时间
            connect_port 3306    #健康检查端口
        }
    }    
}

编写异常处理脚本

sudo vim /usr/local/keepalived/restart_mysql.sh

内容如下,

#!/bin/bash
# 定义变量,重启 mysql 容器
START_MYSQL="docker restart mysql"
# 定义变量,停止 mysql 容器
STOP_MYSQL="docker stop mysql"
# 定义变量,日志文件路径
LOG_FILE="/usr/local/keepalived/logs/mysql-check.log"
# 定义变量,检查 mysql 服务是否正常的命令
HAPS=`ps -C mysqld --no-header |wc -l`
# 打印当前时间到日志文件
date "+%Y-%m-%d %H:%M:%S" >> $LOG_FILE
# 打印提示信息到日志文件
echo "check mysql status" >> $LOG_FILE
# 检查数据库状态,如何返回 ,则重启 mysql 容器,然后休眠 3s 后,再次检测 mysql 状态,如果还是返回 ,则停止 keepalived。
if [ $HAPS -eq  ];then
echo $START_MYSQL >> $LOG_FILE
$START_MYSQL >> $LOG_FILE 2>&1
sleep 3
if [ `ps -C mysqld --no-header |wc -l` -eq  ];then
echo "start mysql failed, killall keepalived" >> $LOG_FILE
killall keepalived
fi
fi

给脚本分配权限

sudo chmod +x /usr/local/keepalived/restart_mysql.sh

创建 logs 文件夹,给 logs 文件夹分配权限

sudo mkdir /usr/local/keepalived/logs
sudo chmod +x /usr/local/keepalived/logs -r

重新加载配置文件

sudo systemctl daemon-reload

6.6 启动 keepalived

6.6.1 启动两台服务器上的 keepalived

启动 node2 节点:

sudo pkill keepalived

sudo systemctl start keepalived

sudo systemctl status keepalived

启动 node1 节点:

pkilll keepalived

sudo systemctl status keepalived

我们可以通过这个命令查看 keepalived 进程

ps -ef | grep keepalived

查看日志

sudo cat /var/log/syslog

6.7 测试 keepalived 是否会重启 mysql

停止 node2 上的 mysql 容器

docker stop 8cc

查看 keepalived 状态,提示移除了 mysql 服务。

因为 keepalived 会每 2s 检查一次 MySQL 的状态,发现 MySQL 异常后,就会重启 mysql 容器。所以过几秒后,重新查看容器状态,会看到 mysql 容器重新启动了。

docker  ps

查看 keepalived 状态,执行 restart_mysql 成功

查看执行日志

问题:每 2s 会打印一次,文件可能会很大。需要执行定期删除。

6.8 测试 MySQL 节点切换

验证下当 MySQL 重启失败后,keepalived 自动停止后,客户端连接的 MySQL 是否会自动切到另外一个 MySQL 节点上。

首先用 mysql 客户端工具 navicat 连接虚拟 ip 地址,账号和密码就是 node 1 和 node2 的 mysql 账号密码(root/123456)

可以连接上,然后执行以下命令,查看当前虚拟 ip 连接的是哪个数据库

SHOW VARIABLES LIKE '%hostname%'

可以看到连接的是 node2 的容器的 id,说明 keepalived 已经通过虚拟 ip 连接到 node2 的 mysql 了,是正常工作的,node2 现在是作为主节点,node1 作为备用节点。

由于本地环境重新启动  MySQL 都是成功的,不会停掉 keepalived 服务。出于演示目的,我就直接停掉 keepalived 服务。

pkill keepalived

执行下面这个命令可以查看 keepalived 进程,发现已经没有了。(控制台显示的 grep --color=auto keepalived 表示是查找命令)

ps -ef | grep keepalived

重新查询客户端的连接信息,发现已经切换到 92b (node1)机器上的 mysql 了。

SHOW VARIABLES LIKE '%hostname%'

再次查看 node1 上 keepalived 上的状态,再发送信息给

sudo systemctl status keepalived

七、遇到的坑

7.1 密码不正确,无法登录的问题

密码不正确,设置跳过密码验证

apt-get update

apt install vim

修改 mysql 配置文件

vim /etc/mysql/my.cnf

添加一行配置,跳过 mysql 密码验证

skip-grant-tables

重启容器

docker restart 9e6

重新计入 mysql 容器,连接 mysql,不需要密码就可以连接上 mysql。

mysql

修改登录密码

update mysql.user set authentication_string=PASSWORD('123456') where User='root'; 

重启容器

7.2 没有映射 mysql 文件夹

cd /home/hss/mysql/etc
sudo chmod 777 mysql -R

拷贝 mysql 文件夹

7.3 mysql data 文件夹没有权限

 sudo chmod 777 /home/hss/mysql/data -R

7.4 安装依赖包失败

sudo apt-get install -y libnl-dev libnl-3-dev libnl-genl-3.dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'libnl-genl-3-dev' for regex 'libnl-genl-3.dev'
Package libnl-dev is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'libnl-dev' has no installation candidate

解决方案:更新包

sudo apt-get -y update

7.5 更新包失败

Err:15 https://download.docker.com/linux/ubuntu bionic Release Could not wait for server fd - select (11: Resource temporarily unavailable) [IP: 198.18.0.39 443] Reading package lists... Done E: The repository 'https://download.docker.com/linux/ubuntu bionic Release' no longer has a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.

解决方案:

修改配置文件

sudo mv /etc/apt/sources.list /etc/apt/sources.list.backup
sudo vim /etc/apt/sources.list

配置内容如下:

deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse 
deb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse 
deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe multiverse 
deb http://archive.ubuntu.com/ubuntu/ trusty-proposed main restricted universe multiverse 
deb http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse

执行更新

sudo apt-get update

依赖包版本太高

apt-get install libnl-dev

The following packages have unmet dependencies:
 libnl-3-dev : Depends: libnl-3-200 (= 3.2.21-1ubuntu4.1) but 3.2.29-ubuntu3 is to be installed
               Conflicts: libnl-dev but 1.1-8ubuntu1 is to be installed
 libnl-genl-3-dev : Depends: libnl-genl-3-200 (= 3.2.21-1ubuntu4.1) but 3.2.29-ubuntu3 is to be installed
E: Unable to correct problems, you have held broken packages.

解决方案:

按照这个报错信息来进行降级,等号后面就是提示信息里括号的版本信息。

sudo apt-get install libnl-3-200=3.2.21-1ubuntu4.1
sudo apt-get install libnl-genl-3-200=3.2.21-1ubuntu4.1

启动 keepalived 报错

root@node1:/usr/local/keepalived/etc/keepalived# service keepalived restart
Failed to restart keepalived.service: Unit keepalived.service is masked.
root@node1:/usr/local/keepalived/etc/keepalived# systemctl status keepalived.service
● keepalived.service
   Loaded: masked (/dev/null; bad)
   Active: inactive (dead)
Condition: start condition failed at Wed 2022-05-11 02:40:46 UTC; 1 day 3h ago

解决方案:

systemctl unmask sshd

再次启动,提示另外一个错误。

解决方案,因为 ubuntu 没有这个命令 /etc/rc.d/init.d/functions,所以需要添加一个命令链接

mkdir -p  /etc/rc.d/init.d
ln -s /lib/lsb/init-functions /etc/rc.d/init.d/functions

install gcc 出现问题

切换回 ubuntu 官方源

sudo mv /etc/apt/sources.list /etc/apt/sources.list.backup2

sudo mv /etc/apt/sources.list.backup /etc/apt/sources.list

sudo apt-get update

sudo apt-get install gcc

启动 keepalived 报错 keepalived_script

WARNING - default user 'keepalived_script' for script execution does not exist - please create.

解决方案:

配置文件的 global_defs  配置里面增加 script_user root

global_defs {
  script_user rot
}

执行脚本失败

May 16 03:50:54 node1 Keepalived_vrrp[19855]: WARNING - script '/usr/local/keepalived/restart_mysql.sh' is not executable for uid:gid : - disabling.
May 16 03:50:54 node1 Keepalived_vrrp[19855]: SECURITY VIOLATION - scripts are being executed but script_security not enabled.

给脚本添加权限。

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

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

相关文章

解决jenkins运行sh报process apparently never started in XXX

个人记录 问题 process apparently never started in /var/jenkins_home/workspace/ks-springboot_mastertmp/durable-bbfe5f99(running Jenkins temporarily with -Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICStrue might make the problem cl…

Electron+React 搭建桌面应用

创建应用程序 创建 Electron 应用 使用 Webpack 创建新的 Electron 应用程序&#xff1a; npm init electron-applatest my-new-app -- --templatewebpack 启动应用 npm start 设置 Webpack 配置 添加依赖包&#xff0c;确保可以正确使用 JSX 和其他 React 功能&#xff…

Java基础(一)--语法入门

文章目录 第一章、语法入门一、Java简介1、JVM2、Java程序执行过程3、JDK4、JRE5、JDK、JRE和JVM三者关系 二、Java常量与变量1、标识符2、关键字3、保留字4、变量5、数据类型6、常量 三、运算符1、算术运算符2、赋值运算符3、关系运算符4、逻辑运算符5、条件运算符6、运算符的…

全国各省环境规制强度数据(2004-2022年)

01、数据简介 以保护环境为目的&#xff0c;对各种环境污染行为进行规制&#xff0c;政府相关政策规制&#xff0c;是社会性规制的重要内容&#xff0c;包含大气、水、废弃物、噪声污染等外部行为&#xff0c;对这些行为进行规制就是要将整个社会为其承担的成本转化为其自身承…

funasr 麦克风实时流语音识别

参考: https://github.com/alibaba-damo-academy/FunASR chunk_size 是用于流式传输延迟的配置。[0,10,5] 表示实时显示的粒度为 1060=600 毫秒,并且预测的向前信息为 560=300 毫秒。每个推理输入为 600 毫秒(采样点为 16000*0.6=960),输出为相应的文本。对于最后一个语音…

根据状态转移图实现时序电路

描述 某同步时序电路的状态转换图如下&#xff0c;→上表示“C/Y”&#xff0c;圆圈内为现态&#xff0c;→指向次态。 请使用D触发器和必要的逻辑门实现此同步时序电路&#xff0c;用Verilog语言描述。 如图所示&#xff1a; 电路的接口如下图所示&#xff0c;C是单bit数据…

MySQL基础入门上篇

MySQL基础 介绍 mysql -uroot -p -h127.0.0.1 -P3306项目设计 具备数据库一定的设计能力和操作数据的能力。 数据库设计DDL 定义 操作 显示所有数据库 show databases;创建数据库 create database db02;数据库名唯一&#xff0c;不能重复。 查询是否创建成功 加入一些…

文本检索粗读

一.前情提要 1.本文理论为主&#xff0c;并且仅为个人理解&#xff0c;能力一般&#xff0c;不喜勿喷 2.本文理论知识较为散碎 3.如有需要&#xff0c;以下是原文&#xff0c;更为完备 Neural Corpus Indexer 文档检索【论文精读47】_哔哩哔哩_bilibili 二.正文 &#xf…

重大璧山院_APP_apk_安卓端下载

主要是方便去重庆大学璧山研究院搞科研的学生&#xff0c; 这个安卓安装包&#xff0c;在网上很难搜到。 找半天才搞到手、蓝奏云下载 https://wwb.lanzn.com/iqnro1v1bwkh 密码:i3n2

防止邮箱发信泄露服务器IP教程

使用QQ邮箱,网易邮箱,189邮箱,新浪邮箱,139邮箱可能会泄露自己的服务器IP。 泄露原理&#xff1a;服务器通过请求登录SMTP邮箱服务器接口&#xff0c;对指定的收件人发送信息。 建议大家使用商业版的邮箱&#xff0c;比如阿里云邮箱发信等 防止邮件发信漏源主要关注的是确保邮件…

C语言 数据输入输出

本文 我们来说 数据的输入与输出 及数据的运算 在程序的运算工程中 往往需要输入一些数据 而程序的运算 所得到的运算结果又需要输出给用户 因此 数据的输入与输出 就显得非常重要 在C语言中 不提供专门的输入输出语句 所有的输入输出 都是通过对标准库的调用 来实现的 一般 …

权威Scrum敏捷开发企业级实训/敏捷开发培训课程

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。 这是一个两天的实训课程&#xff0c;面向研发管理者、项目经理、产品经理、研发团队等&#xff0c;旨在帮助学员全面系统地学习Scrum和敏捷开发, 帮助企业快速启动敏…

抖音滑块验证码加密的盐的位置

最近更新后之前很容易找到盐的位置的方法变了&#xff0c;抖音特意把盐隐藏起来了 {"reply": "RJC","models": "yAd8rl","in_modal": "DTn0nD2","in_slide": "ou7H0Ngda","move": …

基于java+springboot+vue实现的网上购物系统(文末源码+Lw+ppt)23-42

摘 要 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;网上购物系统展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为…

走进MySQL:从认识到入门(针对初学者)

一&#xff0c;引言 MySQL是一款久负盛名且广泛应用的关系型数据库管理系统&#xff0c;自1995年Michael Widenius和David Axmark在瑞典和芬兰发起研发以来&#xff0c;其发展历程可谓辉煌且深远。作为开源软件的代表&#xff0c;MySQL以其卓越的成本效益、高性能及高可靠性赢得…

【数据结构与算法】:二叉树经典OJ

目录 1. 二叉树的前序遍历 (中&#xff0c;后序类似)2. 二叉树的最大深度3. 平衡二叉树4. 二叉树遍历 1. 二叉树的前序遍历 (中&#xff0c;后序类似) 这道题的意思是对二叉树进行前序遍历&#xff0c;把每个结点的值都存入一个数组中&#xff0c;并且返回这个数组。 思路&…

c++11 标准模板(STL)本地化库 - 平面类别(std::codecvt) - 在字符编码间转换,包括 UTF-8、UTF-16、UTF-32 (四)

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 在字符编码间转换&#xff0c;包括 UTF-8、UTF-16、UTF-32 std::…

ReactRouter

React-Router 概念&#xff1a;一个路劲path对应一个组件component 当我们在浏览器中访问一个path的时候&#xff0c;path对应的组件会在页面中进行渲染路由语法&#xff1a; import {createBrowserRouter, RouterProvider} from react-router-dom// 1. 创建router实例对象并…

【数据结构】习题之链表的回文结构和相交链表

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;前路漫漫亦灿灿 前言 今日的习题是关于链表的&#xff0c;分别是链表的回文结构和相交链表的判断。 链表的回文结构 题目为&#xff1a;链表的回文结…

RUM 最佳实践-交互延迟的探索与发现

FID 在互联网高速发展的时代&#xff0c;用户体验已成为企业竞争的关键所在。网页性能作为用户体验的重要组成部分&#xff0c;直接影响着用户的满意度和工作效率。First Input Delay&#xff08;FID&#xff09;作为衡量网页性能的重要指标&#xff0c;越来越受到业界关注。今…