服务发现¶
为什么我们需要服务发现?¶
为了在 Peer 节点上执行链码、向排序节点提交交易以及更新交易的状态,应用程序需要连接到 SDK 暴露的 API。
然而,SDK 为了让应用程序连接到网络中对应的节点需要很多信息。除了 CA 已经通道中的排序节点和 Peer 节点的 TLS 证书,包括他们的 IP 地址和端口号,还有它必须知道相应的背书策略以及哪些 Peer 节点安装了链码(这样应用程序才知道应该将链码提案发送到哪些 Peer 节点)。
在 v1.2 之前,这些信息是静态编码的。然而,这种方式不能动态适应网络的变化(比如增加了安装相应链码的 Peer 节点,或者某些节点临时离线)。静态配置同样也不能让应用程序适应背书策略的变化(比如当一个组织加入到通道的时候,可能会改变背书策略)。
另外,客户端应用程序也没办法知道哪些 Peer 节点更新了账本,哪些没有更新账本。应用程序可能会向没有同步账本的 Peer 节点提交提案,会导致交易在提交过程中验证失败,造成资源浪费。
发现服务 让 Peer 动态计算需要的信息并且发送给 SDK,从而改进了这个过程。
Fabric 中的服务发现是如何运作的¶
应用程序在启动时会知道一组应用程序开发者或者管理员信任的 Peer 节点,以便对发现查询提供可信的响应。客户端应用程序的备选节点最好在同一个组织中。注意,为了让 Peer 知道发现服务,必须定义 EXTERNAL_ENDPOINT。要想知道如何定义,请参考 服务发现命令行界面 文档。
应用程序向发现服务发送一个配置查询,来获得所有的静态信息,如果没有获取到,就需要和网络中的其他节点进行通信。这些信息可以通过查询 Peer 节点的发现服务来更新。
发现服务运行在 Peer 节点上,而不是应用程序上,通过使用 gossip 通信层维护的网络元数据信息来查找在线的 Peer 节点。它也会从 Peer 节点的状态数据库中获取信息,比如相关的背书策略。
有了服务发现,应用程序就不需要在指定要哪些 Peer 来背书了。SDK 可以简单地向发现服务发送一个通道名和链码 ID 来查询需要哪些 Peer 节点。发现服务会计算出包含下边两个对象的描述:
- 布局(Layouts):一个 Peer 节点分组的列表和每组被选择的 Peer 节点的数量。
- Peer 节点和组的映射:从分布中的组到通道中的 Peer 节点。实际上,每个组中的节点都应该是同一个组织的,但是因为服务 API 是通用的并且没有区分组织,所以这里用“组”的概念。
下边是 AND(Org1, Org2) 策略的一个示例,其中每个组织有两个 Peer 节点。
Layouts: [
QuantitiesByGroup: {
“Org1”: 1,
“Org2”: 1,
}
],
EndorsersByGroups: {
“Org1”: [peer0.org1, peer1.org1],
“Org2”: [peer0.org2, peer1.org2]
}
换句话说,背书策略需要分别来自 Org1 和 Org2 中的一个 Peer 节点的签名。它还提供了这些组织中可用背书节点的名字(Org1 和 Org2 中的 peer0 和 peer1)。
然后 SDK 从列表中随机选取一个布局。在上边的示例中,背书策略是 Org1 AND Org2。如果使用 OR 的策略,SDK 就会随机选取 Org1 或 Org2,因为只要任意一个组织的 Peer 节点的签名就能够满足该策略。
在 SDK 选定布局之后,它会根据客户端定义的条件从布局中选出 Peer 节点(SDK 能做到这点,是因为它可以访问像账本高度这样的元数据)。例如,它可以根据布局中每个组的 Peer 节点序号选择账本高度较高的节点,或者排除离线的节点。如果选出的节点不止一个,SDK 会随机从中选取一个节点。
发现服务的作用¶
发现服务可以支持如下查询:
- 配置查询:返回通道中所有组织和排序节点的
MSPConfig。 - 节点成员查询:返回加入通道的 Peer 节点。
- 背书查询:返回通道中指定链码的背书描述。
- 本地节点成员查询:返回响应查询的 Peer 节点的本地成员信息。默认情况下,需要管理员身份的客户端响应该查询。
特殊要求¶
当 Peer 启用了 TLS 的时候,客户端要连接 Peer 节点也必须提供 TLS 证书。如果 Peer 节点没有要求验证客户端证书(clientAuthRequired 设置为 false),这个 TLS 证书就可以是自签名的。