diff --git a/.gitignore b/.gitignore index 5ff6309..5523a78 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ +local/ ### IntelliJ IDEA ### .idea/modules.xml diff --git a/config/.env.node-01 b/config/.env.node-01 new file mode 100644 index 0000000..272a576 --- /dev/null +++ b/config/.env.node-01 @@ -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 diff --git a/config/.env.node-02 b/config/.env.node-02 new file mode 100644 index 0000000..3bab818 --- /dev/null +++ b/config/.env.node-02 @@ -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 diff --git a/config/.env.node-03 b/config/.env.node-03 new file mode 100644 index 0000000..c27b2ae --- /dev/null +++ b/config/.env.node-03 @@ -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 diff --git a/config/mysql/my-master.cnf b/config/mysql/my-master.cnf new file mode 100644 index 0000000..3cdca48 --- /dev/null +++ b/config/mysql/my-master.cnf @@ -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 diff --git a/config/mysql/my-slave.cnf b/config/mysql/my-slave.cnf new file mode 100644 index 0000000..f7aeceb --- /dev/null +++ b/config/mysql/my-slave.cnf @@ -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 diff --git a/config/nacos-mysql.sql b/config/nacos-mysql.sql new file mode 100644 index 0000000..433a90b --- /dev/null +++ b/config/nacos-mysql.sql @@ -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 +); + diff --git a/config/nginx/conf.d/upstream.conf b/config/nginx/conf.d/upstream.conf new file mode 100644 index 0000000..81c6122 --- /dev/null +++ b/config/nginx/conf.d/upstream.conf @@ -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; +} diff --git a/config/nginx/nginx.conf b/config/nginx/nginx.conf new file mode 100644 index 0000000..a6f7296 --- /dev/null +++ b/config/nginx/nginx.conf @@ -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; + } +} diff --git a/config/redis/redis-master.conf b/config/redis/redis-master.conf new file mode 100644 index 0000000..b0a2291 --- /dev/null +++ b/config/redis/redis-master.conf @@ -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 diff --git a/config/redis/redis-slave.conf b/config/redis/redis-slave.conf new file mode 100644 index 0000000..0a03b8f --- /dev/null +++ b/config/redis/redis-slave.conf @@ -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 diff --git a/config/redis/sentinel.conf b/config/redis/sentinel.conf new file mode 100644 index 0000000..e2f9208 --- /dev/null +++ b/config/redis/sentinel.conf @@ -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 +# 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 +# sentinel announce-port + +# 其他配置 +protected-mode no +bind 0.0.0.0 diff --git a/config/rocketmq/broker-a.conf b/config/rocketmq/broker-a.conf new file mode 100644 index 0000000..dd8b4ee --- /dev/null +++ b/config/rocketmq/broker-a.conf @@ -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 diff --git a/config/rocketmq/broker-b.conf b/config/rocketmq/broker-b.conf new file mode 100644 index 0000000..4b7a43d --- /dev/null +++ b/config/rocketmq/broker-b.conf @@ -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 diff --git a/docker-compose-node-01.yml b/docker-compose-node-01.yml new file mode 100644 index 0000000..36c8f73 --- /dev/null +++ b/docker-compose-node-01.yml @@ -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: diff --git a/docker-compose-node-02.yml b/docker-compose-node-02.yml new file mode 100644 index 0000000..7fcd82c --- /dev/null +++ b/docker-compose-node-02.yml @@ -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: diff --git a/docker-compose-node-03.yml b/docker-compose-node-03.yml new file mode 100644 index 0000000..9a83c6b --- /dev/null +++ b/docker-compose-node-03.yml @@ -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: diff --git a/docs/DEBIAN12-DEPLOYMENT-GUIDE.md b/docs/DEBIAN12-DEPLOYMENT-GUIDE.md new file mode 100644 index 0000000..0953a0f --- /dev/null +++ b/docs/DEBIAN12-DEPLOYMENT-GUIDE.md @@ -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 │ +│ └─────────────────┘ └─────────────────┘ +│ (主节点) (从节点) +└─────────────────────────────────────────────────────────────────────────────┘ +``` diff --git a/pom.xml b/pom.xml index 852c1d0..45d17c7 100644 --- a/pom.xml +++ b/pom.xml @@ -50,10 +50,46 @@ + + - junit - junit - 4.13.2 + org.springframework.boot + spring-boot-starter-test + test + + + + + org.junit.jupiter + junit-jupiter + test + + + + + org.mockito + mockito-core + test + + + + org.mockito + mockito-junit-jupiter + test + + + + + com.h2database + h2 + test + + + + + org.assertj + assertj-core + 3.25.3 test diff --git a/sentinel-dashboard/Dockerfile b/sentinel-dashboard/Dockerfile index aa19d92..1cc9d0b 100644 --- a/sentinel-dashboard/Dockerfile +++ b/sentinel-dashboard/Dockerfile @@ -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"] \ No newline at end of file + +ENTRYPOINT ["/entrypoint.sh"]