MySQL InnoDB Replication部署方案与实践

1. 概述

MySQL Innodb ReplicaSet 是 MySQL 团队在 2020 年推出的一款产品,用来帮助用户快速部署和管理主从复制,在数据库层仍然使用的是主从复制技术。

ReplicaSet 主要包含三个组件:MySQL Router、MySQL Server 以及 MySQL Shell 高级客户端。

MySQL Shell 负责管理 ReplicaSet 包括部署、切换、节点加入等,都可以通过内置 AdminAPI 自动化完成。

MySQL Router 是一款轻量级中间件,可在应用程序和 ReplicaSet 之间提供透明路由和读写分离功能。

2. 适用场景

InnoDB ReplicaSet至少由两台MySQL服务器实例组成,提供MySQL主从复制功能。InnoDB ReplicaSet基于异步的主从复制实现,因此适用于用户对高可用性要求不高的环境。可以通过MySQL Shell快速搭建及管理主从复制,避免了搭建主从复制时大量的手动操作。

InnoDB ReplicaSet的不足之处有:

  • 不支持自动故障转移。主库不可用时,需要通过AdminAPI手动发起故障转移。

  • 发生计划外的服务不可用时,可能会丢失部分数据。由于主备之间是异步复制,主库发生故障时,未提交的事务会丢失。

  • 发生计划外的服务不可用时,可能会产生数据不一致。例如由于网络原因导致主库连不上,将备库提升为主库后,可能会同时存在两个主库,即发生“脑裂”。

  • 不支持多主模式,即同一时刻只有一个主库可写。

  • 读扩展受限,不能像组复制那样对流量进行控制。

  • 所有的备库都从同一个主库复制数据。在有大量的小更新时,可能会对主库造成影响。

  • 仅支持MySQL 8.0及其以后的版本。

  • 仅支持基于GTID的日志复制。

  • 仅支持基于行的日志复制(Row-Based Replication, RBR),不支持基于SQL语句的复制(Statement-Based Replication, SBR)。

  • 不支持复制过滤。

  • RS为一个主库加多个从库的架构。需要通过MySQL Router监视RS中的实例,因此从库的数量不能无限制增加。

  • 必须通过MySQL Shell配置和管理,包括复制用户的创建。

3. 安装部署

IProlehostname版本OS
192.168.10.31Mastermysql-rs-1MySQL 8.2Centos_7.9_x86_x64
192.168.10.32Secondarymysql-rs-2MySQL 8.2Centos_7.9_x86_x64

3.1. 安装MySQL servers

分别在两个MySQL服务器下载MySQL Server安装包,并进行安装。

# 配置主机名
echo "192.168.10.31   mysql-rs-1" >> /etc/hosts
echo "192.168.10.32   mysql-rs-2" >> /etc/hosts
​
# 192.168.10.31执行
hostnamectl set-hostname mysql-rs-1
bash
# 192.168.10.32执行
hostnamectl set-hostname mysql-rs-2
bash
# 下载rpm安装包
wget https://cdn.mysql.com//Downloads/MySQL-8.2/mysql-8.2.0-1.el7.x86_64.rpm-bundle.tar
​
# 解压
tar -xvf mysql-8.2.0-1.el7.x86_64.rpm-bundle.tar
​
# 卸载mariadb
rpm -e mariadb-libs-5.5.68-1.el7.x86_64 --nodeps
​
# 安装MySQL
yum localinstall -y *.rpm

分别配置root密码:

[root@mysql-rs-2 server]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.2.0
​
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
​
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
​
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
​
mysql> 
mysql> 
mysql> alter user root@'localhost' identified by 'Abcd@1234';
Query OK, 0 rows affected (0.00 sec)
​
mysql> create user root@'%' identified by 'Abcd@1234';
Query OK, 0 rows affected (0.01 sec)

3.2. 安装mysqlsh

# 下载mysqlshell
wget https://cdn.mysql.com//Downloads/MySQL-Shell/mysql-shell-8.2.0-1.el7.x86_64.rpm
# 安装mysqlshell
rpm -ivh mysql-shell-8.2.0-1.el7.x86_64.rpm

验证mysql shell链接数据库

[root@mysql-rs-1 software]# mysqlsh --mysql -u root -h localhost -C
Please provide the password for 'root@localhost': ************
Save password for 'root@localhost'? [Y]es/[N]o/Ne[v]er (default No): 
Error during auto-completion cache update: You must reset your password using ALTER USER statement before executing this statement.
MySQL Shell 8.2.0
​
Copyright (c) 2016, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.
​
Type '\help' or '\?' for help; '\quit' to exit.
Creating a Classic session to 'root@localhost?compression=REQUIRED'
Your MySQL connection id is 8
No default schema selected; type \use <schema> to set one.MySQL  localhost  JS > 

3.3. 配置实例

在其中一个主机上启动mysqlsh连接

[root@mysql-rs-1 software]# mysqlsh root@mysql-rs-1:3306
MySQL Shell 8.2.0
​
Copyright (c) 2016, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.
​
Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'root@mysql-rs-1:3306'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 21
Server version: 8.2.0 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.

分别给root用户授权:

GRANT CLONE_ADMIN, CONNECTION_ADMIN, CREATE USER, EXECUTE, FILE, GROUP_REPLICATION_ADMIN, PERSIST_RO_VARIABLES_ADMIN, PROCESS, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, REPLICATION_APPLIER, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SELECT, SHUTDOWN, SYSTEM_VARIABLES_ADMIN ON *.* TO 'root'@'%' WITH GRANT OPTION;
GRANT DELETE, INSERT, UPDATE ON mysql.* TO 'root'@'%' WITH GRANT OPTION;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata.* TO 'root'@'%' WITH GRANT OPTION;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_bkp.* TO 'root'@'%' WITH GRANT OPTION;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_previous.* TO 'root'@'%' WITH GRANT OPTION;

在MySQL Shell中执行:

配置mysql-rs-1:

 MySQL  mysql-rs-1:3306 ssl  JS > dba.configureReplicaSetInstance('root@mysql-rs-1:3306', {clusterAdmin: "rs_admin"})
Configuring local MySQL instance listening at port 3306 for use in an InnoDB ReplicaSet...
​
This instance reports its own address as mysql-rs-1:3306
Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed.
Assuming full account name 'rs_admin'@'%' for rs_admin
Password for new account: *********
Confirm password: *********
​
applierWorkerThreads will be set to the default value of 4.
​
NOTE: Some configuration options need to be fixed:
+----------------------------------------+---------------+----------------+--------------------------------------------------+
| Variable                               | Current Value | Required Value | Note                                             |
+----------------------------------------+---------------+----------------+--------------------------------------------------+
| binlog_transaction_dependency_tracking | COMMIT_ORDER  | WRITESET       | Update the server variable                       |
| enforce_gtid_consistency               | OFF           | ON             | Update read-only variable and restart the server |
| gtid_mode                              | OFF           | ON             | Update read-only variable and restart the server |
| server_id                              | 1             | <unique ID>    | Update read-only variable and restart the server |
+----------------------------------------+---------------+----------------+--------------------------------------------------+
​
Some variables need to be changed, but cannot be done dynamically on the server.
Do you want to perform the required configuration changes? [y/n]: y
Do you want to restart the instance after configuring it? [y/n]: y
​
Creating user rs_admin@%.
Account rs_admin@% was successfully created.
​
Configuring instance...
​
WARNING: '@@binlog_transaction_dependency_tracking' is deprecated and will be removed in a future release. (Code 1287).
The instance 'mysql-rs-1:3306' was configured to be used in an InnoDB ReplicaSet.
Restarting MySQL...
NOTE: MySQL server at mysql-rs-1:3306 was restarted.

配置mysql-rs-2:

 MySQL  mysql-rs-1:3306 ssl  JS > dba.configureReplicaSetInstance('root@mysql-rs-2:3306', {clusterAdmin: "rs_admin"})
Please provide the password for 'root@mysql-rs-2:3306': *********
Save password for 'root@mysql-rs-2:3306'? [Y]es/[N]o/Ne[v]er (default No): Y
Configuring MySQL instance at mysql-rs-2:3306 for use in an InnoDB ReplicaSet...
​
This instance reports its own address as mysql-rs-2:3306
Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed.
Assuming full account name 'rs_admin'@'%' for rs_admin
Password for new account: *********
Confirm password: *********
​
applierWorkerThreads will be set to the default value of 4.
​
NOTE: Some configuration options need to be fixed:
+----------------------------------------+---------------+----------------+--------------------------------------------------+
| Variable                               | Current Value | Required Value | Note                                             |
+----------------------------------------+---------------+----------------+--------------------------------------------------+
| binlog_transaction_dependency_tracking | COMMIT_ORDER  | WRITESET       | Update the server variable                       |
| enforce_gtid_consistency               | OFF           | ON             | Update read-only variable and restart the server |
| gtid_mode                              | OFF           | ON             | Update read-only variable and restart the server |
| server_id                              | 1             | <unique ID>    | Update read-only variable and restart the server |
+----------------------------------------+---------------+----------------+--------------------------------------------------+
​
Some variables need to be changed, but cannot be done dynamically on the server.
Do you want to perform the required configuration changes? [y/n]: y
Do you want to restart the instance after configuring it? [y/n]: y
​
Creating user rs_admin@%.
Account rs_admin@% was successfully created.
​
Configuring instance...
​
WARNING: '@@binlog_transaction_dependency_tracking' is deprecated and will be removed in a future release. (Code 1287).
The instance 'mysql-rs-2:3306' was configured to be used in an InnoDB ReplicaSet.
Restarting MySQL...
NOTE: MySQL server at mysql-rs-2:3306 was restarted.

3.4. 创建ReplicationSet

创建ReplicationSet,默认会将当前进入的实例为主库实例:

 MySQL  mysql-rs-1:3306 ssl  JS > dba.createReplicaSet('ReplicaSet')
A new replicaset with instance 'mysql-rs-1:3306' will be created.
​
* Checking MySQL instance at mysql-rs-1:3306
​
This instance reports its own address as mysql-rs-1:3306
mysql-rs-1:3306: Instance configuration is suitable.
​
* Checking connectivity and SSL configuration...
* Updating metadata...
​
ReplicaSet object successfully created for mysql-rs-1:3306.
Use rs.addInstance() to add more asynchronously replicated instances to this replicaset and rs.status() to check its status.
​
<ReplicaSet:ReplicaSet> 

3.5. 将另一个实例加入到创建的 ReplicaSet

 MySQL  mysql-rs-1:3306 ssl  JS > var rs = dba.getReplicaSet()You are connected to a member of replicaset 'ReplicaSet'.MySQL  mysql-rs-1:3306 ssl  JS > rs.addInstance('mysql-rs-2:3306')
Adding instance to the replicaset...
​
* Performing validation checks
​
This instance reports its own address as mysql-rs-2:3306
mysql-rs-2:3306: Instance configuration is suitable.
​
* Checking async replication topology...
​
* Checking connectivity and SSL configuration...
​
* Checking transaction state of the instance...
​
NOTE: The target instance 'mysql-rs-2:3306' has not been pre-provisioned (GTID set is empty). The Shell is unable to decide whether replication can completely recover its state.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely overwrite the state of 'mysql-rs-2:3306' with a physical snapshot from an existing replicaset member. To use this method by default, set the 'recoveryMethod' option to 'clone'.
​
WARNING: It should be safe to rely on replication to incrementally recover the state of the new instance if you are sure all updates ever executed in the replicaset were done with GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the replicaset or a subset of it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.
​
​
Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone): 
* Updating topology
Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.
​
NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.
​
* Waiting for clone to finish...
NOTE: mysql-rs-2:3306 is being cloned from mysql-rs-1:3306
** Stage DROP DATA: Completed
** Clone Transfer  FILE COPY  ############################################################  100%  CompletedPAGE COPY  ############################################################  100%  CompletedREDO COPY  ############################################################  100%  Completed
* Clone process has finished: 76.80 MB transferred in about 1 second (~76.80 MB/s)
​
** Changing replication source of mysql-rs-2:3306 to mysql-rs-1:3306
** Waiting for new instance to synchronize with PRIMARY...
** Transactions replicated  ############################################################  100% 
​
The instance 'mysql-rs-2:3306' was added to the replicaset and is replicating from mysql-rs-1:3306.
​
* Waiting for instance 'mysql-rs-2:3306' to synchronize the Metadata updates with the PRIMARY...
** Transactions replicated  ############################################################  100% 

3.6. 查看副本集状态

 MySQL  mysql-rs-1:3306 ssl  JS > var rs = dba.getReplicaSet()
You are connected to a member of replicaset 'ReplicaSet'.MySQL  mysql-rs-1:3306 ssl  JS > rs.status()
{"replicaSet": {"name": "ReplicaSet", "primary": "mysql-rs-1:3306", "status": "AVAILABLE", "statusText": "All instances available.", "topology": {"mysql-rs-1:3306": {"address": "mysql-rs-1:3306", "instanceRole": "PRIMARY", "mode": "R/W", "status": "ONLINE"}, "mysql-rs-2:3306": {"address": "mysql-rs-2:3306", "instanceRole": "SECONDARY", "mode": "R/O", "replication": {"applierStatus": "APPLIED_ALL", "applierThreadState": "Waiting for an event from Coordinator", "applierWorkerThreads": 4, "receiverStatus": "ON", "receiverThreadState": "Waiting for source to send event", "replicationLag": null, "replicationSsl": "ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2", "replicationSslMode": "REQUIRED"}, "status": "ONLINE"}}, "type": "ASYNC"}
}

3.7. 配置MySQL Router

# 下载MySQL Router
wget https://cdn.mysql.com//Downloads/MySQL-Router/mysql-router-community-8.2.0-1.el7.x86_64.rpm
# 安装
rpm -ivh mysql-router-community-8.2.0-1.el7.x86_64.rpmMySQL  mysql-rs-1:3306 ssl  JS > var rs = dba.getReplicaSet()
You are connected to a member of replicaset 'ReplicaSet'.MySQL  mysql-rs-1:3306 ssl  JS > rs.setupRouterAccount('rs_router1')
​
Missing the password for new account rs_router1@%. Please provide one.
Password for new account: *********
Confirm password: *********
​
​
Creating user rs_router1@%.
Account rs_router1@% was successfully created.

3.8. 引导启动MySQL Router

[root@mysql-rs-1 software]# mysqlrouter --bootstrap root@mysql-rs-1:3306 --user mysqlrouter
Please enter MySQL password for root: 
# Bootstrapping system MySQL Router 8.2.0 (MySQL Community - GPL) instance...
​
- Creating account(s) (only those that are needed, if any)
- Verifying account (using it to run SQL queries that would be run by Router)
- Storing account in keyring
- Adjusting permissions of generated files
- Creating configuration /etc/mysqlrouter/mysqlrouter.conf
​
Existing configuration backed up to '/etc/mysqlrouter/mysqlrouter.conf.bak'
​
# MySQL Router configured for the InnoDB ReplicaSet 'ReplicaSet'
​
After this MySQL Router has been started with the generated configuration
​$ /etc/init.d/mysqlrouter restart
or$ systemctl start mysqlrouter
or$ mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf
​
InnoDB ReplicaSet 'ReplicaSet' can be reached by connecting to:
​
## MySQL Classic protocol
​
- Read/Write Connections: localhost:6446
- Read/Only Connections:  localhost:6447
- Read/Write Split Connections: localhost:6450
​
## MySQL X protocol
​
- Read/Write Connections: localhost:6448
- Read/Only Connections:  localhost:6449

3.9. 读写分离验证

检查ReplicaSet,可以看到主节点(读写)为mysql-rs-1:3306,从节点(只读)为mysql-rs-2:3306

 MySQL  mysql-rs-1:3306 ssl  JS > rs.status()
{"replicaSet": {"name": "ReplicaSet", "primary": "mysql-rs-1:3306", "status": "AVAILABLE", "statusText": "All instances available.", "topology": {"mysql-rs-1:3306": {"address": "mysql-rs-1:3306", "instanceRole": "PRIMARY", "mode": "R/W", "status": "ONLINE"}, "mysql-rs-2:3306": {"address": "mysql-rs-2:3306", "instanceRole": "SECONDARY", "mode": "R/O", "replication": {"applierStatus": "APPLIED_ALL", "applierThreadState": "Waiting for an event from Coordinator", "applierWorkerThreads": 4, "receiverStatus": "ON", "receiverThreadState": "Waiting for source to send event", "replicationLag": null, "replicationSsl": "ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2", "replicationSslMode": "REQUIRED"}, "status": "ONLINE"}}, "type": "ASYNC"}
}

检查mysqlrouter,可以看到MySQL Router读写端口为6450

 MySQL  mysql-rs-1:3306 ssl  JS > rs.listRouters()
{"replicaSetName": "ReplicaSet", "routers": {"mysql-rs-1::system": {"hostname": "mysql-rs-1", "lastCheckIn": "2023-11-14 11:40:21", "roPort": "6447", "roXPort": "6449", "rwPort": "6446", "rwSplitPort": "6450", "rwXPort": "6448", "version": "8.2.0"}}
}

下面通过MySQL Router的读写端口6450连接mysql数据库:

[root@mysql-rs-1 ~]# mysqlsh mysql://root@mysql-rs-1:6450 --sql
MySQL Shell 8.2.0
​
Copyright (c) 2016, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.
​
Type '\help' or '\?' for help; '\quit' to exit.
Creating a Classic session to 'root@mysql-rs-1:6450'
Fetching global names for auto-completion... Press ^C to stop.
Your MySQL connection id is 0
Server version: 8.2.0 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.MySQL  mysql-rs-1:6450 ssl  SQL > 

查询数据,发现当前节点为从节点:

 MySQL  mysql-rs-1:6450 ssl  SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 |   3306 |
+------------+--------+
1 row in set (0.0035 sec)
Statement ID: 13700

开启事务,会自动切换到主节点:

 MySQL  mysql-rs-1:6450 ssl  SQL > start transaction;
Query OK, 0 rows affected (0.0031 sec)
Statement ID: 20477MySQL  mysql-rs-1:6450 ssl  ★  SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-1 |   3306 |
+------------+--------+
1 row in set (0.0007 sec)
Statement ID: 20563

提交或者回滚事务后,自动切换到从节点:

 MySQL  mysql-rs-1:6450 ssl  ★  SQL > rollback;
Query OK, 0 rows affected (0.0006 sec)
Statement ID: 21909MySQL  mysql-rs-1:6450 ssl  SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 |   3306 |
+------------+--------+
1 row in set (0.0020 sec)
Statement ID: 15489

只读事务中,也会切换到从节点:

 MySQL  mysql-rs-1:6450 ssl  SQL > start transaction read only;
Query OK, 0 rows affected (0.0029 sec)
Statement ID: 16970MySQL  mysql-rs-1:6450 ssl  ☆  SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 |   3306 |
+------------+--------+
1 row in set (0.0010 sec)
Statement ID: 16996

用户还可以在会话中使用ROUTER SET access_mode=命令来定义应用要连接的实例类型:

 MySQL  mysql-rs-1:6450 ssl  SQL > router set access_mode='read_write';
Query OK, 0 rows affected (0.0004 sec)MySQL  mysql-rs-1:6450 ssl  -  SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-1 |   3306 |
+------------+--------+
1 row in set (0.0017 sec)
Statement ID: 25535MySQL  mysql-rs-1:6450 ssl  SQL > router set access_mode='read_only';
Query OK, 0 rows affected (0.0006 sec)MySQL  mysql-rs-1:6450 ssl  -  SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 |   3306 |
+------------+--------+
1 row in set (0.0043 sec)
Statement ID: 18508

4. 总结

总之,MySQL Router 8.2支持读写分离。这是一项有价值的功能,可以优化数据库性能和可扩展性,而无需在应用程序中进行任何更改。这种配置使您能够将所有读流量引导到只读实例,将所有写流量引导到读写实例。这不仅增强了用户的整体体验,还简化了数据库管理和部署。

读写实例是主实例或源实例。只读实例是副本(InnoDB集群的非主实例、ReplicaSet的非主实例或复制集群中的非主实例)。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HeartBeat监控Redis状态

目录 一、概述 二、 安装部署 三、配置 四、启动服务 五、查看数据 一、概述 使用heartbeat可以实现在kibana界面对redis服务存活状态进行观察&#xff0c;如有必要&#xff0c;也可在服务宕机后立即向相关人员发送邮件通知 二、 安装部署 参照文章&#xff1a;HeartBeat监…

web服务器之——搭建两个基于不同端口访问的网站

要求如下&#xff1a; 建立一个使用web服务器默认端口的网站&#xff0c;设置DocumentRoot为/www/port/80&#xff0c;网页内容为&#xff1a;the port is 80。建立一个使用10000端口的网站&#xff0c;设置DocumentRoot为/www/port/10000&#xff0c;网页内容为&#xff1a;t…

总结6种@Transactional注解的失效场景

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 引言 昨天有粉丝咨询了…

Appium微信小程序自动化环境准备

一、前置说明 微信从8.0.19开始内核从x5换成xweb之后&#xff0c;原先的开启webview调试的原方案已经会报503错误。 点击下面的链接&#xff0c;都会报503错误&#xff1a; http://debugmm.qq.com/?forcex5ture http://debugx5.qq.com 微信内核升级为xweb之后&#xff0c;需要…

k8s详细教程(一)

—————————————————————————————————————————————— 博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码…

基于单片机的定时插座在智能家居中的应用

近年来&#xff0c;随着科学技术的发展迅速&#xff0c;人们对智能化的要求越来越高。越来越多的智能化产品进入千家万户&#xff0c;如电脑电视、扫地机器人、智能空气净化器等。这些家居电器和电子产品大都需要连接电源&#xff0c;为满足多种用电器的正常使用&#xff0c;延…

@Transactional失效问题

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 关于Transactional 日…

数据结构基础介绍

一.起源及重要性 1968 年&#xff0c;美国的高德纳 Donakl E . Kn uth 教授在其所写的《 计算机程序艺术》第一卷《基本算法 》 中&#xff0c;较系统地阐述了数据的逻辑结构和存储结构及其操作&#xff0c; 开创了数据结构的课程体系 &#xff0c;数据结构作为一门独立的…

1、springboot项目运行报错

问题1&#xff1a;获取不到配置文件的参数 我的配置文件获取的参数如下&#xff1a; public class Configures{Value("${configmdm.apk.apkName}")private static String apkName;private void setApkName(String apkName) {Configures.apkName apkName;}private …

项目中使用Arrays.asList、ArrayList.subList的坑

使用Arrays.asList的注意事项 1.1 可能会踩的坑 先来看下Arrays.asList的使用&#xff1a; List<Integer> statusList Arrays.asList(1, 2); System.out.println(statusList); System.out.println(statusList.contains(1)); System.out.println(statusList.contains(3)…

spring数据校验

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…