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

MGR新节点RECOVERING状态的分析与解决:caching_sha2_password验证插件的影响

起因

在GreatSQL社区上有一位用户提出了“手工构建MGR碰到的次节点一直处于recovering状态”,经过排查后,发现了是因为新密码验证插件caching_sha2_password导致的从节点一直无法连接主节点,帖子地址:(https://greatsql.cn/thread-420-2-1.html))

复现

环境介绍

本文验证环境,以及本文所采用数据库为GreatSQL 8.0.32-24

$ cat /etc/system-release
Red Hat Enterprise Linux Server release 7.9 (Maipo)
$ uname -a
Linux gip 3.10.0-1160.el7.x86_64 #1 SMP Tue Aug 18 14:50:17 EDT 2020 x86_64 x86_64 x86_64 GNU/Linux

部署准备:

采用的是单机多实例的部署方式,如何部署单机多实例可以前往(https://gitee.com/GreatSQL/GreatSQL-Manual/blob/master/6-oper-guide/6-6-multi-instances.md)

IP端口角色
172.17.139.773306mgr01
172.17.139.773307mgr02

MGR有关配置参数:

#mgr settings
loose-plugin_load_add = 'mysql_clone.so'
loose-plugin_load_add = 'group_replication.so'
loose-group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa1"
loose-group_replication_group_seeds = '172.17.139.77:33061,172.17.139.77:33071'
loose-group_replication_start_on_boot = ON
loose-group_replication_bootstrap_group = OFF
loose-group_replication_exit_state_action = READ_ONLY
loose-group_replication_flow_control_mode = "DISABLED"
loose-group_replication_single_primary_mode = ON
loose-group_replication_communication_max_message_size = 10M
loose-group_replication_transaction_size_limit = 3G
loose-group_replication_arbitrator = 0
loose-group_replication_single_primary_fast_mode = 0
loose-group_replication_request_time_threshold = 20000
report_host = "172.17.139.77"

MGR01节点配置如下:

[mysqld@mgr01]
datadir=/data/GreatSQL/mgr01
socket=/data/GreatSQL/mgr01/mysql.sock
port=3306
server_id=103306
log-error=/data/GreatSQL/mgr01/error.log
loose-group_replication_local_address= "172.17.139.77:33061"

MGR02节点配置如下:

[mysqld@mgr02]
datadir=/data/GreatSQL/mgr02
socket=/data/GreatSQL/mgr02/mysql.sock
port=3307
server_id=103317
log-error=/data/GreatSQL/mgr02/error.log
loose-group_replication_local_address= "172.17.139.77:33071"

启动MGR01实例、MGR02实例,并修改密码

#启动两个实例
$ systemctl restart greatsql@mgr01 &
$ systemctl restart greatsql@mgr02 &
#获取初始化密码
$ grep root /data/GreatSQL/mgr01/error.log
$ grep root /data/GreatSQL/mgr02/error.log
#登录数据库并修改密码
$ mysql -S /data/GreatSQL/mgr01/mysql.sock -uroot -p
greatsql> alter user root@'localhost' identified by 'GreatSQL@666';
$ mysql -S /data/GreatSQL/mgr02/mysql.sock -uroot -p
greatsql> alter user root@'localhost' identified by 'GreatSQL@666';

检查两个实例是否正确加载group_replicaiton 插件

greatsql> show plugins;
+----------------------------------+----------+--------------------+----------------------+---------+
| Name                             | Status   | Type               | Library              | License |
+----------------------------------+----------+--------------------+----------------------+---------+
| group_replication                | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------------+----------+--------------------+----------------------+---------+

没有加载的话可以手动加载这个plugin

greatsql> install plugin group_replication soname 'group_replication.so';

搭建MGR

接下来就可以手工搭建MGR,流程如下可参考安装部署MGR集群 | 深入浅出MGR(https://gitee.com/GreatSQL/GreatSQL-Doc/blob/master/deep-dive-mgr/deep-dive-mgr-03.md))

MGR01实例操作:

greatsql> set session sql_log_bin=0;
# 特别注意下面因为8.0.4版本开始使用的默认是“caching_sha2_password”,所以这样创建会采用最新的身份认证插件
greatsql> create user repl@'%' identified by 'GreatSQL@666';
greatsql> GRANT BACKUP_ADMIN, REPLICATION SLAVE ON *.* TO `repl`@`%`;
greatsql> set session sql_log_bin=1;
greatsql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='GreatSQL@666' FOR CHANNEL 'group_replication_recovery';

接下来即可启动MGR集群:

greatsql> set global group_replication_bootstrap_group=ON;greatsql> start group_replication;greatsql> select * from performance_schema.replication_group_members\G
*************************** 1. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: 2920447e-35bf-11ee-89a5-00163e566da1MEMBER_HOST: 172.17.139.77MEMBER_PORT: 3306MEMBER_STATE: ONLINEMEMBER_ROLE: PRIMARYMEMBER_VERSION: 8.0.32
MEMBER_COMMUNICATION_STACK: XCom

MGR02实例操作:

greatsql> set session sql_log_bin=0;
greatsql> create user repl@'%' identified by 'GreatSQL@666';
greatsql> GRANT BACKUP_ADMIN, REPLICATION SLAVE ON *.* TO `repl`@`%`;
greatsql> set session sql_log_bin=1;
greatsql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='GreatSQL@666' FOR CHANNEL 'group_replication_recovery';
greatsql> start group_replication;
Query OK, 0 rows affected (5.39 sec)

此时创建的用户采用的都是caching_sha2_password身份认证插件

greatsql> SELECT USER,PLUGIN FROM mysql.`user` ;
+------------------+-----------------------+
| USER             | PLUGIN                |
+------------------+-----------------------+
| repl             | caching_sha2_password |
| mysql.infoschema | caching_sha2_password |
| mysql.session    | caching_sha2_password |
| mysql.sys        | caching_sha2_password |
| root             | caching_sha2_password |
+------------------+-----------------------+

虽然启动MGR成功,但是查看下节点状态:

greatsql> select * from performance_schema.replication_group_members\G
*************************** 1. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: 2920447e-35bf-11ee-89a5-00163e566da1MEMBER_HOST: 172.17.139.77MEMBER_PORT: 3306MEMBER_STATE: ONLINEMEMBER_ROLE: PRIMARYMEMBER_VERSION: 8.0.32
MEMBER_COMMUNICATION_STACK: XCom
*************************** 2. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: 2a4f068b-35bf-11ee-9504-00163e566da1MEMBER_HOST: 172.17.139.77MEMBER_PORT: 3307MEMBER_STATE: RECOVERINGMEMBER_ROLE: SECONDARYMEMBER_VERSION: 8.0.32
MEMBER_COMMUNICATION_STACK: XCom
2 rows in set (0.00 sec)

此时节点一直处于RECOVERING状态,查看mgr02实例的错误日志如下:

2023-08-08T08:00:47.034870Z 42 [ERROR] [MY-010584] [Repl] Slave I/O for channel 'group_replication_recovery': error connecting to master 'repl@172.17.139.77:3306' - retry-time: 60 retries: 1 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection. Error_code: MY-002061
2023-08-08T08:00:47.037631Z 35 [ERROR] [MY-011582] [Repl] Plugin group_replication reported: 'There was an error when connecting to the donor server. Please check that group_replication_recovery channel credentials and all MEMBER_HOST column values of performance_schema.replication_group_members table are correct and DNS resolvable.'
2023-08-08T08:00:47.037671Z 35 [ERROR] [MY-011583] [Repl] Plugin group_replication reported: 'For details please check performance_schema.replication_connection_status table and error log messages of Slave I/O for channel group_replication_recovery.'

这是由于caching_sha2_password 是 MySQL 8.0.4 引入的一个新的身份验证插件,caching_sha2_password 对密码安全性要求更高,要求用户认证过程中在网络传输的密码是加密的,所以导致的这个问题的出现,caching_sha2_password的介绍可以看社区文章“浅谈 MySQL 新的身份验证插件 caching_sha2_password【微信导入、微信导入】”

解决方式

1、采用旧密码验证插件

旧的身份验证插件mysql_native_passwordmysql_native_password的特点是不需要加密的连接。该插件验证速度特别快,但是不够安全,只需要更改创建用户的语句

create user repl@'%' identified with mysql_native_password by 'GreatSQL@666';

旧密码验证插件容易被破解,如果有 GreatSQL 服务要公网上使用,建议还是尽量使用 caching_sha2_password作为认证插件

2、启用group_replication_recovery_get_public_key

设置 group_replication_recovery_get_public_key=ON 可以确保从节点在连接到主节点时能够获取所需的公钥,从而允许安全连接并成功进行身份验证,避免了连接错误和身份验证问题。

手册中也有明确说明:

18.6.3.1.1 Replication User With The Caching SHA-2 Authentication Plugin
By default, users created in MySQL 8 use Section 6.4.1.2, “Caching SHA-2 Pluggable Authentication”. If the replication user you configure for distributed recovery uses the caching SHA-2 authentication plugin, and you are not using SSL for distributed recovery connections, RSA key-pairs are used for password exchange. For more information on RSA key-pairs, see Section 6.3.3, “Creating SSL and RSA Certificates and Keys”.In this situation, you can either copy the public key of the to the joining member, or configure the donors to provide the public key when requested. The more secure approach is to copy the public key of the replication user account to the joining member. Then you need to configure the group_replication_recovery_public_key_path system variable on the joining member with the path to the public key for the replication user account. rpl_userThe less secure approach is to set group_replication_recovery_get_public_key=ON on donors so that they provide the public key of the replication user account to joining members. There is no way to verify the identity of a server, therefore only set group_replication_recovery_get_public_key=ON when you are sure there is no risk of server identity being compromised, for example by a man-in-the-middle attack.

可以看到,当确认环境安全以及没人任何人攻击集群时,如果不配置ssl,可以最低配置group_replication_recovery_get_public_key=ON来在请求复制用户密钥时给公钥

3、为组复制通道启用SSL支持

以下操作方法仅使用于 GreatSQL/MySQL 8.0.27版本及以上

更安全的方法是将repl用户所需的公钥文件复制到joiner节点的Server所在主机中。然后,在joiner节点的Server中配置group_replication_recovery_public_key_path系统变量,指定rpl_user用户所需的公钥文件路径。

使用caching_sha2_password 插件身份验证会在数据目录下生成如下两个RSA文件:

private_key.pem
public_key.pem
  • private_key.pem:RSA私钥
  • public_key.pem: RSA公钥

对于 MGR ,如果设置 group_replication_ssl_mode=DISABLED 必须使用下面的变量来指定 RSA 公钥,否则报错:

  • group_replication_recovery_get_public_key :向服务端请求 RSA 公钥;
  • group_replication_recovery_public_key_path :指定本地 RSA 公钥文件;

指定本地RSA公钥,首先需要全局MGR配置开启SSL

[mysqld]
#开启use_ssl,指定组成员之间的组复制分布式恢复连接是否应使用 SSL
loose-group_replication_recovery_use_ssl=ON

进入MGR01实例配置

greatsql> set session sql_log_bin=0;
# 此时就可以使用“caching_sha2_password”身份认证插件
greatsql> create user repl@'%' identified by 'GreatSQL@666';
greatsql> GRANT BACKUP_ADMIN, REPLICATION SLAVE ON *.* TO `repl`@`%`;
greatsql> set session sql_log_bin=1;
greatsql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='GreatSQL@666' FOR CHANNEL 'group_replication_recovery';

启动MGR01实例的MGR集群

greatsql> set global group_replication_bootstrap_group=ON;
greatsql> start group_replication;
greatsql> select * from performance_schema.replication_group_members\G
*************************** 1. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: 35b653d2-3658-11ee-93c9-00163e566da1MEMBER_HOST: 172.17.139.77MEMBER_PORT: 3306MEMBER_STATE: ONLINEMEMBER_ROLE: PRIMARYMEMBER_VERSION: 8.0.32
MEMBER_COMMUNICATION_STACK: XCom

启动成功后,需要把MGR01节点的RSA公钥拷贝到MGR02节点上,因为MGR02也会生成此公钥,所以最好创建一个文件夹

$ mkdir mgr01_key
$ chown mysql:mysql mgr01_key/
# 将public_key.pem移动到MGR02
$ mv /data/GreatSQL/mgr01/public_key.pem /data/GreatSQL/mgr02/mgr01_key/

当然,如果有多个节点,也需要把主节点的RSA公钥移动到各个节点上

MGR02节点操作

greatsql> set session sql_log_bin=0;
greatsql> create user repl@'%' identified by 'GreatSQL@666';
greatsql> GRANT BACKUP_ADMIN, REPLICATION SLAVE ON *.* TO `repl`@`%`;
greatsql> set session sql_log_bin=1;
greatsql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='GreatSQL@666' FOR CHANNEL 'group_replication_recovery';# 此命令设置完成后,最好写进my.cnf文件中持久化
greatsql> set global group_replication_recovery_public_key_path = "/data/GreatSQL/mgr02/mgr01key/public_key.pem";greatsql> start group_replication;
greatsql> select * from performance_schema.replication_group_members\G
*************************** 1. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: 35b653d2-3658-11ee-93c9-00163e566da1MEMBER_HOST: 172.17.139.77MEMBER_PORT: 3306MEMBER_STATE: ONLINEMEMBER_ROLE: PRIMARYMEMBER_VERSION: 8.0.32
MEMBER_COMMUNICATION_STACK: XCom
*************************** 2. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: aa031fb9-365a-11ee-9925-00163e566da1MEMBER_HOST: 172.17.139.77MEMBER_PORT: 3307MEMBER_STATE: ONLINEMEMBER_ROLE: SECONDARYMEMBER_VERSION: 8.0.32
MEMBER_COMMUNICATION_STACK: XCom

可以看到双节点ONLINE,新加入的节点不会一直是RECOVERING状态

总结

新身份验证插件caching_sha2_password安全度相比其他的身份验证插件,既解决安全性问题又解决性能问题,建议使用新密码验证插件。

也感谢社区用户指出GreatSQL社区文档中的不足,并给予用户金币奖励,同时欢迎大家来GreatSQL社区捉虫~

Enjoy GreatSQL :)

关于 GreatSQL

GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

image

社区有奖建议反馈: https://greatsql.cn/thread-54-1-1.html

社区博客有奖征稿详情: https://greatsql.cn/thread-100-1-1.html

(对文章有疑问或者有独到见解都可以去社区官网提出或分享哦~)

技术交流群:

微信&QQ群:

QQ群:533341697

微信群:添加GreatSQL社区助手(微信号:wanlidbc )好友,待社区助手拉您进群。

相关文章:

MGR新节点RECOVERING状态的分析与解决:caching_sha2_password验证插件的影响

起因 在GreatSQL社区上有一位用户提出了“手工构建MGR碰到的次节点一直处于recovering状态”,经过排查后,发现了是因为新密码验证插件caching_sha2_password导致的从节点一直无法连接主节点,帖子地址:(https://greatsql.cn/threa…...

git merging两边都被删除的文件

1. 场景: merge 另一个分支到当前分支,解决完冲突列表中的冲突后,发现项目任然在 merging 中,无法进行git下一步操作。 2. 原因: 通过 git status 发现一个文件,显示表面,该文件在当前分支和…...

项目--苍穹外卖

1.| constant | 存放相关常量类 | | context | 存放上下文类 | | enumeration | 项目的枚举类存储 | | exception | 存放自定义异常类 | | json | 处理json转换的类 | | properties | 存放SpringBoot相关的配置属性类 | | result | 返回结果类的封装 | | utils | 常用工具类 | …...

从零开发短视频电商 使用Spring WebClient发起远程Http调用

文章目录 依赖使用创建WebClient实例创建带有超时的WebClient实例示例 请求准备获取响应 高级过滤器自定义过滤器 自定义线程池自定义WebClient连接池开启日志错误处理最佳实践 示例异步请求同步请求上传文件重试过滤错误错误处理 参考 Spring WebClient 是 Spring WebFlux 项目…...

Python实现成语接龙

如图: 详细代码实现: # coding:utf-8 import string import pypinyin import sys import randomprint("初始化中,请稍等……")def main():f2 open(./idiom.txt, r, encodingutf-8)f f2.read() # 一次性读取完成new3_list f.sp…...

继续上一个爬虫,所以说selenium加browsermobproxy

继续,书接上回,这次我通过jsrpc,也学会了不少逆向的知识,感觉对于一般的网站应该都能应付了。当然我说的是简单的网站,遇到那些混淆的,还有那种猿人学里面的题目,还是免谈了。那种需要的水平太高…...

Sentinel服务熔断和流控

Sentinel服务熔断和流控 简介 Sentinel ​ 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来…...

01_TMS320F28004x系列MCU介绍和资料搜集

1. TI C2000 实时微控制器 TI公司在处理器方面的产品线有:基于ARM内核的微控制器/微处理器、MSP430微控制器、C2000系列实时微控制器、还有数字信号处理器(DSP)。 其中,C2000是TI公司专门针对实时控制推出的32位微控制器。TI公司…...

JavaScript中获取对象属性的不同方法

JavaScript中获取对象属性的不同方法 文章目录 JavaScript中获取对象属性的不同方法一、点记法二、方括号记法三、Object.keys()方法四、Object.values()方法五、Object.entries()方法六、Object.getOwnPropertyNames()方法七、Object.getOwnPropertyDescriptors()方法 JavaScr…...

【STM32教程】第四章 STM32的外部中断EXTI

案例代码及相关资料下载链接: 链接:https://pan.baidu.com/s/1hsIibEmsB91xFclJd-YTYA?pwdjauj 提取码:jauj 1 中断系统 1.1 中断的概念 中断系统的定义:中断是指在主程序运行过程中,出现了特定的中断触发条件…...

力扣第40天----第121题、第122题

# 力扣第40天----第121题、第122题 文章目录 一、第121题--买卖股票的最佳时机二、第122题--买卖股票的最佳时机II 一、第121题–买卖股票的最佳时机 ​ 分2种情况考虑,根据持有股票、不持有股票这2种情况,完成递推公式。另外,这里要求只买卖…...

Flask 使用 JWT(二)

在 Python 使用 JWT 主要的方案是 PyJWT 工具。 安装与基本使用 可以使用 pip 安装 PyJWT: $ pip install pyjwt编码与解码 编码函数 def encode( self, payload: Dict[str, Any], # payload 参数 key: str, …...

从0到1理解ChatGPT原理

目录 写在前面 1.Tansformer架构模型 2.ChatGPT原理 3.提示学习与大模型能力的涌现 3.1提示学习 3.2上下文学习 3.3思维链 4.行业参考建议 4.1拥抱变化 4.2定位清晰 4.3合规可控 4.4经验沉淀 机械工业出版社京东自购链接 写在前面 2022年11月30日,ChatG…...

如何解决 “Component cannot be used as a JSX component“

原因是react版本与types/react版本不一致导致的, 在tsconfig.json中加入以下代码,将依赖指向项目里的node_modules "paths": {"react": [ "./node_modules/types/react" ]}改完后代码大概是长这样的 {"compilerOptions": {..."…...

小程序自定义tabbar

前言 使用小程序默认的tabbar可以满足常规开发,但是满足不了个性化需求,如果想个性化开发就需要用到自定义tabbar,以下图为例子 一、在app.json配置 先按照以往默认的形式配置,如果中间的样式特殊则不需要配置 "tabBar": {&qu…...

分布式系统第五讲:分布式事务及实现方案

分布式系统第五讲:分布式事务及实现方案 事务是一个程序执行单元,里面的所有操作要么全部执行成功,要么全部执行失败。而分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。本…...

算法通关村17关 | 透析跳跃游戏

1. 跳跃游戏 题目 LeetCode55 给定一个非负整数数组,最初位于数组的第一个位置,数组中的每个元素代表你再该位置可以跳跃的最大长度,判断你是否能够达到最后一个位置。 思路 如果当前位置元素如果是3,我们无需考虑是跳几步&#…...

ARM接口编程—RTC(exynos 4412平台)

RTC简介 RTC(Real Time Clock)即实时时钟,它是一个可以为系统提供精确的时间基准的元器件,RTC一般采用精度较高的晶振作为时钟源,有些RTC为了在主电源掉电时还可以工作,需要外加电池供电。 RTC内部原理 RTC寄存器 RTC控制寄存器 …...

数据分享|WEKA信贷违约预测报告:用决策树、随机森林、支持向量机SVM、朴素贝叶斯、逻辑回归...

完整报告链接:http://tecdat.cn/?p28579 作者:Nuo Liu 数据变得越来越重要,其核心应用“预测”也成为互联网行业以及产业变革的重要力量。近年来网络 P2P借贷发展形势迅猛,一方面普通用户可以更加灵活、便快捷地获得中小额度的贷…...

逆市而行:如何在市场恐慌时保持冷静并抓住机会?

市场中的恐慌和波动是投资者所不可避免的。当市场出现恐慌情绪时,很多投资者会盲目跟从大众,导致决策出现错误。然而,聪明的投资者懂得在恐慌中保持冷静,并将其视为抓住机会的时机。本文将分享一些在市场恐慌时保持冷静并抓住机会…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

数据链路层的主要功能是什么

数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...