首先找到Nacos官网给的Github仓库,里面有docker compose
可以快速启动Nacos集群。
我们要运行的脚本是example/cluster-hostname.yaml
,可以看到里面包含了来自外界的${NACOS_VERSION}
和加载外界env文件的env_file
条目,于是我们可以找到本yaml
所依赖的以下文件列表:
example/.env
env/mysql.env
env/nacos-hostname.env
example/cluster-hostname.yaml
找到mysql-healthcheck-test
修改为
mysql:
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}" ]
这样做的原因是防止mysql
容器测试时一直报错Access denied(password: No)
example/.env
在后面运行docker compose
时,会加载这个文件为环境变量,填入${NACOS_VERSION}
和${MYSQL_ROOT_PASSWORD}
。
NACOS_VERSION=v2.3.0
MYSQL_ROOT_PASSWORD=1009
NACOS_VERSION
的版本选多少可以参考Nacos官方的对照表。
官方指出Nacos有一定向下兼容性,所以选择新一点的Nacos版本也没问题,同时,某些版本的Nacos已被指出存在部分问题。
MYSQL_ROOT_PASSWORD
为数据库root密码。
env/mysql.env
这是cluster-hostname.yaml
中mysql
容器使用的env_file
MYSQL_ROOT_PASSWORD=1009
MYSQL_DATABASE=nacos
MYSQL_USER=nacos
MYSQL_PASSWORD=nacos
LANG=C.UTF-8
MYSQL_ROOT_PASSWORD
为数据库root密码,和上面那个保持一致
MYSQL_DATABASE
为数据库名称
MYSQL_USER
为数据库用户名
MYSQL_PASSWORD
为用户(nacos)密码
env/nacos-hostname.env
这是cluster-hostname.yaml
中3个nacos
容器使用的env_file
PREFER_HOST_MODE=hostname
NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=mysql
MYSQL_SERVICE_DB_NAME=nacos
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=nacos
MYSQL_SERVICE_PASSWORD=nacos
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
NACOS_AUTH_IDENTITY_KEY=2222
NACOS_AUTH_IDENTITY_VALUE=2xxx
NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
关于docker nacos的环境变量,可以参考Nacos官方给的一张表格。
为什么
NACOS_SERVERS
填的是nacos1,nacos2,nacos3,不是具体的ip地址?
为什么MYSQL_SERVICE_HOST
(数据库连接地址)填的是"mysql"?
同时MYSQL_SERVICE_PORT
应该填mysql容器的端口还是映射到主机的端口?
因为三个
nacos
容器和一个mysql
在一个docker compose文件里,也就是cluster-hostname.yaml
,那么在运行这个yaml
文件时,docker
会默认把这个yaml
里所有的容器放到一个新的bridge
网络中,于是,四个容器可以通过它们在这个bridge
网络里的ip
互相访问,同时也可以通过hostname
互相访问,如果没有指明hostname
,那么默认就是服务的名称(services),比如mysql
的就是mysql
。同时这四个容器之间互相访问的端口是容器开放的端口,而不是映射到主机的端口。
在根目录运行docker-compose -f example/cluster-hostname.yaml up
然后浏览器就可以访问localhost:port/nacos
,port
是三个nacos
的8848
端口映射到主机的三个端口之一。
docker pull nginx:stable
下载nginx的稳定版镜像
然后用这个镜像随便启动一个容器,把里面的以下文件copy到主机,修改后做-v映射。
/etc/nginx/nginx.conf
/etc/nginx/conf.d/default.conf
其中nginx.conf
无需修改
default.conf
参考以下示例
upstream nacos-cluster {
server 172.29.0.3:8848;
server 172.29.0.4:8848;
server 172.29.0.5:8848;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://nacos-cluster;
# root /usr/share/nginx/html;
# index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
主要注意两个地方,一个是
upstream nacos-cluster {
server 172.29.0.3:8848;
server 172.29.0.4:8848;
server 172.29.0.5:8848;
}
这里面写明了3个nacos
容器的ip和端口,其中ip是它们处于docker bridge
小局域网中的ip,以及port也是容器服务的端口,这是因为我们最后会把nginx
容器也加入这个bridge
网络。
用以下命令查看三个nacos的ip
C:\Users\mumu\IdeaProjects\nacos-docker>docker network ls
NETWORK ID NAME DRIVER SCOPE
fdfe3fcab913 bigdata bridge local
45d79fa3e39e bridge bridge local
2d784bdacaa1 example_default bridge local
83b9f11eccaa host host local
d138886a8b5b none null local
C:\Users\mumu\IdeaProjects\nacos-docker>docker network inspect example_default
[
.....
]
另一个是
location / {
proxy_pass http://nacos-cluster;
# root /usr/share/nginx/html;
# index index.html index.htm;
}
这里的意思是把/
的url请求(/
的话基本就是所有请求了)全部转发到上面定义的upstream nacos-cluster
服务器集群中。
这里默认是以轮询
作为负载均衡的策略。
!!!分配方式
Nginx的upstream支持5种分配方式,下面将会详细介绍,其中,前三种为Nginx原生支持的分配方式,后两种为第三方支持的分配方式:
1、轮询
轮询是upstream的默认分配方式,即每个请求按照时间顺序轮流分配到不同的后端服务器,如果某个后端服务器down掉后,能自动剔除。
upstream backend {
server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
}
2、weight
轮询的加强版,即可以指定轮询比率,weight和访问几率成正比,主要应用于后端服务器异质的场景下。
upstream backend {
server 192.168.200.131:8848 weight=1;
server 192.168.200.131:8849 weight=2;
server 192.168.200.131:8850 weight=3;
}
3、ip_hash
每个请求按照访问ip(即Nginx的前置服务器或者客户端IP)的hash结果分配,这样每个访客会固定访问一个后端服务器,可以解决session一致问题。
upstream backend {
ip_hash;
server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
}
4、fair
fair顾名思义,公平地按照后端服务器的响应时间(rt)来分配请求,响应时间短即rt小的后端服务器优先分配请求。
upstream backend {
server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
fair;
}
5、url_hash
与ip_hash类似,但是按照访问url的hash结果来分配请求,使得每个url定向到同一个后端服务器,主要应用于后端服务器为缓存时的场景下。
upstream backend {
server 192.168.200.131:8848;
server 192.168.200.131:8849;
server 192.168.200.131:8850;
hash $request_uri;
hash_method crc32;
}
其中,hash_method为使用的hash算法,需要注意的是:此时,server语句中不能加weight等参数。
参考以下命令运行(cmd版)
docker run -id --name=nacos_nginx ^
-p 80:80 ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\nginx.conf:/etc/nginx/nginx.conf ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\conf.d\default.conf:/etc/nginx/conf.d/default.conf ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\logs:/var/log/nginx ^
-v C:\Users\mumu\IdeaProjects\nacos-docker\nginx\html:/usr/share/nginx/html ^
--network example_default ^
nginx:stable
最后,访问localhost/nacos
就可以访问nginx
,nginx
会通过负载均衡的策略将你的请求重定向到nacos集群中的某一个。