chore(deploy): Add high availability cluster deployment configuration

This commit is contained in:
2026-03-12 15:18:41 +08:00
parent 93edbc4417
commit 38876f93b4
20 changed files with 2604 additions and 4 deletions
+1
View File
@@ -2,6 +2,7 @@ target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
local/
### IntelliJ IDEA ###
.idea/modules.xml
+57
View File
@@ -0,0 +1,57 @@
# ============================================================
# Node-01 环境变量配置 (192.168.1.101)
# 主节点: MySQL Master, Redis Master, Nacos, NameServer, MinIO, 微服务
# ============================================================
# 节点信息
NODE_ID=1
HOST_IP=192.168.1.101
HOSTNAME=node-01
# 集群节点列表
NACOS_SERVERS=192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848
NAMESRV_ADDR=192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876
# MySQL配置 (主节点)
MYSQL_SERVER_ID=1
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=root123456
MYSQL_DATABASE=video_platform
MYSQL_USER=video
MYSQL_PASSWORD=video123
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=redis_HA_Cluster_2024
REDIS_MASTER_HOST=192.168.1.101
REDIS_MASTER_PORT=6379
# Nacos配置
NACOS_HOST=nacos
NACOS_PORT=8848
NACOS_NAMESPACE=public
NACOS_GROUP=DEFAULT_GROUP
# Sentinel配置
SENTINEL_HOST=sentinel
SENTINEL_PORT=8080
# MinIO配置
MINIO_HOST=minio
MINIO_PORT=9000
MINIO_EXTERNAL_PORT=9100
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin123
MINIO_BUCKET=video-platform
# RocketMQ配置
ROCKETMQ_HOST=rmqnamesrv
ROCKETMQ_PORT=9876
# Java配置
JAVA_OPTS=-Xms256m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
# 本节点部署的服务
DEPLOY_SERVICES=mysql,redis,redis-sentinel,nacos,rmqnamesrv,minio,sentinel,video-gateway,video-auth,video-user,video-content,video-comment,video-recommend,video-admin,nginx
+58
View File
@@ -0,0 +1,58 @@
# ============================================================
# Node-02 环境变量配置 (192.168.1.102)
# 从节点: MySQL Slave, Redis Slave, Nacos, NameServer, Broker-A, MinIO, 微服务
# ============================================================
# 节点信息
NODE_ID=2
HOST_IP=192.168.1.102
HOSTNAME=node-02
# 集群节点列表
NACOS_SERVERS=192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848
NAMESRV_ADDR=192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876
# MySQL配置 (从节点)
MYSQL_SERVER_ID=2
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=root123456
MYSQL_DATABASE=video_platform
MYSQL_USER=video
MYSQL_PASSWORD=video123
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=redis_HA_Cluster_2024
REDIS_MASTER_HOST=192.168.1.101
REDIS_MASTER_PORT=6379
# Nacos配置
NACOS_HOST=nacos
NACOS_PORT=8848
NACOS_NAMESPACE=public
NACOS_GROUP=DEFAULT_GROUP
# Sentinel配置
SENTINEL_HOST=sentinel
SENTINEL_PORT=8080
# MinIO配置
MINIO_HOST=minio
MINIO_PORT=9000
MINIO_EXTERNAL_PORT=9100
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin123
MINIO_BUCKET=video-platform
# RocketMQ配置 (Broker-A)
ROCKETMQ_HOST=rmqnamesrv
ROCKETMQ_PORT=9876
BROKER_NAME=broker-a
# Java配置
JAVA_OPTS=-Xms256m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
# 本节点部署的服务
DEPLOY_SERVICES=mysql,redis,redis-sentinel,nacos,rmqnamesrv,rmqbroker,minio,sentinel,video-gateway,video-auth,video-user,video-content,video-comment,video-recommend,video-admin
+59
View File
@@ -0,0 +1,59 @@
# ============================================================
# Node-03 环境变量配置 (192.168.1.103)
# 从节点 - MySQL Slave, Redis Slave, Nacos, NameServer, Broker-B, MinIO
# ============================================================
# 节点信息
NODE_ID=3
HOST_IP=192.168.1.103
HOSTNAME=node-03
# 集群节点列表
NACOS_SERVERS=192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848
NAMESRV_ADDR=192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876
# MySQL配置 (从节点)
MYSQL_SERVER_ID=3
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=root123456
MYSQL_DATABASE=video_platform
MYSQL_USER=video
MYSQL_PASSWORD=video123
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=redis_HA_Cluster_2024
REDIS_MASTER_HOST=192.168.1.101
REDIS_MASTER_PORT=6379
# Nacos配置
NACOS_HOST=nacos
NACOS_PORT=8848
NACOS_NAMESPACE=public
NACOS_GROUP=DEFAULT_GROUP
# Sentinel配置
SENTINEL_HOST=sentinel
SENTINEL_PORT=8080
# MinIO配置
MINIO_HOST=minio
MINIO_PORT=9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin123
MINIO_BUCKET=video-platform
# MinIO分布式节点
MINIO_ENDPOINTS=http://192.168.1.101:9000,http://192.168.1.102:9000,http://192.168.1.103:9000
# RocketMQ配置 (Broker-B)
ROCKETMQ_HOST=rmqnamesrv
ROCKETMQ_PORT=9876
BROKER_NAME=broker-b
# Java配置
JAVA_OPTS=-Xms256m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
# 本节点部署的服务
DEPLOY_SERVICES=mysql,redis,redis-sentinel,nacos,rmqnamesrv,rmqbroker,minio,sentinel
+71
View File
@@ -0,0 +1,71 @@
# MySQL 主节点配置 (Node-01)
# GTID 主从复制
[mysqld]
# 基础配置
user = mysql
port = 3306
bind-address = 0.0.0.0
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-authentication-plugin = mysql_native_password
# 连接配置
max_connections = 500
max_connect_errors = 100
wait_timeout = 28800
interactive_timeout = 28800
connect_timeout = 10
# 缓冲配置 (8GB内存建议)
innodb_buffer_pool_size = 2G
innodb_buffer_pool_instances = 4
innodb_log_buffer_size = 64M
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
# 日志配置
log-error = /var/lib/mysql/mysql-error.log
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/mysql-slow.log
long_query_time = 2
log_queries_not_using_indexes = 0
# 临时目录
tmpdir = /tmp
# 二进制日志配置 (主节点)
server-id = 1
log-bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL
binlog_cache_size = 1M
max_binlog_size = 500M
expire_logs_days = 7
sync_binlog = 1
# GTID 配置
gtid-mode = ON
enforce-gtid-consistency = ON
log-slave-updates = ON
# 复制配置
binlog-do-db = video_auth
binlog-do-db = video_user
binlog-do-db = video_content
binlog-do-db = video_comment
binlog-do-db = video_recommend
binlog-do-db = video_admin
binlog-do-db = nacos_config
# 安全配置
skip-name-resolve
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
[mysql]
default-character-set = utf8mb4
prompt = '\u@\h [\d]> '
[client]
default-character-set = utf8mb4
+61
View File
@@ -0,0 +1,61 @@
# MySQL 高可用配置
# 从节点配置 (Node-02, Node-03)
# 注意: 每个从节点需要设置不同的 server-id
[mysqld]
# 基础配置
user = mysql
port = 3306
bind-address = 0.0.0.0
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-authentication-plugin = mysql_native_password
# 连接配置
max_connections = 500
max_connect_errors = 100
wait_timeout = 28800
interactive_timeout = 28800
# 缓冲配置
innodb_buffer_pool_size = 1G
innodb_buffer_pool_instances = 4
innodb_log_buffer_size = 64M
innodb_log_file_size = 512M
# 日志配置
log-error = /var/lib/mysql/mysql-error.log
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/mysql-slow.log
long_query_time = 2
# 主从复制配置 - 从节点
# server-id 在docker-compose中通过环境变量设置
# server-id = 2 # Node-02
# server-id = 3 # Node-03
log-bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL
relay-log = relay-bin
relay-log-index = relay-bin.index
read_only = ON
super_read_only = ON
# GTID配置
gtid-mode = ON
enforce-gtid-consistency = ON
# 从节点并行复制
slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = 4
slave_preserve_commit_order = ON
# 半同步复制 (可选)
# plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
# rpl_semi_sync_slave_enabled = 1
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
+179
View File
@@ -0,0 +1,179 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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.
*/
/******************************************/
/* 表名称 = config_info */
/******************************************/
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) DEFAULT NULL COMMENT 'group_id',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) DEFAULT NULL COMMENT 'configuration description',
`c_use` varchar(64) DEFAULT NULL COMMENT 'configuration usage',
`effect` varchar(64) DEFAULT NULL COMMENT '配置生效的描述',
`type` varchar(64) DEFAULT NULL COMMENT '配置的类型',
`c_schema` text COMMENT '配置的模式',
`encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' COMMENT '密钥',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
/******************************************/
/* 表名称 = config_info since 2.5.0 */
/******************************************/
CREATE TABLE `config_info_gray` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`src_user` text COMMENT 'src_user',
`src_ip` varchar(100) DEFAULT NULL COMMENT 'src_ip',
`gmt_create` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'gmt_create',
`gmt_modified` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'gmt_modified',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`gray_name` varchar(128) NOT NULL COMMENT 'gray_name',
`gray_rule` text NOT NULL COMMENT 'gray_rule',
`encrypted_data_key` varchar(256) NOT NULL DEFAULT '' COMMENT 'encrypted_data_key',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfogray_datagrouptenantgray` (`data_id`,`group_id`,`tenant_id`,`gray_name`),
KEY `idx_dataid_gmt_modified` (`data_id`,`gmt_modified`),
KEY `idx_gmt_modified` (`gmt_modified`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='config_info_gray';
/******************************************/
/* 表名称 = config_tags_relation */
/******************************************/
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
`tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增长标识',
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
/******************************************/
/* 表名称 = group_capacity */
/******************************************/
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
/******************************************/
/* 表名称 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(20) unsigned NOT NULL COMMENT 'id',
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增标识',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`op_type` char(10) DEFAULT NULL COMMENT 'operation type',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' COMMENT '密钥',
`publish_type` varchar(50) DEFAULT 'formal' COMMENT 'publish type gray or formal',
`gray_name` varchar(50) DEFAULT NULL COMMENT 'gray name',
`ext_info` longtext DEFAULT NULL COMMENT 'ext info',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
/******************************************/
/* 表名称 = tenant_capacity */
/******************************************/
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) default '' COMMENT 'tenant_id',
`tenant_name` varchar(128) default '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY COMMENT 'username',
`password` varchar(500) NOT NULL COMMENT 'password',
`enabled` boolean NOT NULL COMMENT 'enabled'
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL COMMENT 'username',
`role` varchar(50) NOT NULL COMMENT 'role',
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL COMMENT 'role',
`resource` varchar(128) NOT NULL COMMENT 'resource',
`action` varchar(8) NOT NULL COMMENT 'action',
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);
+52
View File
@@ -0,0 +1,52 @@
# Nginx Upstream 配置
# 高可用负载均衡
# API网关集群
upstream gateway_cluster {
# 负载均衡策略: 轮询 (默认)
# 其他选项: ip_hash, least_conn, hash $request_uri
least_conn; # 最少连接数策略
server 192.168.1.101:9000 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.1.102:9000 weight=1 max_fails=3 fail_timeout=30s backup;
# 健康检查
keepalive 32;
}
# Nacos集群
upstream nacos_cluster {
server 192.168.1.101:8848 weight=1;
server 192.168.1.102:8848 weight=1;
server 192.168.1.103:8848 weight=1;
keepalive 16;
}
# Sentinel集群
upstream sentinel_cluster {
server 192.168.1.101:8880 weight=1;
server 192.168.1.102:8880 weight=1;
server 192.168.1.103:8880 weight=1;
keepalive 16;
}
# MinIO API集群 (统一使用9100端口)
upstream minio_cluster {
server 192.168.1.101:9100 weight=1;
server 192.168.1.102:9100 weight=1;
server 192.168.1.103:9000 weight=1 backup;
keepalive 16;
}
# MinIO控制台集群 (统一使用9101端口,Node-03使用9001)
upstream minio_console_cluster {
server 192.168.1.101:9101 weight=1;
server 192.168.1.102:9101 weight=1;
server 192.168.1.103:9001 weight=1 backup;
keepalive 16;
}
+207
View File
@@ -0,0 +1,207 @@
# Nginx 主配置文件
# 高可用负载均衡
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 10240;
use epoll;
multi_accept on;
}
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" '
'upstream: $upstream_addr '
'response_time: $upstream_response_time';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip压缩配置
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml;
# 请求体大小限制 (用于视频上传)
client_max_body_size 1024M;
client_body_buffer_size 128k;
# 代理超时配置
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
# 代理头配置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 加载upstream配置
include /etc/nginx/conf.d/upstream.conf;
# 主服务配置
server {
listen 80;
listen [::]:80;
server_name _;
# 首页
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# API网关路由
location /auth/ {
proxy_pass http://gateway_cluster/auth/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /user/ {
proxy_pass http://gateway_cluster/user/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /content/ {
proxy_pass http://gateway_cluster/content/;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 视频流优化
proxy_buffering off;
proxy_request_buffering off;
}
location /comment/ {
proxy_pass http://gateway_cluster/comment/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /recommend/ {
proxy_pass http://gateway_cluster/recommend/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /admin/ {
proxy_pass http://gateway_cluster/admin/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# Nacos控制台
location /nacos/ {
proxy_pass http://nacos_cluster/nacos/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# Sentinel控制台
location /sentinel/ {
proxy_pass http://sentinel_cluster/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# MinIO API
location /minio/ {
proxy_pass http://minio_cluster/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
}
# MinIO控制台
location /minio-console/ {
proxy_pass http://minio_console_cluster/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 健康检查端点
location /health {
access_log off;
return 200 'OK';
add_header Content-Type text/plain;
}
# 状态监控页面
location /nginx_status {
stub_status on;
access_log off;
allow 192.168.1.0/24;
deny all;
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
# TCP/UDP 流代理 (用于Redis, MySQL等)
stream {
# MySQL负载均衡
upstream mysql_cluster {
server 192.168.1.101:3306 weight=1;
server 192.168.1.102:3306 weight=1 backup;
server 192.168.1.103:3306 weight=1 backup;
}
server {
listen 13306;
proxy_pass mysql_cluster;
proxy_connect_timeout 10s;
}
# Redis负载均衡 (读写分离)
upstream redis_master {
server 192.168.1.101:6379;
}
server {
listen 16379;
proxy_pass redis_master;
proxy_connect_timeout 5s;
}
# Redis Sentinel
upstream redis_sentinel {
server 192.168.1.101:26379;
server 192.168.1.102:26379;
server 192.168.1.103:26379;
}
server {
listen 26379;
proxy_pass redis_sentinel;
}
}
+54
View File
@@ -0,0 +1,54 @@
# Redis 主节点配置 (Node-01)
# 网络配置
bind 0.0.0.0
port 6379
protected-mode no
# 进程配置
daemonize no
pidfile /var/run/redis/redis-server.pid
logfile /var/log/redis/redis-server.log
# 数据目录
dir /data
# 内存配置
maxmemory 2gb
maxmemory-policy allkeys-lru
# 持久化配置 - RDB
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
# 持久化配置 - AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 密码配置
requirepass redis_HA_Cluster_2024
masterauth redis_HA_Cluster_2024
# 性能配置
tcp-keepalive 300
tcp-backlog 511
timeout 0
# 慢查询日志
slowlog-log-slower-than 10000
slowlog-max-len 128
# 客户端配置
maxclients 10000
# 集群配置 (单机模式不需要)
# cluster-enabled no
+60
View File
@@ -0,0 +1,60 @@
# Redis 从节点配置 (Node-02, Node-03)
# 网络配置
bind 0.0.0.0
port 6379
protected-mode no
# 进程配置
daemonize no
pidfile /var/run/redis/redis-server.pid
logfile /var/log/redis/redis-server.log
# 数据目录
dir /data
# 内存配置
maxmemory 2gb
maxmemory-policy allkeys-lru
# 持久化配置 - RDB
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
# 持久化配置 - AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 密码配置
requirepass redis_HA_Cluster_2024
masterauth redis_HA_Cluster_2024
# 从节点配置 (启动后手动执行 REPLICAOF 命令)
# replicaof 192.168.1.101 6379
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
repl-backlog-size 1mb
# 性能配置
tcp-keepalive 300
tcp-backlog 511
timeout 0
# 慢查询日志
slowlog-log-slower-than 10000
slowlog-max-len 128
# 客户端配置
maxclients 10000
+40
View File
@@ -0,0 +1,40 @@
# Redis Sentinel 配置
# 所有节点使用相同配置
port 26379
daemonize no
pidfile /var/run/redis/redis-sentinel.pid
logfile /var/log/redis/redis-sentinel.log
dir /tmp
# 监控主节点配置
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
# quorum: 需要多少个sentinel同意才能判断主节点客观下线
sentinel monitor mymaster 192.168.1.101 6379 2
# 主节点密码
sentinel auth-pass mymaster redis_HA_Cluster_2024
# 主观下线时间 (毫秒)
# 如果主节点在这个时间内没有响应PING,则标记为主观下线
sentinel down-after-milliseconds mymaster 30000
# 故障转移超时时间 (毫秒)
sentinel failover-timeout mymaster 180000
# 同时可以有多少个从节点对新主节点进行同步
sentinel parallel-syncs mymaster 1
# 通知脚本 (可选)
# sentinel notification-script mymaster /var/redis/notify.sh
# 客户端重配置脚本 (可选)
# sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
# 允许Sentinel在启动时更新配置文件
# sentinel announce-ip <ip>
# sentinel announce-port <port>
# 其他配置
protected-mode no
bind 0.0.0.0
+47
View File
@@ -0,0 +1,47 @@
# RocketMQ Broker 配置
# 主节点配置 (Node-02) - 与Node-03互为主备
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
# NameServer地址
namesrvAddr = 192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876
# 网络配置
brokerIP1 = 192.168.1.102
listenPort = 10911
# 存储配置
storePathRootDir = /home/rocketmq/store
storePathCommitLog = /home/rocketmq/store/commitlog
# 性能配置
sendMessageThreadPoolNums = 16
pullMessageThreadPoolNums = 16
queryMessageThreadPoolNums = 8
# 刷盘配置
flushDiskType = ASYNC_FLUSH
# 主从复制配置
brokerRole = ASYNC_MASTER
# 消息保留时间 (小时)
fileReservedTime = 72
# 提交日志文件大小
mapedFileSizeCommitLog = 1073741824
# 消费队列文件大小
mapedFileSizeConsumeQueue = 300000
# 自动创建Topic
autoCreateTopicEnable = true
autoCreateSubscriptionGroup = true
# 消息最大大小
maxMessageSize = 4194304
# 内存配置
brokerMemory = 512m
+47
View File
@@ -0,0 +1,47 @@
# RocketMQ Broker 配置
# 主节点配置 (Node-03) - 与Node-02互为主备
brokerClusterName = DefaultCluster
brokerName = broker-b
brokerId = 0
# NameServer地址
namesrvAddr = 192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876
# 网络配置
brokerIP1 = 192.168.1.103
listenPort = 10911
# 存储配置
storePathRootDir = /home/rocketmq/store
storePathCommitLog = /home/rocketmq/store/commitlog
# 性能配置
sendMessageThreadPoolNums = 16
pullMessageThreadPoolNums = 16
queryMessageThreadPoolNums = 8
# 刷盘配置
flushDiskType = ASYNC_FLUSH
# 主从复制配置
brokerRole = ASYNC_MASTER
# 消息保留时间 (小时)
fileReservedTime = 72
# 提交日志文件大小
mapedFileSizeCommitLog = 1073741824
# 消费队列文件大小
mapedFileSizeConsumeQueue = 300000
# 自动创建Topic
autoCreateTopicEnable = true
autoCreateSubscriptionGroup = true
# 消息最大大小
maxMessageSize = 4194304
# 内存配置
brokerMemory = 512m
+423
View File
@@ -0,0 +1,423 @@
# ============================================================
# Node-01 Docker Compose 配置
# 主节点: MySQL Master, Redis Master, Nacos, NameServer, MinIO, 微服务
# 使用方式: docker compose --env-file config/.env.node-01 up -d
# ============================================================
services:
# ==================== 基础设施 ====================
mysql:
image: mysql:8.0
container_name: mysql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123456}
MYSQL_DATABASE: ${MYSQL_DATABASE:-video_platform}
MYSQL_USER: ${MYSQL_USER:-video}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-video123}
volumes:
- mysql_data:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d
- ./config/mysql/my-master.cnf:/etc/mysql/conf.d/my.cnf:ro
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --server-id=1
- --log-bin=mysql-bin
- --binlog-format=ROW
- --gtid-mode=ON
- --enforce-gtid-consistency=ON
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD:-root123456}"]
interval: 10s
timeout: 5s
retries: 10
networks:
- ha-network
redis:
image: redis:7.0-alpine
container_name: redis
restart: always
ports:
- "6379:6379"
volumes:
- redis_data:/data
- ./config/redis/redis-master.conf:/usr/local/etc/redis/redis.conf:ro
command: redis-server /usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-redis_HA_Cluster_2024}", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
redis-sentinel:
image: redis:7.0-alpine
container_name: redis-sentinel
restart: always
ports:
- "26379:26379"
volumes:
- ./config/redis/sentinel.conf:/usr/local/etc/redis/sentinel.conf:ro
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
depends_on:
redis:
condition: service_healthy
networks:
- ha-network
nacos:
image: nacos/nacos-server:v2.3.2
container_name: nacos
restart: always
ports:
- "8848:8848"
- "9848:9848"
- "9849:9849"
environment:
- MODE=cluster
- NACOS_SERVERS=${NACOS_SERVERS:-192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848}
- NACOS_SERVER_IP=${HOST_IP:-192.168.1.101}
- NACOS_APPLICATION_PORT=8848
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
- NACOS_AUTH_IDENTITY_KEY=serverIdentity
- NACOS_AUTH_IDENTITY_VALUE=security
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_DB_NAME=nacos_config
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=${MYSQL_ROOT_PASSWORD:-root123456}
- JVM_XMS=512m
- JVM_XMX=512m
volumes:
- nacos_logs:/home/nacos/logs
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/liveness"]
interval: 10s
timeout: 5s
retries: 10
depends_on:
mysql:
condition: service_healthy
networks:
- ha-network
rmqnamesrv:
image: apache/rocketmq:5.1.4
container_name: rmqnamesrv
restart: always
ports:
- "9876:9876"
environment:
- JAVA_OPT_EXT=-server -Xms256m -Xmx256m
command: sh mqnamesrv
healthcheck:
test: ["CMD", "sh", "-c", "nc -z localhost 9876"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
minio:
image: quay.io/minio/minio
container_name: minio
restart: always
ports:
- "9100:9000"
- "9101:9001"
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin123
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
sentinel:
image: sentinel-dashboard:1.8.6
container_name: sentinel
restart: always
ports:
- "8880:8080"
environment:
- JAVA_OPTS=-Xms128m -Xmx256m
- SERVER_PORT=8080
- DASHBOARD_SERVER=localhost:8080
- PROJECT_NAME=sentinel-dashboard
networks:
- ha-network
# ==================== 微服务 ====================
video-gateway:
build:
context: ./video-gateway
dockerfile: Dockerfile
container_name: video-gateway
restart: always
ports:
- "9000:9000"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- NACOS_SERVERS=${NACOS_SERVERS:-192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- GATEWAY_IP=${HOST_IP:-192.168.1.101}
- JAVA_OPTS=-Xms256m -Xmx512m
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
depends_on:
nacos:
condition: service_healthy
networks:
- ha-network
video-auth:
build:
context: ./video-auth
dockerfile: Dockerfile
container_name: video-auth
restart: always
ports:
- "9001:9001"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- NACOS_SERVERS=${NACOS_SERVERS:-192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848}
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- AUTH_IP=${HOST_IP:-192.168.1.101}
- JAVA_OPTS=-Xms256m -Xmx512m
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9001/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-user:
build:
context: ./video-user
dockerfile: Dockerfile
container_name: video-user
restart: always
ports:
- "9002:9002"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- USER_IP=${HOST_IP:-192.168.1.101}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-content:
build:
context: ./video-content
dockerfile: Dockerfile
container_name: video-content
restart: always
ports:
- "9003:9003"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- ROCKETMQ_HOST=rmqnamesrv
- ROCKETMQ_PORT=9876
- MINIO_HOST=minio
- MINIO_PORT=9000
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin123
- MINIO_BUCKET=video-platform
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- CONTENT_IP=${HOST_IP:-192.168.1.101}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
rmqnamesrv:
condition: service_healthy
minio:
condition: service_healthy
networks:
- ha-network
video-comment:
build:
context: ./video-comment
dockerfile: Dockerfile
container_name: video-comment
restart: always
ports:
- "9004:9004"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- COMMENT_IP=${HOST_IP:-192.168.1.101}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-recommend:
build:
context: ./video-recommend
dockerfile: Dockerfile
container_name: video-recommend
restart: always
ports:
- "9005:9005"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- RECOMMEND_IP=${HOST_IP:-192.168.1.101}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-admin:
build:
context: ./video-admin
dockerfile: Dockerfile
container_name: video-admin
restart: always
ports:
- "9006:9006"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- ADMIN_IP=${HOST_IP:-192.168.1.101}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
# ==================== 负载均衡 ====================
nginx:
image: nginx:alpine
container_name: nginx-lb
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./config/nginx/conf.d:/etc/nginx/conf.d:ro
- nginx_logs:/var/log/nginx
depends_on:
- video-gateway
networks:
- ha-network
networks:
ha-network:
driver: bridge
volumes:
mysql_data:
redis_data:
nacos_logs:
minio_data:
nginx_logs:
+417
View File
@@ -0,0 +1,417 @@
# ============================================================
# Node-02 Docker Compose 配置
# 从节点: MySQL Slave, Redis Slave, Nacos, NameServer, Broker-A, MinIO, 微服务
# 使用方式: docker compose --env-file config/.env.node-02 up -d
# ============================================================
services:
# ==================== 基础设施 ====================
mysql:
image: mysql:8.0
container_name: mysql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123456}
MYSQL_DATABASE: ${MYSQL_DATABASE:-video_platform}
MYSQL_USER: ${MYSQL_USER:-video}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-video123}
volumes:
- mysql_data:/var/lib/mysql
- ./config/mysql/my-slave.cnf:/etc/mysql/conf.d/my.cnf:ro
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --server-id=2
- --log-bin=mysql-bin
- --binlog-format=ROW
- --gtid-mode=ON
- --enforce-gtid-consistency=ON
- --read-only=ON
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD:-root123456}"]
interval: 10s
timeout: 5s
retries: 10
networks:
- ha-network
redis:
image: redis:7.0-alpine
container_name: redis
restart: always
ports:
- "6379:6379"
volumes:
- redis_data:/data
- ./config/redis/redis-slave.conf:/usr/local/etc/redis/redis.conf:ro
command: redis-server /usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-redis_HA_Cluster_2024}", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
redis-sentinel:
image: redis:7.0-alpine
container_name: redis-sentinel
restart: always
ports:
- "26379:26379"
volumes:
- ./config/redis/sentinel.conf:/usr/local/etc/redis/sentinel.conf:ro
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
depends_on:
redis:
condition: service_healthy
networks:
- ha-network
nacos:
image: nacos/nacos-server:v2.3.2
container_name: nacos
restart: always
ports:
- "8848:8848"
- "9848:9848"
- "9849:9849"
environment:
- MODE=cluster
- NACOS_SERVERS=${NACOS_SERVERS:-192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848}
- NACOS_SERVER_IP=${HOST_IP:-192.168.1.102}
- NACOS_APPLICATION_PORT=8848
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
- NACOS_AUTH_IDENTITY_KEY=serverIdentity
- NACOS_AUTH_IDENTITY_VALUE=security
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_DB_NAME=nacos_config
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=${MYSQL_ROOT_PASSWORD:-root123456}
- JVM_XMS=512m
- JVM_XMX=512m
volumes:
- nacos_logs:/home/nacos/logs
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/liveness"]
interval: 10s
timeout: 5s
retries: 10
depends_on:
mysql:
condition: service_healthy
networks:
- ha-network
rmqnamesrv:
image: apache/rocketmq:5.1.4
container_name: rmqnamesrv
restart: always
ports:
- "9876:9876"
environment:
- JAVA_OPT_EXT=-server -Xms256m -Xmx256m
command: sh mqnamesrv
healthcheck:
test: ["CMD", "sh", "-c", "nc -z localhost 9876"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
rmqbroker:
image: apache/rocketmq:5.1.4
container_name: rmqbroker
restart: always
ports:
- "10909:10909"
- "10911:10911"
- "10912:10912"
environment:
- NAMESRV_ADDR=${NAMESRV_ADDR:-192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876}
- JAVA_OPT_EXT=-server -Xms512m -Xmx512m
volumes:
- ./config/rocketmq/broker-a.conf:/home/rocketmq/rocketmq-5.1.4/conf/broker.conf:ro
- rmqbroker_logs:/home/rocketmq/logs
- rmqbroker_store:/home/rocketmq/store
command: sh mqbroker -c /home/rocketmq/rocketmq-5.1.4/conf/broker.conf
depends_on:
rmqnamesrv:
condition: service_healthy
networks:
- ha-network
minio:
image: quay.io/minio/minio
container_name: minio
restart: always
ports:
- "9100:9000"
- "9101:9001"
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin123
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
sentinel:
image: sentinel-dashboard:1.8.6
container_name: sentinel
restart: always
ports:
- "8880:8080"
environment:
- JAVA_OPTS=-Xms128m -Xmx256m
- SERVER_PORT=8080
- DASHBOARD_SERVER=localhost:8080
- PROJECT_NAME=sentinel-dashboard
networks:
- ha-network
# ==================== 微服务 ====================
video-gateway:
build:
context: ./video-gateway
dockerfile: Dockerfile
container_name: video-gateway
restart: always
ports:
- "9000:9000"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- NACOS_SERVERS=${NACOS_SERVERS:-192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- GATEWAY_IP=${HOST_IP:-192.168.1.102}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
networks:
- ha-network
video-auth:
build:
context: ./video-auth
dockerfile: Dockerfile
container_name: video-auth
restart: always
ports:
- "9001:9001"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- AUTH_IP=${HOST_IP:-192.168.1.102}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-user:
build:
context: ./video-user
dockerfile: Dockerfile
container_name: video-user
restart: always
ports:
- "9002:9002"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- USER_IP=${HOST_IP:-192.168.1.102}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-content:
build:
context: ./video-content
dockerfile: Dockerfile
container_name: video-content
restart: always
ports:
- "9003:9003"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- ROCKETMQ_HOST=rmqnamesrv
- ROCKETMQ_PORT=9876
- MINIO_HOST=minio
- MINIO_PORT=9000
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin123
- MINIO_BUCKET=video-platform
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- CONTENT_IP=${HOST_IP:-192.168.1.102}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
rmqnamesrv:
condition: service_healthy
minio:
condition: service_healthy
networks:
- ha-network
video-comment:
build:
context: ./video-comment
dockerfile: Dockerfile
container_name: video-comment
restart: always
ports:
- "9004:9004"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- COMMENT_IP=${HOST_IP:-192.168.1.102}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-recommend:
build:
context: ./video-recommend
dockerfile: Dockerfile
container_name: video-recommend
restart: always
ports:
- "9005:9005"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- RECOMMEND_IP=${HOST_IP:-192.168.1.102}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
video-admin:
build:
context: ./video-admin
dockerfile: Dockerfile
container_name: video-admin
restart: always
ports:
- "9006:9006"
environment:
- SPRING_PROFILES_ACTIVE=ha
- NACOS_HOST=nacos
- NACOS_PORT=8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-redis_HA_Cluster_2024}
- SENTINEL_HOST=sentinel
- SENTINEL_PORT=8080
- ADMIN_IP=${HOST_IP:-192.168.1.102}
- JAVA_OPTS=-Xms256m -Xmx512m
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- ha-network
networks:
ha-network:
driver: bridge
volumes:
mysql_data:
redis_data:
nacos_logs:
rmqbroker_logs:
rmqbroker_store:
minio_data:
+196
View File
@@ -0,0 +1,196 @@
# ============================================================
# Node-03 Docker Compose 配置
# 从节点: MySQL Slave, Redis Slave, Nacos, NameServer, Broker-B, MinIO
# 仅部署基础设施,作为热备份节点
# 使用方式: docker compose --env-file config/.env.node-03 up -d
# ============================================================
services:
# ==================== 基础设施 ====================
mysql:
image: mysql:8.0
container_name: mysql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123456}
MYSQL_DATABASE: ${MYSQL_DATABASE:-video_platform}
MYSQL_USER: ${MYSQL_USER:-video}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-video123}
volumes:
- mysql_data:/var/lib/mysql
- ./config/mysql/my-slave.cnf:/etc/mysql/conf.d/my.cnf:ro
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --server-id=3
- --log-bin=mysql-bin
- --binlog-format=ROW
- --gtid-mode=ON
- --enforce-gtid-consistency=ON
- --read-only=ON
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD:-root123456}"]
interval: 10s
timeout: 5s
retries: 10
networks:
- ha-network
redis:
image: redis:7.0-alpine
container_name: redis
restart: always
ports:
- "6379:6379"
volumes:
- redis_data:/data
- ./config/redis/redis-slave.conf:/usr/local/etc/redis/redis.conf:ro
command: redis-server /usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-redis_HA_Cluster_2024}", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
redis-sentinel:
image: redis:7.0-alpine
container_name: redis-sentinel
restart: always
ports:
- "26379:26379"
volumes:
- ./config/redis/sentinel.conf:/usr/local/etc/redis/sentinel.conf:ro
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
depends_on:
redis:
condition: service_healthy
networks:
- ha-network
nacos:
image: nacos/nacos-server:v2.3.2
container_name: nacos
restart: always
ports:
- "8848:8848"
- "9848:9848"
- "9849:9849"
environment:
- MODE=cluster
- NACOS_SERVERS=${NACOS_SERVERS:-192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848}
- NACOS_SERVER_IP=${HOST_IP:-192.168.1.103}
- NACOS_APPLICATION_PORT=8848
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
- NACOS_AUTH_IDENTITY_KEY=serverIdentity
- NACOS_AUTH_IDENTITY_VALUE=security
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_DB_NAME=nacos_config
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=${MYSQL_ROOT_PASSWORD:-root123456}
- JVM_XMS=512m
- JVM_XMX=512m
volumes:
- nacos_logs:/home/nacos/logs
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/liveness"]
interval: 10s
timeout: 5s
retries: 10
depends_on:
mysql:
condition: service_healthy
networks:
- ha-network
rmqnamesrv:
image: apache/rocketmq:5.1.4
container_name: rmqnamesrv
restart: always
ports:
- "9876:9876"
environment:
- JAVA_OPT_EXT=-server -Xms256m -Xmx256m
command: sh mqnamesrv
healthcheck:
test: ["CMD", "sh", "-c", "nc -z localhost 9876"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
rmqbroker:
image: apache/rocketmq:5.1.4
container_name: rmqbroker
restart: always
ports:
- "10909:10909"
- "10911:10911"
- "10912:10912"
environment:
- NAMESRV_ADDR=${NAMESRV_ADDR:-192.168.1.101:9876;192.168.1.102:9876;192.168.1.103:9876}
- JAVA_OPT_EXT=-server -Xms512m -Xmx512m
volumes:
- ./config/rocketmq/broker-b.conf:/home/rocketmq/rocketmq-5.1.4/conf/broker.conf:ro
- rmqbroker_logs:/home/rocketmq/logs
- rmqbroker_store:/home/rocketmq/store
command: sh mqbroker -c /home/rocketmq/rocketmq-5.1.4/conf/broker.conf
depends_on:
rmqnamesrv:
condition: service_healthy
networks:
- ha-network
minio:
image: quay.io/minio/minio
container_name: minio
restart: always
ports:
- "9000:9000"
- "9001:9001"
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin123
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ha-network
sentinel:
image: sentinel-dashboard:1.8.6
container_name: sentinel
restart: always
ports:
- "8880:8080"
environment:
- JAVA_OPTS=-Xms128m -Xmx256m
- SERVER_PORT=8080
- DASHBOARD_SERVER=localhost:8080
- PROJECT_NAME=sentinel-dashboard
networks:
- ha-network
networks:
ha-network:
driver: bridge
volumes:
mysql_data:
redis_data:
nacos_logs:
rmqbroker_logs:
rmqbroker_store:
minio_data:
+529
View File
@@ -0,0 +1,529 @@
# Debian 12 高可用集群部署手册
## 一、环境准备
### 1.1 虚拟机配置要求
| 节点 | IP地址 | CPU | 内存 | 磁盘 | 操作系统 |
|------|--------|-----|------|------|----------|
| Node-01 | 192.168.1.101 | 4核 | 8GB | 100GB | Debian 12 (Bookworm) |
| Node-02 | 192.168.1.102 | 4核 | 8GB | 100GB | Debian 12 (Bookworm) |
| Node-03 | 192.168.1.103 | 4核 | 8GB | 100GB | Debian 12 (Bookworm) |
### 1.2 Debian 12 安装建议
下载地址: https://www.debian.org/distrib/
推荐使用 **Debian 12 Netinst** 最小化安装:
- 选择 "无图形界面" 安装
- 仅安装 SSH server 和标准系统工具
- 使用 LVM 分区,便于扩展
### 1.3 系统初始化
在每台虚拟机上执行以下操作:
```bash
# 切换到 root 用户
su -
# 上传 init-debian12.sh 脚本并执行
chmod +x init-debian12.sh
./init-debian12.sh
# 使环境变量生效
source /etc/profile
# 验证安装
java -version
mvn -version
docker --version
docker compose version
```
### 1.4 网络配置
#### 配置静态 IP
```bash
# 编辑网络配置
vim /etc/network/interfaces
# 添加以下内容 (根据实际网络调整)
# Node-01
# The primary network interface
auto ens33
iface ens33 inet static
address 192.168.1.101
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8 114.114.114.114
# 重启网络
systemctl restart networking
reboot
```
#### 配置主机名
```bash
# Node-01
hostnamectl set-hostname node-01
echo "192.168.1.101 node-01" >> /etc/hosts
echo "192.168.1.102 node-02" >> /etc/hosts
echo "192.168.1.103 node-03" >> /etc/hosts
# Node-02
hostnamectl set-hostname node-02
# 添加 hosts...
# Node-03
hostnamectl set-hostname node-03
# 添加 hosts...
```
#### 配置 SSH 免密登录
```bash
# 在 Node-01 生成密钥
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
# 分发公钥到其他节点
ssh-copy-id root@192.168.1.102
ssh-copy-id root@192.168.1.103
# 测试连接
ssh node-02 "hostname"
ssh node-03 "hostname"
```
---
## 二、部署步骤
### 2.1 克隆项目
```bash
# 在所有节点执行
cd /opt
git clone <项目地址> ha-ovp
cd ha-ovp
```
### 2.2 构建项目
```bash
# 在 Node-01 执行 (只需执行一次)
# 构建所有模块
mvn clean package -DskipTests
# 构建 Sentinel 镜像
cd sentinel-dashboard
docker build -t sentinel-dashboard:1.8.6 .
cd ..
# 验证构建产物
ls -la video-*/target/*.jar
```
### 2.3 同步构建产物
```bash
# 从 Node-01 同步到其他节点
rsync -avz --progress /opt/ha-ovp/ root@192.168.1.102:/opt/ha-ovp/
rsync -avz --progress /opt/ha-ovp/ root@192.168.1.103:/opt/ha-ovp/
```
### 2.4 启动服务
#### Node-01 启动 (主节点)
```bash
cd /opt/ha-ovp
# 启动所有服务
docker compose -f docker-compose-node-01.yml --env-file config/.env.node-01 up -d
# 查看日志
docker compose -f docker-compose-node-01.yml logs -f
```
#### Node-02 启动 (从节点)
```bash
cd /opt/ha-ovp
# 等待 Node-01 完全启动后 (约3分钟)
docker compose -f docker-compose-node-02.yml --env-file config/.env.node-02 up -d
# 查看日志
docker compose -f docker-compose-node-02.yml logs -f
```
#### Node-03 启动 (备份节点)
```bash
cd /opt/ha-ovp
# 启动基础设施
docker compose -f docker-compose-node-03.yml --env-file config/.env.node-03 up -d
```
### 2.5 初始化数据库
```bash
# 在 Node-01 执行,等待MySQL完全启动后
# 创建 Nacos 数据库并导入表结构
docker exec -i mysql mysql -uroot -proot123456 << 'EOF'
CREATE DATABASE IF NOT EXISTS nacos_config CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EOF
docker exec -i mysql mysql -uroot -proot123456 nacos_config < config/nacos-mysql.sql
# 导入业务数据库
docker exec -i mysql mysql -uroot -proot123456 < sql/init.sql
```
### 2.6 配置 MySQL 主从复制
```bash
# 在 Node-01 (主节点) 创建复制用户
docker exec mysql mysql -uroot -proot123456 << 'EOF'
CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl_password_2024';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
EOF
# 在 Node-02 和 Node-03 (从节点) 分别配置主从
docker exec mysql mysql -uroot -proot123456 << 'EOF'
CHANGE MASTER TO
MASTER_HOST='192.168.1.101',
MASTER_USER='repl',
MASTER_PASSWORD='repl_password_2024',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G
EOF
# 确认 Slave_IO_Running 和 Slave_SQL_Running 都为 Yes
```
### 2.7 配置 Redis 主从复制
```bash
# 在 Node-02 和 Node-03 执行
docker exec redis redis-cli -a redis_HA_Cluster_2024 REPLICAOF 192.168.1.101 6379
# 验证主从状态
docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication
```
### 2.8 配置 Nacos
访问 http://192.168.1.101:8848/nacos (账号: nacos/nacos)
1. 创建命名空间: `public`
2. 添加各服务的配置文件 (参考 `config/nacos-config/` 目录)
### 2.9 初始化 MinIO
```bash
# 安装 mc 客户端
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
mv mc /usr/local/bin/
# 配置别名 (注意端口是 9100)
mc alias set myminio http://192.168.1.101:9100 minioadmin minioadmin123
# 创建存储桶
mc mb myminio/video-platform --ignore-existing
# 设置公开访问策略
mc anonymous set download myminio/video-platform
# 验证
mc ls myminio
```
---
## 三、端口分配汇总
### 3.1 各节点端口分配
| 服务 | Node-01 | Node-02 | Node-03 | 说明 |
|------|---------|---------|---------|------|
| **MySQL** | 3306 | 3306 | 3306 | 数据库主从 |
| **Redis** | 6379 | 6379 | 6379 | 缓存主从 |
| **Redis Sentinel** | 26379 | 26379 | 26379 | 哨兵监控 |
| **Nacos** | 8848 | 8848 | 8848 | 配置中心集群 |
| **RocketMQ NameServer** | 9876 | 9876 | 9876 | NameServer集群 |
| **RocketMQ Broker** | - | 10911 | 10911 | Broker双主 |
| **MinIO API** | 9100 | 9100 | 9000 | 对象存储API |
| **MinIO Console** | 9101 | 9101 | 9001 | 对象存储控制台 |
| **Sentinel Dashboard** | 8880 | 8880 | 8880 | 熔断控制台 |
| **video-gateway** | 9000 | 9000 | - | API网关 |
| **video-auth** | 9001 | 9001 | - | 认证服务 |
| **video-user** | 9002 | 9002 | - | 用户服务 |
| **video-content** | 9003 | 9003 | - | 内容服务 |
| **video-comment** | 9004 | 9004 | - | 评论服务 |
| **video-recommend** | 9005 | 9005 | - | 推荐服务 |
| **video-admin** | 9006 | 9006 | - | 管理后台 |
| **Nginx** | 80 | - | - | 负载均衡 |
### 3.2 端口说明
- **MinIO 端口调整**: Node-01 和 Node-02 的 MinIO 端口改为 9100(API) 和 9101(Console),避免与微服务端口冲突
- **Node-03**: 仅部署基础设施,不部署微服务,作为热备份节点
---
## 四、验证部署
### 4.1 检查服务状态
```bash
# 检查 Docker 容器状态
docker ps
# 检查 Nacos 服务注册
curl http://192.168.1.101:8848/nacos/v1/ns/service/list
# 检查 MySQL 主从
docker exec mysql mysql -uroot -proot123456 -e "SHOW SLAVE STATUS\G" | grep Running
# 检查 Redis 主从
docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication | grep role
# 检查 Sentinel 状态
docker exec redis-sentinel redis-cli -p 26379 SENTINEL master mymaster
```
### 4.2 访问控制台
| 服务 | 地址 | 账号密码 |
|------|------|---------|
| Nacos | http://192.168.1.101:8848/nacos | nacos/nacos |
| Sentinel | http://192.168.1.101:8880 | sentinel/sentinel |
| MinIO Console | http://192.168.1.101:9101 | minioadmin/minioadmin123 |
| API Gateway | http://192.168.1.101:9000 | - |
### 4.3 API 测试
```bash
# 获取验证码
curl http://192.168.1.101:9000/auth/captcha
# 健康检查
curl http://192.168.1.101:9000/actuator/health
curl http://192.168.1.102:9000/actuator/health
```
---
## 五、高可用测试
### 5.1 测试服务故障转移
```bash
# 停止 Node-01 的网关
docker stop video-gateway
# 测试 API (应该自动切换到 Node-02)
curl http://192.168.1.102:9000/auth/captcha
# 恢复服务
docker start video-gateway
```
### 5.2 测试 Redis 主从切换
```bash
# 停止 Node-01 的 Redis
docker stop redis
# 查看 Sentinel 日志 (自动将从节点提升为主)
docker logs redis-sentinel
# 验证新的主节点
docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication
# 恢复 Redis (会自动变为从节点)
docker start redis
```
### 5.3 测试 Nacos 集群
```bash
# 停止 Node-01 的 Nacos
docker stop nacos
# 验证服务注册仍然可用
curl http://192.168.1.102:8848/nacos/v1/ns/service/list
# 恢复 Nacos
docker start nacos
```
---
## 六、常见问题
### Q1: Docker 镜像拉取失败
```bash
# 配置国内镜像源
vim /etc/docker/daemon.json
# 添加镜像加速器
# 重启 Docker
systemctl restart docker
```
### Q2: Nacos 集群无法启动
```bash
# 检查时间同步
apt-get install -y ntpdate
ntpdate pool.ntp.org
# 检查数据库连接
docker exec mysql mysql -uroot -proot123456 -e "SHOW DATABASES;"
```
### Q3: 内存不足
```bash
# 查看内存使用
free -h
# 调整 JVM 参数
# 编辑 config/.env.node-xx 文件中的 JAVA_OPTS
JAVA_OPTS=-Xms128m -Xmx256m
```
### Q4: 端口冲突
```bash
# 查看端口占用
ss -tlnp | grep -E '3306|6379|8848|9000|9002'
# 停止冲突服务
systemctl stop mysql
systemctl stop redis
```
---
## 七、日常运维
### 7.1 日志查看
```bash
# 查看服务日志
docker logs -f --tail 100 video-gateway
docker logs -f --tail 100 video-auth
# 查看所有服务状态
docker compose -f docker-compose-node-01.yml ps
```
### 7.2 服务重启
```bash
# 重启单个服务
docker restart video-gateway
# 重启所有服务
docker compose -f docker-compose-node-01.yml restart
```
### 7.3 数据备份
```bash
# MySQL 备份
docker exec mysql mysqldump -uroot -proot123456 --all-databases > backup_$(date +%Y%m%d).sql
# Redis 备份
docker exec redis redis-cli -a redis_HA_Cluster_2024 BGSAVE
docker cp redis:/data/dump.rdb redis_backup_$(date +%Y%m%d).rdb
# MinIO 备份
mc mirror myminio/video-platform minio_backup_$(date +%Y%m%d)
```
---
## 八、性能调优
### 8.1 JVM 调优
根据实际内存调整 JVM 参数:
```bash
# 8GB 内存服务器建议配置
JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:+UseG1GC
# 16GB 内存服务器建议配置
JAVA_OPTS=-Xms1g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+UseG1GC
```
### 8.2 MySQL 调优
```bash
# 编辑 MySQL 配置
vim config/mysql/my-master.cnf
# 关键参数
innodb_buffer_pool_size = 2G # 设置为物理内存的 50-70%
innodb_log_file_size = 512M
max_connections = 500
```
### 8.3 Redis 调优
```bash
# 编辑 Redis 配置
vim config/redis/redis-master.conf
# 关键参数
maxmemory 2gb
maxmemory-policy allkeys-lru
```
---
## 九、架构图
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 高可用集群架构 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ │ Node-01 │ │ Node-02 │ │ Node-03 │
│ │ 192.168.1.101 │ │ 192.168.1.102 │ │ 192.168.1.103 │
│ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ │ MySQL Master │ ──────▶ │ MySQL Slave │ ──────▶ │ MySQL Slave │
│ │ Redis Master │ ◀────── │ Redis Slave │ ◀────── │ Redis Slave │
│ │ Nacos Node1 │ ◀─────▶ │ Nacos Node2 │ ◀─────▶ │ Nacos Node3 │
│ │ NameServer │ │ NameServer │ │ NameServer │
│ │ MinIO :9100 │ │ Broker-A :10911 │ │ Broker-B :10911 │
│ │ Sentinel :8880 │ │ MinIO :9100 │ │ MinIO :9000 │
│ ├─────────────────┤ │ Sentinel :8880 │ │ Sentinel :8880 │
│ │ Gateway :9000 │ ├─────────────────┤ └─────────────────┘
│ │ Auth :9001 │ │ Gateway :9000 │ (备份节点)
│ │ User :9002 │ │ Auth :9001 │
│ │ Content :9003 │ │ User :9002 │
│ │ Comment :9004 │ │ Content :9003 │
│ │ Recommend :9005 │ │ Comment :9004 │
│ │ Admin :9006 │ │ Recommend :9005 │
│ │ Nginx :80 │ │ Admin :9006 │
│ └─────────────────┘ └─────────────────┘
│ (主节点) (从节点)
└─────────────────────────────────────────────────────────────────────────────┘
```
+39 -3
View File
@@ -50,10 +50,46 @@
<!-- 全局dependencies部分 -->
<dependencies>
<!-- 所有子模块共享的依赖 -->
<!-- Spring Boot Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- H2 Database for testing -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<!-- AssertJ -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.25.3</version>
<scope>test</scope>
</dependency>
</dependencies>
+7 -1
View File
@@ -12,5 +12,11 @@ RUN apt-get update && \
# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
# 创建启动脚本
RUN echo '#!/bin/sh\n\
exec java ${JAVA_OPTS} -Dserver.port=${SERVER_PORT:-8080} -Dcsp.sentinel.dashboard.server=${DASHBOARD_SERVER:-localhost:8080} -Dproject.name=${PROJECT_NAME:-sentinel-dashboard} -jar /sentinel-dashboard.jar\n\
' > /entrypoint.sh && chmod +x /entrypoint.sh
EXPOSE 8080
CMD ["java", "-Dserver.port=8080", "-Dcsp.sentinel.dashboard.server=localhost:8080", "-jar", "/sentinel-dashboard.jar"]
ENTRYPOINT ["/entrypoint.sh"]