一個新節點經過已知的節點加入到網絡中,此時,它所知的網絡節點信息是很是有限的,須要經過節點發現獲知更多的節點,創建起足夠的鏈接。另外,當一個新節點加入到網絡時,原有網絡節點也須要經過節點發現感知到新節點的加入。bootstrap
分佈在各地的網絡節點老是會有上線離線的變化,有這就須要Fabric網絡必須動態維護一個節點成員列表,這就須要節點成員管理。網絡
一個節點要加入Fabric網絡,必需要知道至少一個已知Fabric節點做爲啓動節點。ide
相關配置以下:ui
# Gossip related configuration gossip: # Bootstrap set to initialize gossip with bootstrap: 127.0.0.1:7051
Fabric節點發現與成員管理流程以下圖所示:
this
在線節點(Peer)經過持續不斷地廣播「活着」的消息,來代表他們的可用性。spa
這一部分至關於心跳檢測,若是節點離線,就在channel成員列表中刪除節點。3d
// AliveMessage is sent to inform remote peers // of a peer's existence and activity message AliveMessage { Member membership = 1; PeerTime timestamp = 2; bytes identity = 4; } // MembershipRequest is used to ask membership information // from a remote peer message MembershipRequest { Envelope self_information = 1; repeated bytes known = 2; } // MembershipResponse is used for replying to MembershipRequests message MembershipResponse { repeated Envelope alive = 1; repeated Envelope dead = 2; }
這裏採用的是push和pull方式。code
節點有了新消息後,隨機選擇\(k\)個節點(例如,3),向它們發送新消息。\(k\)個節點收到後,繼續隨機選擇\(k\)個節點發送新信息,直到全部節點都知道該新信息。orm
全部節點週期性的隨機選取\(k\)個(默認配置=3)個節點,向它們獲取數據。Fabric中gossip協議pull操做以下:
blog
/* PullEngine is an object that performs pull-based gossip, and maintains an internal state of items identified by string numbers. The protocol is as follows: 1) The Initiator sends a Hello message with a specific NONCE to a set of remote peers. 2) Each remote peer responds with a digest of its messages and returns that NONCE. 3) The initiator checks the validity of the NONCEs received, aggregates the digests, and crafts a request containing specific item ids it wants to receive from each remote peer and then sends each request to its corresponding peer. 4) Each peer sends back the response containing the items requested, if it still holds them and the NONCE. Other peer Initiator O <-------- Hello <NONCE> ------------------------- O /|\ --------- Digest <[3,5,8, 10...], NONCE> --------> /|\ | <-------- Request <[3,8], NONCE> ----------------- | / \ --------- Response <[item3, item8], NONCE>-------> / \ */
// GossipHello is the message that is used for the peer to initiate // a pull round with another peer message GossipHello { uint64 nonce = 1; bytes metadata = 2; PullMsgType msg_type = 3; } // DataDigest is the message sent from the receiver peer // to the initator peer and contains the data items it has message DataDigest { uint64 nonce = 1; repeated bytes digests = 2; // Maybe change this to bitmap later on PullMsgType msg_type = 3; } // DataRequest is a message used for a peer to request // certain data blocks from a remote peer message DataRequest { uint64 nonce = 1; repeated bytes digests = 2; PullMsgType msg_type = 3; } // DataUpdate is the final message in the pull phase // sent from the receiver to the initiator message DataUpdate { uint64 nonce = 1; repeated Envelope data = 2; PullMsgType msg_type = 3; }