Docker容器中部署高可用的前后端分离的Java Web项目
1 项目说明
1.1 项目运行效果
- 登录页面:
- 项目首页:
1.2 项目运行环境
- 运行环境版本说明:
环境名称 | 环境版本 | 环境说明 |
---|---|---|
Ubuntu | ubuntu-18.04.3-desktop-amd64 | 虚拟机操作系统 |
Docker | 19.03.5 | Docker容器版本 |
Java | 8 | 后端API服务运行环境 |
MySQL | latest | 存储数据库 |
Redis | latest | 缓存数据库 |
Nginx | latest | 前端Web服务运行环境 |
Haproxy | latest | 集群负载均衡工具软件 |
Keepalived | 虚拟高可用工具软件 |
1.3 项目组成架构
- 项目组成架构:该前端后分离的项目由一个高可用且具有负载均衡的MySQL存储服务集群,一个高可用的Redis缓存服务集群、一个高可用且具有负载均衡的API服务集群、一个高可用且具有负载均衡的Web服务集群组成。
1.4 项目部署总览
- 项目部署总览:
- 项目部署说明:所有的容器节点都部署在一台基于虚拟机的Ubuntu操作系统的Docker环境中,且都在同一个Docker网络中,因此所有容器节点之间可以相互访问。因为没有做容器内部虚拟IP和主机IP之间的映射,所以只能在基于虚拟机的Ubuntu操作系统中才能访问虚拟IP,而在虚拟机所在的宿主机中无法访问虚拟IP。而所有的容器节点都做了端口映射,把基于虚拟机的Ubuntu操作系统的指定端点映射到了容器节点的指定端点,所以可以通过特定方式在虚拟机所在的宿主机中访问容器节点。
2 准备工作
2.1 下载项目源代码
-
项目说明:本项目使用的是人人开源社区当中的renren-fast项目,该项目是开源的Java Web前后端分离项目,功能较为丰富,且具有较高的代码质量。后端是基于Spring Boot技术构建的Java项目,前端基于Vue.js和Element-UI组件开发。
-
下载地址:
https://www.renren.io/community/project
-
下载说明:访问上述地址后界面如下图所示,分别下载前端源码和后端源码。
2.2 创建Docker网络
- 项目网络说明:本次部署的高可用的前后端分离项目所涉及到的各个容器全部都在同一个Docker网络中,这样部署在该网络中的各个容器之间就可以相互访问。
- 创建Docker网络:
docker network create --subnet 172.20.0.0/16 net-renren
- 容器网络规划:这里列举了所有容器节点的IP,在创建容器节点时会指定IP地址。
节点类型 容器名称 容器IP 说明 PXC pxc-node1 172.20.0.2 MySQL工作节点 PXC pxc-node2 172.20.0.3 MySQL工作节点 PXC pxc-node3 172.20.0.4 MySQL工作节点 PXC haproxy-pxc1 172.20.0.11 MySQL集群负载均衡节点 PXC haproxy-pxc2 172.20.0.12 MySQL集群负载均衡节点 PXC 172.20.0.100 MySQL集群高可用的访问地址(虚拟IP地址) Redis redis-node1 172.20.1.2 Redis工作节点 Redis redis-node2 172.20.1.3 Redis工作节点 Redis redis-node3 172.20.1.4 Redis工作节点 Redis redis-node4 172.20.1.5 Redis工作节点 Redis redis-node5 172.20.1.6 Redis工作节点 Redis redis-node6 172.20.1.7 Redis工作节点 API api-node1 172.20.2.2 API工作节点 API api-node2 172.20.2.3 API工作节点 API api-node3 172.20.2.4 API工作节点 API nginx-api1 172.20.2.11 API集群负载均衡节点 API nginx-api2 172.20.2.12 API集群负载均衡节点 API 172.20.2.100 API服务集群高可用的访问地址(虚拟IP地址) Web web-node1 172.20.3.2 Web工作节点 Web web-node2 172.20.3.3 Web工作节点 Web web-node3 172.20.3.4 Web工作节点 Web nginx-web1 172.20.3.11 Web集群负载均衡节点 Web nginx-web2 172.20.3.12 Web集群负载均衡节点 Web 172.20.3.100 Web服务集群高可用的访问地址(虚拟IP地址)
2.3 查看本机IP地址
- 查看本机IP地址:使用 ip a 命令可以查看本机IP地址如下图所示,可知本机IP地址为192.168.0.114,后面会多次使用到这个地址。
3 搭建高可用的MySQL集群
3.1 搭建PXC集群
3.1.1 集群方案选择
- Republication方案:MySQL官方的Republication方案是单向同步、弱一致性的集群解决方案。
- PXC方案:PXC方案是双向同步、强一致性的集群解决方案。
- MySQL集群说明:此次使用的是PXC集群方案,搭建的PXC集群中包含三个PXC节点(一般建议集群的节点个数为大于1的奇数)。
3.1.2 拉取Docker镜像
- 拉取镜像:由于镜像名称太长,不便于书写,所以对镜像进行重命名。
docker pull percona/percona-xtradb-cluster:latest docker tag percona/percona-xtradb-cluster:latest pxc:latest docker rmi percona/percona-xtradb-cluster:latest
3.1.3 创建Docker数据卷
- 创建数据卷:
docker volume create pxc1 docker volume create pxc2 docker volume create pxc3
3.1.4 创建PXC容器
- 创建并启动pxc容器:该PXC集群中的三个节点的名称分别为pxc-node1、pxc-node2、pxc-node3,具体的创建命令信息如下所示。
# 创建名称为pxc-node1的pxc容器,该容器的ip地址为172.20.0.2,主机的3001端口映射到该容器的3306端口,用户名为root,密码为123456 docker run -d -p 3001:3306 -v pxc1:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e XTRABACKUP_PASSWORD=123456 \ -e CLUSTER_NAME=pxc-cluster \ --privileged --name=pxc-node1 --net=net-renren --ip=172.20.0.2 pxc:latest # 创建名称为pxc-node2的pxc容器,该容器的ip地址为172.20.0.3,主机的3002端口映射到该容器的3306端口,用户名为root,密码为123456 docker run -d -p 3002:3306 -v pxc2:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e XTRABACKUP_PASSWORD=123456 \ -e CLUSTER_NAME=pxc-cluster \ -e CLUSTER_JOIN=pxc-node1 \ --privileged --name=pxc-node2 --net=net-renren --ip=172.20.0.3 pxc:latest # 创建名称为pxc-node3的pxc容器,该容器的ip地址为172.20.0.4,主机的3003端口映射到该容器的3306端口,用户名为root,密码为123456 docker run -d -p 3003:3306 -v pxc3:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e XTRABACKUP_PASSWORD=123456 \ -e CLUSTER_NAME=pxc-cluster \ -e CLUSTER_JOIN=pxc-node1 \ --privileged --name=pxc-node3 --net=net-renren --ip=172.20.0.4 pxc:latest
- 查看PXC容器是否启动成功:执行 docker ps 命令可以查看已启动的容器列表,结果如下图所示,如果STATUS列显示为UP,则表示容器启动成功。
3.1.5 连接PXC容器
- 连接PXC容器:由创建pxc容器的命令可知,pxc-node1容器映射到主机的3001端口,连接用户名为 root,连接密码为 123456。在主机上使用Navicat for MySQL的客户端工具连接pxc-node1容器如下图所示,连接成功后以同样的方式分别连接pxc-node2容器和pxc-node3容器。
3.1.6 验证PXC集群
- 验证PXC集群:使用Navicat for MySQL客户端连接工具连接该PXC集群中的pxc-node1、pxc-node2、pxc-node这3三个节点,连接成功后如下图所示。如果在其中一个节点中创建一个数据库(数据库名称自定),然后刷新其它两个节点,如果在其它两个节点中也成功出现了新建的数据库,则表示集群中的各节点之间同步成功,即表示PXC集群创建成功。
3.2 实现集群负载均衡
3.2.1 集群负载均衡方案
- 集群负载均衡方案:本文通过haproxy技术来实现MySQL集群的负载均衡访问,创建的haproxy容器节点会把对MySQL集群的访问负载均衡到三个数据库节点上,默认选用了轮询的负载远程策略。负载均衡方案如下图所示:
3.2.2 拉取Docker镜像
- 拉取Haproxy镜像:
docker pull haproxy:latest
3.2.3 创建haproxy配置
-
配置文件:在 /home/soft/config/pxc/haproxy/haproxy-node1 目录和 /home/soft/config/pxc/haproxy/haproxy-node2 目录下各创建一个haproxy.cfg配置文件,两个配置文件内容完全相同,文件内容如下所示。
# Haproxy配置可分成为部分,这五部分不是必选的,可以根据需要进行配置: # global: 进程参数配置,通常和操作系统相关,只配置一次 # defaults: 默认参数配置,可以被用到frontend、backend、listen部分 # frontend: 接收请求的前端虚拟节点,可以根据规则直接指定具体使用的backend(可动态选择) # backend: 后端服务集群的配置,是真实的服务,一个backend对应一个或多个实体服务器 # listen: frontend和backend的组合体 ########## global参数配置 ########## global log 127.0.0.1 local0 err # 日志配置,使用rsyslog服务中local0日志设备(/var/log/local5),等级err chroot /usr/local/etc/haproxy # 当前工作目录 daemon # 守护进程运行 nbproc 1 # 进程数量 ########## defaults参数配置 ########## defaults mode http # 模式:默认{tcp:http:health},tcp是4层,http是7层,health只会返回ok,如果要让haproxy支持虚拟机,mode必须设为http log global # 日志配置 option httplog # 采用http日志格式 option dontlognull # 日志中不记录负载均衡的心跳检测记录 option http-server-close # 每次请求完毕后主动关闭http通道 option redispatch # 当serverId对应的服务器挂掉后,强制定向到其他健康的服务器 maxconn 4096 # 默认的最大连接数 retries 3 # 两次连接失败就认为是服务器不可用,也可以通过后面设置 timeout connect 5000ms # 连接超时 timeout server 50000ms # 服务器超时 timeout client 50000ms # 客户端超时 timeout check 5000ms # 心跳检测超时 balance roundrobin # 负载均衡算法:static-rr 权重, leastconn 最少连接, source 请求IP, 轮询 roundrobin ########## 监控界面配置 ########## listen admin_status mode http # 模式 bind 0.0.0.0:8888 # 监控端口 stats enable # 开启监控 stats uri /dbs # 统计页面url stats auth admin:123456 # 统计页面用户名和密码设置 stats realm Global\ statistics # 统计报告格式 stats refresh 30s # 统计页面自动刷新时间 option httplog # 采用http日志格式 ########## mysql负载均衡配置 ########## listen proxy-mysql mode tcp # 模式 bind 0.0.0.0:3306 # 监控端口 balance roundrobin # 负载均衡算法: static-rr 权重, leastconn 最少连接, source 请求IP, 轮询 roundr