前言
本文素材來(lái)源朋友學(xué)習(xí)nacos2.1.1踩到的坑。直接上正菜
坑點(diǎn)一:出現(xiàn)端口被占用
因?yàn)槭菍W(xué)習(xí)使用炉旷,朋友就在物理機(jī)搭建了搭建了nacos偽集群庶香,即ip都一樣掠河,端口分別為8848,8847,8849担平。然而啟動(dòng)nacos服務(wù)器后救崔,一臺(tái)正常啟動(dòng),其他兩臺(tái)都報(bào)了端口被占用
出現(xiàn)這種情況的原因纬黎,官網(wǎng)有做了解釋
通過(guò)官網(wǎng)我們可以很容易得知本今,這個(gè)端口被占用主要是因?yàn)間rpc引起的主巍,因?yàn)樗丝诘纳煞绞剑怯芍鞫丝?1000铐达、主端口+1001生成檬果。
解決方法
集群的端口不要采用相鄰數(shù)字唐断,步長(zhǎng)盡量搞大點(diǎn)脸甘。比如設(shè)置為7777偏灿、8888、9999之類(lèi)的
坑二:微服務(wù)項(xiàng)目啟動(dòng)出現(xiàn)com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING異常
這個(gè)問(wèn)題出現(xiàn)在朋友在項(xiàng)目中配置的nacos地址為nginx地址铆遭,配置示例如下
spring.cloud.nacos.discovery.server-addr=nginx ip
一開(kāi)始朋友nginx的配置示例如下
upstream nacos-cluster {
server 127.0.0.1:7777;
server 127.0.0.1:8888;
server 127.0.0.1:9999;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://nacos-cluster;
}
}
瀏覽器通過(guò)nginx訪問(wèn)沒(méi)問(wèn)題枚荣,但是項(xiàng)目中把nacos服務(wù)地址配置為nginx ip就報(bào)了
com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING
這個(gè)異常信息啼肩,后面朋友查資料,官網(wǎng)上有寫(xiě)
于是他就將轉(zhuǎn)發(fā)方式改為T(mén)CP害碾,他的nginx版本是1.9+以上版本慌随,默認(rèn)就支持TCP代理了躺同,不用額外安裝stream模塊。nginx配置TCP的示例形如下
stream {
upstream nacos-cluster-grpc{
# nacos2版本,grpc端口與要比主端口多1000车海,主端口為7777隘击、8888、9999
server 127.0.0.1:8777;
server 127.0.0.1:9888;
server 127.0.0.1:10999;
}
server{
listen 9848;
proxy_pass nacos-cluster-grpc;
}
}
當(dāng)朋友配置好nginx tcp代理轉(zhuǎn)發(fā)后州叠,通過(guò)telnet命令
telnet 127.0.0.1 9848
來(lái)看是否能正常轉(zhuǎn)發(fā)給nacos服務(wù)端凶赁,經(jīng)過(guò)驗(yàn)證逆甜,網(wǎng)絡(luò)可以連通交煞。接著朋友在微服務(wù)項(xiàng)目的nacos配置填寫(xiě)如下地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:9848 #nginx代理tcp的地址
本來(lái)以為萬(wàn)事大吉斟或,結(jié)果項(xiàng)目一啟動(dòng),仍然報(bào)
com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING
于是朋友懵了御毅,啥情況怜珍?就來(lái)找我交流一下
其實(shí)在nacos官網(wǎng)的FAQ就有提到相應(yīng)的解題思路了
因?yàn)槲覀冊(cè)趎ginx配置的代理tcp端口為9848绘面,這個(gè)端口可以看成是grpc的端口揭璃,因?yàn)間rpc的端口 = nacos主端口 + 1000,因此我們套這個(gè)公式就可以得出歼秽,nacos的主端口為 = 9848 - 1000 = 8848情组,而我們微服務(wù)項(xiàng)目配置nacos端口,其實(shí)配置是主端口肆氓,因此實(shí)際上我們配置要寫(xiě)成
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 #nginx代理tcp端口 - 1000
配置這個(gè)后底瓣,果然成功注冊(cè)。這個(gè)思路是官網(wǎng)帶給我們的拨扶,但作為一個(gè)有點(diǎn)追求的程序員應(yīng)該不會(huì)僅僅滿(mǎn)足與此茁肠,我們可以直接根據(jù)控制臺(tái)報(bào)出的異常來(lái)獲取答案
異常排查過(guò)程就省略了垦梆,直接貼出關(guān)鍵的解題代碼
1仅孩、首先解析主端口號(hào)的核心代碼
位置在
com.alibaba.nacos.common.remote.client.RpcClient#resolveServerInfo
ServerInfo private RpcClient.ServerInfo resolveServerInfo(String serverAddress) {
Matcher matcher = EXCLUDE_PROTOCOL_PATTERN.matcher(serverAddress);
if (matcher.find()) {
serverAddress = matcher.group(1);
}
String[] ipPortTuple = serverAddress.split(":", 2);
int defaultPort = Integer.parseInt(System.getProperty("nacos.server.port", "8848"));
String serverPort = (String)CollectionUtils.getOrDefault(ipPortTuple, 1, Integer.toString(defaultPort));
return new RpcClient.ServerInfo(ipPortTuple[0], NumberUtils.toInt(serverPort, defaultPort));
}
2杠氢、其次設(shè)置grpc端口的核心代碼
位置在:
com.alibaba.nacos.common.remote.client.grpc.GrpcClient#connectToServer
[圖片上傳失敗...(image-17c2d3-1660878696992)]
端口設(shè)置就是在截圖圈紅部分另伍,然后從this.rpcPortOffset()我們可以發(fā)現(xiàn)
public int rpcPortOffset() {
return Integer.parseInt(System.getProperty("nacos.server.grpc.port.offset", String.valueOf(Constants.SDK_GRPC_PORT_DEFAULT_OFFSET)));
}
這個(gè)偏移量是可以通過(guò)nacos.server.grpc.port.offset進(jìn)行修改摆尝,不修改默認(rèn)就是1000。因此跟蹤源碼勺爱,我們可以得出另外一種解法讯检。在微服務(wù)的nacos配置仍然填代理的nginx 的tcp地址,示例
spring.cloud.nacos.discovery.server-addr=127.0.0.1:9848 #nginx代理tcp的地址
同時(shí)啟動(dòng)的時(shí)候围段,加上
-Dnacos.server.grpc.port.offset=0
或者在主啟動(dòng)類(lèi)硬編碼也 可以
System.setProperty("nacos.server.grpc.port.offset","0");
注: 這邊很重要的細(xì)節(jié)點(diǎn)就是:GRPC port = 主端口 + grpc端口偏移量投放,這個(gè)計(jì)算出來(lái)的端口值要和nginx代理tcp 端口值相等灸芳。
總結(jié)
因?yàn)榕笥延玫氖悄壳白钚掳娴膎acos2,所以有些問(wèn)題搜索引擎不是那么好找答案烙样,因此遇到這種問(wèn)題谒获,最好的解題思路就是官網(wǎng)和相應(yīng)的github,還有就是源碼跟蹤了。
后面那個(gè)
Client not connected, current status:STARTING儒洛,其實(shí)還有一種解法,就是把客戶(hù)端版本調(diào)低到1.x版本卦停,因?yàn)檫@個(gè)問(wèn)題本質(zhì)上是連接不上grpc問(wèn)題,因此我們可以不用grpc僵芹,直接用http就好了小槐,而2.x服務(wù)端版本是同時(shí)支持http和grpc凿跳,因此客戶(hù)端版本調(diào)成1.x,他就是以http的方式和服務(wù)端進(jìn)行交互茧彤。不過(guò)是不建議這么做疆栏,因?yàn)槟闵?jí)了2.x,有一方面就是為高性能珠洗,如果把版本降低博助,那還不如直接使用1.x就好了。
還有文中的那兩種解法蛔糯,我個(gè)人是建議不要改偏移量窖式,直接通過(guò)主端口 + 1000這種方式去算就好了
附錄
本文很多關(guān)于nacos2解題思路都是出自官網(wǎng)這篇文章