來談談Incoming connections與Outoging connections的數量。
一、TCP連線
首先了解TCP怎麼建立連線。通常是由一端(伺服器端)打開一個通訊端(socket)然後監聽來自另一方(客戶端)的連接,這就是通常所指的被動打開(passive open)。伺服器端被被動打開以後,客戶端就能開始建立主動打開(active open)。
當你的節點有開通PORT 31401-31403,就是扮演伺服器端的角色,監聽著PORT 31402,等待其他節點(客戶端)發起連線。如果有其他節點連進來,Incoming connections就會加一。
反過來,你的節點想連到其他節點,就是扮演客戶端的角色,其他節點(伺服器端)必須開通PORT 31402讓你連進去。如果成功建立連線,你的Outoging connections就會加一。
而Pi節點是一個點對點網路(peer-to-peer,P2P),彼此傳遞交易與SCP訊息,所以必然會有Outoging與Incoming連線。
二、參數
連線數分別可以透過TARGET_PEER_CONNECTIONS(out)、MAX_ADDITIONAL_PEER_CONNECTIONS(in)參數來設定,目前stellar-core.cfg都沒有設定,所以是採用預設值out 8、in 64。
三、peers
core資料庫內有一個public.peers表格,存放了其他節點的資訊。節點跟節點之間,會彼此分享這些資料。
你的節點會連接到哪些節點,就是由這個清單一台一台的嘗試。反過來說,其他節點會不會連進來,也是看你的節點有沒有在對方的peers表格內。
(不要問怎麼查這些資料,因為讓一位不懂資料庫的人去操作資料庫,是一件很危險的事,所以我不打算寫出來。)
一開始你的節點並不知道網路上有哪些節點,只知道核心團隊的節點(在KNOWN_PEERS與PREFERRED_PEERS參數設定),所以起初資料是連到核心團隊節點取得的。當你(out)連線到其他節點(in),你只會從對方節點隨機得到幾筆IP資料,而不是整個peers表格。
peers表格有5個欄位:
l ip:這個不用解釋
l port:都是31402
l nextattempt:下一次嘗試連線的時間
l numfailures:連線失敗的次數,超過120次會刪除
l type:有3種
n 0:還沒有連線成功,會重複嘗試連線
n 1:曾經連線成功
n 2:preferred peer,優先選擇的節點,目前全網就三個IP:161.35.227.222、161.35.227.224、161.35.238.87。都是核心團隊的節點。
你的節點會依照nextattempt的時間順序,不斷嘗試向其他節點發起連線。如果網路不通、SYN-SENT封包根本沒回應,numfailures會加一,type設定為0。然後試下一個節點。
當全部試過後,type = 0的節點會再重試,nextattempt的時間會往後延。而嘗試失敗120次(numfailures = 120)的節點,該筆資料會被刪除。
如果網路有通,TCP三向交握能完成,會做身分驗證,建立起連線,numfailures會設定為0、type設定為1。但這個連線不一定會持續,可能馬上就中斷(peer rejected),因為你的Outoging connections已經8了,或是對方的Incoming connections已經64了,無法再容納新的連線。
如果你目前嘗試連過去的節點是preferred peer,而且有回應,但是Outoging connections已經滿了,這時會自動砍掉一個Outoging connection,好讓出名額。但是也要看對方的Incoming connections有沒有滿,若滿了,一樣無法維持連線。下圖的log就是這種情況。
preferred peer的連線如果失敗或中斷了,nextattempt時間都會往後延,過一段時間再試,也就是說它會無限次嘗試連線。而其他節點嘗試失敗就算了,過去就不回頭了(要等全部試完一輪才重試)。
另外,節點之間的連線一旦建立了,基本上就不會中斷,可以從elapsed看到已連線的秒數。
但偶爾還是會變動,例如對方(或自己)的節點網路斷線、換IP、關機,或是為了preferred peer踢掉其他連線。
四、手動連線
stellar-core http-command connect?"peer=xxx.xxx.xxx.xxx&port=31402"
上面的xxx.xxx.xxx.xxx是IP。
這個指令不一定成功,原因上面講過了,可能網路根本不通,或是彼此的in/out連線數滿了。
五、刪除連線
先查出節點的ID:
stellar-core http-command peers?fullkeys=true
刪除連線:
stellar-core http-command droppeer?node="GD5OPFFD2ANXGPHJ76FYAYAEMXNHRQ5JMQ5OHBWA4LJOQ3GEOGEO3EIF"
填入要中斷連線的節點ID。
這樣就能空出一個out連線的位置,不過通常馬上就被補上了。
六、結論
如果你的Incoming connections數量很低,不是什麼不正常的情況,可能其他節點不認識你(peers表格沒有你的資訊),或是對方嘗試過連線了,但它的Outoging connections已經8個了,所以就放棄你。只要節點在網路上掛的越久,且IP沒有一直換,會有越多的節點認識你,Incoming connections數量有機會增加。
再舉個例子說明,假設全網共有20000台節點,總共會發出160000(20000*8=160000)個Outoging connections,則至少要有2500(160000/64=2500)台節點有開通PORT 31402讓其他節點連入。
如果這時候有8000台節點開PORT,則平均Incoming connections數量是20(160000/8000=20)。20就只是一個平均值,既然稱為平均值,就會有人多、有人少,所以沒有任何意義,不是成為超節的資格。只要有開PORT,就有資格被選為超節。
而在8000台節點有開PORT的情況下,整個網路最多可容納64000(8000*64/8=64000)台節點,所以從20000台再多加44000台沒開PORT的節點也沒問題。
上面節點數量大家能隨意替換數字,自己計算一下就了解了。總之,不要再牽拖Docker的版本,或是下雨天了。討論這個數字也沒意義。
七、附上老尼回答Pi友的翻譯
输入连接越多,表示被访问的次数自然越多。
@尼古拉斯:“其他节点找不到您要连接的对象,并且您没有太多传入连接,这可能有多种原因。这些原因大多与运气有关。通常,当一个新节点尝试连接时(或者在计算机重新启动或从睡眠状态恢复后),它会尝试从它已“学习”的IP列表中查找其他节点。如果这些节点具有可用的传入连接,则新节点将连接到它们。
如果没有可用的传入连接,则会将其已知节点IP列表提供给请求节点并关闭连接。然后新节点尝试连接到这些IP并不断发现更多IP,直到它成功连接到8个节点。由于这个过程包含一定程度的随机性,一些节点变得更加广为人知,而另一些节点则不那么广为人知。让你的IP地址不经常改变,这对你在网络中的知名度有很大帮助。还有一点是你与核心团队节点的距离。
连接到一个核心团队节点的64个节点很可能总是将其所有的64个传入连接都填满。这是因为全新的节点不知道其他节点,它们最初尝试连接到核心团队的节点,它们可能会收到“拒绝”和已知IP的列表。直接连接到核心团队节点上的节点的IP被这些节点明确地知道,因此也很容易被发现。在您提问之前:哪些节点最终连接到核心团队节点是完全随机的。
核心团队节点相互优先,并始终相互接受。对于其余的64个传入连接,它们以先到先服务的方式接受任何其他节点。但是,连接到核心团队节点并不重要,区块链在任何地方都是相同的,甚至一个字节的差异都会立即触发错误,因为这会使块散列无效。”