阿里云部署MySQL、Redis、RocketMQ、Nacos集群

文章目录

  • 🔊博主介绍
  • 🥤本文内容
  • MySQL集群配置
    • 云服务器选购
      • CPU选择
      • 内存选择
      • 云盘选择
        • ESSD AutoPL云盘
        • 块存储性能(ESSD)
      • 镜像选择
      • 带宽选择
      • 密码配置
      • 注意事项
    • 安装docker和docker-compose
    • 部署MySQL三主六从半同步集群
      • 一主二从同步集群规划
      • 部署node1节点的master1
        • docker-compose.yaml文件
        • my.cnf文件
        • 授权启动
      • 部署node1节点的slave1
        • docker-compose.yaml文件
        • my.cnf文件
        • 授权启动
      • 部署node1节点的slave2
        • docker-compose.yaml文件
        • my.cnf文件
        • 授权启动
      • 配置三个从节点的主从同步配置
        • 在slave1和slave2上配置master1为主节点
    • 校验三主六从集群同步是否正常
    • 主从复制容易遇错中断
  • Redis集群配置
    • redis.conf配置文件
    • 配置过程
  • RocketMQ
    • 配置runserver.sh
    • runbroker.sh
    • 配置分组
    • 配置JDK
    • 配置属性文件
      • broker-n0.conf
      • broker-n1.conf
      • broker-n2.conf
      • docker-compose.yaml
  • 配置Nacos
    • 配置JDK
  • Nginx高可用负载
  • 📢文章总结
  • 📥博主目标

🔊博主介绍

🌟我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文专业写手、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。🌎跑过十五公里、🚀徒步爬过衡山、🔥有过三个月减肥20斤的经历、是个喜欢躺平的狠人。

📕拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、Spring MVC、SpringCould、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RockerMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。

📙有过从0到1的项目高并发项目开发与管理经验,对JVM调优、MySQL调优、Redis调优 、ElasticSearch调优、消息中间件调优、系统架构调优都有着比较全面的实战经验。

📘有过云端搭建服务器环境,自动化部署CI/CD,弹性伸缩扩容服务器(最高200台),了解过秒级部署(阿里云的ACK和华为云的云容器引擎CCE)流程,能独立开发和部署整个后端服务,有过分库分表的实战经验。

🎥经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧,与清华大学出版社签下了四本书籍的合约,并将陆续在明年出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码–沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!


文章目录

  • 🔊博主介绍
  • 🥤本文内容
  • MySQL集群配置
    • 云服务器选购
      • CPU选择
      • 内存选择
      • 云盘选择
        • ESSD AutoPL云盘
        • 块存储性能(ESSD)
      • 镜像选择
      • 带宽选择
      • 密码配置
      • 注意事项
    • 安装docker和docker-compose
    • 部署MySQL三主六从半同步集群
      • 一主二从同步集群规划
      • 部署node1节点的master1
        • docker-compose.yaml文件
        • my.cnf文件
        • 授权启动
      • 部署node1节点的slave1
        • docker-compose.yaml文件
        • my.cnf文件
        • 授权启动
      • 部署node1节点的slave2
        • docker-compose.yaml文件
        • my.cnf文件
        • 授权启动
      • 配置三个从节点的主从同步配置
        • 在slave1和slave2上配置master1为主节点
    • 校验三主六从集群同步是否正常
    • 主从复制容易遇错中断
  • Redis集群配置
    • redis.conf配置文件
    • 配置过程
  • RocketMQ
    • 配置runserver.sh
    • runbroker.sh
    • 配置分组
    • 配置JDK
    • 配置属性文件
      • broker-n0.conf
      • broker-n1.conf
      • broker-n2.conf
      • docker-compose.yaml
  • 配置Nacos
    • 配置JDK
  • Nginx高可用负载
  • 📢文章总结
  • 📥博主目标

🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。

💡在这个美好的时刻,本人不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

🥤本文内容

CSDN

MySQL集群配置

云服务器选购

CPU选择

在这里插入图片描述可以看到除了IO线程的其他线程,都只占一个线程,io线程有四个,其中write和read需要相同的数量。

如果是master thread1条,IO thread(write1条,read1条,insert buffer thread1条,log io thread1条),purge thread1条,page cleaner thread1条,给它凑个整,就是8核cpu。

如果是master thread1条,IO thread(write5条,read5条,insert buffer thread1条,log io thread1条),purge thread1条,page cleaner thread1条,给它凑个整就是16核cpu。

这里为了部署集群,我选择八核,最大化利用cpu资源的同时也能节约成本。

内存选择

在这里插入图片描述在这里插入图片描述
MySQL服务器的最佳内存配置实际上并没有一个固定的答案,因为它取决于多个因素,如服务器的物理内存大小、MySQL的配置文件、所处理的数据量、工作负载、查询的复杂性以及期望的性能等。

一般来说,根据MySQL官方文档的建议,一个典型的MySQL服务器至少需要2GB的物理内存。但在实际应用中,这个数字可能会更高,特别是当MySQL服务器需要处理大量的数据时。例如,如果MySQL需要处理1GB的数据,那么至少需要4GB的物理内存。

InnoDB存储引擎使用缓冲池(Buffer Pool)来缓存数据和索引,因此为InnoDB配置足够的内存是非常重要的。通常,一个好的起点是将总内存的50%到80%分配给MySQL的InnoDB缓冲池。你可以使用SHOW ENGINE INNODB STATUS命令来查看当前Buffer pool的使用情况,以便根据实际情况调整配置。

此外,除了InnoDB缓冲池外,MySQL还需要内存来存储其他信息,如线程堆栈、排序缓冲区、连接缓冲区等。因此,在配置内存时,需要确保为这些操作预留足够的内存。

请注意,内存配置只是MySQL性能调优的一部分。你还需要考虑其他因素,如磁盘I/O、CPU、网络等。在调整任何配置之前,最好先在测试环境中进行验证,以确保更改不会对生产环境造成负面影响。

前面我选择了八核的cpu,那么对应的云服务器选择就少很多了
在这里插入图片描述

由于需要部署集群,单台服务器肯定是不够的,所以考虑到成本,这里选择经济型,16GiB内存就够了。

云盘选择

ESSD AutoPL云盘

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
如果不开启预配置性能只有6800的IOPS,如果开启最高的预配置性能有56800,但是价格也会高出不少。云盘才0.21元一个小时,预配置性能则高达3.125元一小时。

在这里插入图片描述

块存储性能(ESSD)

在这里插入图片描述在这里插入图片描述在这里插入图片描述

ESSD Entry的IOPS要低很多,价格也便宜

在这里插入图片描述

在这里插入图片描述
ESSD云盘,上限的IOPS是五万,正常运行的IOPS是6800,综合而已,选择这宽经济实惠,也能满足一定的IOPS。

这里说一下IOPS:

IOPS,即Input/Output Operations Per Second,是一个用于计算机存储设备(如硬盘(HDD)、固态硬盘(SSD)或存储区域网络(SAN))性能测试的量测方式,可以视为是每秒的读写次数。这是一个衡量随机存取性能的关键指标,常用于数据库和应用程序工作负载,因为这些应用通常需要快速的随机读写。
IOPS的数值会根据读写操作的大小和类型(随机或顺序)而变化。因此,当比较或评估IOPS时,应确保在相同的条件下进行。此外,IOPS和吞吐量都是描述存储性能的指标,但它们衡量的是不同的操作和应用场景。

镜像选择

首先我这里选择的是CentOS7.9版本,虽然CentOS官方不再进行新的维护了。具体来说,CentOS 7将在2024年6月30日停止维护(EOL, End Of Life),而CentOS 8在2021年底就已经停止了维护。尽管CentOS不再进行新的维护,但已经安装和运行的CentOS系统仍然可以继续使用。

同时CentOS的普及率也有一定程度了,加上大部分开发者对CentOS也是比较熟悉,网上也有很多前辈踩过坑,所以我依然选择这个镜像,就是为了保证稳定性以及遇到问题可以即时检索出答案。

带宽选择

首先,需要估计每个I/O操作平均需要传输多少数据。然后将这个数字乘以预期的IOPS来得到一个粗略的带宽需求估计。

例如,如果每个I/O操作平均传输1KB的数据,并且你预计在高并发时会有10000的IOPS,那么你需要的带宽大约是10MBps(10000 * 1KB/s)。

这里我按照顶额处理给到100MBps,因为是按量付费,选择10MBps和100MBps价格都不变,变的是使用的量。

密码配置

在这里插入图片描述
企业级通常使用密钥对保证安全性,我这里因为就是简单做个压测,就直接使用密码了。
在这里插入图片描述
这里提供一个生成密码的网站:https://suijimimashengcheng.bmcx.com/

9ND%8cnNyAr!##ptRz^n@tbRLf$dsau%

注意事项

购买阿里云服务器,账户最少100元才可以购买。
另外这二个配置一定加上
在这里插入图片描述
避免扣钱过度

安装docker和docker-compose

在Linux服务器上安装Docker的命令主要包括以下步骤:

检查CentOS系统的内核版本是否高于3.10,因为Docker要求CentOS系统的内核版本高于3.10。可以使用uname -r命令来查看当前的内核版本。
更新yum包,使用命令sudo yum update
安装必要的软件包,包括yum-utils(提供yum-config-manager功能)、device-mapper-persistent-data和lvm2。使用命令

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

设置yum源,以便可以从Docker的官方仓库中安装Docker。使用命令

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

查看所有可用的Docker版本,以便可以选择要安装的特定版本。使用命令

yum list docker-ce --showduplicates | sort -r

安装Docker CE(社区版)。如果要安装特定版本,可以在安装命令中指定版本号。使用命令

sudo yum install docker-ce docker-ce-cli containerd.io

进行安装。
启动Docker服务,使用命令systemctl start docker
查看Docker版本信息,使用命令docker version。如果看到版本号,表示安装成功。
配置开机自启动

systemctl enable docker.service   

请注意,安装Docker的过程中可能需要根据提示输入“y”以继续安装过程。此外,如果服务器开启了防火墙,需要在安装前关闭防火墙,并确保禁止开机启动防火墙,以避免影响Docker的正常运行。

这些步骤是Linux服务器上安装Docker的基本命令,具体步骤可能会因服务器环境和版本的不同而有所差异。在安装过程中,建议仔细阅读命令的输出信息,并根据需要进行适当的调整。

具体操作:https://blog.csdn.net/java_wxid/article/details/121317129

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager   --add-repo   http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
sudo yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl enable docker.service   
systemctl daemon-reload
systemctl start firewalld
systemctl enable firewalld
docker version
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
sudo systemctl restart docker

部署MySQL三主六从半同步集群

一主二从同步集群规划

master节点:ip地址:8.134.108.60 mysql端口:33061
slave1节点:ip地址:8.134.108.60 mysql端口:33062
slave2节点:ip地址:8.134.108.60 mysql端口:33063
服务器登录的用户名密码都是root用户admin密码
master节点的mysql登录账户是root用户masterroot密码
slave1节点和slave2节点的mysql登录账户是root用户slaveroot密码

mkdir -p /var/lib/mysql
sudo useradd -r -s /sbin/nologin -d /var/lib/mysql mysql
sudo chmod -R 755 /var/lib/mysql
grep mysql /etc/passwd
sudo usermod -d /var/lib/mysql mysql
sudo setenforce 0

部署node1节点的master1

docker-compose.yaml文件

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

mkdir -p /var/lib/mysql
chmod 755 /var/lib/mysql
mkdir -p /opt/software/mysqlcluster/master1
cd /opt/software/mysqlcluster/master1
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_master1  # 指定容器名称为mysql_node1_master1restart: unless-stopped  # 在容器退出时自动重新启动ports:  # 定义容器和主机之间的端口映射- "33061:3306"  # 将容器的3306端口映射到主机的33061端口environment:  # 定义环境变量MYSQL_ROOT_PASSWORD: node1master1root  # 设置root用户的密码  volumes:  # 定义数据卷- /var/lib/mysql:/var/lib/mysql # 数据目录healthcheck:  test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-pnode1master1root"]  # 设置容器健康检查命令interval: 20s  # 每隔20秒进行一次健康检查timeout: 10s  # 健康检查超时时间为10秒retries: 3  # 健康检查失败时重试次数为3次

授权文件

sudo chmod 777 docker-compose.yaml
mkdir /opt/software/mysqlcluster/master1/conf
vi /opt/software/mysqlcluster/master1/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 = 1010  # 服务器的唯一标识符
bind-address = 0.0.0.0  # 服务器监听的IP地址
port = 3306  # 服务器监听的端口号
character-set-server = utf8mb4  # 服务器使用的字符集
skip-external-locking  # 不使用外部锁定
skip-name-resolve  # 不进行域名解析
log-bin = mysql-bin # 启用二进制日志  
log-bin-trust-function-creators = 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_MODEENFORCE_GTID_CONSISTENCY 的设置是一致的,强制全局事务标识的一致性
# 日志设置
log-short-format = 1  # 使用短格式记录日志
slow_query_log  # 启用慢查询日志
long_query_time = 2  # 慢查询的时间阈值
# 二进制日志设置
log_bin_trust_function_creators=1  # 允许二进制日志中记录函数创建的事件
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 = rpl_semi_sync_master.so   # 配置半同步复制
# rpl_semi_sync_master_enabled = 1  # 开启半同步复制
# rpl_semi_sync_master_timeout = 5000 # 配置主从同步超时时间(毫秒)
[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/master1/conf/my.cnf
docker-compose up -d
docker-compose ps
sudo chown -R mysql:mysql /var/lib/mysql  

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

docker cp /opt/software/mysqlcluster/master1/conf/my.cnf mysql_node1_master1:/etc/mysql/my.cnf

重启容器

docker restart mysql_node1_master1

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

docker exec -it mysql_node1_master1 bash

登录mysql,命令如下:

mysql -u root -pnode1master1root

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

SHOW VARIABLES LIKE 'server_id';

安装semisync_master模块,通过扩展库来安装半同步复制模块,需要指定扩展库的文件名,命令如下:

install plugin rpl_semi_sync_master soname 'semisync_master.so';

查看系统全局参数,命令如下:

show global variables like 'rpl_semi%';

输出结果如下:

mysql> show global variables like 'rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

rpl_semi_sync_master_timeout就是半同步复制时等待应答的最长等待时间,默认是10秒,可以根据情况自行调整。rpl_semi_sync_master_wait_point其实表示一种半同步复制的方式。半同步复制有两种方式,一种是我们现在看到的这种默认的AFTER_SYNC方式。这种方式下,主库把日志写入binlog,并且复制给从库,然后开始等待从库的响应。从库返回成功后,主库再提交事务,接着给客户端返回一个成功响应。而另一种方式是叫做AFTER_COMMIT方式。他不是默认的。这种方式,在主库写入binlog后,等待binlog复制到从库,主库就提交自己的本地事务,再等待从库返回给自己一个成功响应,然后主库再给客户端返回响应。

打开半同步复制的开关,命令如下:

set global rpl_semi_sync_master_enabled=ON;

授权,命令如下:

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

查看master节点状态

show master status;

输出结果:

mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000003 |      196 |              |                  | 7410e8b2-e12b-11ee-9499-0242ac160002:1-3 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)mysql> 

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

# rpl_semi_sync_master_enabled = 1  # 开启半同步复制
# rpl_semi_sync_master_timeout = 5000 # 配置主从同步超时时间(毫秒)

打开:

rpl_semi_sync_master_enabled = 1  # 开启半同步复制
rpl_semi_sync_master_timeout = 5000 # 配置主从同步超时时间(毫秒)

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

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_slave1restart: 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_MODEENFORCE_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_slave2restart: 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_MODEENFORCE_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  
# 循环执行6for 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 01  
server_cpulist 0-1 
# 后台I/O线程绑定到的CPU内核列表,这里绑定到CPU 23  
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`" inDarwin)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`" inLinux)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 serversystem_memory_in_mb="2048"system_cpu_cores="2";;esac# some systems like the raspberry pi don't report cores, use at least 1if [ "$system_cpu_cores" -lt "1" ]thensystem_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 maxhalf_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" ]thenhalf_system_memory_in_mb="1024"fiif [ "$quarter_system_memory_in_mb" -gt "8192" ]thenquarter_system_memory_in_mb="8192"fiif [ "$half_system_memory_in_mb" -gt "$quarter_system_memory_in_mb" ]thenmax_heap_size_in_mb="$half_system_memory_in_mb"elsemax_heap_size_in_mb="$quarter_system_memory_in_mb"fiMAX_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" ]thenHEAP_NEWSIZE="${max_sensible_yg_in_mb}M"elseHEAP_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`" inDarwin)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`" inLinux)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 serversystem_memory_in_mb="2048"system_cpu_cores="2";;esac# some systems like the raspberry pi don't report cores, use at least 1if [ "$system_cpu_cores" -lt "1" ]thensystem_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 maxhalf_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" ]thenhalf_system_memory_in_mb="1024"fiif [ "$quarter_system_memory_in_mb" -gt "8192" ]thenquarter_system_memory_in_mb="8192"fiif [ "$half_system_memory_in_mb" -gt "$quarter_system_memory_in_mb" ]thenmax_heap_size_in_mb="$half_system_memory_in_mb"elsemax_heap_size_in_mb="$quarter_system_memory_in_mb"fiMAX_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" ]thenHEAP_NEWSIZE="${max_sensible_yg_in_mb}M"elseHEAP_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 ]
thenif [ -z "$RMQ_NUMA_NODE" ] ; thennumactl --interleave=all $JAVA ${JAVA_OPT} $@elsenumactl --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异步复制MasterSYNC_MASTER同步双写MasterSLAVE从节点接收来自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
#刷新CommitLogConsumeQueue到磁盘时的最小页面数
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#彻底刷新CommitLogConsumeQueue到磁盘的间隔时间(以毫秒为单位)
#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异步复制MasterSYNC_MASTER同步双写MasterSLAVE从节点接收来自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
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#强制销毁映射文件的间隔时间(以毫秒为单位)。如果某个映射文件在指定的时间内没有被访问,它将被强制销毁以释放资源
#destroyMapedFileIntervalForcibly=120000
#重新删除悬挂文件的间隔时间。悬挂文件是指在某些情况下没有被正常关闭的文件。通过定期检查和删除这些文件,可以避免资源泄漏。
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#限制的消息大小
maxMessageSize=65536
#刷新CommitLogConsumeQueue到磁盘时的最小页面数
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#彻底刷新CommitLogConsumeQueue到磁盘的间隔时间(以毫秒为单位)
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
# 是否启动DLedger
enableDLegerCommitLog=true
# DLedger Raft Group的名字,建议和brokerName保持一致
dLegerGroup=broker1
# DLedger Group内各节点的端口信息,同一个Group内的各个节点配置必须要保证一致
dLegerPeers=n0-8.138.134.212:40912;n1-8.138.134.212:40912;n2-8.138.134.212:40912
# 节点id, 必须属于dLegerPeers中的一个;同Group内各个节点要唯一
dLegerSelfId=n0

broker-n2.conf

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

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

添加配置,代码如下:

# broker名,名称一样的节点就是一组主从节点。
brokerName=broker2
# broker对外服务的监听端口
listenPort=30913
# 所属集群名,名称一样的节点就在同一个集群内
brokerClusterName=CustomRocketMQCluster
# brokerid,0就表示是Master>0的都是表示Slave
brokerId=2
# 删除文件时间点,默认凌晨4点
deleteWhen=04
# 文件保留时间,默认48 小时
fileReservedTime=48
# broker角色,ASYNC_MASTER异步复制MasterSYNC_MASTER同步双写MasterSLAVE从节点接收来自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-n2
# commitLog存储路径
storePathCommitLog=/home/rocketmq/rocketmq-4.7.1/store-n2/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/home/rocketmq/rocketmq-4.7.1/store-n2/consumequeue
#消息索引存储路径
storePathIndex=/home/rocketmq/rocketmq-4.7.1/store-n2/index
#checkpoint 文件存储路径
storeCheckpoint=/home/rocketmq/rocketmq-4.7.1/store-n2/checkpoint
#abort 文件存储路径
abortFile=/home/rocketmq/rocketmq-4.7.1/store-n2/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
#刷新CommitLogConsumeQueue到磁盘时的最小页面数
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#彻底刷新CommitLogConsumeQueue到磁盘的间隔时间(以毫秒为单位)
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
# 是否启动DLedger
enableDLegerCommitLog=true
# DLedger Raft Group的名字,建议和brokerName保持一致
dLegerGroup=broker2
# DLedger Group内各节点的端口信息,同一个Group内的各个节点配置必须要保证一致
dLegerPeers=n0-8.138.134.212:40913;n1-8.138.134.212:40913;n2-8.138.134.212:40913
# 节点id, 必须属于dLegerPeers中的一个;同Group内各个节点要唯一
dLegerSelfId=n0

docker-compose.yaml

创建docker-compose.yaml文件,代码如下:

vi /opt/software/rocketmqcluster/docker-compose.yaml

添加配置,代码如下:

version: '3.5'
services:namesrv:restart: alwaysimage: apache/rocketmq:4.7.1container_name: namesrvports:- 9876:9876environment:# runbroker.sh文件中设置Java堆的最大内存限制为512兆字节(MB- MAX_HEAP_SIZE=512m# runbroker.sh文件中设置新生代的大小为256MB- HEAP_NEWSIZE=256m# 通常情况下设置上述二个配置,JAVA_OPT_EXT中就不需要设置堆大小和新生代大小了,不过这里还是重复设置(有些可能不对runbroker.sh进行配置,使用下面进行jvm调优也不受影响)- JAVA_OPT_EXT=-Duser.home=/home/rocketmq/rocketmq-4.7.1 -Xms512m -Xmx512m -Xmn256m -XX:InitiatingHeapOccupancyPercent=30 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:SoftRefLRUPolicyMSPerMB=0 -verbose:gc - TZ=Asia/Shanghaivolumes:- /opt/software/rocketmqcluster/bin/runserver.sh:/home/rocketmq/rocketmq-4.7.1/bin/runserver.shcommand: sh mqnamesrvbroker-n0:restart: alwaysimage: apache/rocketmq:4.7.1container_name: broker-n0ports:- 30911:30911- 40911:40911environment:- NAMESRV_ADDR=8.138.134.212:9876;8.138.134.212:9876;8.138.134.212:9876;# runbroker.sh文件中设置Java堆的最大内存限制为512兆字节(MB- MAX_HEAP_SIZE=512m# runbroker.sh文件中设置新生代的大小为256MB- HEAP_NEWSIZE=256m# 通常情况下设置上述二个配置,JAVA_OPT_EXT中就不需要设置堆大小和新生代大小了,不过这里还是重复设置(有些可能不对runbroker.sh进行配置,使用下面进行jvm调优也不受影响)- JAVA_OPT_EXT=-Duser.home=/home/rocketmq/rocketmq-4.7.1 -Xms512m -Xmx512m -Xmn256m -XX:InitiatingHeapOccupancyPercent=30 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:SoftRefLRUPolicyMSPerMB=0 -verbose:gc - TZ=Asia/Shanghaivolumes:- /opt/software/rocketmqcluster/conf/dledger/broker-n0.conf:/home/rocketmq/rocketmq-4.7.1/conf/dledger/broker-n0.conf- /opt/software/rocketmqcluster/bin/runbroker.sh:/home/rocketmq/rocketmq-4.7.1/bin/runbroker.shcommand: sh mqbroker -c /home/rocketmq/rocketmq-4.7.1/conf/dledger/broker-n0.confbroker-n1:restart: alwaysimage: apache/rocketmq:4.7.1container_name: broker-n1ports:- 30912:30912- 40912:40912environment:- NAMESRV_ADDR=8.138.134.212:9876;8.138.134.212:9876;8.138.134.212:9876;# runbroker.sh文件中设置Java堆的最大内存限制为512兆字节(MB- MAX_HEAP_SIZE=512m# runbroker.sh文件中设置新生代的大小为256MB- HEAP_NEWSIZE=256m# 通常情况下设置上述二个配置,JAVA_OPT_EXT中就不需要设置堆大小和新生代大小了,不过这里还是重复设置(有些可能不对runbroker.sh进行配置,使用下面进行jvm调优也不受影响)      - JAVA_OPT_EXT=-Duser.home=/home/rocketmq/rocketmq-4.7.1 -Xms512m -Xmx512m -Xmn256m -XX:InitiatingHeapOccupancyPercent=30 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:SoftRefLRUPolicyMSPerMB=0 -verbose:gc - TZ=Asia/Shanghaivolumes:- /opt/software/rocketmqcluster/conf/dledger/broker-n1.conf:/home/rocketmq/rocketmq-4.7.1/conf/dledger/broker-n1.conf- /opt/software/rocketmqcluster/bin/runbroker.sh:/home/rocketmq/rocketmq-4.7.1/bin/runbroker.shcommand: sh mqbroker -c /home/rocketmq/rocketmq-4.7.1/conf/dledger/broker-n1.confbroker-n2:restart: alwaysimage: apache/rocketmq:4.7.1container_name: broker-n2ports:- 30913:30913- 40913:40913environment:- NAMESRV_ADDR=8.138.134.212:9876;8.138.134.212:9876;8.138.134.212:9876;# runbroker.sh文件中设置Java堆的最大内存限制为512兆字节(MB- MAX_HEAP_SIZE=512m# runbroker.sh文件中设置新生代的大小为256MB- HEAP_NEWSIZE=256m# 通常情况下设置上述二个配置,JAVA_OPT_EXT中就不需要设置堆大小和新生代大小了,不过这里还是重复设置(有些可能不对runbroker.sh进行配置,使用下面进行jvm调优也不受影响)- JAVA_OPT_EXT=-Duser.home=/home/rocketmq/rocketmq-4.7.1 -Xms512m -Xmx512m -Xmn256m -XX:InitiatingHeapOccupancyPercent=30 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:SoftRefLRUPolicyMSPerMB=0 -verbose:gc - TZ=Asia/Shanghaivolumes:- /opt/software/rocketmqcluster/conf/dledger/broker-n2.conf:/home/rocketmq/rocketmq-4.7.1/conf/dledger/broker-n2.conf- /opt/software/rocketmqcluster/bin/runbroker.sh:/home/rocketmq/rocketmq-4.7.1/bin/runbroker.shcommand: sh mqbroker -c /home/rocketmq/rocketmq-4.7.1/conf/dledger/broker-n2.confconsole:restart: alwaysimage: apacherocketmq/rocketmq-dashboardcontainer_name: consoleports:- 19081:8080environment:TZ: "Asia/Shanghai"JAVA_OPTS: "-Drocketmq.namesrv.addr=8.138.134.212:9876;8.138.134.212:9876;8.138.134.212:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"depends_on:- namesrv
# 网络声明
networks:rmq:name: rmq # 指定网络名称driver: bridge # 指定网络驱动程序
# 通用日志设置
x-logging:&default-logging# 日志大小和数量options:max-size: "100m"max-file: "3"# 文件存储类型driver: json-file

访问控制台:http://8.138.134.212:19081/#/
在这里插入图片描述

配置Nacos

配置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

如果存在就删除

rm -rf /usr/bin/java
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]# 

使用脚本运行:

vim docker-nacos-cluster.sh

docker-nacos-cluster.sh文件:

#!/bin/bash  
# 初始化端口号为8848  
port=8848  
# 循环执行8for i in $(seq 8)  
do  instance_name="nacos$i"  # 每个实例使用不同的宿主机端口  host_port=$((port + i - 1))  # 容器内部仍然监听8848端口,但映射到不同的宿主机端口  container_port=8848      # 构建 docker run 命令字符串  docker_command="docker run -d -p $host_port:$container_port --name $instance_name --restart=unless-stopped --hostname $instance_name -e MYSQL_SERVICE_HOST=8.138.136.184 -e MYSQL_SERVICE_PORT=33061 -e MYSQL_SERVICE_DB_NAME=nacos -e MYSQL_SERVICE_USER=root -e MYSQL_SERVICE_PASSWORD=node1master1root -e SERVER_SERVLET_CONTEXTPATH=/nacos -e NACOS_APPLICATION_PORT=8848 nacos/nacos-server:1.4.1"      # 打印命令日志  echo "Executing: $docker_command"  # 执行 docker run 命令  eval $docker_command      # 更新端口号以供下一个实例使用  let "port+=1"  
done
sh docker-nacos-cluster.sh

需要注意更换mysql数据库中配置的nacos连接地址和用户名、密码

正常到这一步就可以直接访问了。

nacos访问地址:
http://8.134.108.60:8848/nacos
http://8.134.108.60:8850/nacos
http://8.134.108.60:8852/nacos
http://8.134.108.60:8854/nacos
http://8.134.108.60:8856/nacos
http://8.134.108.60:8858/nacos
http://8.134.108.60:8860/nacos
http://8.134.108.60:8862/nacos

默认用户密码:nacos/nacos

但是如果需要定制化修改,可以参考下面:
在/opt/software/nacoscluster/config目录下创建cluster.conf属性文件:

mkdir -p /opt/software/nacoscluster/config
vi /opt/software/nacoscluster/config/cluster.conf
8.134.108.60:8848
8.134.108.60:8850
8.134.108.60:8852
8.134.108.60:8854
8.134.108.60:8856
8.134.108.60:8858
8.134.108.60:8860
8.134.108.60:8862
vim /opt/software/nacoscluster/config/application.properties
server.servlet.contextPath=${SERVER_SERVLET_CONTEXTPATH:/nacos}
server.contextPath=/nacos
server.port=${NACOS_APPLICATION_PORT:8848}
spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:""}
nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
db.num=${MYSQL_DATABASE_NUM:1}
db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST:8.138.136.184}:${MYSQL_SERVICE_PORT:33061}/${MYSQL_SERVICE_DB_NAME:nacos}?${MYSQL_SERVICE_DB_PARAM:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true}
db.url.1=jdbc:mysql://${MYSQL_SERVICE_HOST:8.138.136.184}:${MYSQL_SERVICE_PORT:33064}/${MYSQL_SERVICE_DB_NAME:nacos}?${MYSQL_SERVICE_DB_PARAM:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true}
db.url.2=jdbc:mysql://${MYSQL_SERVICE_HOST:8.138.136.184}:${MYSQL_SERVICE_PORT:33065}/${MYSQL_SERVICE_DB_NAME:nacos}?${MYSQL_SERVICE_DB_PARAM:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true}
db.user=${MYSQL_SERVICE_USER:root}
db.password=${MYSQL_SERVICE_PASSWORD:node1master1root}
nacos.core.auth.system.type=${NACOS_AUTH_SYSTEM_TYPE:nacos}
nacos.core.auth.default.token.expire.seconds=${NACOS_AUTH_TOKEN_EXPIRE_SECONDS:18000}
nacos.core.auth.default.token.secret.key=${NACOS_AUTH_TOKEN:SecretKey012345678901234567890123456789012345678901234567890123456789}
nacos.core.auth.caching.enabled=${NACOS_AUTH_CACHE_ENABLE:false}
nacos.core.auth.enable.userAgentAuthWhite=${NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE:false}
nacos.core.auth.server.identity.key=${NACOS_AUTH_IDENTITY_KEY:serverIdentity}
nacos.core.auth.server.identity.value=${NACOS_AUTH_IDENTITY_VALUE:security}
server.tomcat.accesslog.enabled=${TOMCAT_ACCESSLOG_ENABLED:false}
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
server.tomcat.basedir=
nacos.security.ignore.urls=${NACOS_SECURITY_IGNORE_URLS:/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**}
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
nacos.naming.distro.taskDispatchThreadCount=10
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true
docker cp /opt/software/nacoscluster/config/application.properties nacos1:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos1:/home/nacos/conf/cluster.conf
docker cp /opt/software/nacoscluster/config/application.properties nacos2:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos2:/home/nacos/conf/cluster.conf
docker cp /opt/software/nacoscluster/config/application.properties nacos3:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos3:/home/nacos/conf/cluster.conf
docker cp /opt/software/nacoscluster/config/application.properties nacos4:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos4:/home/nacos/conf/cluster.conf
docker cp /opt/software/nacoscluster/config/application.properties nacos5:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos5:/home/nacos/conf/cluster.conf
docker cp /opt/software/nacoscluster/config/application.properties nacos6:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos6:/home/nacos/conf/cluster.conf
docker cp /opt/software/nacoscluster/config/application.properties nacos7:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos7:/home/nacos/conf/cluster.conf
docker cp /opt/software/nacoscluster/config/application.properties nacos8:/home/nacos/conf/application.properties
docker cp /opt/software/nacoscluster/config/cluster.conf nacos8:/home/nacos/conf/cluster.conf
docker restart nacos1
docker restart nacos2
docker restart nacos3
docker restart nacos4
docker restart nacos5
docker restart nacos6
docker restart nacos7
docker restart nacos8

Nginx高可用负载

拷贝nginx配置文件出来:

mkdir -p /opt/software/nginxcluster/log
cd /opt/software/nginxcluster
docker pull nginx
docker run --name nginx-test -p 80:80 -d nginx
docker cp nginx-test:/etc/nginx/nginx.conf /opt/software/nginxcluster/nginx.conf
chmod 777 nginx.conf
docker stop nginx-test && docker rm nginx-test 

拷贝出来的文件,在最后一行(和http同级)添加以下代码:

cd /opt/software/nginxcluster
vi nginx.conf
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;
events {worker_connections  1024;
}
http {include       /etc/nginx/mime.types;default_type  application/octet-stream;log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile        on;#tcp_nopush     on;keepalive_timeout  65;#gzip  on;include /etc/nginx/conf.d/*.conf;
}
# 添加以下配置
stream {upstream nacos {server HOST_IP:8848 weight=1 max_fails=2 fail_timeout=10s;server HOST_IP:8850 weight=1 max_fails=2 fail_timeout=10s;server HOST_IP:8852 weight=1 max_fails=2 fail_timeout=10s;server HOST_IP:8854 weight=1 max_fails=2 fail_timeout=10s;		server HOST_IP:8856 weight=1 max_fails=2 fail_timeout=10s;server HOST_IP:8858 weight=1 max_fails=2 fail_timeout=10s;	server HOST_IP:8860 weight=1 max_fails=2 fail_timeout=10s;server HOST_IP:8862 weight=1 max_fails=2 fail_timeout=10s;        }server {listen 8048;proxy_pass nacos;}
}

配置脚本文件

vi docker-nginx-cluster.sh

docker-nginx-cluster.sh文件:

#!/bin/bash
# Nginx配置文件的路径  
NGINX_CONF_PATH="/opt/software/nginxcluster/nginx.conf"    
# 检查Nginx配置文件是否存在  
if [ ! -f "$NGINX_CONF_PATH" ]; then  echo "Nginx配置文件不存在: $NGINX_CONF_PATH"  exit 1  
fi   
for i in $(seq 3)  
do# 获取宿主机的一个 IPv4 地址  HOST_IP=$(hostname -I | awk '{print $1}')  # 检查是否获取到了 IP 地址  if [ -z "$HOST_IP" ]; then  echo "无法获取宿主机 IP 地址"  exit 1  fi# 更新 Nginx 配置文件中的 IP 地址  sed -i "s/HOST_IP/$HOST_IP/g" $NGINX_CONF_PATH   docker run -p 804$i:8048  --name nginx$i --restart=unless-stopped -v /opt/software/nginxcluster/log/:/var/log/nginx -v "$NGINX_CONF_PATH":/etc/nginx/nginx.conf -d nginx# 检查容器是否成功启动  if [ $? -ne 0 ]; then  echo "启动容器 $CONTAINER_NAME 失败"  else  echo "成功启动容器 $CONTAINER_NAME,监听在宿主机端口 $CURRENT_HOST_PORT"  fi
done
chmod 777 /opt/software/nginxcluster/*
sh docker-nginx-cluster.sh

默认的用户名和密码:nacos

http://8.134.108.60:8041/nacos
http://8.134.108.60:8042/nacos
http://8.134.108.60:8043/nacos

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
虽然大部分博客都说Nginx单节点QPS在五万,但是这个是受限机器的,很多时候机器的cpu、云盘、内存、带宽等都会影响。

我这台服务器16G内存,部署了三台Nginx,分发了8个Nacos集群,不连接时,机器的负载如下:
在这里插入图片描述
通常情况下,都会对机器进行冗余。

以下是对应的Nginx配置示例:

  1. 调整worker_processes和worker_connections:
    在nginx.conf配置文件中,可以通过修改worker_processes参数来增加Nginx的工作进程数量,从而提高并发处理能力。同时,可以通过修改events块中的worker_connections参数来调整每个工作进程的最大连接数。例如:

    worker_processes 4;
    events {worker_connections 1024;
    }
    
  2. 启用keepalive连接:
    在http块中添加以下配置,启用keepalive连接:

    keepalive_timeout 65;
    keepalive_requests 100;
    
  3. 启用缓存:
    在location块中添加以下配置,启用缓存功能:

    location / {proxy_cache my_cache;proxy_cache_valid 200 302 10m;proxy_cache_valid 404 1m;
    }
    
  4. 启用gzip压缩:
    在http块中添加以下配置,启用gzip压缩:

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
  5. 调整Nginx的配置参数:
    根据实际情况,可以调整以下参数来优化Nginx的性能:

    • client_body_buffer_size:设置请求体缓冲区大小。
    • client_header_buffer_size:设置请求头缓冲区大小。
    • client_max_body_size:设置请求体的最大大小。
    • send_timeout:设置发送超时时间。
    • proxy_read_timeout:设置代理读取超时时间。

以上只是一些常见的Nginx QPS优化方法和配置示例,具体的配置还需要根据实际情况进行调整。

CSDN

📢文章总结

对本篇文章进行总结:

🔔以上就是今天要讲的内容,阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。

以梦为马,不负韶华

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

🚀🎉希望各位读者大大多多支持用心写文章的博主,现在时代变了,🚀🎉 信息爆炸,酒香也怕巷子深🔥,博主真的需要大家的帮助才能在这片海洋中继续发光发热🎨,所以,🏃💨赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

  • 💂 博客主页: 我是廖志伟
  • 👉开源项目:java_wxid
  • 🌥 哔哩哔哩:我是廖志伟
  • 🎏个人社区:幕后大佬
  • 🔖个人微信号SeniorRD
  • 🎉微信号二维码SeniorRD

📥博主目标

探寻内心世界,博主分享人生感悟与未来目标

  • 🍋程序开发这条路不能停,停下来容易被淘汰掉,吃不了自律的苦,就要受平庸的罪,持续的能力才能带来持续的自信。我本是一个很普通的程序员,放在人堆里,除了与生俱来的盛世美颜,就剩180的大高个了,就是我这样的一个人,默默写博文也有好多年了。
  • 📺有句老话说的好,牛逼之前都是傻逼式的坚持,希望自己可以通过大量的作品、时间的积累、个人魅力、运气、时机,可以打造属于自己的技术影响力。
  • 💥内心起伏不定,我时而激动,时而沉思。我希望自己能成为一个综合性人才,具备技术、业务和管理方面的精湛技能。我想成为产品架构路线的总设计师,团队的指挥者,技术团队的中流砥柱,企业战略和资本规划的实战专家。
  • 🎉这个目标的实现需要不懈的努力和持续的成长,但我必须努力追求。因为我知道,只有成为这样的人才,我才能在职业生涯中不断前进并为企业的发展带来真正的价值。在这个不断变化的时代,我们必须随时准备好迎接挑战,不断学习和探索新的领域,才能不断地向前推进。我坚信,只要我不断努力,我一定会达到自己的目标。

🔔有需要对自己进行综合性评估,进行职业方向规划,我可以让技术大牛帮你模拟面试、针对性的指导、传授面试技巧、简历优化、进行技术问题答疑等服务。

可访问:https://java_wxid.gitee.io/tojson/

开发人员简历优化、面试突击指导、技术问题解答

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

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

相关文章

pytorch如何向tensor结尾添加元素或维度--torch.cat()、torch.unsqueeze()的用法

目录 示例1 矢量后增加元素 示例2 tensor维度增加1 示例3 另一种替代unsqueeze的方法 示例1 矢量后增加元素 使用torch.cat()函数 ptorch.Tensor([1,5,0]) ptorch.cat((p, torch.Tensor([4])), 0) 结果: 这里,cat的第一个输入变量用()包绕&#xf…

Request请求参数----中文乱码问题

一: GET POST获取请求参数: 在处理为什么会出现中文乱码的情况之前, 首先我们要直到GET 以及 POST两种获取请求参数的不同 1>POST POST获取请求参数是通过输入流getReader来进行获取的, 通过字符输入流来获取响应的请求参数, 并且在解码的时候, 默认的情况是 ISO_885…

由浅到深认识Java语言(21):Math类

该文章Github地址:https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.c…

GaussDB WDR分析之集群报告篇

AWR报告目前已经成为Oracle DBA分析问题,定位故障最为重要的报告,阅读与分析AWR报告的技能也是Oracle DBA必备的技能。国产数据库为了提高运维便捷性,都在做类似Oracle AWR报告的模仿,只不过由于指标体系不够完善,因此…

postman 用上一个请求的响应体中的字段设置下一个请求的请求参数

文章目录 IntroPostman usagePre-request ScriptTests javascripts API Intro 这一切都是为了增加自动化动作所占的比例(减少人手工操作复制粘贴可能会造成的错误)。 Postman usage 最常用的:选HTTP方法类型、写URL,在Headers中…

如何解决Layui后台接口返回数据,但是table.render不渲染表格数据的问题

我这边进行了pareData数据格式转换,response重新定义了layui的参数格式规范 接口正常返回了数据 但是就是不渲染,我这个郁闷啊!! 忽然,我把后台重新定义的layui规定的格式参数,有个参数名叫data&#xff0…

sql注入五-WEB攻防-注入工具SQLMAPTamper编写指纹修改高权限操作目录架构

演示案例: 数据猜解-库表列数据&字典权限操作-文件&命令&交互式提交方法-POST&HEAD&JSON绕过模块-Tamper脚本-使用&开发分析拓展-代理&调试&指纹&风险&等级 #参考: https://www.cnblogs.com/bmjoker/p/9326258.…

自动化的免下车服务——银行、餐厅、快餐店、杂货店

如果您在20世纪70年代和2020年分别驾车经过免下车服务餐厅(汽车穿梭餐厅),您会发现,唯一的不同是排队的车型。50多年来,免下车技术一直为我们提供着良好的服务,但现在也该对它进行现代化改造了。 乘着AI和自…

先进电机技术 —— 长线缆驱动电机面临哪些问题?

一、长线驱动问题简述 电机变频驱动器(VFD)输出侧采用长线缆驱动电机运行时,将会面对多种问题,主要包括但不限于: 此图片来源于网络 1. **电压降**: - 长线缆的电阻会导致电压降增大,当电…

53 initrd/initramfs 相关

前言 呵呵 这里主要是 探究一下 根文件系统 相关的东西 以及 附加了一些 系统启动的相关信息 计算机启动 硬件重置寄存器 设置初始化数据 计算机访问 0xffff0, 执行 bios 的代码, bios 选择启动设备, 然后执行 启动设备 boolloader 的代码 bootloader 将 boot.img 加载…

你可敢信这是 AI 写的歌?suno 真的惊到我了!

你可敢信这是 AI 写的歌?suno 真的惊到我了! AI 音乐平台 suno 横空出世,效果惊人,我赶紧试了一下,amazing!!! suno创作 - 背叛 这是我随意创作的,这几天对诅咒前男友那首…

MySQL常用函数整理,建议收藏!

常见函数 字符串函数数字函数日期函数聚合函数流程控制函数 一、字符串函数 concat(s1,s2...,sn) --将s1,s2...,sn连接成字符串,如果该函数中的任何参数为 null,返回结果为 null concat_ws(sep,s1,s2...,sn) --将s1,s2...,sn连接成字符串,并用sep字符…

xilinx的高速接口构成原理和连接结构

本文来源: V3学院 尤老师的培训班笔记【高速收发器】xilinx高速收发器学习记录Xilinx-7Series-FPGA高速收发器使用学习—概述与参考时钟GT Transceiver的总体架构梳理 文章目录 一、概述:二、高速收发器结构:2.1 QUAD2.1.1 时钟2.1.2 CHANNEL…

【阅读论文】When Large Language Models Meet Vector Databases: A Survey

摘要 本调查探讨了大型语言模型(LLM)和向量数据库(VecDB)之间的协同潜力,这是一个新兴但迅速发展的研究领域。随着LLM的广泛应用,出现了许多挑战,包括产生虚构内容、知识过时、商业应用成本高昂…

【Godot4.2】基础知识 - Godot中的2D向量

概述 在Godot中,乃至一切游戏编程中,你应该都躲不开向量。这是每一个初学者都应该知道和掌握的内容,否则你将很难理解和实现某些其实原理非常简单的东西。 估计很多刚入坑Godot的小伙伴和我一样,不一定是计算机专业或编程相关专…

利用sealos安装k8s集群

1. 环境准备 准备三台干净(未安装过k8s环境)的虚拟机 # 所有的主机都要配置主机名和域名映射 # 设置主机名 hostnamectl set-hostname k8s-master01 # vim /etc/hosts 192.168.59.201 k8s-master01 192.168.59.202 k8s-worker01 192.168.59.203 k8…

基于ssm停车场管理系统(程序+文档+数据库)

** 🍅点赞收藏关注 → 私信领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅** 一、项目概述…

腾讯云GPU云服务器_并行计算_弹性计算_AI_深度学习

腾讯云GPU服务器是提供GPU算力的弹性计算服务,腾讯云GPU服务器具有超强的并行计算能力,可用于深度学习训练、科学计算、图形图像处理、视频编解码等场景,腾讯云百科txybk.com整理腾讯云GPU服务器租用价格表、GPU实例优势、GPU解决方案、GPU软…

java数据结构与算法基础-----字符串------正则表达式的练习案例---持续补充中

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 正则表达式基础:https://blog.csdn.net/grd_java/article/det…

xercesc库中文保存XML功能实现

目录 一 参考链接 二 运行结果 三 代码 一 参考链接 DOM Programming Guide (apache.org) Xerces-c DOM XML文件的构造_xerces-c domimplementation-CSDN博客 Xerces-c库的使用-CSDN博客 二 运行结果 三 代码 #if 1//参考链接: https://blog.csdn.net/RGBMa…