购物商城系统搭建实战指南
GPMall商城系统搭建实战指南
一、项目概述与环境规划
1. 项目需求
搭建基于多技术栈的GPMall商城系统,核心实现高可用、高性能、可扩展的电商业务支撑,具体技术架构包含:
- 数据库层:MariaDB主从复制 + MyCat读写分离(提升数据库并发能力,避免单点故障)
- 中间件层:Zookeeper集群(分布式协调) + Kafka集群(消息队列,解耦业务模块)
- 缓存层:Redis(缓存高频访问数据,减轻数据库压力)
- 负载均衡层:Nginx(分发前端请求,实现应用集群负载均衡)
- 静态资源层:Httpd(部署项目资源与YUM源,提供文件服务)
2. 主机与服务规划
| 主机名 | IP地址 | 部署服务清单 | 核心角色 |
|---|---|---|---|
| node1 | 192.168.100.10 | Zookeeper、Kafka、MyCat、Redis、Nginx | 中间件核心节点 + 负载均衡节点 |
| node2/db1 | 192.168.100.20 | Zookeeper、Kafka、MariaDB(主库)、Java应用(Jar包) | 数据库主节点 + 应用服务节点 |
| node3/db2 | 192.168.100.30 | Zookeeper、Kafka、MariaDB(从库)、Java应用(Jar包) | 数据库从节点 + 应用服务节点 |
| node4 | 192.168.100.40 | Httpd、本地YUM源、项目资源存储 | 静态资源服务器 + YUM源服务器 |
3. 前置准备
- 操作系统:所有节点统一使用CentOS 7/8系统(确保内核版本≥3.10,避免兼容性问题)
- 网络配置:所有节点关闭防火墙(或开放必要端口,如2181、9092、3306、80、8066等),关闭SELinux:
# 关闭防火墙(临时+永久) systemctl stop firewalld && systemctl disable firewalld # 关闭SELinux(临时+永久) setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config - 工具准备:所有节点安装基础工具(如
vim、wget、lrzsz、net-tools),便于操作:yum -y install vim wget lrzsz net-tools
二、基础环境部署(node4节点:YUM源与Httpd服务)
node4作为统一资源服务器,需配置本地YUM源(供其他节点安装软件)和Httpd服务(存储项目资源),步骤如下:
1. 配置node4本地YUM源
本地YUM源基于系统ISO镜像构建,避免依赖外部网络,确保软件安装稳定性。
- 清空默认YUM源:删除系统自带的YUM仓库配置,避免冲突:
rm -rf /etc/yum.repos.d/* - 创建自定义YUM仓库配置文件:
vim /etc/yum.repos.d/server.repo - 写入YUM仓库配置(
baseurl指向ISO挂载路径):[aa] # 仓库ID(唯一,不能重复) name=aa1 # 仓库名称(自定义,便于识别) baseurl=file:///mnt # 仓库路径(ISO镜像挂载到/mnt目录) enabled=1 # 启用该仓库(1=启用,0=禁用) gpgcheck=0 # 关闭GPG校验(本地ISO源无需校验,生产环境建议开启) - 挂载ISO镜像:将系统ISO镜像挂载到
/mnt目录(需确保ISO已通过虚拟机挂载到node4):mount /dev/cdrom /mnt # /dev/cdrom为ISO镜像设备文件,部分系统可能为/dev/sr0- 验证挂载:执行
ls /mnt,若能看到Packages、repodata等目录,说明挂载成功。
- 验证挂载:执行
- 刷新YUM缓存:使新配置的YUM源生效:
yum clean all && yum makecache
2. 安装并启动Httpd服务
Httpd(Apache)用于提供HTTP服务,存储GPMall项目资源(如前端代码、软件包),供其他节点下载。
- 安装Httpd:
yum -y install httpd - 了解Httpd核心路径:
- 网页资源根目录:
/var/www/html/(项目静态文件需放在此目录) - 配置文件目录:
/etc/httpd/conf/(主配置文件httpd.conf) - 日志目录:
/var/log/httpd/(访问日志access_log、错误日志error_log)
- 网页资源根目录:
- 启动Httpd服务并设置开机自启:
systemctl start httpd # 启动服务 systemctl enable httpd # 设置开机自启(避免服务器重启后服务中断) - 验证Httpd服务:
- 执行
systemctl status httpd,若输出“active (running)”,表示服务正常。 - 在浏览器访问
http://192.168.100.40,若看到Httpd默认测试页面,说明服务可正常访问。
- 执行
3. 上传项目资源到node4
通过FTP工具(如FileZilla)或SCP命令,将GPMall项目资源(project4)上传到/var/www/html/目录,资源包含:
- 软件包:
gpmall-Cluster.tar.gz、kafka_2.11-1.1.1.tgz、Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz等 - 仓库目录:
gpmall-repo(包含项目所需的RPM包,供其他节点配置YUM源) - 前端文件:
dist(GPMall前端静态页面,后续部署到Nginx)
上传完成后,验证资源可访问:在其他节点执行curl http://192.168.100.40/gpmall-repo/,若能看到目录列表,说明资源上传成功。
三、其他节点YUM源配置(node1、node2、node3)
为确保node1、node2、node3能统一从node4获取软件包(避免版本不一致),需将它们的YUM源指向node4的gpmall-repo目录。
1. 清空默认YUM源
所有节点执行:
rm -rf /etc/yum.repos.d/*
2. 创建YUM仓库配置文件
所有节点执行:
vim /etc/yum.repos.d/server.repo
3. 写入YUM源配置(指向node4的Httpd服务)
[aa]
name=a1
baseurl=http://192.168.100.40/project4/gpmall-repo
enabled=1
gpgcheck=0
4. 刷新YUM缓存
所有节点执行:
yum clean all && yum makecache
- 验证:执行
yum list | grep mariadb,若能看到mariadb相关包,说明YUM源配置成功。
四、数据库主从复制部署(node2为主库,node3为从库)
数据库主从复制是实现读写分离的基础,核心作用是将主库的写操作同步到从库,避免主库单点故障,同时为后续MyCat读写分离提供数据节点。
1. 安装MariaDB(node2、node3)
MariaDB是MySQL的分支,兼容MySQL协议,性能更优,所有数据库节点执行:
yum -y install mariadb mariadb-server # 安装客户端与服务端
2. 启动MariaDB并设置开机自启(node2、node3)
systemctl restart mariadb # 启动服务(修改配置后需重启)
systemctl enable mariadb # 开机自启
- 验证:
systemctl status mariadb,确保服务状态为“active (running)”。
3. 数据库安全初始化(node2、node3)
MariaDB默认安装后安全性较低(无root密码、允许匿名登录),需通过mysql_secure_installation工具优化:
- 执行初始化命令:
mysql_secure_installation - 按以下步骤配置(括号内为操作说明):
- 提示“Enter current password for root (enter for none)”:直接回车(默认无密码)。
- 提示“Set root password?”:输入
y→ 输入密码(如123456)→ 再次确认密码。 - 提示“Remove anonymous users?”:输入
y(删除匿名用户,防止未授权访问)。 - 提示“Disallow root login remotely?”:输入
n(允许root远程登录,便于MyCat连接)。 - 提示“Remove test database and access to it?”:输入
y(删除默认test库,减少攻击面)。 - 提示“Reload privilege tables now?”:输入
y(立即重载权限表,使配置生效)。
4. 验证初始化结果(node2、node3)
执行以下命令登录数据库,若能成功登录,说明初始化完成:
mysql -uroot -p123456 # 用户名root,密码123456
- 登录后执行
show databases;,若能看到mysql、information_schema等系统库,验证成功。
5. 配置主库(node2/db1)
主库需开启二进制日志(用于记录写操作),并设置唯一server_id(主从复制标识)。
- 编辑MariaDB主配置文件:
vim /etc/my.cnf - 在
[mysqld]模块下添加以下配置:[mysqld] log_bin=mysql-bin # 开启二进制日志(日志文件名前缀) server_id=20 # 主库唯一ID(整数,范围1-2^32-1,需小于从库ID) - 重启MariaDB服务,使配置生效:
systemctl restart mariadb - 登录主库,授权复制用户与远程访问权限:
执行以下SQL:mysql -uroot -p123456-- 授权root用户远程访问(允许从任意IP操作所有库表,便于MyCat连接) grant all privileges on *.* to root@'%' identified by '123456'; -- 创建复制专用用户user(仅允许从从库IP(192.168.100.30)访问,权限最小化) grant replication slave on *.* to 'user'@'192.168.100.30' identified by '123456'; -- 刷新权限,使配置生效 flush privileges; - 查看主库状态(记录二进制日志信息,供从库配置使用):
输出示例(需记录show master status;File和Position值):File Position Binlog_Do_DB Binlog_Ignore_DB mysql-bin.000001 154
6. 配置从库(node3/db2)
从库需设置唯一server_id,并指向主库的复制信息(主库IP、复制用户、二进制日志文件)。
- 编辑MariaDB主配置文件:
vim /etc/my.cnf - 在
[mysqld]模块下添加以下配置:[mysqld] log_bin=mysql-bin # 可选(若需从库作为其他从库的主库,需开启;仅作为从库可关闭) server_id=30 # 从库唯一ID(需大于主库ID,且与其他节点不重复) - 重启MariaDB服务:
systemctl restart mariadb - 登录从库,授权root远程访问(与主库一致):
执行SQL:mysql -uroot -p123456grant all privileges on *.* to root@'%' identified by '123456'; flush privileges; - 配置从库指向主库(使用主库
show master status的输出信息):change master to master_host='192.168.100.20', # 主库IP(node2) master_user='user', # 复制专用用户(主库创建的user) master_password='123456', # 复制用户密码 master_log_file='mysql-bin.000001', # 主库二进制日志文件名(需与主库一致) master_log_pos=154; #注意154要与前文一致 # 主库二进制日志位置(需与主库一致) - 启动从库复制进程:
start slave; - 查看从库状态(验证主从复制是否正常):
关键验证项(需均为show slave status \G; # \G垂直输出,便于查看关键信息Yes):Slave_IO_Running: Yes(从库IO线程正常,负责读取主库二进制日志)Slave_SQL_Running: Yes(从库SQL线程正常,负责执行二进制日志中的SQL)- 若为
No,查看Last_IO_Error或Last_SQL_Error字段排查问题(如网络不通、密码错误、日志文件/位置不匹配)。
7. 主从复制功能测试
- 主库(node2)创建测试数据:
mysql -uroot -p123456 create database test; # 创建测试库 show databases; # 查看库列表(应包含test) - 从库(node3)验证数据同步:
mysql -uroot -p123456 show databases; # 应能看到主库创建的test库,说明同步成功
五、Zookeeper与Kafka集群部署(node1、node2、node3)参考上一章节
Zookeeper是分布式协调服务,用于Kafka集群的元数据管理(如主题、分区、Broker状态);Kafka是高吞吐量的消息队列,用于解耦GPMall的业务模块(如订单提交、库存更新)。
1. 前置条件:安装Java环境(所有节点)
Zookeeper和Kafka均基于Java开发,需安装JDK(推荐Java 8,避免版本兼容性问题):
yum -y install java java-devel # 安装JDK与开发工具
- 验证:
java -version,输出“openjdk version “1.8.0_xxx””即正常。
2. Zookeeper集群部署(node1、node2、node3)
(1)上传并解压Zookeeper安装包(以node1为例,同步到其他节点)
- 从node4下载Zookeeper安装包(或通过FTP上传):
wget http://192.168.100.40/gpmall-Cluster/zookeeper-3.4.8.tar.gz -P /root/ - 解压到
/usr/local/目录(推荐安装路径):tar -zxvf /root/zookeeper-3.4.8.tar.gz -C /usr/local/ - 创建软链接(简化路径,便于操作):
ln -s /usr/local/zookeeper-3.4.8 /usr/local/zookeeper
(2)配置Zookeeper集群(所有节点)
- 进入Zookeeper配置目录:
cd /usr/local/zookeeper/conf - 复制默认配置文件并改名(Zookeeper默认读取
zoo.cfg):cp zoo_sample.cfg zoo.cfg - 编辑
zoo.cfg(核心配置集群节点信息):
修改并添加以下内容:vim zoo.cfg# 数据存储目录(Zookeeper保存数据和日志的路径) dataDir=/usr/local/zookeeper/data # 客户端连接端口(默认2181) clientPort=2181 # 集群节点配置(server.N=IP:通信端口:选举端口,N为节点ID) server.1=192.168.100.10:2888:3888 server.2=192.168.100.20:2888:3888 server.3=192.168.100.30:2888:3888- 端口说明:
2888为集群内节点通信端口(Follower与Leader交互),3888为选举端口(节点选举Leader时使用)。
- 端口说明:
- 创建数据存储目录:
mkdir -p /usr/local/zookeeper/data
(3)设置节点ID(所有节点,与zoo.cfg的server.N对应)
Zookeeper通过myid文件识别节点ID,每个节点的ID需唯一:
- node1(server.1):
echo 1 > /usr/local/zookeeper/data/myid - node2(server.2):
echo 2 > /usr/local/zookeeper/data/myid - node3(server.3):
echo 3 > /usr/local/zookeeper/data/myid
(4)启动Zookeeper集群(所有节点)
- 启动Zookeeper服务:
/usr/local/zookeeper/bin/zkServer.sh start - 查看Zookeeper状态(验证集群角色):
/usr/local/zookeeper/bin/zkServer.sh status- 输出
Mode: leader:该节点为集群Leader(唯一,负责协调集群)。 - 输出
Mode: follower:该节点为集群Follower(负责接收客户端请求并同步Leader数据)。 - 若所有节点均为
Mode: standalone,说明集群配置异常(需检查myid、zoo.cfg、网络连通性)。
- 输出
3. Kafka集群部署(node1、node2、node3)
(1)上传并解压Kafka安装包(以node1为例,同步到其他节点)
- 从node4下载Kafka安装包:
wget http://192.168.100.40/gpmall-Cluster/kafka_2.11-1.1.1.tgz -P /root/ - 解压到
/usr/local/目录:tar -zxvf /root/kafka_2.11-1.1.1.tgz -C /usr/local/ - 创建软链接:
ln -s /usr/local/kafka_2.11-1.1.1 /usr/local/kafka
(2)配置Kafka集群(所有节点,核心修改3处)
-
进入Kafka配置目录:
cd /usr/local/kafka/config -
编辑
server.properties(Kafka核心配置文件):vim server.properties -
关键配置修改(根据节点不同调整
broker.id和listeners):配置项 说明 node1配置 node2配置 node3配置 broker.idKafka节点唯一ID(需与其他节点不重复) broker.id=1broker.id=2broker.id=3listeners客户端连接地址(IP:端口,需指定节点实际IP) listeners=PLAINTEXT://192.168.100.10:9092listeners=PLAINTEXT://192.168.100.20:9092listeners=PLAINTEXT://192.168.100.30:9092zookeeper.connect关联的Zookeeper集群地址(多个节点用逗号分隔) zookeeper.connect=192.168.100.10:2181,192.168.100.20:2181,192.168.100.30:2181同node1 同node1 log.dirsKafka消息日志存储路径(默认 /tmp/kafka-logs,可自定义)log.dirs=/usr/local/kafka/logs同node1 同node1 - 其他默认配置保持不变(如
num.partitions=1(默认分区数)、default.replication.factor=1(默认副本数))。
- 其他默认配置保持不变(如
-
创建日志存储目录(所有节点):
mkdir -p /usr/local/kafka/logs
(3)启动Kafka集群(所有节点)
- 后台启动Kafka服务(
-daemon表示后台运行,避免占用终端):/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties - 验证Kafka进程(所有节点):
jps # Java进程查看命令- 输出包含
Kafka进程,说明服务启动正常(同时会看到Zookeeper的QuorumPeerMain进程)。
- 输出包含
(4)Kafka集群功能测试
-
创建测试主题(在node1执行):
/usr/local/kafka/bin/kafka-topics.sh \ --create \ --zookeeper 192.168.100.10:2181 \ --replication-factor 1 \ # 副本数(建议生产环境设为2-3,确保数据冗余) --partitions 1 \ # 分区数(根据业务并发需求调整) --topic test # 主题名(自定义,如gpmall-order)- 输出“Created topic “test””,表示主题创建成功。
-
查看主题列表(在node2执行,验证集群同步):
/usr/local/kafka/bin/kafka-topics.sh \ --list \ --zookeeper 192.168.100.20:2181- 输出“test”,说明主题已同步到所有Kafka节点。
-
发送与接收消息(可选,验证通信):
- 启动生产者(node1,发送消息):
输入“hello kafka”并回车(发送消息)。/usr/local/kafka/bin/kafka-console-producer.sh \ --broker-list 192.168.100.10:9092 \ --topic test - 启动消费者(node2,接收消息):
/usr/local/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server 192.168.100.20:9092 \ --topic test \ --from-beginning # 从主题开头消费消息- 若能接收到“hello kafka”,说明Kafka集群通信正常。
- 启动生产者(node1,发送消息):
六、GPMall业务数据库导入(node2主库)
将GPMall的业务SQL脚本导入主库(node2),后续从库(node3)会自动同步,为应用提供数据支撑。
1. 上传SQL脚本到node2
直接拖过来gpmall.sql(或通过FTP上传):
2. 导入SQL脚本到主库
-
登录node2的MariaDB:
mysql -uroot -p123456 -
执行SQL导入操作:
create database gpmall; # 创建业务数据库(与脚本中的库名一致) use gpmall; # 切换到gpmall库 source /root/gpmall.sql; # 导入脚本(需确保脚本路径正确)- 导入过程中若提示“Query OK”,表示执行成功;若有错误,需检查脚本语法或数据库权限。
-
验证导入结果:
show tables; # 查看gpmall库中的表(应包含tb_address、tb_comment、tb_user等业务表) select count(*) from tb_user; # 示例:查询用户表数据量(确认数据导入) -
从库(node3)验证同步:
mysql -uroot -p123456 use gpmall; show tables; # 应能看到与主库一致的表,说明同步成功
七、MyCat读写分离部署(node1)
MyCat是开源的数据库中间件,核心功能是实现读写分离(写操作走主库,读操作走从库),提升数据库并发能力,同时对应用透明(应用只需连接MyCat,无需关心后端主从库)。
1. 上传并解压MyCat安装包(node1)
- 从node4下载MyCat安装包:
wget http://192.168.100.40/gpmall-Cluster/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -P /root/ - 解压到
/usr/local/目录:tar -zxvf /root/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/
2. 配置MyCat环境变量(node1)
设置MYCAT_HOME环境变量,便于执行MyCat命令:
- 编辑
/etc/profile文件:vim /etc/profile - 在文件末尾添加以下内容:
export MYCAT_HOME=/usr/local/mycat export PATH=$PATH:$MYCAT_HOME/bin # 可选,将MyCat命令加入系统PATH - 使环境变量立即生效:
source /etc/profile - 验证:
echo $MYCAT_HOME,输出“/usr/local/mycat”即正常。
3. 配置schema.xml(核心:定义读写分离规则)
schema.xml是MyCat的核心配置文件,用于定义逻辑库、数据节点、读写分离策略,需关联GPMall的gpmall数据库。
- 进入MyCat配置目录:
cd /usr/local/mycat/conf - 编辑
schema.xml(替换默认内容):vim schema.xml - 写入以下配置(关键参数已标注):
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"><!-- 逻辑库配置:name为逻辑库名(gpmall),关联数据节点dn1 --><schema name="gpmall" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1"></schema> <!-- 数据节点配置:关联物理数据库(gpmall)和数据主机(localhost1) --><dataNode name="dn1" dataHost="localhost1" database="gpmall" /> <!-- 数据主机配置:定义读写分离策略、数据库类型、连接信息 --><dataHost name="localhost1" maxCon="1000" # 最大连接数minCon="10" # 最小连接数balance="3" # 读写分离策略(3=所有读操作走从库,写操作走主库)dbType="mysql" # 数据库类型(MySQL/MariaDB)dbDriver="native" # 驱动类型(native=原生JDBC驱动)writeType="0" # 写操作策略(0=所有写操作走第一个writeHost)switchType="1" # 故障切换策略(1=自动切换,主库故障时切换到备用写节点)slaveThreshold="100"> # 从库读负载阈值(超过阈值则切换其他从库)<!-- 心跳检测:通过执行select user()验证数据库连通性 --><heartbeat>select user()</heartbeat><!-- 写节点(主库node2):host为节点名,url为主库IP:端口,user/password为主库root账号 --><writeHost host="hostM1" url="192.168.100.20:3306" user="root" password="123456"><!-- 读节点(从库node3):嵌套在writeHost下,指定从库IP:端口 --><readHost host="hostS1" url="192.168.100.30:3306" user="root" password="123456" /></writeHost></dataHost> </mycat:schema>
4. 配置server.xml(定义MyCat访问账号)
server.xml用于配置MyCat的客户端访问账号、密码及关联的逻辑库,需删除默认配置并添加自定义账号。
- 编辑
server.xml:vim server.xml - 删除默认的
root用户配置(如下内容):<user name="root"><property name="password">user</property><property name="schemas">TESTDB</property><property name="readOnly">true</property> </user> - 添加新的
root用户配置(关联逻辑库gpmall,密码123456):<user name="root"><property name="password">123456</property> <!-- MyCat访问密码 --><property name="schemas">gpmall</property> <!-- 关联的逻辑库(与schema.xml一致) --><!-- 可选:添加只读账号,设置<property name="readOnly">true</property> --> </user>
5. 启动MyCat服务(node1)
- 启动MyCat(默认前台启动,日志输出到控制台;生产环境可加
&后台启动):/usr/local/mycat/bin/mycat start- MyCat命令说明:
start(启动)、stop(停止)、restart(重启)、status(查看状态)。
- MyCat命令说明:
- 验证MyCat端口(MyCat默认开放2个端口):
ss -anlt | grep -E "8066|9096"8066:数据端口(客户端连接MyCat执行SQL操作,类似MySQL的3306)。9066:管理端口(用于管理MyCat集群,如查看数据源状态)。- 若能看到两个端口处于“LISTEN”状态,说明MyCat启动正常。
6. 验证MyCat读写分离功能
(1)安装MariaDB客户端(node1,用于连接MyCat)
yum -y install MariaDB-client
(2)连接MyCat数据端口(8066),测试读写操作
- 连接MyCat:
mysql -h127.0.0.1 -P8066 -uroot -p123456 # -h为MyCatIP,-P为数据端口 - 执行SQL操作(验证读写分离):
show databases; # 应显示逻辑库gpmall(而非物理库) use gpmall; # 切换到逻辑库 show tables; # 应显示gpmall库中的业务表(与主库一致)-- 写操作(插入数据,会路由到主库node2) insert into tb_company (id, name, addr) values (1, "gpmall", "beijing");-- 读操作(查询数据,会路由到从库node3) select * from tb_company;- 验证主从同步:在node3的MariaDB中执行
select * from tb_company;,应能看到插入的数据,说明写操作已同步到从库。
- 验证主从同步:在node3的MariaDB中执行
(3)连接MyCat管理端口(9066),查看数据源状态
- 连接MyCat管理端口:
mysql -h127.0.0.1 -P9066 -uroot -p123456 - 查看数据源状态(验证读写节点是否正常):
输出示例(关键列说明):show @@datasource;DATANODE NAME TYPE HOST PORT W/R ACTIVE IDLE dn1 hostM1 mysql 192.168.100.20 3306 W 0 10 dn1 hostS1 mysql 192.168.100.30 3306 R 0 10 W/R列:W表示写节点(主库),R表示读节点(从库)。ACTIVE/IDLE列:活跃连接数/空闲连接数,均为正常数值说明数据源可用。
八、Redis缓存部署(node1)
Redis是高性能的内存数据库,用于缓存GPMall的高频访问数据(如用户会话、商品列表、热点商品库存),减轻数据库压力,提升系统响应速度。
1. 安装Redis(node1)
yum -y install redis
2. 配置Redis(允许远程访问)
默认Redis仅允许本地访问,需修改配置文件,使应用节点(node2、node3)能连接。
- 编辑Redis配置文件:
vim /etc/redis.conf - 关键配置修改:
- 注释
bind 127.0.0.1(默认只允许本地访问,注释后允许所有IP访问):# bind 127.0.0.1 - 关闭保护模式(
protected-mode设为no,允许远程连接):protected-mode no - 可选:设置Redis密码(生产环境建议开启,添加
requirepass 123456,密码自定义)。
- 注释
3. 启动Redis并设置开机自启
systemctl restart redis # 重启服务(使配置生效)
systemctl enable redis # 开机自启
4. 验证Redis服务
-
查看Redis端口(默认6379):
ss -anlt | grep 6379- 输出“LISTEN 0 128 *:6379 :”,表示服务正常且允许远程访问。
-
测试Redis连接(本地或远程节点):
redis-cli -h 192.168.100.10 # 远程连接Redis(-h为Redis节点IP) set test_key "gpmall_redis" # 设置键值对 get test_key # 获取值,输出"gpmall_redis"即正常 exit # 退出Redis客户端
九、Java应用集群部署(node2、node3)
GPMall应用以Java Jar包形式部署(如用户服务、购物服务),node2和node3作为应用节点,通过集群实现高可用,后续由Nginx负载均衡分发请求。
1. 上传应用Jar包到node2、node3
从node4下载应用Jar包(或通过FTP上传),需上传的Jar包包括:
user-provider-0.0.1-SNAPSHOT.jar(用户服务提供者)shopping-provider-0.0.1-SNAPSHOT.jar(购物服务提供者)gpmall-user-0.0.1-SNAPSHOT.jar(用户应用服务)gpmall-shopping-0.0.1-SNAPSHOT.jar(购物应用服务)
上传命令(以node2为例):
wget http://192.168.100.40/gpmall-Cluster/user-provider-0.0.1-SNAPSHOT.jar -P /root/
wget http://192.168.100.40/gpmall-Cluster/shopping-provider-0.0.1-SNAPSHOT.jar -P /root/
wget http://192.168.100.40/gpmall-Cluster/gpmall-user-0.0.1-SNAPSHOT.jar -P /root/
wget http://192.168.100.40/gpmall-Cluster/gpmall-shopping-0.0.1-SNAPSHOT.jar -P /root/
- node3执行相同命令,确保Jar包同步。
2. 启动应用Jar包(node2、node3)
使用nohup命令后台启动Jar包(避免终端关闭后服务停止),并将日志输出到nohup.out文件。
(1)node2启动应用
# 启动用户服务提供者(端口8082,具体端口以应用配置为准)
nohup java -jar /root/user-provider-0.0.1-SNAPSHOT.jar &
# 启动购物服务提供者(端口8081)
nohup java -jar /root/shopping-provider-0.0.1-SNAPSHOT.jar &
# 启动用户应用服务(依赖用户服务提供者)
nohup java -jar /root/gpmall-user-0.0.1-SNAPSHOT.jar &
# 启动购物应用服务(依赖购物服务提供者)
nohup java -jar /root/gpmall-shopping-0.0.1-SNAPSHOT.jar &
(2)node3启动应用(与node2一致)
nohup java -jar /root/user-provider-0.0.1-SNAPSHOT.jar &
nohup java -jar /root/shopping-provider-0.0.1-SNAPSHOT.jar &
nohup java -jar /root/gpmall-user-0.0.1-SNAPSHOT.jar &
nohup java -jar /root/gpmall-shopping-0.0.1-SNAPSHOT.jar &
3. 验证应用启动状态
-
查看Java进程(所有应用节点):
jps- 输出包含多个
jar进程(如3970 jar、3925 jar),说明应用启动正常。
- 输出包含多个
-
验证应用端口(以8081、8082为例):
ss -anlt | grep -E "8081|8082"- 若能看到端口处于“LISTEN”状态,说明应用服务正常对外提供服务。
-
查看应用日志(排查启动错误):
tail -f nohup.out # 实时查看日志,若无报错(如数据库连接失败、Redis连接失败),说明应用正常。
十、Nginx负载均衡部署(node1)
Nginx作为前端请求入口,核心作用是将用户请求分发到后端应用集群(node2、node3),实现负载均衡,同时提供静态资源服务(GPMall前端页面)。
1. 安装Nginx(node1)
yum -y install nginx
2. 部署前端静态页面(dist目录)
- 使用fz传输
dist目录到node1的/root/目录: - 将
dist目录下的静态文件复制到Nginx的网页根目录(/usr/share/nginx/html/):rm -rf /usr/share/nginx/html/* # 清空默认页面(避免冲突) cp -rvf /root/dist/* /usr/share/nginx/html/ # 复制前端文件 - 验证静态文件:
ls /usr/share/nginx/html/,应包含index.html、static等文件。
3. 配置Nginx负载均衡(核心:关联应用集群)
编辑Nginx默认配置文件,添加负载均衡规则,将/user、/shopping、/cashier路径的请求分发到对应的应用集群。
- 进入Nginx配置目录:
cd /etc/nginx/conf.d - 编辑
default.conf文件:vim default.conf - 写入以下配置(关键:定义upstream集群与请求转发规则):
# 1. 定义用户服务集群(关联node2、node3的8082端口)顶部添加 upstream myuser {server 192.168.100.20:8082; # node2的用户服务端口server 192.168.100.30:8082; # node3的用户服务端口ip_hash; # 负载均衡策略(基于IP哈希,确保同一用户请求到同一应用节点,保持会话) }# 2. 定义购物服务集群(关联node2、node3的8081端口) upstream myshopping {server 192.168.100.20:8081; # node2的购物服务端口server 192.168.100.30:8081; # node3的购物服务端口ip_hash; # 同上述策略 }# 3. 定义收银服务集群(关联node2、node3的8083端口) upstream mycashier {server 192.168.100.20:8083; # node2的收银服务端口server 192.168.100.30:8083; # node3的收银服务端口ip_hash; # 同上述策略 }# 4. 虚拟主机配置(处理前端请求) server {listen 80; # Nginx默认监听80端口(HTTP端口)server_name localhost; # 服务器名(生产环境可改为域名,如www.gpmall.com)# 4.1 处理前端静态资源请求(根路径/)location / {root /usr/share/nginx/html; # 静态资源根目录index index.html index.htm; # 默认首页try_files $uri $uri/ /index.html; # 解决SPA(单页应用)路由问题}# 4.2 处理用户服务请求(/user路径转发到myuser集群)location /user {proxy_pass http://myuser; # 转发到用户服务集群# 传递客户端原始信息(如IP、Host,便于应用获取真实客户端IP)proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}# 4.3 处理购物服务请求(/shopping路径转发到myshopping集群)location /shopping {proxy_pass http://myshopping; # 转发到购物服务集群proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}# 4.4 处理收银服务请求(/cashier路径转发到mycashier集群)location /cashier {proxy_pass http://mycashier; # 转发到收银服务集群proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}# 4.5 错误页面配置(可选)error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;} }
4. 验证Nginx配置语法
nginx -t
- 输出“nginx: configuration file /etc/nginx/nginx.conf test is successful”,表示配置语法正确。
5. 启动Nginx并设置开机自启
systemctl restart nginx # 重启Nginx(使配置生效)
systemctl enable nginx # 开机自启
6. 验证Nginx服务
-
查看Nginx端口(默认80):
ss -anlt | grep 80- 输出“LISTEN 0 128 *:80 :”,表示服务正常。
-
访问GPMall商城(客户端浏览器):
- 在浏览器输入
http://192.168.100.10(Nginx节点IP)。 - 若能看到GPMall前端首页(如登录页、商品列表页),说明静态资源部署正常。
- 测试功能:输入账号密码登录(需确保数据库中存在测试账号),若能登录并查看商品,说明Nginx负载均衡与应用集群联动正常。
- 在浏览器输入
十一、整体功能验证与故障排查
1. 核心功能验证清单
| 功能模块 | 验证操作 | 预期结果 |
|---|---|---|
| 数据库主从 | node2创建表/插入数据,node3查看 | node3同步node2的数据 |
| MyCat读写分离 | 连接MyCat 8066端口插入数据,node2/node3查看 | 写操作走node2,读操作走node3 |
| Kafka消息队列 | 创建主题、发送/接收消息 | 消息正常生产与消费 |
| Redis缓存 | 应用写入缓存,Redis客户端查看 | 缓存数据正常存储与读取 |
| Nginx负载均衡 | 多次访问http://192.168.100.10,查看node2/node3日志 | 请求均匀分发到两个应用节点 |
| 前端功能 | 登录、浏览商品、下单 | 操作无报错,数据正常展示与提交 |
2. 常见故障排查方法
- 数据库主从同步失败:查看
show slave status \G的Last_IO_Error,检查主库IP、复制用户密码、二进制日志文件/位置是否正确。 - MyCat连接失败:检查MyCat端口(8066/9066)是否开放,主从库是否正常,
schema.xml中url、user、password是否正确。 - 应用启动失败:查看
nohup.out日志,排查数据库/Redis/Kafka连接配置是否正确(如IP、端口、密码)。 - Nginx 404错误:检查静态文件路径是否正确(
/usr/share/nginx/html/),负载均衡配置中的proxy_pass路径是否与应用接口匹配。 - Kafka主题创建失败:检查Zookeeper集群是否正常(
zkServer.sh status),Kafka配置中的zookeeper.connect是否正确。
十二、总结
本指南基于“数据库主从+读写分离、Zookeeper+Kafka、Redis、Nginx负载均衡”技术栈,完成了GPMall商城系统的全流程部署。系统架构具备以下特点:
- 高可用:数据库主从、应用集群、Zookeeper/Kafka集群均避免单点故障。
- 高性能:MyCat读写分离分散数据库压力,Redis缓存高频数据,Nginx负载均衡分发请求。
- 可扩展:各模块独立部署,可根据业务需求横向扩展(如增加应用节点、Kafka节点)。
后续可基于此架构进行优化,如:
- 数据库:引入分库分表(MyCat支持),应对海量数据。
- 缓存:Redis集群化,提升缓存容量与可用性。
- 监控:添加Prometheus+Grafana监控,实时监控各模块状态。
- 安全:配置HTTPS(Nginx支持),加密传输数据;数据库/Redis添加密码,限制访问IP。
