1、环境准备
三台centos7虚拟机,主机名分别是192.168.2.8 、 192.168.2.89 、192.168.2.810 ,三台虚拟机安装好docker ,另外看一下nacos集群架构,一个简单的集群需要3个以上的nacos服务和一个vip服务(通常使用nginx做反向代理,负载均衡),配置的共享数据存储在mysql.
2、搭建步骤
(1)搭建mysql服务,在192.168.2.8这个虚拟机上操作
拉取得mysql5.7镜像
docker pull docker.io/mysql:5.7
启动mysql容器 (密码设置为root 端口为3308)
docker run -d --name mysql57 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=root --privileged=true
mysql:57
启动成功后,用链接工具连上,创建义名位nacos的数据库,将nacos官网提供的sql脚本执行
(2)在192.168.2.8 192.168.2.9 192.168.2.10 分别搭建nacos集群服务,现在以搭建192.168.2.8为例
在指定的目录创建Dockfile 、conf配置、启动脚本
Dockerfile的内容如下:
FROM docker.io/nacos/nacos-server
EXPOSE 8848
在conf/init目录 ,指定定制化配置custom.properties
server.servlet.contextPath=/nacos
server.port=8848
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.2.8:3308/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root
### Connection pool configuration: hikariCP
db.pool.config.connectionTimeout=30000
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2
nacos.naming.empty-service.auto-clean=true
nacos.naming.empty-service.clean.initial-delay-ms=50000
nacos.naming.empty-service.clean.period-time-ms=30000
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=false
nacos.core.auth.default.token.expire.seconds=18000
### The default token:
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
nacos.core.auth.enable.userAgentAuthWhite=true
nacos.core.auth.enable.userAgentAuthWhite=false.
nacos.core.auth.server.identity.key=
nacos.core.auth.server.identity.value=
nacos.istio.mcp.server.enabled=false
Leader tenure is confirmed by heartbeat
创建启动脚本 start.sh
#容器数据卷映射目录
vpath=/docker/data/
# 容器名称
cname=nacos-service-container
# 镜像名称
iname=nacos-service-image
# 私有网络名称
netname=yang123
# 查找正在运行的j容器ID并关闭
serverId=`docker ps -a | grep $cname | awk '{print $1}'`
if [ -z $serverId ]; then
echo "没有检测到正在运行的服务容器。开始启动新的容器......"
else
echo "扫描到正在运行的服务容器,执行关闭......"
docker rm $(docker stop $serverId)
fi
# 删除旧javaweb服务镜像
serverId=`docker images | grep $iname | awk '{print $3}'`
if [ -z $serverId ]; then
echo "没有检测到正在运行的服务容器。开始启动新的容器......"
else
echo "扫描到正在运行的服务容器,执行关闭......"
docker rmi $iname
fi
# 构建新的服务镜像
echo "构建所需镜像......"
docker build -t $iname .
if [ $? -eq 0 ]; then
echo "镜像构建完成,开始启动新容器......"
else
echo "镜像构建失败,请查看错误日志"
exit;
fi
# 启动新javaweb容器
docker run \
-d \
--env MODE=cluster \
--name $cname \
-p 8848:8848 \
-e PREFER_HOST_MODE=192.168.2.8 \
-e NACOS_SERVER_IP=192.168.2.8 \
-e NACOS_SERVERS="192.168.2.8:8848 192.168.2.9:8848 192.168.2.10:8848" \
-e JVM_XMS=256m \
-e JVM_XMX=256m \
-e JVM_XMN=64M \
-v /docker/nacos-server/conf/logs:/home/nacos/logs \
-v /docker/nacos-server/conf/init/custom.properties:/home/nacos/init.d/custom.properties \
--privileged=true \
$iname
serverId=`docker ps | grep $cname | awk '{print $1}'`
echo "新容器已启动,ID:$serverId, name:$cname, 网络:$netname"
执行启动脚本 ./start.sh
至此192.168.2.8上的nacos服务就创建成功,将conf Dockerfile start.sh 拷贝至192.168.2.9 192.168.2.10上,修改start.sh脚本
在192.168.2.9上启动容器替换为
docker run \
-d \
--env MODE=cluster \
--name $cname \
-p 8848:8848 \
-e PREFER_HOST_MODE=192.168.2.9 \
-e NACOS_SERVER_IP=192.168.2.9 \
-e NACOS_SERVERS="192.168.2.8:8848 192.168.2.9:8848 192.168.2.10:8848" \
-e JVM_XMS=256m \
-e JVM_XMX=256m \
-e JVM_XMN=64M \
-v /docker/nacos-server/conf/logs:/home/nacos/logs \
-v /docker/nacos-server/conf/init/custom.properties:/home/nacos/init.d/custom.properties \
--privileged=true \
$iname
在192.168.2.10上启动容器替换为
docker run \
-d \
--env MODE=cluster \
--name $cname \
-p 8848:8848 \
-e PREFER_HOST_MODE=192.168.2.10 \
-e NACOS_SERVER_IP=192.168.2.10 \
-e NACOS_SERVERS="192.168.2.8:8848 192.168.2.9:8848 192.168.2.10:8848" \
-e JVM_XMS=256m \
-e JVM_XMX=256m \
-e JVM_XMN=64M \
-v /docker/nacos-server/conf/logs:/home/nacos/logs \
-v /docker/nacos-server/conf/init/custom.properties:/home/nacos/init.d/custom.properties \
--privileged=true \
$iname
分别启动192.168.2.9 192.168.2.10上的nacos服务
3、nginx服务搭建,在192.168.2.8上操作
在指定目录创建nginx默认配置文件default81.conf
upstream nacoscluster {
server 192.168.2.8:8848;
server 192.168.2.9:8848;
server 192.168.2.10:8848;
}
server {
#nginx监听81端口
listen 81;
#在hosts中注册号主机名
server_name master;
location / {
proxy_pass http://nacoscluster;
#proxy_pass http://127.0.0.1:8848/nacos;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
proxy_set_header Host $host:81;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
}
Dockfile文件
FROM docker.io/nginx:1.15
RUN rm -rf /etc/nginx/conf.d/*
COPY ./conf.d/*.conf /etc/nginx/conf.d/
start_nginx.sh启动脚本
#!/bin/bash
dkfilePath=/docker/nginx/Dockerfile
nginxContentPath=/docker/nginx
# 容器名称
cname=nginx
# 镜像名称
iname=nginxssl
# 私有网络名称
netname=yang123
# 查找正在运行的nginx容器ID并关闭
ngxId=`docker ps -a| grep nginx | awk '{print $1}'`
if [ -z $ngxId ]; then
echo "没有检测到正在运行的nginx容器。开始启动新的nginx容器......"
else
echo "扫描到正在运行的nginx容器,执行关闭......"
docker rm $(docker stop $ngxId)
fi
# 删除旧nginx image
chk=`docker images | grep $iname | awk '{print $3}'`
if [ -z $chk ]; then
echo "旧nginx 镜像不存在"
else
echo "开始删除旧nginx镜像......"
docker rmi -f $iname
fi
# 构建新的nginx容器,并命名为nginxssl
echo "构建所需镜像......"
docker build -t $iname -f $dkfilePath $nginxContentPath
if [ $? -eq 0 ]; then
echo "镜像构建完成,开始启动新容器......"
else
echo "镜像构建失败,请查看错误日志"
exit;
fi
# 启动新nginx容器
docker run \
-d --name $cname \
-p 8080:80 \
-p 81:81 \
-v /docker/nginx/conf.d/index.html:/usr/share/nginx/html/index.html \
-v /docker/nginx/conf.d/logs:/var/log/nginx \
--privileged=true \
$iname
nId=`docker ps | grep $cname`
echo "新nginx容器已启动......"
ngxId=`docker ps | grep $cname | awk '{print $1}'`
echo "ID:$ngxId, name:$cname, 网络:$netname"
启动nginx服务 ./start_nginx.sh
4、测试访问集群 http://master:81/nacos
6、关于分布式服务注册中心原理
提到注册中不得不提分布式一致性(强一致性、弱一致性、多数派模型)算法: PAXOS 、RAFT、ZAB.常用的分布式注册中心的有Zookeeper、Eureka、Nacos、Consul等,它们的集群状态的工作原理也有所不同:
(1)zookeeper采用CP保证数据一致性,原理采用Zab原子广播协议,当zk集群的leader宕机 后,会自动重新选择一个新的领导角色,在选举过程中,zk环境不可使用。zk可运行的节点必须 过半才能使用;
(2)Eureka采用AP设计,完全去中心化。各个节点之间相互注册,只要有一个节点,整个微 服务就可以通讯;
(3)Nacos采用AP+CP模式混合实现,默认为AP,Nacos使用Raft协议会产生领导角色。