一、Nacos 集群配置
Nacos 在测试时,只开启了一个注册中心,但在实际生产、上线环境下,都需要进行集群化部署,防止一台宕机影响整体应用。
《Nacos 集群部署 官方文档》
[问:]什么是VIP?
此处的vip,称为虚拟ip。
通俗易懂的流程图如下所示:
如何才能配置好Nacos集群呢?
本次按照 Nacos集群部署官方文档 步骤实现配置。
1.1、开发前的准备:
1、nacos-server-1.2.1.tar.gz
https://github.com/alibaba/nacos/tags2、centos 版本 cat /proc/version
3、工具 SecureCRT
4、Nginx 做虚拟 IP ( VIP )
1.2、解压 nacos-server.tar.gz 文件
tar -zxvf nacos-server-1.2.1.tar.gz
1.3、修改nacos/conf/cluster.conf 文件
cp cluster.conf.example cluster.conf
由于我的云服务器有限,这里采取虚拟集群(ip不变,端口改变)的形式,集群配置Nacos
修改 cluster.conf 文件中的配置信息:
这个版本的Nacos 可以在服务器上配置 127.0.0.1。
能否配置,还需要使用如下命令进行查询:
hostname -i
1.4、修改 nacos 的启动脚本代码
使用的 nacos 集群端口分别为 3333 4444 5555,需要在 nacos 中配置启动端口。
操作前,需要对原有的 startup.sh 进行备份操作。
cp startup.sh startup.sh.bk
其中,startup.sh 文件中自带的逻辑代码为:
此时,需要增加一个 port 性质的启动:
while getopts ":m:f:s:p:" opt
do
case $opt in
m)
MODE=$OPTARG;;
f)
FUNCTION_MODE=$OPTARG;;
s)
SERVER=$OPTARG;;
p)
PORT=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
末尾追加启动脚本配置:
# start
echo "$JAVA ${JAVA_OPT}" > ${BASE_DIR}/logs/start.out 2>&1 &
#nohup $JAVA ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
### change this code to add port start application
nohup $JAVA -Dserver.port=${PORT} ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
echo "nacos is starting,you can check the ${BASE_DIR}/logs/start.out"
保存,退出!
1.5、启动nacos
./startup.sh -p 3333
./startup.sh -p 5555
但是,本次博客使用的服务器配置较低,启动单个Nacos,会顺带有如下命令:
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
代号 | 含义 | 数据值 |
---|---|---|
-Xms2g | 设定堆内存初始的大小(新生代+老年代) | 堆的初始总大小为2G |
-Xmx2g | 设定堆内存的最大分配大小 | 堆内存需要占用2G |
-Xmn1g | 设定堆内存中新生代的大小 | 堆内存中的新生代大小为1G |
MetaspaceSize=128m | 设定堆中(jdk1.8 方法区中的静态变量、常量池在堆中)的方法区内存大小 | 方法区的大小占用128M |
本次测试使用的服务器配置为 1核2G ,如果不配置启动时,jvm的大小信息,则只能启动一个,不能达到集群化配置地要求。
修改内存大小:
#===========================================================================================
# JVM Configuration
#===========================================================================================
if [[ "${MODE}" == "standalone" ]]; then
JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m"
JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true"
else
### change jvm properties #################################
# JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
################ add new jvm properties ###################
JAVA_OPT="${JAVA_OPT} -server -Xms800m -Xmx800m -Xmn400m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=200m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE_DIR}/logs/java_heapdump.hprof"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
fi
真实服务器上,需要配置好防火墙对端口的入站/出站权限!
1.6、配置Nginx,使其负载均衡
上面的案例,暂时只启动了 3333 4444 端口的Nacos项目,此时还需要 Nginx 配置,实现 负载均衡 操作。
不会Centos7 安装 Nginx 可以参考博客:《Centos安装Nginx》
本次的配置采取真实 腾讯云 服务器实现配置操作。
nginx的目录地址为:
修改配置文件中的 server、upstream 项:
完整 Nginx 配置文件内容为:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
###################add new configurations
proxy_temp_path /usr/local/nginxCache/temp ;
proxy_cache_path /usr/local/nginxCache/cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;
proxy_connect_timeout 5;
proxy_read_timeout 60;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_http_version 1.1;
gzip_types text/plain application/x-JavaScript text/css application/xml;
gzip_disable "MSIE [1-6]\.";
###################################
#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 logs/access.log main;
################change
sendfile off;
#sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
###########updata one
upstream xiangjiao{
server localhost:3333 weight=2;
server localhost:5555 weight=3;
## server localhost:8888 down;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#####################
error_page 403 http://localhost:8080/403.jsp;
error_page 404 http://localhost:8080/404.jsp;
#############update two
location /{
proxy_pass http://xiangjiao;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
##########################
#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;
}
# location / {
# root html;
# index index.html index.htm;
#}
###########start###################
location ~ /purge(/.*) {
allow 127.0.0.1;
allow 192.168.122.0/24;
allow all;
proxy_cache_purge cache_one $host$1$is_args$args;
}
location ~ .*\.(gif|jpg|png|htm|html|css|js|flv|ico|swf)(.*) {
proxy_pass http://xiangjiao ;
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_cache cache_one;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 302 1h;
proxy_cache_valid 301 1d;
proxy_cache_valid any 1m;
expires 30d;
}
###########end################
#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 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;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
配置完成后,启动Nginx:
./nginx
1.7、请求测试
http://linkpower-iot.cn/nacos/
由于nginx监听的是 80 端口,以80端口负载均衡至3333 和 5555。
如果成功请求,表示配置成功
1.8、更改代码配置
做好了注册中心的集群化配置后,需要修改各个 微服务
中的application.yml 配置文件。
## 该服务的端口信息
server:
port: 9102
## 服务别名和nacos服务注册发现地址配置
spring:
application:
name: nacos-product
cloud:
nacos:
discovery:
#server-addr: localhost:8848
server-addr: 服务器ip:80 ## 换成自己服务器的ip(由于nginx是监听的80端口后,请求负载均衡至3333、4444和5555)
## 监控相关
management.endpoints.web.exposure.include: '*'
1.9、不使用Nginx配置Nacos集群
直接在Centos 操作系统中起多个Nacos注册中心。
修改配置文件,增加服务注册指向:
## 该服务的端口信息
server:
port: 9102
## 服务别名和nacos服务注册发现地址配置
spring:
application:
name: nacos-product
cloud:
nacos:
discovery:
#server-addr: localhost:8848
# 不使用nginx
server-addr: 192.168.99.100:3333,192.168.99.100:5555
## 监控相关
management.endpoints.web.exposure.include: '*'
[注意1:]Nacos启动出现 failed to req API:/nacos/v1/ns/instance after all servers([192.168.99.100:3333, 192.168.99.100:5555]) tried: failed to req API:192.168.99.100:3333/nacos/v1/ns/instance. code:500 msg: java.net.SocketTimeoutException: Read timed out
网上的解释 《java.lang.IllegalStateException: failed to req API》《编译Nacos,解决failed to req API》
nacos 配置了集群后出现的问题,需要在配置中增加:
添加启动参数-Dnacos.standalone=true
杀掉 Nacos 的进程,重新启动:
sh startup.sh -p 3333 -m standalone
sh startup.sh -p 5555 -m standalone
重新启动 nacos-product 微服务!
[注意2:出现服务器nacos启动正常,但微服务无法注册至nacos的解决思路]
如果是云服务器,检查各项出站/入站规则端口开放设定。
如果是本地服务器,则需要放开防火墙限制,测试需要可以使用iptables -F
指令,暂时关闭防火墙限制。(服务器重启后会恢复原来的限制)
二、Nacos 数据持久化和一致性问题
Nacos 本身自带有 Derby(内嵌式数据库),项目正常上线后,需要对Nacos做集群部署方案,此时的每个Nacos都会自带一个独立的Derby内嵌式数据库,不利于Nacos 配置等文件数据的一致性!
其次,内嵌式数据库的数据保存于内存中,若出现服务器宕机重启,数据可能会存在丢失性问题,此时需要对数据做持久化处理。但Nacos 目前仅支持 Mysql 数据库做数据的持久化操作配置。
2.1、连接指定服务器,创建对应的数据库
连接服务器,创建一个数据库,名称自定义,本次使用名称为:
nacos_config
2.2、运行指定sql,生成表格
sql 脚本位于:
\nacos-server文件路径\conf
其中包含一个 nacos-mysql.sql 脚本,只需要运行即可,不要动其中的数据和表格名称!
2.3、更改 Nacos 的配置文件,增加数据库连接配置
Nacos 目前只支持于 MySql;
修改 \nacos-server文件路径\conf 目录下的 application.properties 文件信息,增加数据库连接的配置:
#*************** Config Module Related Configurations ***************#
### If user MySQL as datasource:
# spring.datasource.platform=mysql
### Count of DB:
# db.num=1
### Connect URL of DB:
# db.url.0=jdbc:mysql://1.1.1.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
# db.user=user
# db.password=password
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://数据库服务器ip:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=你的服务器密码
2.4、重启 Nacos
- 登录账号设置
- 创建新的工作空间
- 创建配置文件
2.5、总结
配置了数据库的连接后,正常的配置信息将会保存至指定的数据库中。
信息得到了持久化的存储。