目录
前言
一、源码包下载
1.1.Nginx下载
1.2.PCRE下载
1.3.Zlib下载
1.4.OpenSSL下载
二、安装
2.1.PCRE安装
2.2.Zlib安装
2.3.OpenSSL安装
2.4.Nginx安装
2.5.Nginx常用命令
三、配置部署
3.1.nacos1.x和2.x的差异
3.2.兼容性
3.3.Nginx配置示例
四、问题汇总
4.1.如何请求控制台与配置服务地址
4.2.Nginx编译添加允许TCP转发参数
4.3.nacos服务启动未按照2.x版本运行
4.4.nacos的group配置问题
4.5.nacos用户名密码转义问题
本文主要讲述采用Nginx代理转发Nacos2.0.3版本集群,涉及内容包括:
1.Nginx的安装与配置;
2.Nacos服务注册失败问题汇总与解决方案;
3.Nacos1.x版本和2.x版本的差异,以及Nginx配置的差异。
关于nacos集群的搭建与配置,请参考本人文章:
Linux系统安装部署nacos集群:基于nacos2.0.3
废话不说,我们直接进入正题。
说明:
本文的Nginx安装是基于源码包的形式,而非yum方式。主要原因是,公司内网不能采用yum方式。源码包的安装方式相较于yum方式比较麻烦一些,当然也更能达到个人的要求。
安装Nginx一共需要下载4个安装包,分别是:
Nginx
PCRE
Zlib
OpenSSL
直接从官网下载:https://nginx.org/en/download.html
我们选择稳定版,点击nginx-1.22.0下载linux版本的。
PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。这些在执行正规表达式模式匹配时用与Perl 5同样的语法和语义是很有用的。Boost太庞大了,使用boost regex后,程序的编译速度明显变慢。测试了一下,同样一个程序,使用boost::regex编译时需要3秒,而使用pcre不到1秒。因此改用pcre来解决C语言中使用正则表达式的问题。
简而言之,就是兼容的正则表达式库。
官网:https://www.pcre.org/
版本:
PCRE 库有两个主要版本。当前版本 PCRE2 于 2015 年发布, 现在版本为10.39。
较旧但仍广泛部署的 PCRE 库最初于 1997 年发布,版本为8.45。此版本的 PCRE 现已终止,不再积极维护。8.45 版预计将是旧版 PCRE 库的最终版本,新项目应使用 PCRE2。
下载:
您可以从GitHub 上的官方主页下载当前版本的 PCRE2 库:
您还可以从SourceForge的非官方镜像 下载 PCRE2 或更旧的、未维护的 PCRE 库:
您可以通过 Git 或 Subversion 查看 PCRE2 源代码:
git clone https://github.com/PhilipHazel/pcre2.git
请注意,以前的ftp.pcre.org FTP 站点不再可用。您将需要更新任何下载 PCRE 源代码的脚本,以通过 HTTPS、Git 或 Subversion 从 GitHub 上的新主页下载。
具体情况请移步官网:https://www.pcre.org/
GitHub截图:
下载其他版本或者自选版本,请点击Tags进行选择。
我们直接下载pcre2-10.40.tar.gz
上面我们下载的是PCRE2的,关于PCRE和PCRE2,我们上面已经说过了,这里不再赘述。
zlib被设计成一个免费的、通用的、不受法律约束的——即不受任何专利保护的——无损数据压缩库,几乎可以在任何计算机硬件和操作系统上使用。zlib 数据格式本身可以跨平台移植。与 Unix compress (1) 和 GIF 图像格式中使用的 LZW 压缩方法不同,zlib 目前使用的压缩方法基本上从不扩展数据。(在极端情况下,LZW 可以使文件大小增加一倍或三倍。)zlib 的内存占用量也与输入数据无关,并且可以在必要时以一定的压缩成本来减少。
详情请移步官网:zlib Home Site
下载地址:http://www.zlib.net/fossils/
向下翻,翻到最后(为什么最新版的不是在最上面,这个有点,哈哈),我们下载最新的zlib-1.2.12.tar.gz
官网:https://www.openssl.org/source/
OpenSSL目前有两个分支,一个是1.x一个是3.x,我们下载3.x的。
或者从这里下载:OpenSSL官方下载 - 码客
注意:最新的稳定版本是支持到 2026 年 9 月 7 日的 3.0 系列。这也是长期支持 (LTS) 版本。之前的 LTS 版本(1.1.1 系列)也可用,并且支持到 2023 年 9 月 11 日。所有旧版本(包括 1.1.0、1.0.2、1.0.0 和 0.9.8)现在都不再支持,应该不被使用。鼓励这些旧版本的用户尽快升级到 3.0。提供对 1.0.2 的扩展支持,以获得对该版本的安全修复程序的访问权限。
最终下载之后的截图如下:
先将以上软件上传到服务器上,然后分别进行安装。
# 1.解压
tar -xvf pcre2-10.40.tar.gz -C /usr/local
# 2.进入目录
cd /usr/local/pcre2-10.40/
# 3.编译
./configure
# 4.执行安装
make && make install
# 5.检查版本
pcre-config --version
pcre2-config --version
# 1.解压
tar -xvf zlib-1.2.12.tar.gz -C /usr/local
# 2.进入目录
cd /usr/local/zlib-1.2.12
# 3.编译
./configure
# 4.执行安装
make && make install
# 5.检查版本
cat /usr/lib64/pkgconfig/zlib.pc
# 1.解压
tar -xvf openssl-3.0.5.tar.gz -C /usr/local
# 2.进入目录
cd /usr/local/openssl-3.0.5
# 3.编译
./config
# 或者
./config --prefix=/usr/local/openssl-3.0.0 --openr/local/openssl-3.0.0
# 4.执行安装
make && make install
如果有以下类似错误
smime.pod around line 272: Expected text after =item, not a number
smime.pod around line 276: Expected text after =item, not a number
smime.pod around line 280: Expected text after =item, not a number
smime.pod around line 285: Expected text after =item, not a number
smime.pod around line 289: Expected text after =item, not a number
POD document had syntax errors at /usr/bin/pod2man line 71.
Makefile:544: recipe for target 'install_docs' failed
make: *** [install_docs] Error 255
可以先进行一下操作,再进行上面的解压等一些列操作:
vim /usr/bin/pod2man
#注释69行, #$parser->parse_from_file (@files);
# Initialize and run the formatter, pulling a pair of input and output off at
# a time. For each file, we check whether the document was completely empty
# and, if so, will remove the created file and exit with a non-zero exit
# status.
my $parser = Pod::Man->new (%options);
my $status = 0;
my @files;
do {
@files = splice (@ARGV, 0, 2);
print " $files[1]\n" if $verbose;
#$parser->parse_from_file (@files);
#以上内容修改完毕,按 esc键,输入:wq 回车保存退出
编译过程可能会报错:
Can't locate IPC/Cmd.pm in @INC
报错原因:缺少IPC/Cmd.pm模块
解决方法:
安装perl-CPAN
yum install -y perl-CPAN
进入CPAN的shell模式,首次进入需要配置shell,按照提示操作即可(本人perl小白,全部选择默认配置,高手请根据提示自行选择)
perl -MCPAN -e shell
在shell中安装缺少的模块
cpan[1]> install IPC/Cmd.pm
注意:cpan[1]> 不是命令,是cpan的shell提示,类似于linux的
[root@localhost dake]#
安装成功后,重新编译OpenSSL即可。
关于该错误,请参考:编译OpenSSL时报错,Can‘t locate IPC/Cmd.pm in @INC
至此,Nginx需要的依赖库已经安装完毕,我们可以着手开始安装Nginx。
# 1.解压
tar -xvf nginx-1.22.0.tar.gz -C /usr/local
# 2.进入目录
cd /usr/local/nginx-1.22.0
# 3.编译
./configure --with-stream --with-http_ssl_module --with-pcre=../../tools/pcre2-10.40 --with-zlib=../../tools/zlib-1.2.12 --with-openssl=../../tools/openssl-3.0.5
# 4.执行安装
make && make install
# 5.修改配置
cd /usr/local/nginx
# 修改nginx配置,这个需要根据实际情况进行调整
vim ./conf/nginx.conf
#以上内容修改完毕,按 esc键,输入:wq 保存退出
# 6.启动
./sbin/nginx -c ./conf/nginx.conf
# 7.检查版本
nginx -v
或者
nginx -V
# 也许以上两个命令都不行,可以执行以下命令
./sbin/nginx -v
# 8.检查启动情况
ps -ef | grep nginx
结尾显示如下内容,则正常
est -d '/usr/local/nginx/logs' || mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/logs' || mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/html' || cp -R html '/usr/local/nginx'
test -d '/usr/local/nginx/logs' || mkdir -p '/usr/local/nginx/logs'
make[1]: Leaving directory “/usr/local/nginx/nginx-1.22.0”
# 常用命令
# 重启
./sbin/nginx -s reload
# 强制停止Nginx
./sbin/nginx -s stop
# 优雅停止Nginx
./sbin/nginx -s quit
# 测试配置文件是否OK,查看当前使用的是哪个配置文件
./sbin/nginx -t
# 查看nginx帮助相关的内容
./sbin/nginx -h
# 显示nginx版本,小写v
./sbin/nginx -v
# 显示nginx版本,同时会显示编译、组件、参数等内容,大写V
./sbin/nginx -V
注意:
1.以上./sbin/nginx是在Nginx的安装目录下执行的,如果你的不是,那么执行可能会报错。
2.由于没有来得及配置systemctl服务,所以,直接执行nginx -v等命令也是不行的。当然,如果你是通过yum方式安装的,就不需要这些配置了。
3.关于systemctl的配置,后面还有时间再补充进来,务必要求实战、亲测可用。
4.在修改了conf的配置文件时,请务必reload一下Nginx,不然配置不生效。
如果防火墙没有开通,直接在浏览器中访问你电脑的ip,Nginx是连不通的,需要开通80端口防火墙。本文不赘述这一点,可以参考本文开头的nacos配置中的防火墙问题。
今天先到这里,后面我们继续。
-------------------------------------------未完,待续----------------------------------------------------------------------
2022年10月11日09:30:01
今天我们继续未完的文章。
以上Nginx的安装,也可以参考文章:Nginx简要安装配置方法图文教程(nginx安装及配置教程)
nacos2.x版本和1.x版本差异比较大,我们引用官网的说法来介绍一下。
官网:Nacos 2.0.0 兼容性文档
经过社区的讨论和开发, Nacos 基于长连接的2.0.0版本的核心功能已开发完成,目前2.0.0正式版本已发布,欢迎大家使用。
Nacos2.0版本相比1.X新增了gRPC的通信方式,因此需要增加2个端口。新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成。
客户端拥有相同的计算逻辑,用户如同1.X的使用方式,配置主端口(默认8848),通过相同的偏移量,计算对应gRPC端口(默认9848)。
因此如果客户端和服务端之前存在端口转发,或防火墙时,需要对端口转发配置和防火墙配置做相应的调整。
Nacos2.0的服务端完全兼容1.X客户端。Nacos2.0客户端由于使用了gRPC,无法兼容Nacos1.X服务端,请勿使用2.0以上版本客户端连接Nacos1.X服务端。
通过上面2张图我们看到,nacos2.x之后,采用了长连接取代了之前的短连接,增加了gRPC协议,同时Nacos在1.4版本后使用Jraft替换了自研的Raft实现,Jraft的选主比原先自研的Raft更加严格,会记录之前启动时的ip或host。因此重启时如果ip变动了,有可能造成选主失败,从而导致nacos无法正确提供服务。
解决方式为删除nacos目录下的data,再启动。
或者使用-Dnacos.server.ip=${domain}
,然后将nacos/conf的cluster.conf配置domain列表,避免重启时ip变动导致的raft选主问题。
在Nginx的配置文件nginx.cong中,创建和http请求同级的请求服务:
# tpc服务
stream {
# tcp负载均衡
upstream nacos-grpc {
server 192.168.247.128:9846;
server 192.168.247.128:9848;
server 192.168.247.128:9850;
}
# Nacos客户端gRPC请求服务端端口
server {
listen 9848;
proxy_pass nacos-grpc;
}
# tcp负载均衡
upstream nacos-tcp-9849 {
server 192.168.247:9847 weight=1;
server 192.168.247:9849 weight=1;
server 192.168.247:9851 weight=1;
}
# Nacos服务端gRPC请求服务端端口
server {
listen 9849;
proxy_pass nacos-tcp-9849;
}
# tcp负载均衡
# upstream nacos-tcp-7848 {
# server 192.168.247:7846 weight=1;
# server 192.168.247:7848 weight=1;
# server 192.168.247:7850 weight=1;
# }
# Nacos服务端gRPC请求服务端端口
# server {
# listen 7848;
# proxy_pass nacos-tcp-7848;
# }
}
注意:
Nginx服务器要开通9848/9849端口,以及nacos默认的8848端口。同时,在http请求中和nacos1.x一样,还是要配置nacos集群:
# http请求服务
http {
include 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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream nacos-cluster {
ip_hash;
server 192.168.247.128:8846;
server 192.168.247.128:8848;
server 192.168.247.128:8850;
}
# server {
# listen 7800;
# server_name localhost;
# location / {
# proxy_pass http://nacos-cluster;
# }
# }
server {
listen 80;
# listen 7800;
server_name localhost;
#server_name 192.168.247.128;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
# root html;
index index.html index.htm;
proxy_pass http://nacos-cluster;
}
#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;
# }
#}
}
我们看到,在http请求中也增加了nacos集群的配置。
注意:
以上的stream的TCP请求和http请求的两个配置都不可少,缺一不可。
我们还需注意到,我们Nginx默认监听的是80端口,这里我们没有做修改。如果我们请求nacos控制台,只需要ip+/nacos即可。
http://192.168.247.128/nacos/
但是,如果是在服务注册时填写服务地址的取值,则需要添加8848端口,因为我们未对8848端口进行监听。如果我们对8848端口进行了 转发,则只需要ip加上转发的路径即可。
spring.cloud.nacos.server-addr=http://192.168.247.128:8848
我们配置好之后,可以重启Nginx,在重启之前可以先检测一下修改的nginx.conf文件是否正确:
# 在Nginx安装目录下执行
./sbin/nginx -t
有上图的结果,证明配置的语法没问题。
然后可以重启Nginx。不过此时可能会报错:
nginx: [emerg] unknown directive "stream" in /usr/local/nginx
这个错误的原因是编译Nginx的时候未添加--with-stream参数,也就是说没有配置允许Nginx进行TCP转发,所以重新加载Nginx会报错。我们只需要重新编译Nginx,并启动即可。
此时我们可以启动我们的SpringCloud项目,静静地等待项目注册到nacos上即可。但是此时依然可能会报错:
Nacos cluster is running with 1.X mode, can't accept gRPC request temporarily. Please check the server status or close Double write to force open 2.0 mode. Detail https://nacos.io/en-us/docs/2.0.0-upgrading.html.
什么意思呢?
意思是说Nacos群集正在1.X模式下运行,暂时无法接受gRPC请求。请检查服务器状态或关闭Double write以强制打开2.0模式。
这是什么情况呢?我们命名是下载并安装的nacos2.0.3的安装包,为什么是以1.x模式运行呢?这是因为nacos启动的时候未必都是以你指定版本启动并运行的,存在一定情况的降级可能。
参考官网:https://nacos.io/en-us/docs/2.0.0-upgrading.html
启动后自检
集群中所有机器部署为2.0.X版本并启动时,应当进行启动之后的检查。当集群中所有节点logs/naming-server.log日志中观察到upgrade check result true及Upgrade to 2.0.X,便判定为集群准备完毕时,此时才可以使用Nacos2.0。
关闭双写
为了节省性能开销,当集群部署完成后,可以先观察一段时间运行情况,当确认无误后,可以关闭双写,从而释放性能,具体的关闭方式是通过API进行:
curl -X PUT 'localhost:8848/nacos/v1/ns/operator/switches?entry=doubleWriteEnabled&value=false'
关闭后可以从logs/naming-server.log
日志中观察到Disable Double write, stop and clean v1.x cache and features
字样。说明关闭双写。
注意,关闭双写后无法在进行平滑降级,请先确认关闭前集群正确运行。
我们看看
less /usr/local/nacos/nacos-2.0.3/nacos-8848/logs/naming-server.log
有个别nacos节点并未以2.x模式启动,导致我的服务注册失败。我的做法是将该nacos节点服务停止并重启,但是此时依然是upgrade false。之后我强行关闭了双写,此时服务正常注册上去了。
sh nacos-8846/bin/shutdown.sh
sh nacos-8848/bin/shutdown.sh
sh nacos-8850/bin/shutdown.sh
sh nacos-8846/bin/startup.sh
sh nacos-8848/bin/startup.sh
sh nacos-8850/bin/startup.sh
关闭双写
curl -X PUT '192.168.247.128:8850/nacos/v1/ns/operator/switches?entry=doubleWriteEnabled&value=false'
我们再看几张图
我们看到节点元数据,有的有 readyToUpgrade 字段,有的没有,该字段的取值,有的是true,有的是false(这个上图没有显示)。这个就是我们上面说的是否准备好升级。
我个人看法是(未必准确),如果最终所有节点都升级成功,则该字段就不显示了。
此时,Nginx转发nacos集群并通过服务注册大概应该成功了,但是我这里遇到了一个奇怪问题。之前公司的nacos是1.x的,我们在项目的pom文件中定义了profile,如图:
然后在bootstrap.properties文件中直接引用该文件的取值。
看红框中的group,本来我们是采用
${NACOS_GROUP:DEV_GROUP}
这个方式给group赋值的,但是到了nacos2.0.3就服务一直注册不上去,也没有什么错误提示,最后看到服务注册的时候的group一直没有变化,我修改了也没效果。刚开始通过各种方式处理,最后不经意间想着是不是这个问题,直接删除了外面的$,直接赋值为自己要取值的group,比如,GROUP_PLAT。此时服务注册的日志显示的group竟然正确了,我就把服务配置的也修改了,此时服务正常注册上去,并获取到nacos配置中心的取值,不然之前要不服务注册不上去,要不服务注册上去了,但是获取不到nacos配置中心的取值。
还有一个问题,就是如果nacos配置采用了账户密码的模式,如果密码中存在#号,最后获取的时候会出现转义的情况,被转义成了%23(如果我没记错的话)。同理,如果用户名存在#,我感觉也是一样的,这个我没有找到解决办法,唯一的方法是用户名和密码不要使用#。因为这个是通过浏览器的形式获取的(如果我没记错的话。同时,浏览器好像确实不能拼接#参数,会被转义)。
至此,Nginx代理转发nacos集群,以及服务注册到nacos2.0.3,完美结束!
----------------------------------------------------本文完----------------------------------------------------------------
与君共勉,砥砺前行,不负此生!
祝好运!