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

MYSQL双主双从,使用Keepalived双机热备+LVS高可用群集

MYSQL双主双从,使用Keepalived双机热备+LVS高可用群集

​ 文档只记录Keepalived+LVS+mysql主从,不包含检验,如需检验,请自行添加web服务器

一、IP规划

服务器IP备注
master1192.168.100.131master2的从
master2192.168.100.132master1的从
slave1192.168.100.134master1的从
slave2192.168.100.135master2的从
KI1192.168.100.137
KI2192.168.100.138
虚拟ip192.168.100.200热备ip

二、具体配置

1.master1

​ 配置ip:192.168.100.131

​ 关闭防护墙,selinux

# 关闭防火墙
systemctl stop firewalld# 关闭selinux
setenforce 0

​ 下载mariadb

yum -y install mariadb mariadb-server

​ 编辑mariadb配置文件

vi /etc/my.cnf

​ 添加以下内容

# 标识(0-65535范围)
server-id=1# 日志文件名称前缀
log-bin=mysql-bin# 排除不复制的库
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys# 配置中继日志名称
relay-log=mysql-relay-bin# 配置排除的库
replicate-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=sys# 编码格
init-connect='SET NAMES UTF8'
skip-character-set-client-handshake
character-set-server=utf8# 开启联等备份
log_slave_updates=1

​ 修改完成重启服务

# 重启服务
systemctl restart mariadb# 配置mysql密码,123456
mysql_secure_installation 

​ 授权

# 进入mysql
mysql -uroot -p123456# 创建用户
create user "backup"@"%" identified by '123456';# 授权
grant replication slave on *.* to "backup"@"%" identified by "123456";
grant all privileges on *.* to 'root'@'%' identified by '123456';# 刷新权限
flush privileges;# 查询Log_file,log_pos
show master status;
+------------------+----------+--------------+-------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                                |
+------------------+----------+--------------+-------------------------------------------------+
| mysql-bin.000003 |     1947 |              | mysql,information_schema,performance_schema,sys |
+------------------+----------+--------------+-------------------------------------------------+
1 row in set (0.00 sec)# 从库连接主库,MASTER_LOG_FILE与MASTER_LOG_POS的值由主库信息获得
change master to 
MASTER_HOST='192.168.100.132', 
MASTER_USER='backup', 
MASTER_PASSWORD='123456', 
MASTER_PORT=3306, 
MASTER_LOG_FILE='mysql-bin.000003', 
MASTER_LOG_POS=1947;# 开启复制
start slave;# 查看slave状态,Slave_IO_Running,Slave_SQL_Running的状态要为Yes
show slave status \G;

2.master2

​ 配置ip:192.168.100.132

​ 关闭防护墙,selinux

# 关闭防火墙
systemctl stop firewalld# 关闭selinux
setenforce 0

​ 下载mariadb

yum -y install mariadb mariadb-server

​ 编辑mariadb配置文件

vi /etc/my.cnf

​ 添加以下内容

# 标识(0-65535范围)
server-id=2# 日志文件名称前缀
log-bin=mysql-bin# 排除不复制的库
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys# 配置中继日志名称
relay-log=mysql-relay-bin# 配置排除的库
replicate-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=sys# 编码格
init-connect='SET NAMES UTF8'
skip-character-set-client-handshake
character-set-server=utf8# 开启联等备份
log_slave_updates=1

​ 修改完成重启服务

# 重启服务
systemctl restart mariadb# 配置mysql密码,123456
mysql_secure_installation 

​ 授权

# 进入mysql
mysql -uroot -p123456# 创建用户
create user "backup"@"%" identified by '123456';# 授权
grant replication slave on *.* to "backup"@"%" identified by "123456";
grant all privileges on *.* to 'root'@'%' identified by '123456';# 刷新权限
flush privileges;# 查询Log_file,log_pos
show master status;
+------------------+----------+--------------+-------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                                |
+------------------+----------+--------------+-------------------------------------------------+
| mysql-bin.000003 |     1947 |              | mysql,information_schema,performance_schema,sys |
+------------------+----------+--------------+-------------------------------------------------+
1 row in set (0.00 sec)# 从库连接主库,MASTER_LOG_FILE与MASTER_LOG_POS的值由主库信息获得
change master to 
MASTER_HOST='192.168.100.134', 
MASTER_USER='backup', 
MASTER_PASSWORD='123456', 
MASTER_PORT=3306, 
MASTER_LOG_FILE='mysql-bin.000004', 
MASTER_LOG_POS=1947;# 开启复制
start slave;# 查看slave状态,Slave_IO_Running,Slave_SQL_Running的状态要为Yes
show slave status \G;

3.slave1

​ 配置ip:192.168.100.134

​ 关闭防护墙,selinux

# 关闭防火墙
systemctl stop firewalld# 关闭selinux
setenforce 0

​ 下载mariadb

yum -y install mariadb mariadb-server

​ 编辑mariadb配置文件

vi /etc/my.cnf

​ 添加以下内容

# 标识(0-65535范围)
server-id=3# 配置中继日志名称
relay-log=mysql-relay-bin# 配置排除的库
replicate-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=sys# 编码格式
init-connect='SET NAMES UTF8'
skip-character-set-client-handshake
character-set-server=utf8

​ 修改完成重启服务

# 重启服务
systemctl restart mariadb# 配置mysql密码,123456
mysql_secure_installation 

​ 授权

# 连接数据库
mysql -uroot -p123456# 授权
grant all privileges on *.* to "root"@"%" identified by "123456"; # 刷新权限
flush privileges;# 从库连接主库,MASTER_LOG_FILE与MASTER_LOG_POS的值由主库信息获得
change master to 
MASTER_HOST='192.168.100.131', 
MASTER_USER='backup', 
MASTER_PASSWORD='123456', 
MASTER_PORT=3306, 
MASTER_LOG_FILE='mysql-bin.000003', 
MASTER_LOG_POS=1947;# 开启复制
start slave;# 查看slave状态,Slave_IO_Running,Slave_SQL_Running的状态要为Yes
show slave status \G;

4.slave2

​ 配置ip:192.168.100.135

​ 关闭防护墙,selinux

# 关闭防火墙
systemctl stop firewalld# 关闭selinux
setenforce 0

​ 下载mariadb

yum -y install mariadb mariadb-server

​ 编辑mariadb配置文件

vi /etc/my.cnf

​ 添加以下内容

# 标识(0-65535范围)
server-id=4# 配置中继日志名称
relay-log=mysql-relay-bin# 配置排除的库
replicate-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=sys# 编码格
init-connect='SET NAMES UTF8'
skip-character-set-client-handshake
character-set-server=utf8

​ 修改完成重启服务

# 重启服务
systemctl restart mariadb# 配置mysql密码,123456
mysql_secure_installation 

​ 授权

# 连接数据库
mysql -uroot -p123456# 授权
grant all privileges on *.* to "root"@"%" identified by "123456"; # 刷新权限
flush privileges;# 从库连接主库,MASTER_LOG_FILE与MASTER_LOG_POS的值由主库信息获得
change master to 
MASTER_HOST='192.168.100.132', 
MASTER_USER='backup', 
MASTER_PASSWORD='123456', 
MASTER_PORT=3306, 
MASTER_LOG_FILE='mysql-bin.000003', 
MASTER_LOG_POS=1947;# 开启复制
start slave;# 查看slave状态,Slave_IO_Running,Slave_SQL_Running的状态要为Yes
show slave status \G;

5.KI1

​ 配置ip:192.168.100.137

​ 关闭防护墙,selinux

# 关闭防火墙
systemctl stop firewalld# 关闭selinux
setenforce 0

​ 下载keepalived和ipvsadm

yum -y install keepalived ipvsadm

​ 备份默认配置文件

cp -p /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

​ 删除原有文件,创建新内容

# 删除原有文件
rm -rf /etc/keepalived/keepalived.conf # 创建新文件
vi /etc/keepalived/keepalived.conf 

​ 添加以下内容

! Configuration File for keepalived# 配置双机热备(主)
lobal_defs {router_id 1
}
vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 1priority 120advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.100.200}
}# 虚拟服务器ip及mysql地址
virtual_server 192.168.100.200 3306 {delay_loop 15lb_algo rrlb_kind DRprotocol TCPreal_server 192.168.100.131 3306 {weight 1TCP_CHECK {connect_port 3306connect_timeout 3nb_get_retry 3delay_before_retry 4}}real_server 192.168.100.132 3306 {weight 1TCP_CHECK {connect_port 3306connect_timeout 3nb_get_retry 3delay_before_retry 4}}
}

​ 启动keepalived

systemctl start keepalived

​ 服务模块

# 加载系统内核的服务模块
modprobe ip_vs# 查看运行状态
lsmod | grep ip_vs

​ 查看规则

ipvsadm -l

​ 下载net网络工具

yum -y install net-tools

​ 查看网卡信息

# 停用物理网卡
ifconfig ens33 down# 启动物理网卡(如在连接工具上,需到虚拟机上启动)
ifconfig ens33 up# 查看网卡信息(在ens33网卡下是否有ip:192.168.100.200)
ip a

​ 虚拟网卡

# 添加虚拟网卡(回环地址)
cat >> /etc/sysconfig/network-scripts/ifcfg-lo:0  << EOF
DEVICE=lo:0
IPADDR=192.168.100.200
NETMASK=255.255.255.255
ONBOOT=yes
EOF# 重启网络
systemctl restart network# 查看是否有虚拟ip
ip a

​ 写入路由指向

# 添加路由信息
route add -host 192.168.100.200 dev lo:0

6.KI2

​ 配置ip:192.168.100.138

​ 关闭防护墙,selinux

# 关闭防火墙
systemctl stop firewalld# 关闭selinux
setenforce 0

​ 下载keepalived和ipvsadm

yum -y install keepalived ipvsadm

​ 备份默认配置文件

cp -p /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

​ 添加以下内容

! Configuration File for keepalived# 配置双机热备(备)
lobal_defs {router_id 2
}
vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 1priority 100advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.100.200}
}# 虚拟服务器ip及mysql地址
virtual_server 192.168.100.200 3306 {delay_loop 15lb_algo rrlb_kind DRprotocol TCPreal_server 192.168.100.131 3306 {weight 1TCP_CHECK {connect_port 3306connect_timeout 3nb_get_retry 3delay_before_retry 4}}real_server 192.168.100.132 3306 {weight 1TCP_CHECK {connect_port 3306connect_timeout 3nb_get_retry 3delay_before_retry 4}}
}

​ 启动keepalived

systemctl start keepalived

​ 服务模块

# 加载系统内核的服务模块
modprobe ip_vs# 查看运行状态
lsmod | grep ip_vs

​ 查看规则

ipvsadm -l

​ 下载net网络工具

yum -y install net-tools

​ 查看网卡信息

# 停用物理网卡
ifconfig ens33 down# 启动物理网卡(如在连接工具上,需到虚拟机上启动)
ifconfig ens33 up# 查看网卡信息(在ens33网卡下是否有ip:192.168.100.200)
ip a

​ 虚拟网卡

# 添加虚拟网卡(回环地址)
cat >> /etc/sysconfig/network-scripts/ifcfg-lo:0  << EOF
DEVICE=lo:0
IPADDR=192.168.100.200
NETMASK=255.255.255.255
ONBOOT=yes
EOF# 重启网络
systemctl restart network# 查看是否有虚拟ip
ip a

​ 写入路由指向

# 添加路由信息
route add -host 192.168.100.200 dev lo:0

三、检验

​ 可自行添加一台web服务器,连接虚拟ip,开启KI1或KI2的防火墙进行检测

或者,开启KI1的防火墙,查看ip是否跳转到KI2上

相关文章:

MYSQL双主双从,使用Keepalived双机热备+LVS高可用群集

MYSQL双主双从&#xff0c;使用Keepalived双机热备LVS高可用群集 ​ 文档只记录KeepalivedLVSmysql主从&#xff0c;不包含检验&#xff0c;如需检验&#xff0c;请自行添加web服务器 一、IP规划 服务器IP备注master1192.168.100.131master2的从master2192.168.100.132maste…...

9.计算机视觉—目标检测

目录 1.物体检测边缘框目标检测数据集总结边缘框代码实现2.锚框:目标检测的一种方法IoU—交并比赋予锚框标号使用非极大值抑制(NMS)输出总结代码实现1.物体检测 边缘框 一个边缘框可以通过四个数字定义 (左上x,左上y),(右下x,右下y)(左上x,左上y,宽,高)(中间x,中间y…...

构造函数深入理解

目录 构造函数构造函数体赋值初始化列表初始化列表格式初始化列表的意义以及注意点const修饰的成员变量初始化对象成员具体初始化的地方缺省值存在的意义例子1例子2 初始化与赋值引用成员变量的初始化注意点1注意点2我的疑惑 自定义类型成员初始化例子1例子2例子3例子4 初始化列…...

Rocky Linux 9 快速安装docker 教程

前述 CentOS 7系统将于2024年06月30日停止维护服务。CentOS官方不再提供CentOS 及后续版本&#xff0c;不再支持新的软件和补丁更新。CentOS用户现有业务随时面临宕机和安全风险&#xff0c;并无法确保及时恢复。由于 CentOS Stream 相对不稳定&#xff0c;刚好在寻找平替系统…...

go语言并发编程1-Gouroutine

参考文档&#xff1a;www.topgoer.com 使用方法 直接包装成函数&#xff0c;go关键字触发即可 注意事项 1 main方法结束后&#xff0c;main方法内启动的子协程会立即结束&#xff0c;无论是否执行完毕&#xff1b; 启动多个groutine 使用sync包的WaitGroup来控制&#xf…...

Sylar服务器框架——Http模块

1、http.h 定义了HttpMethod和HttpStatus /* Request Methods */ #define HTTP_METHOD_MAP(XX) \XX(0, DELETE, DELETE) \XX(1, GET, GET) \XX(2, HEAD, HEAD) \XX(3, POST, POST) \XX(4, PUT, …...

7km远距离WiFi实时图传模块,无人机海上无线传输方案,飞睿智能WiFi MESH自组网技术

在浩瀚无垠的海洋上&#xff0c;无人机正在开启一场前所未有的技术创新。它们不再只是天空的舞者&#xff0c;更是海洋的守望者&#xff0c;为我们带来前所未有的视野和数据。而这一切的背后&#xff0c;都离不开一项创新性的技术——飞睿智能远距离WiFi实时图传模块与无线Mesh…...

2024年上半年网络工程师下午真题及答案解析

试题一(20分) 某高校网络拓扑如下图所示&#xff0c;两校区核心&#xff08;CORE-1、CORE-2&#xff09;&#xff0c;出口防火墙&#xff08;NGFW-1、NGFW-2&#xff09;通过校区间光缆互联&#xff0c;配置OSPF实现全校路由收敛&#xff0c;两校区相距40km。两校区默认由本地…...

Jmeter下载、安装及配置

1 Jmeter介绍 Jmeter是进行负载测试的工具&#xff0c;可以在任何支持Java虚拟机环境的平台上运行&#xff0c;比如Windows、Linux、Mac。 Jmeter模拟一组用户向目标服务器发送请求&#xff0c;并统计目标服务器的性能信息&#xff0c;比如CPU、memory usage。 2 Jmeter下载 …...

掌握高效实用的VS调试技巧

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 1.编程常见的错误 1.1编译型错误 编程编译型错误是指在编译代码时发现的错误。编译器在编译过程中会检查代码是否符合语法规范和语义要求&#xff0c;如果发现错误会产生编译错误。 直接看错误提示信息&#xff08;双击&#…...

实验2 字符及字符串输入输出与分支程序设计实验

字符及字符串输入输出 从键盘输入两个一位十进制数&#xff0c;计算这两个数之和&#xff0c;并将结果在屏幕上显示出来。 分支程序设计 从键盘输入一字符&#xff0c;判断该字符是小写字母、大写字母、数字或者其他字符。若输入为小写字母&#xff0c;显示“You Input a Lo…...

docker容器间网络仿真工具-pumba

docker-tc&pumba docker-tc:docker-tc项目仓库 pumba:pumba项目仓库 这两个项目理论上都可以实现对容器间的网络环境进行各种模拟干预&#xff0c;包括延迟&#xff0c;丢包&#xff0c;带宽限制等。 但是我在实际使用时&#xff0c;发现docker-tc这个工具在进行网络进行模…...

A36 STM32_HAL库函数 之PCD通用驱动 -- B -- 所有函数的介绍及使用

A36 STM32_HAL库函数 之PCD通用驱动 -- B -- 所有函数的介绍及使用 1 该驱动函数预览1.11 HAL_PCD_SOFCallback1.12 HAL_PCD_ResetCallback1.13 HAL_PCD_SuspendCallback1.14 HAL_PCD_ResumeCallback1.15 HAL_PCD_ISOOUTIncompleteCallback1.16 HAL_PCD_ISOINIncompleteCallbac…...

vue2 + element三级菜单实现模板

需求&#xff1a; 需要一个含有三级菜单的结构模板&#xff0c;用于业务快速开发。 解决&#xff1a; sidebar.vue <template><el-menu :default-active"defaultActive" class"el-menu-vertical-demo" active-text-color"#ffd04b"&…...

vue H5页面video 视频流自动播放, 解决ios不能自动播放问题

视频组件 <videostyle"width: 100%; height: 100%;object-fit: fill"class"player"refplayer_big_boxcontrolspreloadautoplay //自动播放muted //是否静音playsinline"true"x5-playsinline""webkit-playsinline"tru…...

自闭症儿童:探索症状背后的多彩内心世界

在星启帆自闭症康复中心&#xff0c;我们每天与一群独特而珍贵的孩子相遇——他们&#xff0c;是自闭症谱系障碍的患儿。自闭症&#xff0c;这一复杂的神经发育障碍&#xff0c;以其多样化的症状表现&#xff0c;为每个孩子的生活轨迹绘上了不同的色彩。 自闭症孩子的症状各异…...

在Centos7上安装PostgreSQL16的详细步骤

文章目录 环境一、准备二、postgresql下载方法一&#xff1a;wget下载方法二&#xff1a;下载压缩包解压 三、创建用户组、用户四、创建数据主目录五、配置环境变量六、initdb初使化数据库七、配置服务八、设置开机自启动九、设置防火墙十、启动数据库服务 环境 CPU: 4 核心或以…...

MySQL 图形化界面

填完信息之后&#xff0c;圆圈处可以验证是否可以连接数据库 展示所有数据库&#xff08;因为有的可能连上&#xff0c;却没有数据库显示&#xff09;...

【人工智能】GPT-5的即将到来:从高中生进化到,,,博士生?

GPT-5的即将到来&#xff1a;从高中生进化到,博士生&#xff1f; 随着近月GPT-4o的出世&#xff0c;OpenAI也在进行一系列的采访和介绍接下来的展望和目标。 在6月22日的采访中&#xff0c;美国达特茅斯工程学院公布了OpenAI首席技术官米拉穆拉蒂的访谈内容。穆拉蒂确认&#…...

【收录率高丨投稿范围广 | 往届均已EI检索】第四届光学与通信技术国际学术会议(ICOCT 2024,8月9-11)

欢迎参加第四届光学与通信技术国际学术会议&#xff08;ICOCT 2024&#xff09;&#xff0c;该会议将于2024年8月9-11日在南京举办。自2021年首次会议以来&#xff0c;ICOCT已经发展成为光学和通信领域较有影响力的国际会议之一&#xff0c;聚焦最前沿的技术进展与未来发展趋势…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...