若依高可用架构 若依官网
一、环境准备 1.1 规划
序号
主机名
IP地址
用途
1
nginx-proxy-01
192.168.10.111 (VIP: 110)
静态文件 / 集群入口 (Master)
2
nginx-proxy-02
192.168.10.112 (VIP: 110)
静态文件 / 集群入口 (Backup)
3
java-backend
192.168.10.115
Java 后端服务
4
mysql-proxy
192.168.10.120
数据库读写分离入口
5
mysql-master
192.168.10.121
MySQL 主库 (写)
6
mysql-slave-01
192.168.10.122
MySQL 从库 (读)
7
redis-01
192.168.10.131
Redis 分片集群节点
8
redis-02
192.168.10.132
Redis 分片集群节点
9
redis-03
192.168.10.133
Redis 分片集群节点
10
compile-machine
192.168.10.130
编译机 / 运维中控
1 2 3 4 5 6 7 8 9 10 11 cat >> /etc/hosts <<EOF 192.168.10.111 nginx-proxy-01 192.168.10.112 nginx-proxy-02 192.168.10.115 java-backend 192.168.10.120 mysql-proxy 192.168.10.121 mysql-master 192.168.10.122 mysql-slave-01 192.168.10.131 redis-01 192.168.10.132 redis-02 192.168.10.133 redis-03 EOF
graph TD
%% 1. 样式定义 (放在最前面)
classDef user fill:#fff9c4,stroke:#fbc02d,stroke-width:2px;
classDef vip fill:#ffecb3,stroke:#ff6f00,stroke-width:2px,stroke-dasharray: 5 5;
classDef web fill:#bbdefb,stroke:#1565c0,stroke-width:2px;
classDef app fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px;
classDef db fill:#ffccbc,stroke:#d84315,stroke-width:2px;
classDef cache fill:#e1bee7,stroke:#6a1b9a,stroke-width:2px;
%% 2. 节点定义
User(👤 用户):::user
VIP(💎 VIP: 192.168.10.110):::vip
subgraph LB [接入层 / Keepalived]
N1[nginx-01 192.168.10.111]:::web
N2[nginx-02 192.168.10.112]:::web
end
subgraph APP [应用层]
Java[java-backend 192.168.10.115]:::app
end
subgraph MYSQL [MySQL 集群]
Proxy[mysql-proxy 192.168.10.120]:::db
Master[Master 写 192.168.10.121]:::db
Slave[Slave 读 192.168.10.122]:::db
end
subgraph REDIS [Redis 集群]
R1[redis-01]:::cache
R2[redis-02]:::cache
R3[redis-03]:::cache
end
%% 3. 连线关系
User --> VIP
VIP -.-> N1
VIP -.-> N2
N1 --> Java
N2 --> Java
Java -- JDBC连接 --> Proxy
Proxy -- 写 --> Master
Proxy -- 读 --> Slave
Master -. 同步 .-> Slave
Java -- 缓存连接 --> R1
Java
1.2 安装软件 1.2.1 Nginx
nginx-proxy-01
nginx-proxy-02
1 vim /etc/yum.repos.d/nginx.repo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [nginx-stable] name=nginx stable repo baseurl=https://nginx.org/packages/centos/$releasever /$basearch / gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=https://nginx.org/packages/mainline/centos/$releasever /$basearch / gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
1 yum install -y keepalived nginx
1.2.2 数据库
mysql-master 192.168.10.121
mysql-slave-01 192.168.10.122
1 2 wget https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm yum localinstall mysql80-community-release-el7-11.noarch.rpm -y
1 yum install mysql-community-server -y
1 systemctl enable --now mysqld
1 grep 'temporary password' /var/log/mysqld.log
1 ALTER USER 'root' @'localhost' IDENTIFIED BY 'Root21..' ;
1 mysql -u root -p'Root21..'
1 2 3 4 5 6 7 cat <<EOF | sudo tee /etc/yum.repos.d/proxysql.repo [proxysql] name=ProxySQL YUM repository baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.7.x/centos/7 gpgcheck=1 gpgkey=https://repo.proxysql.com/ProxySQL/proxysql-2.7.x/repo_pub_key EOF
1 systemctl enable --now proxysql
1.2.3 Java
1 tar xf jdk-8u461-linux-x64.tar.gz -C /usr/local/
1 ln -s /usr/local/jdk1.8.0_461/ /usr/local/java
1 2 3 4 5 6 7 cat >> /etc/profile.d/jdk.sh <<-EOF #!/bin/bash # 指定java安装目录 export JAVA_HOME=/usr/local/java # 用于指定java系统查找命令的路径 export PATH=\$JAVA_HOME/bin:\$PATH EOF
1 source /etc/profile.d/jdk.sh
1.2.4 redis
编译机编译,然后 scp 到目标机器。
1 wget https://download.redis.io/releases/redis-7.4.7.tar.gz
1 tar xf redis-7.4.7.tar.gz -C /usr/local
1 2 cd /usr/local/redis-7.4.7make
1 cd /usr/local/redis-7.4.7/src
1 scp redis-server redis-cli redis-sentinel redis-benchmark redis-check-aof redis-check-rdb root@redis-01:/usr/local/bin/
1 scp redis-server redis-cli redis-sentinel redis-benchmark redis-check-aof redis-check-rdb root@redis-02:/usr/local/bin/
1 scp redis-server redis-cli redis-sentinel redis-benchmark redis-check-aof redis-check-rdb root@redis-03:/usr/local/bin/
redis-01
redis-02
redis-03
1.2.5 java、node、maven、mysql
1 tar xf jdk-8u461-linux-x64.tar.gz -C /usr/local/
1 ln -s /usr/local/jdk1.8.0_461/ /usr/local/java
1 2 3 4 5 6 7 cat >> /etc/profile.d/jdk.sh <<-EOF #!/bin/bash # 指定java安装目录 export JAVA_HOME=/usr/local/java # 用于指定java系统查找命令的路径 export PATH=\$JAVA_HOME/bin:\$PATH EOF
1 source /etc/profile.d/jdk.sh
compile-machine node
注意 :尽量使用 16 的长期版本,若伊前端的加密算法没有更新。
1 wget https://nodejs.org/download/release/v17.9.1/node-v17.9.1-linux-x64.tar.gz
1 tar xf node-v17.9.1-linux-x64.tar.gz -C /usr/local/
1 ln -sv /usr/local/node-v17.9.1-linux-x64 /usr/local/node
1 2 3 4 5 6 cat >> /etc/profile.d/node.sh <<-EOF #!/bin/bash export NODE_HOME=/usr/local/node export PATH=\$PATH:\$NODE_HOME/bin export NODE_PATH=\$NODE_HOME/lib/node_modules EOF
1 source /etc/profile.d/node.sh
1 tar xf apache-maven-3.9.12-bin.tar.gz -C /usr/local/
1 ln -s /usr/local/apache-maven-3.9.12/ /usr/local/maven
1 2 3 4 5 cat >> /etc/profile.d/mvn.sh <<EOF #!/bin/bash export MAVEN_HOME=/usr/local/maven/ export PATH=\$MAVEN_HOME/bin:\$PATH EOF
1 source /etc/profile.d/mvn.sh
compile-machine mysql
使用mysql连接工具
1.2.6 拉取代码
1 2 3 cd ~git clone https://gitee.com/y_project/RuoYi-Vue cd RuoYi-Vue
二、构建前的配置 2.1 mysql相关 2.1.1 设置主从
1 2 3 4 5 6 7 8 9 10 11 12 13 [mysqld] datadir =/var/lib/mysqlsocket =/var/lib/mysql/mysql.socklog-error =/var/log/mysqld.logpid-file =/var/run/mysqld/mysqld.pidserver-id =121 port =3306 gtid_mode =ON enforce_gtid_consistency =ON log_bin =mysql-binbinlog_format =ROWexpire_logs_days =7 log_slave_updates =ON
1 systemctl restart mysqld
1 mysql -u root -p'Root21..'
1 2 3 4 5 -- 创建复制专用用户 CREATE USER 'repl' @'%' IDENTIFIED WITH mysql_native_password BY 'Repl21..' ; -- 赋予复制权限 GRANT REPLICATION SLAVE ON *.* TO 'repl' @'%' ; FLUSH PRIVILEGES;
1 2 3 4 5 6 7 8 9 10 11 12 [mysqld] datadir =/var/lib/mysqlsocket =/var/lib/mysql/mysql.socklog-error =/var/log/mysqld.logpid-file =/var/run/mysqld/mysqld.pidserver-id = 122 port = 3306 gtid_mode = ON enforce_gtid_consistency = ON log_bin = mysql-binbinlog_format = ROWread_only = 1
1 systemctl restart mysqld
1 mysql -u root -p'Root21..'
1 2 3 4 5 6 7 CHANGE MASTER TO MASTER_HOST='192.168.10.121' , MASTER_USER='repl' , MASTER_PASSWORD='Repl21..' , MASTER_PORT=3306, MASTER_AUTO_POSITION=1; -- 【核心】这句话告诉它:用 GTID 自动找位置 START SLAVE;
2.1.2 读写分离
注意 :这里顺带创建若伊数据库,mysql8 创建用户需携带 WITH mysql_native_password
1 mysql -u root -p'Root21..'
1 2 CREATE USER 'monitor' @'%' IDENTIFIED WITH mysql_native_password BY 'Monitor21..' ; GRANT REPLICATION CLIENT ON *.* TO 'monitor' @'%' ;
1 create database ruoyi character set utf8mb4;
1 2 create user ruoyi@'192.168.10.%' identified WITH mysql_native_password by 'Ruoyi21..' ; grant all privileges on ruoyi.* to ruoyi@'192.168.10.%' ;
1 mysql -u admin -padmin -h 127.0.0.1 -P 6032 --prompt='ProxySQLAdmin> '
1 INSERT INTO mysql_servers (hostgroup_id, hostname, port) VALUES (10, '192.168.10.121' , 3306);
1 INSERT INTO mysql_servers (hostgroup_id, hostname, port) VALUES (20, '192.168.10.122' , 3306);
1 2 LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;
1 2 3 4 5 UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username' ; UPDATE global_variables SET variable_value='Monitor21..' WHERE variable_name='mysql-monitor_password' ; LOAD MYSQL VARIABLES TO RUNTIME; SAVE MYSQL VARIABLES TO DISK;
1 2 3 4 5 -- 这里的 default_hostgroup 是默认路由,万一没匹配到规则,就去这个组(通常设为写组10) INSERT INTO mysql_users (username, password, default_hostgroup) VALUES ('ruoyi' , 'Ruoyi21..' , 10); LOAD MYSQL USERS TO RUNTIME; SAVE MYSQL USERS TO DISK;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -- 先清空旧规则,防止干扰 DELETE FROM mysql_query_rules; -- 规则 1:特殊读 -> 走主库 (HG 10) INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply) VALUES (1, 1, '^SELECT.*FOR UPDATE$' , 10, 1); -- 规则 2:普通读 -> 走从库 (HG 20) INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply) VALUES (2, 1, '^SELECT' , 20, 1); -- 加载生效 LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;
1 SELECT hostgroup_id, hostname, status FROM runtime_mysql_servers;
2.1.3 导入数据
1 2 mysql -h mysql-proxy -P 6033 -u ruoyi -p'Ruoyi21..' ruoyi < quartz.sql mysql -h mysql-proxy -P 6033 -u ruoyi -p'Ruoyi21..' ruoyi < ry_20250522.sql
2.1.4 连接配置 1 mysql -h 192.168.10.120 -P 6033 -u ruoyi -p'Ruoyi21..'
1 2 3 4 192.168.10.120 6033 ruoyi Ruoyi21..
2.1.5 补充配置
不要伪装成 mysql5,否则后续连接不成功。
1 mysql -u admin -padmin -h 127.0.0.1 -P 6032 --prompt='ProxySQLAdmin> '
1 2 3 4 5 6 7 8 -- 1. 修改全局变量,伪装成 8.0 版本 UPDATE global_variables SET variable_value='8.0.30' WHERE variable_name='mysql-server_version' ; -- 2. 让配置在运行时生效 LOAD MYSQL VARIABLES TO RUNTIME; -- 3. 保存配置到磁盘(重启不丢失) SAVE MYSQL VARIABLES TO DISK;
关键报错
1 2 16:18:04.666 [Druid-ConnectionPool-Create-1121401953] ERROR c.a.d.p.DruidDataSource - [run,2795] - create connection SQLException, url: jdbc:mysql://192.168.10.120:6033/ruoyi?useUnicode=true &characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true &serverTimezone=GMT%2B8, errorCode 1193, state HY000 java.sql.SQLException: Unknown system variable 'query_cache_size'
2.2 redis 2.2.1 生产环境调优
redis-01
redis-02
redis-03
1 vim /etc/security/limits.conf
1 2 net.core.somaxconn = 10240 vm.overcommit_memory = 1
2.2.3 配置启动
redis-01 7001、7002
redis-02 7001、7002
redis-03 7001、7002
1 2 3 4 5 6 7 8 9 10 11 12 13 14 mkdir -pv /data/redis/{7001,7002}cat > /data/redis/7001/redis.conf <<EOF port 7001 bind 0.0.0.0 requirepass "redispwd" protected-mode no daemonize yes pidfile /var/run/redis_7001.pid dir /data/redis/7001 appendonly yes cluster-enabled yes cluster-config-file nodes-7001.conf cluster-node-timeout 5000 EOF
1 2 cp /data/redis/7001/redis.conf /data/redis/7002/redis.confsed -i 's/7001/7002/g' /data/redis/7002/redis.conf
1 2 redis-server /data/redis/7001/redis.conf redis-server /data/redis/7002/redis.conf
1 2 3 4 5 6 redis-cli -a redispwd --cluster create \ 192.168.10.131:7001 192.168.10.131:7002 \ 192.168.10.132:7001 192.168.10.132:7002 \ 192.168.10.133:7001 192.168.10.133:7002 \ --cluster-replicas 1
1 redis-cli -a redispwd -c -p 7002 cluster nodes
2.3 修改 Ruoyi 项目配置信息
mysql 连接信息
1 vim ~/RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml
1 2 3 4 5 6 7 8 9 10 11 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver druid: master: url: jdbc:mysql://192.168.10.120:6033/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: ruoyi password: Ruoyi21..
redis 连接配置
compile-machine
注意 :集群和单机配置稍有不同
1 vim ~/RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 redis: database: 0 password: redispwd timeout: 10s cluster: max-redirects: 3 nodes: - 192.168 .10 .131 :7001 - 192.168 .10 .131 :7002 - 192.168 .10 .132 :7001 - 192.168 .10 .132 :7002 - 192.168 .10 .133 :7001 - 192.168 .10 .133 :7002 lettuce: pool: min-idle: 0 max-idle: 8 max-active: 8 max-wait: -1ms
三、编译 3.1 编译后端
1 cd ~/RuoYi-Vue/ruoyi-admin/
1 ls /root/RuoYi-Vue/ruoyi-admin/target/
验证
1 java -jar /root/RuoYi-Vue/ruoyi-admin/target/ruoyi-admin.jar
3.2 编译前端
1 cd ~/RuoYi-Vue/ruoyi-ui/
1 npm install -registry=http://registry.npmmirror.com
(可选,17版本及以上需要)高版本临时降级使用加密算法
1 export NODE_OPTIONS=--openssl-legacy-provider
1 ll /root/RuoYi-Vue/ruoyi-ui/dist/
3.3 移动构建产物到目标机器 前端静态资源
1 tar zcvf front-end.tar.gz dist
1 scp front-end.tar.gz root@nginx-proxy-01:/root
1 scp front-end.tar.gz root@nginx-proxy-02:/root
后端 jar 包
1 scp /root/RuoYi-Vue/ruoyi-admin/target/ruoyi-admin.jar root@java-backend:/root
四、部署 4.1 启动后端
1 java -jar /root/ruoyi-admin.jar
后台启动,8080
1 nohup java -jar /root/ruoyi-admin.jar > ruoyi.log 2>&1 &
4.2 启动前端
nginx-proxy-01
nginx-proxy-02
修改配置
1 mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
1 vim /etc/nginx/conf.d/ruoyi.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 server { listen 80 ; server_name localhost; access_log /var/log/nginx/ruoyi-access.log main; location / { root /www/wwwroot/ruoyi; try_files $uri $uri / /index.html; index index.html; } location /prod-api/ { proxy_set_header Host $http_host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header REMOTE-HOST $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_pass http://192.168.10.115:8080/; } }
验证配置
设置站点目录
1 2 3 4 5 mkdir -pv /www/wwwroot/ruoyicd ~tar xf front-end.tar.gz -C /www/wwwroot/ruoyi cd /www/wwwroot/ruoyimv dist/* .
启动
1 systemctl enable --now nginx
4.3 设置nginx高可用
1 cp /etc/keepalived/keepalived.conf{,.bak}
1 vim /etc/keepalived/keepalived.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 global_defs { router_id nginx-proxy-01 } vrrp_script check_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -20 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.110 } track_script { check_nginx } }
1 cp /etc/keepalived/keepalived.conf{,.bak}
1 vim /etc/keepalived/keepalived.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 global_defs { router_id nginx-proxy-02 } vrrp_script check_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -20 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.110 } track_script { check_nginx } }
1 systemctl enable --now keepalived
五、访问 http://192.168.10.110