阿里云部署MySQL、Redis、RocketMQ(1),被面试官问的Linux运维-Framework难倒了

docker restart mysql_node1_master1

部署node1节点的slave1
docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir -p /var/lib/mysqlslave1
ls -ld /var/lib/mysqlslave1/
chmod 755 /var/lib/mysqlslave1/
ls -ld /var/lib/mysqlslave1/
mkdir -p /opt/software/mysqlcluster/slave1
cd /opt/software/mysqlcluster/slave1
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql\_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node1_slave1  # 指定容器名称为mysql\_node2\_slave1
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33064:3309"  # 将容器的3306端口映射到主机的33061端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node1slave1root  # 设置root用户的密码 
    volumes:  # 定义数据卷
      - /var/lib/mysqlslave1:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode1slave1root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir -p /opt/software/mysqlcluster/slave1/conf
vi /opt/software/mysqlcluster/slave1/conf/my.cnf

my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1011  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3309  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
relay_log = relay-log  # 开启中继日志
relay_log_index = slave-relay-bin.index  # 设置中继日志索引的文件名
read_only = ON # 启用只读属性
relay_log_purge = 0 # 是否自动清空不再需要中继日志
log_slave_updates=1  # 开启从服务器记录二进制日志更新的功能
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID\_MODE 和 ENFORCE\_GTID\_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O\_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
# plugin-load = semisync_slave.so  # 半同步复制
# rpl_semi_sync_slave_enabled = 1 # 开启半同步复制
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时

授权启动
sudo chmod 644 /opt/software/mysqlcluster/slave1/conf/my.cnf

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/slave1/conf/my.cnf mysql_node1_slave1:/etc/mysql/my.cnf

重启容器

docker restart mysql_node1_slave1

进入主节点容器,命令如下:

docker exec -it mysql_node1_slave1 bash

登录mysql,命令如下:

mysql -u root -pnode1slave1root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装smeisync_slave模块,命令如下:

install plugin rpl_semi_sync_slave soname 'semisync\_slave.so';
set global rpl_semi_sync_slave_enabled = on;

查看效果,命令如下:

show global variables like 'rpl\_semi%';

输出结果:

mysql> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

rpl_semi_sync_slave_enabled为ON表示设置成功。

授权,命令如下:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node1slave1root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node1slave1root';
FLUSH PRIVILEGES;

退出容器将my.cnf文件中的:

# plugin-load = semisync\_slave.so # 半同步复制
# rpl\_semi\_sync\_slave\_enabled = 1 # 开启半同步复制

打开:

plugin-load = semisync_slave.so  # 半同步复制
rpl_semi_sync_slave_enabled = 1 # 开启半同步复制

重启从节点1的mysql服务,命令如下:

docker cp /opt/software/mysqlcluster/slave1/conf/my.cnf mysql_node1_slave1:/etc/mysql/my.cnf
docker restart mysql_node1_slave1
docker exec -it mysql_node1_slave1 bash
mysql -u root -pnode1slave1root

部署node1节点的slave2
docker-compose.yaml文件

编辑docker-compose.yaml文件,代码如下:

mkdir -p /var/lib/mysqlslave2
ls -ld /var/lib/mysqlslave2/
chmod 755 /var/lib/mysqlslave2/
ls -ld /var/lib/mysqlslave2/
mkdir /opt/software/mysqlcluster/slave2
cd /opt/software/mysqlcluster/slave2
vi docker-compose.yaml

文件内容,代码如下:

version: '3'  # 使用docker-compose版本3
services:  # 定义服务
  mysql_master:  # 定义一个名为mysql\_master的服务
    image: mysql:8.0.20  # 使用MySQL 8.0.20镜像
    container_name: mysql_node1_slave2  # 指定容器名称为mysql\_node1\_slave2
    restart: unless-stopped  # 在容器退出时自动重新启动
    ports:  # 定义容器和主机之间的端口映射
      - "33065:3310"  # 将容器的3306端口映射到主机的33061端口
    environment:  # 定义环境变量
      MYSQL_ROOT_PASSWORD: node2slave2root  # 设置root用户的密码 
    volumes:  # 定义数据卷
      - /var/lib/mysqlslave2:/var/lib/mysql # 数据目录
    healthcheck:  
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode2slave2root"]  # 设置容器健康检查命令
      interval: 20s  # 每隔20秒进行一次健康检查
      timeout: 10s  # 健康检查超时时间为10秒
      retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir -p /opt/software/mysqlcluster/slave2/conf
vi /opt/software/mysqlcluster/slave2/conf/my.cnf

my.cnf文件
[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
secure-file-priv= NULL
symbolic-links=0
default-storage-engine = InnoDB # 默认存储引擎
server_id = 1021  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3310  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
relay_log = relay-log  # 开启中继日志
relay_log_index = slave-relay-bin.index  # 设置中继日志索引的文件名
read_only = ON # 启用只读属性
relay_log_purge = 0 # 是否自动清空不再需要中继日志
log_slave_updates=1  # 开启从服务器记录二进制日志更新的功能
max_connections = 2000  # 最大连接数
max_user_connections = 1000  # 单个用户最大连接数
max_connect_errors = 4000  # 最大连接错误数
wait_timeout = 300  # 空闲连接的超时时间
interactive_timeout = 600  # 交互式连接的超时时间
table_open_cache = 512  # 表缓存大小
max_allowed_packet = 32M  # 最大允许的数据包大小
sort_buffer_size = 2M  # 排序缓冲区大小
join_buffer_size = 2M  # 连接缓冲区大小
thread_cache_size = 8  # 线程缓存大小
sync_binlog = 0  # 数据刷盘参数=0时,由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大
gtid_mode = ON # 开启GTID模式,用于自动处理复制中的事务  
enforce_gtid_consistency = ON # GTID\_MODE 和 ENFORCE\_GTID\_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
binlog_format = MIXED  # 二进制日志格式
binlog_expire_logs_seconds = 864000  # 二进制日志过期时间(单位:秒)
# InnoDB特定选项
innodb_buffer_pool_size = 4G  # InnoDB缓冲池大小
innodb_thread_concurrency = 8  # InnoDB线程并发数
innodb_flush_method = O\_DIRECT  # InnoDB刷新日志的方法
innodb_flush_log_at_trx_commit = 1 # 控制事务日志的同步方式  
innodb_log_buffer_size = 128M  # InnoDB日志缓冲区大小
innodb_log_file_size = 256M  # InnoDB日志文件大小
innodb_log_files_in_group = 3  # InnoDB日志文件组中的文件数
innodb_max_dirty_pages_pct = 90  # InnoDB脏页的最大比例
innodb_lock_wait_timeout = 50  # InnoDB锁等待超时时间(单位:秒)
innodb_file_per_table = 1  # 每个表使用独立的表空间文件
plugin-load = semisync_slave.so  # 半同步复制
rpl_semi_sync_slave_enabled = 1 # 开启半同步复制
[mysqldump]
quick  # 快速导出数据
max_allowed_packet = 16M  # 最大允许的数据包大小
[myisamchk]
key_buffer_size = 256M  # MyISAM键缓冲区大小
sort_buffer_size = 256M  # MyISAM排序缓冲区大小
read_buffer = 2M  # MyISAM读缓冲区大小
write_buffer = 2M  # MyISAM写缓冲区大小
[mysqlhotcopy]
interactive-timeout = 3600  # 交互式超时时间,超时时间设置为 1 小时

授权启动
sudo chmod 644 /opt/software/mysqlcluster/slave2/conf/my.cnf

启动运行,命令如下:

docker-compose up -d
docker-compose ps

复制配置文件my.cnf到容器中

docker cp /opt/software/mysqlcluster/slave2/conf/my.cnf mysql_node1_slave2:/etc/mysql/my.cnf

重启容器

docker restart mysql_node1_slave2

进入主节点容器,命令如下:

docker exec -it mysql_node1_slave2 bash

登录mysql,命令如下:

mysql -u root -pnode2slave2root

参考server_id是否配置正确,判断my.cnf是否生效

SHOW VARIABLES LIKE 'server_id';

安装smeisync_slave模块,命令如下:

install plugin rpl_semi_sync_slave soname 'semisync\_slave.so';
set global rpl_semi_sync_slave_enabled = on;

查看效果,命令如下:

show global variables like 'rpl\_semi%';

输出结果:

mysql> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

rpl_semi_sync_slave_enabled为ON表示设置成功。

授权,命令如下:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'node2slave2root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'node2slave2root';
FLUSH PRIVILEGES;

退出容器将my.cnf文件中的:

# plugin-load = semisync\_slave.so # 半同步复制
# rpl\_semi\_sync\_slave\_enabled = 1 # 开启半同步复制

打开:

plugin-load = semisync_slave.so  # 半同步复制
rpl_semi_sync_slave_enabled = 1 # 开启半同步复制

重启从节点2的mysql服务,命令如下:

docker cp /opt/software/mysqlcluster/slave2/conf/my.cnf mysql_node1_slave2:/etc/mysql/my.cnf
docker restart mysql_node1_slave2
docker exec -it mysql_node1_slave2 bash
mysql -u root -pnode2slave2root

查看master节点状态

show master status;

配置三个从节点的主从同步配置

配置规划

node1node2node3
master1master2master3
slave1slave1slave1
slave2slave2slave2

查看master节点状态:

show master status

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      156 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> 

在slave1和slave2上配置master1为主节点
CHANGE MASTER TO
MASTER\_HOST='8.134.108.60',
MASTER\_PORT=33061,
MASTER\_USER='root',
MASTER\_PASSWORD='node1master1root',
MASTER\_LOG\_FILE='mysql-bin.000001',
MASTER\_LOG\_POS=156;

开启主从配置,查看从节点状态,命令如下:

START SLAVE;
show slave status\G;

只要Slave_IO_Running: Yes和Slave_SQL_Running: Yes主从同步配置就好了。

校验三主六从集群同步是否正常

在所有master节点查看数据库,命令如下:

show databases;

输出结果如下:

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

在其中一个master节点上创建一个test数据库,命令如下:

create database test;

去其他所有节点上查看数据库是否同步过去,同步过去说明真个集群处于同步状态。

主从复制容易遇错中断

START SLAVE; 命令用于启动 MySQL 的主从复制功能。如果配置的时候主从,但是在同步过程中出现异常错误,则会打断主从同步,并且需要重新手动重新配置,而这个过程需要每隔一段时间监听,使用SHOW SLAVE STATUS\G; 命令来查看从服务器的复制状态,这可能就需要通过手写程序或者使用某云产品来实现。

Redis集群配置

执行编写脚本docker-redis-cluster.sh:

vim docker-redis-cluster.sh

#!/bin/bash  
# 循环执行6次  
for i in $(seq 6)  
do  
  # 设置端口号  
  PORT=637$i    
  # 获取当前主机的IP地址  
  REDIS\_CLUSTER\_IP=$(hostname -I | awk '{print $1}')    
  # 设置配置文件路径  
  CONFIG\_FILE="/opt/software/rediscluster/conf/redis-$i.conf"  
  # 检查配置文件是否存在,如果存在并且是目录,则删除  
  if [ -d "$CONFIG\_FILE" ]; then  
    echo "配置文件$CONFIG\_FILE已经是一个目录,正在删除它..."  
    rm -rf "$CONFIG\_FILE"  
  fi  
  
  # 检查模板文件是否存在  
  if [ ! -f /opt/software/rediscluster/conf/redis.conf ]; then  
    echo "模板文件/opt/software/rediscluster/conf/redis.conf不存在,请确保它存在并且包含正确的占位符。"  
    exit 1  
  fi  
  
  # 通过sed命令替换模板文件中的占位符,生成实际的配置文件  
  sed "s/PORT/${PORT}/g;s/REDIS\_CLUSTER\_IP/${REDIS\_CLUSTER\_IP}/g;" /opt/software/rediscluster/conf/redis.conf > "$CONFIG\_FILE"    
  # 使用docker运行Redis容器,并挂载配置文件和数据目录  
  docker run -d --name redis-node-$i --restart=unless-stopped --net host --privileged=true -v /opt/software/rediscluster/node/redis-node-$i:/data -v "$CONFIG\_FILE":/etc/redis/redis.conf redis:7.2.4 redis-server /etc/redis/redis.conf  
done

redis.conf配置文件

# Redis配置文件示例  
# 绑定到所有网络接口  
bind 0.0.0.0
# 保护模式设置为no,这样Redis就可以接受来自任何主机的连接  
protected-mode no
# Redis 集群节点监听的端口  
port PORT
# TCP backlog的数量,默认是1500,在高并发环境下你可能需要增加这个值。同时需要编辑sudo nano /etc/sysctl.conf文件,添加或者编辑net.core.somaxconn = 1500,在 nano 编辑器中,按 Ctrl + O(这是“O”字母,不是数字零)。这将会提示你保存文件。如果文件是第一次创建或之前没有被修改过,它会询问你文件名,此时你可以直接按 Enter 键确认使用当前的文件名。如果文件已经被修改过,它会直接保存更改。保存文件后,按 Ctrl + X。这将会退出 nano 编辑器并返回到终端。否则会出现提示 TCP 的 backlog 设置(1500)不能强制执行,因为 /proc/sys/net/core/somaxconn 的值被设置为更低的 128。/proc/sys/net/core/somaxconn 是一个内核参数,它定义了系统中每一个端口上排队的最大 TCP 连接数。sudo sysctl -p
tcp-backlog 1500
# 开启集群模式
cluster-enabled yes
# 超时时间,超时则认为master宕机,随后主备切换。单位是毫秒  
cluster-node-timeout 5000
# 集群配置文件的路径,Redis 集群节点会自动创建和更新这个文件  
cluster-config-file nodes-PORT.conf
#集群各节点IP地址,记得修改为你的ip地址
cluster-announce-ip REDIS\_CLUSTER\_IP
#集群节点映射端口 
cluster-announce-port PORT
#集群总线端口 
cluster-announce-bus-port 1PORT 
# TCP 后台线程和I/O线程:如果启用了 TCP 后台线程(io-threads-do-reads)或 I/O 线程(io-threads),确保为这些线程配置了正确的 CPU 内核列表(server_cpulist、bio_cpulist 等)。
io-threads-do-reads yes
io-threads 4
# Redis Server绑定到的CPU内核列表,这里绑定到CPU 0和1  
server_cpulist 0-1 
# 后台I/O线程绑定到的CPU内核列表,这里绑定到CPU 2和3  
bio_cpulist 2-3
# AOF重写进程绑定到的CPU内核列表,这里绑定到CPU 4  
aof_rewrite_cpulist 4 
# RDB持久化进程绑定到的CPU内核列表,这里绑定到CPU 5  
bgsave_cpulist 5
# 启用AOF持久化  
appendonly yes
# AOF文件名称  
appendfilename "appendonly.aof"
# appendonly 文件同步策略,always 表示每个写命令都立即同步,everysec 表示每秒同步一次,no 表示由操作系统决定何时同步  
appendfsync everysec
# 密码设置  
requirepass admin
# Redis集群启用了密码验证,那么除了在每个节点的配置文件中设置requirepass之外,还需要设置masterauth
masterauth admin
# 禁用 RDB 快照持久化,因为集群模式下有节点复制功能  
save ""
# 禁用 AOF 重写
auto-aof-rewrite-percentage 0
auto-aof-rewrite-min-size 0

配置过程

通常情况下内存overcommit(超额提交)未启用,这可能在内存不足的情况下导致后台保存或复制失败。即使在不出现内存不足的情况下,这也可能导致失败。在/etc/sysctl.conf文件中添加vm.overcommit_memory = 1,然后重启系统以启用内存overcommit。

[root@node3 rediscluster]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.core.somaxconn = 1500
sysctl vm.overcommit_memory = 1


或者执行以下命令并查看是否更改成功。

sysctl -w vm.overcommit\_memory=1

然后重启服务器,执行以下命令运行脚本:

chmod 777 /opt/software/rediscluster/conf/redis.conf
chmod 777 /opt/software/rediscluster/docker-redis-cluster.sh
sh docker-redis-cluster.sh

docker exec -it redis-node-1 bash

用私网ip:
在这里插入图片描述

redis-cli  -a admin --cluster create 10.0.0.14:6371 10.0.0.14:6372 10.0.0.14:6373 10.0.0.14:6374 10.0.0.14:6375 10.0.0.14:6376 --cluster-replicas 1

在这里插入图片描述我的Redis实例是在Docker容器内部运行的,应该使用容器内部或宿主机的私有IP地址,而不是公网IP地址。使用的是宿主机公网IP,需要确保防火墙或安全组规则允许外部连接到这些端口。

但是如果防火墙关闭了,就需要使用公网ip,否则客户端连接不上。

redis-cli  -a admin --cluster create 8.138.135.85:6371 8.138.135.85:6372 8.138.135.85:6373 8.138.135.85:6374 8.138.135.85:6375 8.138.135.85:6376 --cluster-replicas 1

redis-cli -p 6371 -a admin

cluster info 

cluster nodes

在这里插入图片描述

RocketMQ

配置runserver.sh

mkdir -p /opt/software/rocketmqcluster/bin
vi /opt/software/rocketmqcluster/bin/runserver.sh

#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#===========================================================================================
# Java Environment Setting
#===========================================================================================
error\_exit ()
{
    echo "ERROR: $1 !!"
    exit 1
}

find\_java\_home()
{
    case "`uname`" in
        Darwin)
            JAVA\_HOME=$(/usr/libexec/java\_home)
        ;;
        *)
            JAVA\_HOME=$(dirname $(dirname $(readlink -f $(which javac))))
        ;;
    esac
}

find_java_home

[ ! -e "$JAVA\_HOME/bin/java" ] && JAVA\_HOME=$HOME/jdk/java
[ ! -e "$JAVA\_HOME/bin/java" ] && JAVA\_HOME=/usr/java
[ ! -e "$JAVA\_HOME/bin/java" ] && error_exit "Please set the JAVA\_HOME variable in your environment, We need java(x64)!"

export JAVA_HOME
export JAVA="$JAVA\_HOME/bin/java"
export BASE\_DIR=$(dirname $0)/..
export CLASSPATH=.:${BASE\_DIR}/conf:${CLASSPATH}

#===========================================================================================
# JVM Configuration
#===========================================================================================
calculate\_heap\_sizes()
{
    case "`uname`" in
        Linux)
            system\_memory\_in\_mb=`free -m| sed -n '2p' | awk '{print $2}'`
            system\_cpu\_cores=`egrep -c 'processor([[:space:]]+):.\*' /proc/cpuinfo`
        ;;
        FreeBSD)
            system\_memory\_in\_bytes=`sysctl hw.physmem | awk '{print $2}'`
            system\_memory\_in\_mb=`expr $system\_memory\_in\_bytes / 1024 / 1024`
            system\_cpu\_cores=`sysctl hw.ncpu | awk '{print $2}'`
        ;;
        SunOS)
            system\_memory\_in\_mb=`prtconf | awk '/Memory size:/ {print $3}'`
            system\_cpu\_cores=`psrinfo | wc -l`
        ;;
        Darwin)
            system\_memory\_in\_bytes=`sysctl hw.memsize | awk '{print $2}'`
            system\_memory\_in\_mb=`expr $system\_memory\_in\_bytes / 1024 / 1024`
            system\_cpu\_cores=`sysctl hw.ncpu | awk '{print $2}'`
        ;;
        *)
            # assume reasonable defaults for e.g. a modern desktop or
            # cheap server
            system\_memory\_in\_mb="2048"
            system\_cpu\_cores="2"
        ;;
    esac

    # some systems like the raspberry pi don't report cores, use at least 1
    if [ "$system\_cpu\_cores" -lt "1" ]
    then
        system\_cpu\_cores="1"
    fi

    # set max heap size based on the following
    # max(min(1/2 ram, 1024MB), min(1/4 ram, 8GB))
    # calculate 1/2 ram and cap to 1024MB
    # calculate 1/4 ram and cap to 8192MB
    # pick the max
    half\_system\_memory\_in\_mb=`expr $system\_memory\_in\_mb / 2`
    quarter\_system\_memory\_in\_mb=`expr $half\_system\_memory\_in\_mb / 2`
    if [ "$half\_system\_memory\_in\_mb" -gt "1024" ]
    then
        half\_system\_memory\_in\_mb="1024"
    fi
    if [ "$quarter\_system\_memory\_in\_mb" -gt "8192" ]
    then
        quarter\_system\_memory\_in\_mb="8192"
    fi
    if [ "$half\_system\_memory\_in\_mb" -gt "$quarter\_system\_memory\_in\_mb" ]
    then
        max\_heap\_size\_in\_mb="$half\_system\_memory\_in\_mb"
    else
        max\_heap\_size\_in\_mb="$quarter\_system\_memory\_in\_mb"
    fi
    MAX\_HEAP\_SIZE="${max\_heap\_size\_in\_mb}M"

    # Young gen: min(max\_sensible\_per\_modern\_cpu\_core \* num\_cores, 1/4 \* heap size)
    max\_sensible\_yg\_per\_core\_in\_mb="100"
    max\_sensible\_yg\_in\_mb=`expr $max\_sensible\_yg\_per\_core\_in\_mb "\*" $system\_cpu\_cores`

    desired\_yg\_in\_mb=`expr $max\_heap\_size\_in\_mb / 4`

    if [ "$desired\_yg\_in\_mb" -gt "$max\_sensible\_yg\_in\_mb" ]
    then
        HEAP\_NEWSIZE="${max\_sensible\_yg\_in\_mb}M"
    else
        HEAP\_NEWSIZE="${desired\_yg\_in\_mb}M"
    fi
}
# calculate\_heap\_sizes 函数就是用来根据系统的总内存和其他一些因素,动态地计算出一个合适的堆内存大小。这里我想自定义,所以注释掉了
calculate_heap_sizes

# Dynamically calculate parameters, for reference.
Xms=$MAX\_HEAP\_SIZE
Xmx=$MAX\_HEAP\_SIZE
Xmn=$HEAP\_NEWSIZE
# Set for `JAVA\_OPT`.
JAVA\_OPT="${JAVA\_OPT} -server -Xms${Xms} -Xmx${Xmx} -Xmn${Xmn}"
JAVA\_OPT="${JAVA\_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC"
JAVA\_OPT="${JAVA\_OPT} -verbose:gc -Xloggc:/dev/shm/rmq\_srv\_gc.log -XX:+PrintGCDetails"
JAVA\_OPT="${JAVA\_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA\_OPT="${JAVA\_OPT} -XX:-UseLargePages"
JAVA\_OPT="${JAVA\_OPT} -Djava.ext.dirs=${JAVA\_HOME}/jre/lib/ext:${BASE\_DIR}/lib"
#JAVA\_OPT="${JAVA\_OPT} -Xdebug -Xrunjdwp:transport=dt\_socket,address=9555,server=y,suspend=n"
JAVA\_OPT="${JAVA\_OPT} ${JAVA\_OPT\_EXT}"
JAVA\_OPT="${JAVA\_OPT} -cp ${CLASSPATH}"

$JAVA ${JAVA\_OPT} $@

runbroker.sh

vi /opt/software/rocketmqcluster/bin/runbroker.sh

#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#===========================================================================================
# Java Environment Setting
#===========================================================================================
error\_exit ()
{
    echo "ERROR: $1 !!"
    exit 1
}

find\_java\_home()
{
    case "`uname`" in
        Darwin)
            JAVA\_HOME=$(/usr/libexec/java\_home)
        ;;
        *)
            JAVA\_HOME=$(dirname $(dirname $(readlink -f $(which javac))))
        ;;
    esac
}

find_java_home

[ ! -e "$JAVA\_HOME/bin/java" ] && JAVA\_HOME=$HOME/jdk/java
[ ! -e "$JAVA\_HOME/bin/java" ] && JAVA\_HOME=/usr/java
[ ! -e "$JAVA\_HOME/bin/java" ] && error_exit "Please set the JAVA\_HOME variable in your environment, We need java(x64)!"

export JAVA_HOME
export JAVA="$JAVA\_HOME/bin/java"
export BASE\_DIR=$(dirname $0)/..
export CLASSPATH=.:${BASE\_DIR}/conf:${CLASSPATH}

#===========================================================================================
# JVM Configuration
#===========================================================================================
calculate\_heap\_sizes()
{
    case "`uname`" in
        Linux)
            system\_memory\_in\_mb=`free -m| sed -n '2p' | awk '{print $2}'`
            system\_cpu\_cores=`egrep -c 'processor([[:space:]]+):.\*' /proc/cpuinfo`
        ;;
        FreeBSD)
            system\_memory\_in\_bytes=`sysctl hw.physmem | awk '{print $2}'`
            system\_memory\_in\_mb=`expr $system\_memory\_in\_bytes / 1024 / 1024`
            system\_cpu\_cores=`sysctl hw.ncpu | awk '{print $2}'`
        ;;
        SunOS)
            system\_memory\_in\_mb=`prtconf | awk '/Memory size:/ {print $3}'`
            system\_cpu\_cores=`psrinfo | wc -l`
        ;;
        Darwin)
            system\_memory\_in\_bytes=`sysctl hw.memsize | awk '{print $2}'`
            system\_memory\_in\_mb=`expr $system\_memory\_in\_bytes / 1024 / 1024`
            system\_cpu\_cores=`sysctl hw.ncpu | awk '{print $2}'`
        ;;
        *)
            # assume reasonable defaults for e.g. a modern desktop or
            # cheap server
            system\_memory\_in\_mb="2048"
            system\_cpu\_cores="2"
        ;;
    esac

    # some systems like the raspberry pi don't report cores, use at least 1
    if [ "$system\_cpu\_cores" -lt "1" ]
    then
        system\_cpu\_cores="1"
    fi

    # set max heap size based on the following
    # max(min(1/2 ram, 1024MB), min(1/4 ram, 8GB))
    # calculate 1/2 ram and cap to 1024MB
    # calculate 1/4 ram and cap to 8192MB
    # pick the max
    half\_system\_memory\_in\_mb=`expr $system\_memory\_in\_mb / 2`
    quarter\_system\_memory\_in\_mb=`expr $half\_system\_memory\_in\_mb / 2`
    if [ "$half\_system\_memory\_in\_mb" -gt "1024" ]
    then
        half\_system\_memory\_in\_mb="1024"
    fi
    if [ "$quarter\_system\_memory\_in\_mb" -gt "8192" ]
    then
        quarter\_system\_memory\_in\_mb="8192"
    fi
    if [ "$half\_system\_memory\_in\_mb" -gt "$quarter\_system\_memory\_in\_mb" ]
    then
        max\_heap\_size\_in\_mb="$half\_system\_memory\_in\_mb"
    else
        max\_heap\_size\_in\_mb="$quarter\_system\_memory\_in\_mb"
    fi
    MAX\_HEAP\_SIZE="${max\_heap\_size\_in\_mb}M"

    # Young gen: min(max\_sensible\_per\_modern\_cpu\_core \* num\_cores, 1/4 \* heap size)
    max\_sensible\_yg\_per\_core\_in\_mb="100"
    max\_sensible\_yg\_in\_mb=`expr $max\_sensible\_yg\_per\_core\_in\_mb "\*" $system\_cpu\_cores`

    desired\_yg\_in\_mb=`expr $max\_heap\_size\_in\_mb / 4`

    if [ "$desired\_yg\_in\_mb" -gt "$max\_sensible\_yg\_in\_mb" ]
    then
        HEAP\_NEWSIZE="${max\_sensible\_yg\_in\_mb}M"
    else
        HEAP\_NEWSIZE="${desired\_yg\_in\_mb}M"
    fi
}
# calculate\_heap\_sizes 函数就是用来根据系统的总内存和其他一些因素,动态地计算出一个合适的堆内存大小。这里我想自定义,所以注释掉了
# calculate\_heap\_sizes

# Dynamically calculate parameters, for reference.
Xms=$MAX\_HEAP\_SIZE
Xmx=$MAX\_HEAP\_SIZE
Xmn=$HEAP\_NEWSIZE
MaxDirectMemorySize=$MAX\_HEAP\_SIZE
# Set for `JAVA\_OPT`.
JAVA\_OPT="${JAVA\_OPT} -server -Xms${Xms} -Xmx${Xmx} -Xmn${Xmn}"
JAVA\_OPT="${JAVA\_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8"
JAVA\_OPT="${JAVA\_OPT} -verbose:gc -Xloggc:/dev/shm/mq\_gc\_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
JAVA\_OPT="${JAVA\_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
JAVA\_OPT="${JAVA\_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA\_OPT="${JAVA\_OPT} -XX:+AlwaysPreTouch"
JAVA\_OPT="${JAVA\_OPT} -XX:MaxDirectMemorySize=${MaxDirectMemorySize}"
JAVA\_OPT="${JAVA\_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
JAVA\_OPT="${JAVA\_OPT} -Djava.ext.dirs=${JAVA\_HOME}/jre/lib/ext:${BASE\_DIR}/lib"
#JAVA\_OPT="${JAVA\_OPT} -Xdebug -Xrunjdwp:transport=dt\_socket,address=9555,server=y,suspend=n"
JAVA\_OPT="${JAVA\_OPT} ${JAVA\_OPT\_EXT}"
JAVA\_OPT="${JAVA\_OPT} -cp ${CLASSPATH}"

numactl --interleave=all pwd > /dev/null 2>&1
if [ $? -eq 0 ]
then
	if [ -z "$RMQ\_NUMA\_NODE" ] ; then
		numactl --interleave=all $JAVA ${JAVA\_OPT} $@
	else
		numactl --cpunodebind=$RMQ\_NUMA\_NODE --membind=$RMQ\_NUMA\_NODE $JAVA ${JAVA\_OPT} $@
	fi
else
	$JAVA ${JAVA\_OPT} $@
fi

配置分组

使用root用户创建rocketmq组,增加rocketmq用户并加入rocketmq组,设置用户密码

groupadd rocketmq
useradd -g rocketmq rocketmq
passwd rocketmq

输入密码,8位以上复杂密码

liaozhiwei12345678

更改组的 gid,更改用户的 uid,查看是否更改成功

groupmod -g 3000 rocketmq
usermod -u 3000 rocketmq
id rocketmq

递归地将/opt/software/rocketmqcluster目录及其所有子目录和文件的所有者和所属组都更改为rocketmq

chown -R rocketmq:rocketmq /opt/software/rocketmqcluster

配置JDK

安装配置JDK,根据实际情况选择版本,注意JDK的版本和RocketMQ的版本是否匹配。
运行RocketMQ需要先安装JDK。我们采用目前最稳定的JDK1.8版本。可以自行去Oracle官网上下载也可以使用我从官网拉下来的jdk版本。链接:https://pan.baidu.com/s/10YA9SBV7Y6TKJ9keBrNVWw?pwd=2022
提取码:2022
用FTP或者WSP上传到rocketmq用户的工作目录下。由rocketmq用户解压到/opt/jdk目录下

chmod 777 jdk-8u152-linux-x64.tar.gz
tar -zxvf jdk-8u152-linux-x64.tar.gz

先查看是否安装过Jdk

which java

如果安装了,需要删除

[root@node0 opt]# which java
/usr/bin/java
[root@node0 opt]# rm -rf /usr/bin/java
[root@node0 opt]# 

vi /etc/profile

尾部添加:

export JAVA\_HOME=/opt/jdk1.8.0_152
export JRE\_HOME=$JAVA\_HOME/jre
export CLASSPATH=./:JAVA_HOME/lib:$JRE\_HOME/lib
export ROCKETMQ\_HOME=/opt/software/rocketmqcluster
export PATH=/bin:/user/bin:/sbin:$JAVA\_HOME/bin:$ROCKETMQ\_HOME/bin:$PATH

source /etc/profile
java -version

java version "1.8.0\_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)
[root@iZ7xv7y4w2otz9udxctoa6Z jdk1.8.0_152]# 

配置属性文件

进入到rocketmqcluster目录,代码如下:

cd /opt/software/rocketmqcluster

创建rocket存储、日志、配置目录,代码如下:

mkdir -p /opt/software/rocketmqcluster/conf/dledger

broker-n0.conf

编辑broker-n0的broker属性文件,代码如下:

vi /opt/software/rocketmqcluster/conf/dledger/broker-n0.conf

添加配置,代码如下:

# broker名,名称一样的节点就是一组主从节点。
brokerName=broker0
# broker对外服务的监听端口
listenPort=30911
# 所属集群名,名称一样的节点就在同一个集群内
brokerClusterName=CustomRocketMQCluster
# brokerid,0就表示是Master,>0的都是表示Slave
brokerId=0
# 删除文件时间点,默认凌晨4点
deleteWhen=04
# 文件保留时间,默认48 小时
fileReservedTime=48
# broker角色,ASYNC\_MASTER异步复制Master,SYNC\_MASTER同步双写Master,SLAVE从节点接收来自Master节点的复制消息。在高可用集群中,建议将所有的Broker节点都配置成ASYNC\_MASTER角色,以便在主节点挂掉后进行主从切换
brokerRole=ASYNC\_MASTER
# 刷盘方式,ASYNC\_FLUSH异步刷盘,SYNC\_FLUSH同步刷盘
flushDiskType=ASYNC\_FLUSH
# broker ip多网卡配置,容器配置宿主机网卡ip
brokerIP1=8.138.134.212
# name-server地址,分号间隔
namesrvAddr=8.138.134.212:9876;8.138.134.212:9876;8.138.134.212:9876;
# 存储路径
storePathRootDir=/home/rocketmq/rocketmq-4.7.1/store-n0
# commitLog存储路径
storePathCommitLog=/home/rocketmq/rocketmq-4.7.1/store-n0/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/home/rocketmq/rocketmq-4.7.1/store-n0/consumequeue
#消息索引存储路径
storePathIndex=/home/rocketmq/rocketmq-4.7.1/store-n0/index
#checkpoint 文件存储路径
storeCheckpoint=/home/rocketmq/rocketmq-4.7.1/store-n0/checkpoint
#abort 文件存储路径
abortFile=/home/rocketmq/rocketmq-4.7.1/store-n0/abort
# 是否允许broker自动创建Topic
autoCreateTopicEnable=true
# autoCreateTopicKeyWord 定义了哪些主题名称会被自动创建。星号 \* 表示所有主题名称都会被自动创建。
autoCreateTopicKeyWord=\*
# 是否允许broker自动创建订阅组
autoCreateSubscriptionGroup=true
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#强制销毁映射文件的间隔时间(以毫秒为单位)。如果某个映射文件在指定的时间内没有被访问,它将被强制销毁以释放资源
#destroyMapedFileIntervalForcibly=120000
#重新删除悬挂文件的间隔时间。悬挂文件是指在某些情况下没有被正常关闭的文件。通过定期检查和删除这些文件,可以避免资源泄漏。
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#限制的消息大小
maxMessageSize=65536
#刷新CommitLog和ConsumeQueue到磁盘时的最小页面数
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#彻底刷新CommitLog和ConsumeQueue到磁盘的间隔时间(以毫秒为单位)
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
# 是否启动DLedger
enableDLegerCommitLog=true
# DLedger Raft Group的名字,建议和brokerName保持一致
dLegerGroup=broker0
# DLedger Group内各节点的端口信息,同一个Group内的各个节点配置必须要保证一致
dLegerPeers=n0-8.138.134.212:40911;n1-8.138.134.212:40911;n2-8.138.134.212:40911
# 节点id, 必须属于dLegerPeers中的一个;同Group内各个节点要唯一
dLegerSelfId=n0

broker-n1.conf

编辑broker-n1的broker属性文件,代码如下:

vi /opt/software/rocketmqcluster/conf/dledger/broker-n1.conf

添加配置,代码如下:

# broker名,名称一样的节点就是一组主从节点。
brokerName=broker1
# broker对外服务的监听端口
listenPort=30912
# 所属集群名,名称一样的节点就在同一个集群内
brokerClusterName=CustomRocketMQCluster
# brokerid,0就表示是Master,>0的都是表示Slave
brokerId=1
# 删除文件时间点,默认凌晨4点
deleteWhen=04
# 文件保留时间,默认48 小时
fileReservedTime=48
# broker角色,ASYNC\_MASTER异步复制Master,SYNC\_MASTER同步双写Master,SLAVE从节点接收来自Master节点的复制消息。在高可用集群中,建议将所有的Broker节点都配置成ASYNC\_MASTER角色,以便在主节点挂掉后进行主从切换
brokerRole=ASYNC\_MASTER
# 刷盘方式,ASYNC\_FLUSH异步刷盘,SYNC\_FLUSH同步刷盘
flushDiskType=ASYNC\_FLUSH
# broker ip多网卡配置,容器配置宿主机网卡ip
brokerIP1=8.138.134.212
# name-server地址,分号间隔
namesrvAddr=8.138.134.212:9876;8.138.134.212:9876;8.138.134.212:9876;
# 存储路径
storePathRootDir=/home/rocketmq/rocketmq-4.7.1/store-n1
# commitLog存储路径
storePathCommitLog=/home/rocketmq/rocketmq-4.7.1/store-n1/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/home/rocketmq/rocketmq-4.7.1/store-n1/consumequeue
#消息索引存储路径
storePathIndex=/home/rocketmq/rocketmq-4.7.1/store-n1/index
#checkpoint 文件存储路径
storeCheckpoint=/home/rocketmq/rocketmq-4.7.1/store-n1/checkpoint
#abort 文件存储路径
abortFile=/home/rocketmq/rocketmq-4.7.1/store-n1/abort
# 是否允许broker自动创建Topic
autoCreateTopicEnable=true
# autoCreateTopicKeyWord 定义了哪些主题名称会被自动创建。星号 \* 表示所有主题名称都会被自动创建。
autoCreateTopicKeyWord=\*
# 是否允许broker自动创建订阅组
autoCreateSubscriptionGroup=true
#commitLog每个文件的大小默认1G


**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Linux运维工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/a837b760829e153ef0534d8043a7ac93.png)
![img](https://img-blog.csdnimg.cn/img_convert/bd6a7b5263a26fc429c7686190360b24.png)
![img](https://img-blog.csdnimg.cn/img_convert/ab89b0c88ccc8d495c71cfc0209e1f6f.png)
![img](https://img-blog.csdnimg.cn/img_convert/22d30224761c1df8c2c76a720e4e103d.png)
![img](https://img-blog.csdnimg.cn/img_convert/c8b81cdac195ec7fa1668891dd096151.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Linux运维知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)**
![img](https://img-blog.csdnimg.cn/img_convert/54f5236cc2f08a9c1f68f12b27993acf.jpeg)



### 最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

### 资料预览

给大家整理的视频资料:

![](https://img-blog.csdnimg.cn/img_convert/addd092fa05ee01ba89920b13e7efcd1.png)

给大家整理的电子书资料:

  

![](https://img-blog.csdnimg.cn/img_convert/14e7a099ba8719525d3fc14e1d2b7dd5.png)



**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**


[**一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)

**AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**


# 是否允许broker自动创建Topic
autoCreateTopicEnable=true
# autoCreateTopicKeyWord 定义了哪些主题名称会被自动创建。星号 \* 表示所有主题名称都会被自动创建。
autoCreateTopicKeyWord=\*
# 是否允许broker自动创建订阅组
autoCreateSubscriptionGroup=true
#commitLog每个文件的大小默认1G


**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Linux运维工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中...(img-whoIkVQc-1712439791449)]
[外链图片转存中...(img-0yDbjASG-1712439791449)]
[外链图片转存中...(img-GTL333nE-1712439791450)]
[外链图片转存中...(img-gi9JKtci-1712439791450)]
[外链图片转存中...(img-f0Rzfdwa-1712439791450)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Linux运维知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)**
[外链图片转存中...(img-x7kgWqYs-1712439791450)]



### 最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

### 资料预览

给大家整理的视频资料:

[外链图片转存中...(img-wJpyuAOS-1712439791451)]

给大家整理的电子书资料:

  

[外链图片转存中...(img-NM7eNuYE-1712439791451)]



**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**


[**一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)

**AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值