Docker环境下的前后端分离项目部署与运维 第1章 RR开源前后端分离项目
第2章 RR开源前后端分离项目下载与配置 2.1 项目描述
项目地址: https://gitee.com/renrenio
2.2 后端项目下载与配置
下载后台源码,
后端:https://gitee.com/renrenio/renren-fast.git
前端:https://gitee.com/renrenio/renren-fast-vue.git
使用IDEA打开后端,Webstrom或者VScode打开前端
新建数据库renren_fast 后端项目打开之后将mysql.sql导入数据库
导入数据库后运行该项目,访问 http://localhost:8080/renren-fast/swagger/index.html
2.3 前台项目的下载与配置
1 2 3 4 5 6 安装node.js 安装依赖&运行项目 cd 工程目录 npm install npm run dev
1 2 3 4 5 6 7 8 9 10 11 firewall-cmd --permanent --add-port=8080-8085/tcp firewall-cmd --reload firewadd-cmd --permanent --remove-port=8080=8085/tcp # 查看防火墙开启的端口号是 firewall-cmd --permanent --list-ports # 查看有哪些服务通过防火墙连接了互联网 firewall-cmd --permanent --list-services
1 2 3 4 # 导入导出镜像 docker save java > /home/java.tar.gz docker load < /home/java.tar.gz
第3章 搭建MySQL集群 单节点数据库的弊端
大型互联网程序用户群体庞大,所以架构必须要特殊设计
单节点的数据库无法满足性能上的要求
单节点的数据库没有冗余设计,无法满足高可用
3.1 常见MySQl集群方案
mysql 集群方案介绍,建议使用pxc,因为弱一致性会有问题,比如说a节点数据库显示我购买成功,b 节点数据库显示没有成功,这就麻烦了,pxc 方案是在全部节点都写入成功之后才会告诉你成功,是可读可写双向同步的,但是replication是单向的,不同节点的数据库之间都会开放端口进行通讯,如果从防火墙的这个端口关闭,pxc就不会同步成功,也不会返给你成功了。
PXC集群示意图
PXC集群同步是双向的在任何一个节点写入数据,都会同步到其他节点中。在一个节点写入数据会同步到第二个,第三个,第四个节点中去。在任何一个节点上都是可以同时读写数据的,Replication同步数据时单向的,无法做到任何一个节点同时读写数据
Replication集群示意图
负责写入数据的节点叫做master,我们在master上写入数据,因为同步是单向的,数据会同步到另外一个节点上。这个节点比如说叫做slave节点,那么这个节点是可以读取到数据的。因为数据同步是单向的,那么这个数据不会同步到Master节点中。Replication同步数据时单向的,导致不是每一个节点都是可以同时读写的
PXC数据的强一致性 同步复制,事务在所有节点要么同时提交,要么不提交
Replication采用异步复制,无法保证数据的一致性
3.2 创建MySQL集群 安装PXC镜像 1 2 3 4 5 6 7 8 # 安装PXC镜像 docker pull percona/percona-xtradb-cluster # 为PXC镜像改名(因为原来的名字有点长) docker tag percona/percona-xtradb-cluster pxc # 删除原来的镜像 docker rmi percona/percona-xtradb-cluster
创建内部网络 出于安全考虑,需要给PXC集群实例创建Docker内部网络
1 2 3 4 5 6 7 docker network create net1 # 这个网段相关的信息 docker network inspect net1 # 删除网段 docker network rm net1
Docker 内置的网段 172.17.0.XX
自己创建的网段 172.18.0.XX 、172.19.0.XX 以此类推
也可以自定义网段
1 docker network create --subnet=172.18.0.0/24 net1
创建Docker卷 容器中的PXC节点映射数据目录的解决办法
1 2 3 4 # --name 可以省略 docker volume create --name v1 docker volume rm v1
3.3 创建PXC容器 创建5个数据卷
1 2 3 4 5 docker volume create --name v1 docker volume create --name v2 docker volume create --name v3 docker volume create --name v4 docker volume create --name v5
只要向PXC镜像传入运行参数就能创建出PXC容器
容器的创建非常快,但是容器中mysql的初始话不是一瞬间就完成的,MySQL数据库的初始话至少要2分钟以上,如果第一个PXC容器里的MySQL没有初始话成功,就创建第二个PXC容器,第二个PXC容器会闪退,因为第二个里面的mysql和第一个里面的mysql做同步的时候,他发现第一个容器里得MySQL没有启动,他就会出现一些故障,导致第二个PXC容器闪退,所以必须第1个MySQL节点启动成功,用MySQL客户端能连接上之后,再去创建其他MySQL节点。
1 2 3 4 5 6 7 8 9 10 # 创建第1个MySQL节点 docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc # 创建第2个MySQL节点 docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v2:/var/lib/mysql --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc # 创建第3个MySQL节点 docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v3:/var/lib/mysql --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc # 创建第4个MySQL节点 docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v4:/var/lib/mysql --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc # 创建第5个MySQL节点 docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v5:/var/lib/mysql --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc
node1节点成功启动,node2节点启动时报错:New joining cluster node didn‘t find all needed SSL artifacts
解决方案:https://www.cnblogs.com/nhdlb/p/14046323.html
PXC8.0官方说明:https://www.percona.com/doc/percona-xtradb-cluster/8.0/howtos/upgrade_guide.html
官网描述:https://www.percona.com/doc/percona-xtradb-cluster/8.0/security/encrypt-traffic.html#ssl-auto-conf
解决方案属实有点小麻烦,我选择放弃采用5.7版本….
1 2 3 4 5 6 7 8 // 拉取PXC docker pull percona/percona-xtradb-cluster:5.7.21 // 修改镜像名称为PXC docker tag percona/percona-xtradb-cluster:5.7.21 pxc // 删除原来的percona/percona-xtradb-cluster镜像 docker rmi percona/percona-xtradb-cluster:5.7.21
全部启动后
在其中一个节点中新建数据库,新建表,然后增加一条字段会同步到所有节点中
3.4 数据库负载均衡 数据库负载均衡的必要性 负载均衡首先是数据库的集群,加入5个集群,每次请求都是第一个的话,有可能第一个数据库就挂掉了,所以更优的方案是对不同的节点都进行请求,这就需要有中间件进行转发,比较好的中间件有nginx,haproxy等,因nginx 支持插件,但是刚刚支持了tcp/ip 协议,haproxy 是一个老牌的中间转发件。如果要用haproxy的话,可以从官方下载镜像,然后呢对镜像进行配置(自己写好配置文件,因为这个镜像是没有配置文件的,配置好之后再运行镜像的时候进行文件夹的映射,配置文件开放3306(数据库请求,然后根据check心跳检测访问不同的数据库,8888 对数据库集群进行监控))。配置文件里面设置用户(用户在数据库进行心跳检测,判断哪个数据库节点是空闲的,然后对空闲的进行访问),还有各种算法(比如轮训),最大连接数,时间等,还有对集群的监控。配置文件写好以后运行这个镜像,镜像运行成功后进入容器启动配置文件 。其实haprocy返回的也是一个数据库实例(但是并不存储任何的数据,只是转发请求),这个实例用来check其他节点。最好生成至少两个这样的实例。当一个挂掉的时候,另外 一个可以顶上(这就是双机热备见下一节)。
安装Haproxy
创建Haproxy的配置文件
1 touch /home/soft/haproxy/haproxy.cfg
配置文件详情可以参考 https://zhangge.net/5125.html
配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 global # 工作目录 chroot /usr/local/etc/haproxy # 日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info log 127.0.0.1 local5 info # 守护进程运行 daemon defaults log global mode http # 日志格式 option httplog # 日志中不记录负载均衡的心跳检测记录 option dontlognull #连接超时(毫秒) timeout connect 5000 #客户端超时(毫秒) timeout client 50000 # 服务器超时(毫秒) timeout server 50000 # 监控界面 listen admin_stats # 监控界面的访问的IP和端口 bind 0.0.0.0:8888 # 访问协议 mode http # URI相对地址 stats uri /dbs # 统计报告格式 stats realm Global\ statistics # 登陆帐户信息 stats auth admin:abc123456 # 数据库负载均衡 listen proxy-mysql # 访问的IP和端口 bind 0.0.0.0:3306 #网络协议 mode tcp # 负载均衡算法(轮询算法) # 轮询算法:roundrobin # 权重算法:static-rr # 最少连接算法:leastconn # 请求源IP算法:source balance roundrobin # 日志格式 option tcplog # 在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测 option mysql-check user haproxy server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000 server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000 server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000 server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000 server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000 # 使用keepalive检测死链 option tcpka
创建Haproxy容器 1 2 3 4 5 6 7 # 创建第1个Haproxy负载均衡服务器 docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=net1 --ip 172.18.0.7 haproxy # 进入h1容器 docker exec -it h1 bash # 启动Haproxy haproxy -f /usr/local/etc/haproxy/haproxy.cfg
在数据库节点中新增haproxy用户,Haproxy使用这个账户对MySQL数据库心跳检测
1 create user 'haproxy'@'%' identified by ''
测试 直接访问ip:4001/dbs 账号:admin 密码: abc123456
节点状态都正常
1 2 # 将一个节点挂掉之后 docker stop node1
使用客户端连接Haproxy 端口号为之前映射的4002
新增一条数据会同步到所有节点
3.5 负载均衡的高可用方案 为什么要采用双机热备 双机就是两个请求处理程序,比如两个haproxy,当一个挂掉的时候,另外 一个可以顶上。热备我理解就是keepalive。在haproxy 容器中安装keepalive。
关键就是虚拟ip,定义一个虚拟ip,然后比如两个haproxy分别安装keepalive镜像,因为haproxy是ubuntu系统的,所以安装用apt-get,keepalive是作用是抢占虚拟ip,抢到的就是主服务器,没有抢到的就是备用服务器,然后两个keepalive进行心跳检测(就是创建一个用户到对方那里试探,看是否还活着,mysql的集群之间也是心跳检测),如果 挂掉抢占ip。所以在启动keepalive 之前首先要编辑好他的配置文件,怎么抢占,权重是什么,虚拟ip是什么,创建的用户交什么。配置完启动完以后可以ping一下看是否正确.
然后将虚拟ip映射到局域网的ip
实现Haproxy双机热备离不开虚拟Ip的技术
利用Keepalived实现双机热备
Haproxy双机热备方案
安装Keepalived Keepalived必须安装在Haproxy所在的容器之内
1 2 apt-get update apt-get install keepalived
Keepalived配置文件 Keepalived的配置文件时/etc/keepalived/keepalived.conf
1 2 3 4 5 6 7 8 9 10 11 interface 网卡设备 virtual_router_id 虚拟路径标识 MASTER和BACKUP的虚拟路由标识必须一致。标识可以是0-255 priority MASTER权重要搞域BACKUP 数字越大优先级越高 advert_int MASTER与BACKUP节点间同步检查的时间间隔,单位为秒,主备之间必须一致 authentication 心跳检测需要登录到Keepalived节点,主从服务器验证方式,主备必须使用相同的密码才能正常通信 virtual_ipaddress xuniIP地址,而可以设置多个虚拟IP地址,每行一个
advert
搭建双击热备
安装Haproxy镜像
宿主机上编写Haproxy配置文件
1 vi /home/soft/haproxy.cfg
配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 global chroot /usr/local/etc/haproxy log 127.0.0.1 local5 info daemon defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 listen admin_stats bind 0.0.0.0:8888 mode http stats uri /dbs stats realm Global\ statistics stats auth admin:abc123456 listen proxy-mysql bind 0.0.0.0:3306 mode tcp balance roundrobin option tcplog option mysql-check user haproxy server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000 server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000 server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000 server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000 server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000 option tcpka
创建两个Haproxy容器
1 2 3 4 5 6 7 8 9 10 11 12 13 # 创建第1个Haproxy负载均衡服务器 docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=net1 --ip 172.18.0.7 haproxy # 进入h1容器,启动Haproxy docker exec -it h1 bash haproxy -f /usr/local/etc/haproxy/haproxy.cfg # 创建第2个Haproxy负载均衡服务器 docker run -it -d -p 4003:8888 -p 4004:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h2 --privileged --net=net1 --ip 172.18.0.8 haproxy # 进入h2容器,启动Haproxy docker exec -it h2 bash haproxy -f /usr/local/etc/haproxy/haproxy.cfg
Haproxy容器内安装Keepalived,设置虚拟IP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 进入h1容器 docker exec -it h1 bash # 更新软件包 apt-get update # 安装VIM apt-get install vim # 安装Keepalived apt-get install keepalived # 编辑Keepalived配置文件(参考下方配置文件) vim /etc/keepalived/keepalived.conf # 启动Keepalived service keepalived start # 宿主机执行ping命令 ping 172.18.0.201
配置文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 172.18.0.201 } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 进入h2容器 docker exec -it h2 bash # 更新软件包 apt-get update # 安装VIMshell apt-get install vim # 安装Keepalived apt-get install keepalived # 编辑Keepalived配置文件 vim /etc/keepalived/keepalived.conf # 启动Keepalived service keepalived start # 宿主机执行ping命令 ping 172.18.0.201
配置文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 172.18.0.201 } }
宿主机安装Keepalived,实现双机热备
1 2 3 4 5 6 # 宿主机执行安装Keepalived yum -y install keepalived # 修改Keepalived配置文件 vi /etc/keepalived/keepalived.conf # 启动Keepalived service keepalived start
Keepalived配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.99.150 } } virtual_server 192.168.99.150 8888 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 172.18.0.201 8888 { weight 1 } } virtual_server 192.168.99.150 3306 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 172.18.0.201 3306 { weight 1 } }
3.6 热备份数据 1.冷备份 导出数据库进行备份,但是数据库需要停机,影响业务
2.热备份
全量备份:整个都备份 增量备份:对变化的数据进行备份 。
方案:lvm 和xtrabackup lvm 需要对数据库进行加锁(锁表),只能读取数据不能写入数据。
具体方法:利用mysql集群的技术,暂停删除一个节点镜像,新建一个节点进行备份(先要创造一个数据卷用来映射容器中备份的数据),然后下载xtrabackup 进行备份。
备份数据进行恢复
冷备份
热备份
XtraBackup介绍
XtraBackup优势
全量备份和增量备份 1 2 3 4 5 6 7 8 # 必须挂载备份数据目录 docker volume create backup docker stop node1 docker rm node1 docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup1:/data --privileged -e CLUSTER_JOIN=node2 --name=node1 --net=net1 --ip 172.18.0.2 pxc
热备份数据 1 2 3 4 5 6 7 8 # 进入node1容器 docker exec -it node1 bash # 更新软件包 apt-get update # 安装热备工具 apt-get install percona-xtrabackup-24 # 全量热备 innobackupex --user=root --password=abc123456 /data/backup/full
冷还原数据 停止其余4个节点,并删除节点
1 2 3 4 5 6 7 8 docker stop node2 docker stop node3 docker stop node4 docker stop node5 docker rm node2 docker rm node3 docker rm node4 docker rm node5
node1容器中删除MySQL的数据
1 2 3 4 5 6 # 删除数据 rm -rf /var/lib/mysql/* # 清空事务 innobackupex --user=root --password=abc123456 --apply-back /data/backup/full/2020-04-15_05-09-07/ # 还原数据 innobackupex --user=root --password=abc123456 --copy-back /data/backup/full/2020-04-15_05-09-07/
重新创建其余4个节点,组件PXC集群
第5章 搭建Redis集群 5.1 高速缓存的介绍
高速缓存利用内存保存数据,读写速度远超硬盘
高速缓存可以减少I/O操作,降低I/O压力
5.2 Redis 集群介绍
RedisCluster:官方推荐,没有中心节点
Codis:中间件产品,存在中心节点
Twemproxy:中间件产品,存在中心节点
5.3 RedisCluster
5.4 主从同步
5.5 Redis集群高可用
Redis集群中应该包含奇数个Master,至少应该有三个
Redis集群中每个Master都应该有Slave、
1 2 3 # 新建一个网段(用来存放Reids集群) docker network create --subnet=172.19.0.0/16 net2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # 创建配置文件 for port in $(seq 1 6); \ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat << EOF >/mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.19.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 # 启动Redis docker run -p 5001:6379 -p 15001:16379 --name redis-1 \ -v /mydata/redis/node-1/data:/data \ -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \ -d --net net2 --ip 172.19.0.2 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 5002:6379 -p 15002:16379 --name redis-2 \ -v /mydata/redis/node-2/data:/data \ -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \ -d --net net2 --ip 172.19.0.3 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 5003:6379 -p 15003:16379 --name redis-3 \ -v /mydata/redis/node-3/data:/data \ -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \ -d --net net2 --ip 172.19.0.4 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 5004:6379 -p 15004:16379 --name redis-4 \ -v /mydata/redis/node-4/data:/data \ -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \ -d --net net2 --ip 172.19.0.5 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 5005:6379 -p 15005:16379 --name redis-5 \ -v /mydata/redis/node-5/data:/data \ -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \ -d --net net2 --ip 172.19.0.6 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 5006:6379 -p 15006:16379 --name redis-6 \ -v /mydata/redis/node-6/data:/data \ -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \ -d --net net2 --ip 172.19.0.7 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
1 2 3 4 5 6 7 8 # 创建集群 进入一个Redis容器中执行 redis-cli --cluster create 172.19.0.2:6379 172.19.0.3:6379 172.19.0.4:6379 172.19.0.5:6379 172.19.0.6:6379 172.19.0.7:6379 --cluster-replicas 1 # 通过集群连接 redis-cli -c cluster info cluster nodes
1 2 docekr pause redis-3 docker unpause redis-3
第6章 部署前后端分离项目 6.1 打包部署后端项目 1 ,Java程序假设分配到Net3网段上想访问宿主机上net1网段的mysql 以及net2网段上的Redis集群。Doker容器是禁止跨网段访问的,就需要把Java程序的网络对接到宿主机的网络上,不要给Java程序划分网段,直接使用宿主机的网络。这样可能存在一个问题就是端口号冲突问题,因此需要给Java程序设置不同的端口
进入人人开源后端项目,执行打包(修改配置文件,更改端口,打包三次生成三个JAR文件)
mvn clean install -Dmaven.test.skip=true
安装Java镜像
docker pull java
创建3节点Java容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 创建数据卷,上传JAR文件 docker volume create j1 # 将jar放到该数据卷中 # 启动容器(需要和宿主机同一网络) docker run -it -d --name j1 -v j1:/home/soft --net=host java # 进入j1容器 docker exec -it j1 bash # 启动Java项目 nohup java -jar /home/soft/renren-fast.jar # 创建数据卷,上传JAR文件 docker volume create j2 # 启动容器 docker run -it -d --name j2 -v j2:/home/soft --net=host java # 进入j1容器 docker exec -it j2 bash # 启动Java项目 nohup java -jar /home/soft/renren-fast.jar --server.port=6002 & # 创建数据卷,上传JAR文件 docker volume create j3 # 启动容器 docker run -it -d --name j3 -v j3:/home/soft --net=host java # 进入j1容器 docker exec -it j3 bash # 启动Java项目 nohup java -jar /home/soft/renren-fast.jar --server.port=6003 &
后程序负载均衡 Nginx是性能非常出色的反向代理服务器,最大可以支持8w/s的并发访问
安装Nginx
创建Nginx容器,配置负载均衡
宿主机上/home/n1/nginx.conf配置文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; upstream tomcat { server 192.168.99.104:6001; server 192.168.99.104:6002; server 192.168.99.104:6003; } server { listen 6101; server_name 192.168.99.104; location / { proxy_pass http://tomcat; index index.html index.htm; } } }
创建第1个Nginx节点
1 docker run -it -d --name n1 -v /home/n1/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
宿主机上/home/n2/nginx.conf配置文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; upstream tomcat { server 192.168.99.104:6001; server 192.168.99.104:6002; server 192.168.99.104:6003; } server { listen 6102; server_name 192.168.99.104; location / { proxy_pass http://tomcat; index index.html index.htm; } } }
创建第2个Nginx节点
1 docker run -it -d --name n2 -v /home/n2/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
在Nginx容器安装Keepalived
1 2 3 4 5 6 7 8 9 10 11 12 # 进入n1节点 docker exec -it n1 bash # 更新软件包 apt-get update # 安装VIM apt-get install vim # 安装Keepalived apt-get install keepalived # 编辑Keepalived配置文件(如下) vim /etc/keepalived/keepalived.conf # 启动Keepalived service keepalived start
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.99.151 } } virtual_server 192.168.99.151 6201 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.99.104 6101 { weight 1 } }
1 2 3 4 5 6 7 8 9 10 11 12 # 进入n1节点 docker exec -it n2 bash # 更新软件包 apt-get update # 安装VIM apt-get install vim # 安装Keepalived apt-get install keepalived # 编辑Keepalived配置文件(如下) vim /etc/keepalived/keepalived.conf # 启动Keepalived service keepalived start
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.99.151 } } virtual_server 192.168.99.151 6201 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.99.104 6102 { weight 1 } }
6.2 打包部署前端项目 在前端项目路径下执行打包指令
文件拷贝到宿主机
build目录的文件拷贝到宿主机的/home/fn1/renren-vue、/home/fn2/renren-vue、/home/fn3/renren-vue的目录下面
创建3节点的Nginx,部署前端项目
宿主机/home/fn1/nginx.conf的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; server { listen 6501; server_name 192.168.99.104; location / { root /home/fn1/renren-vue; index index.html; } } }
1 2 # 启动第fn1节点 docker run -it -d --name fn1 -v /home/fn1/nginx.conf:/etc/nginx/nginx.conf -v /home/fn1/renren-vue:/home/fn1/renren-vue --privileged --net=host nginx
宿主机/home/fn2/nginx.conf的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; server { listen 6502; server_name 192.168.99.104; location / { root /home/fn2/renren-vue; index index.html; } } }
1 2 # 启动第fn2节点 docker run -it -d --name fn2 -v /home/fn2/nginx.conf:/etc/nginx/nginx.conf -v /home/fn2/renren-vue:/home/fn2/renren-vue --privileged --net=host nginx
宿主机/home/fn3/nginx.conf的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; server { listen 6503; server_name 192.168.99.104; location / { root /home/fn3/renren-vue; index index.html; } } }
启动fn3节点
1 2 # 启动第fn3节点 docker run -it -d --name fn3 -v /home/fn3/nginx.conf:/etc/nginx/nginx.conf -v /home/fn3/renren-vue:/home/fn3/renren-vue --privileged --net=host nginx
配置负载均衡
宿主机/home/ff1/nginx.conf配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; upstream fn { server 192.168.99.104:6501; server 192.168.99.104:6502; server 192.168.99.104:6503; } server { listen 6601; server_name 192.168.99.104; location / { proxy_pass http://fn; index index.html index.htm; } } }
1 2 # 启动ff1节点 docker run -it -d --name ff1 -v /home/ff1/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
宿主机/home/ff2/nginx.conf配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } 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"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 5s; proxy_send_timeout 5s; proxy_read_timeout 5s; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; upstream fn { server 192.168.99.104:6501; server 192.168.99.104:6502; server 192.168.99.104:6503; } server { listen 6602; server_name 192.168.99.104; location / { proxy_pass http://fn; index index.html index.htm; } } }
1 2 # 启动ff2节点 docker run -it -d --name ff2 -v /home/ff2/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
配置双机热备 1 2 3 4 5 6 7 8 9 10 11 12 # 进入ff1节点 docker exec -it ff1 bash # 更新软件包 apt-get update # 安装VIM apt-get install vim # 安装Keepalived apt-get install keepalived # 编辑Keepalived配置文件(如下) vim /etc/keepalived/keepalived.conf # 启动Keepalived service keepalived start
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.99.152 } } virtual_server 192.168.99.151 6701 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.99.104 6601 { weight 1 } }
1 2 3 4 5 6 7 8 9 10 11 12 # 进入ff1节点 docker exec -it ff2 bash # 更新软件包 apt-get update # 安装VIM apt-get install vim # 安装Keepalived apt-get install keepalived # 编辑Keepalived配置文件(如下) vim /etc/keepalived/keepalived.conf # 启动Keepalived service keepalived start
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.99.152 } } virtual_server 192.168.99.151 6701 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.99.104 6602 { weight 1 } }