Hyperledger Fabric是最主流的联盟链框架。我用Fabric做了一年多的企业级项目。踩了很多坑。本文是我的踩坑总结。包括环境搭建、链码开发、节点管理、权限控制、性能优化、升级维护等各个方面的坑。以及对应的解决方法。这些都是我亲身经历过的问题。希望能帮到正在做Fabric开发的你。让你少走弯路。

一、写在前面

先说说我和Fabric的故事。

我们公司要做一个企业级的联盟链项目。多方参与。需要数据共享和信任。调研之后选了Hyperledger Fabric。因为它是目前最成熟的联盟链框架。支持权限管理。支持私有数据。性能也还可以。

最开始我觉得Fabric就是一个区块链框架。和其他后端技术差不多。学一学就能上手。但是真正做了之后才发现。Fabric的复杂度远超我的想象。概念多。配置复杂。坑也多。

这一年多我踩了很多坑。有些坑折腾了好几天才解决。这篇文章就是我踩坑的总结。希望能帮到大家。

二、环境搭建的坑

坑1:版本不兼容

Fabric的版本更新比较快。不同版本之间的API和配置格式可能不一样。我们最开始用的是1.4版本。后来想升级到2.0版本。结果发现很多API都变了。链码也需要重写。折腾了很久才升级完成。

解决方法是:项目开始之前就确定好版本。不要轻易升级。如果一定要升级。先仔细看官方的升级文档。在测试环境充分测试之后再升级生产环境。

还有一个坑是Fabric的各个组件版本要一致。Peer、Orderer、CLI、SDK的版本要匹配。否则可能会出现兼容性问题。我们就遇到过Peer是2.2版本。SDK是1.4版本。结果调用链码一直报错。查了很久才发现是版本不匹配。

坑2:Docker环境问题

Fabric一般用Docker部署。Docker的版本和配置也很重要。我们最开始用的Docker版本太旧。导致Fabric的容器启动失败。后来升级了Docker版本才解决。

还有Docker的资源限制问题。Fabric的节点比较消耗资源。如果Docker分配的内存和CPU不够。节点会很卡。甚至会OOM被系统杀掉。

解决方法是:用较新的稳定版Docker。给Docker分配足够的资源。至少4核8G。生产环境建议8核16G以上。

坑3:网络配置复杂

Fabric的网络配置非常复杂。包括组织、节点、通道、证书、MSP等。配置文件很多。格式要求严格。一个地方配错了。整个网络就起不来。

我们最开始搭建网络的时候。因为一个证书路径配错了。节点启动失败。查了一整天才找到原因。

解决方法是:先用官方的测试网络跑通。然后在测试网络的基础上慢慢修改。不要一开始就自己从零写配置。每改一个配置就测试一次。不要一次改很多。否则出了问题不知道是哪里改坏的。

三、链码开发的坑

坑4:链码逻辑设计不合理

链码(智能合约)是Fabric的核心。链码的设计直接影响整个系统的功能和性能。我们最开始设计链码的时候。把所有业务逻辑都写在一个链码里。结果链码越来越大。越来越难维护。修改一个小功能就要重新部署整个链码。

后来我们把链码拆分成了多个。每个链码负责一个业务领域。这样维护起来就方便多了。

解决方法是:合理拆分链码。按照业务领域来划分。每个链码的职责要单一。不要把所有逻辑都塞在一个链码里。链码之间可以通过跨链码调用来交互。但是要注意跨链码调用的性能开销。

坑5:状态数据设计不合理

Fabric用LevelDB或者CouchDB来存储状态。状态数据的设计很重要。我们最开始把所有数据都存在一个key下面。结果数据越来越大。查询和修改都很慢。

后来我们对数据做了拆分。按照业务类型和查询需求来设计key。用复合键来支持多维度查询。性能提升了很多。

解决方法是:根据查询需求来设计状态数据的结构。如果需要复杂查询。用CouchDB作为状态数据库。合理设计文档结构。用复合键来支持范围查询。不要把所有数据都存在一个key下面。

坑6:不处理并发冲突

Fabric的交易是先背书后排序。如果多个交易同时修改同一个key。就会出现并发冲突。后面的交易会被拒绝。我们最开始没有考虑这个问题。结果在高并发的时候。很多交易失败了。

解决方法是:在应用层处理并发冲突。交易失败之后重试。或者设计数据结构的时候尽量避免多个交易修改同一个key。比如把一个大的key拆分成多个小的key。减少冲突的概率。

坑7:链码升级不向后兼容

链码升级是Fabric开发中常见的操作。但是如果升级的时候不注意向后兼容。就会出问题。我们有一次升级链码。修改了数据结构。结果旧的数据读不出来了。整个系统都用不了了。

解决方法是:链码升级要保证向后兼容。数据结构的修改要考虑旧数据的迁移。可以在链码里加一个数据迁移的逻辑。升级的时候自动把旧数据转换成新格式。升级之前要在测试环境充分测试。特别是旧数据的读取和迁移。

四、节点管理的坑

坑8:节点崩溃后恢复困难

Fabric的节点如果崩溃了。恢复起来比较麻烦。我们有一次Peer节点的磁盘满了。节点崩溃了。数据也损坏了。恢复的时候花了很长时间。

解决方法是:定期备份节点的数据。包括账本数据和状态数据库。监控节点的磁盘使用率。超过80%就告警。节点崩溃之后。可以用备份恢复。或者从其他节点同步账本数据。

坑9:Orderer节点单点故障

Fabric的Orderer节点负责交易排序。如果用的是单节点的Orderer。就会有单点故障的问题。Orderer挂了整个网络就不能提交交易了。

我们最开始用的是单节点Orderer。有一次Orderer挂了。整个系统停了好几个小时。后来我们换成了Raft共识的多节点Orderer。就没有这个问题了。

解决方法是:生产环境一定要用多节点的Orderer。用Raft或者Kafka共识。不要用单节点的Solo共识。Solo只适合开发和测试。

坑10:证书过期

Fabric用证书来做身份认证和权限控制。证书是有有效期的。我们最开始没有注意证书过期的问题。结果有一天证书过期了。整个网络都不能用了。所有节点都连不上。

解决方法是:记录所有证书的过期时间。提前准备续期。Fabric 2.0之后支持证书续期。可以在不重启网络的情况下更新证书。监控证书的过期时间。提前一个月就开始准备续期。

五、权限控制的坑

坑11:权限设计太粗或者太细

Fabric的权限控制很灵活。可以在组织、节点、通道、链码、键值等多个层面做权限控制。但是权限设计是一个难点。太粗了起不到控制作用。太细了管理起来很复杂。

我们最开始权限设计得太粗。所有成员都能读写所有数据。后来发现不符合业务需求。又改成了很细的权限。结果管理起来非常复杂。新增一个成员要配置很多东西。

后来我们找到了一个平衡点。按照业务角色来设计权限。每个角色有一组权限。成员分配角色就可以了。这样既灵活又好管理。

解决方法是:先理清业务需求。确定有哪些角色。每个角色能做什么不能做什么。然后按照角色来设计权限。不要一开始就做得太细。可以先粗一点。然后根据需要慢慢细化。

坑12:私有数据使用不当

Fabric支持私有数据(Private Data)。可以让部分成员看到数据。其他成员只能看到哈希。我们最开始想用私有数据来保护敏感信息。结果用了之后发现。私有数据的管理很复杂。而且查询和同步都有一些限制。

后来我们只在真正需要保护的敏感数据上用私有数据。大部分数据还是用普通的通道数据。这样就简单多了。

解决方法是:私有数据只用于真正敏感的、只有部分成员需要看到的数据。不要滥用私有数据。使用之前要充分了解私有数据的特性和限制。在测试环境充分测试。

六、性能优化的坑

坑13:TPS上不去

Fabric的性能一直是大家关心的问题。我们最开始做的系统。TPS只有几十。远远达不到业务需求。

后来做了很多优化。TPS提升到了几百。优化的方法包括:增加Peer节点的数量。用批量提交。优化链码逻辑。减少跨链码调用。用CouchDB的时候加索引。调整Orderer的批量参数等。

解决方法是:性能优化是一个系统工程。要从多个层面入手。先找到性能瓶颈在哪里。然后针对性地优化。不要盲目优化。可以用Fabric的性能分析工具来定位瓶颈。

坑14:查询性能差

Fabric的查询性能也很重要。特别是数据量大了之后。查询会变慢。我们最开始数据量到了几十万条之后。查询一次要好几秒。用户体验很差。

后来我们做了优化。给CouchDB加了索引。优化了查询语句。限制了每次查询返回的数据量。增加了分页查询。查询性能提升了很多。

解决方法是:用CouchDB作为状态数据库的时候。一定要给常用的查询字段加索引。避免全表扫描。查询的时候用分页。不要一次返回太多数据。复杂的查询可以考虑用链码来实现。在链码里做过滤和聚合。

七、升级维护的坑

坑15:升级链码影响业务

链码升级是不可避免的。但是如果升级方式不对。会影响业务。我们最开始升级链码的时候。直接在生产环境升级。结果升级过程中有几分钟的时间交易失败了。影响了用户使用。

后来我们改成了灰度升级。先在部分节点升级。观察没问题之后再全部升级。而且选择在业务低峰期升级。减少对用户的影响。

解决方法是:链码升级要在业务低峰期做。升级之前在测试环境充分测试。升级的时候可以用灰度发布。先升级部分节点。观察没问题之后再全部升级。升级之后要监控交易成功率和性能。发现问题及时回滚。

坑16:没有监控告警

我们最开始没有做监控告警。节点出了问题都不知道。直到用户反馈了才发现。有一次一个Peer节点挂了三天。我们都不知道。

后来我们加了完整的监控。包括节点状态、交易成功率、交易延迟、磁盘使用率、CPU和内存使用率等。出了问题立刻告警。

解决方法是:生产环境一定要有监控告警。监控节点的状态和性能。监控交易的成功率和延迟。监控资源使用率。设置合理的告警阈值。出了问题能第一时间发现和处理。

八、给新手的建议

如果你是Fabric开发新手。我有几个建议。

1. 先理解概念再动手

Fabric的概念很多。组织、节点、通道、链码、MSP、证书、共识等。在动手之前。先把这些概念理解清楚。否则写代码和配置的时候会很迷茫。

可以先看官方文档。再看一些入门教程。把基本概念搞懂了再开始写代码。

2. 从官方测试网络开始

不要一开始就自己搭建网络。先用官方的测试网络跑通。熟悉基本的操作和流程。然后在测试网络的基础上慢慢修改。这样可以避免很多配置的坑。

3. 多做测试

Fabric的复杂度高。很多问题只有在测试中才能发现。要多做测试。单元测试、集成测试、压力测试都要做。特别是链码的测试。要覆盖各种边界情况。

4. 做好文档

Fabric的配置和操作都很复杂。一定要做好文档。记录网络拓扑、配置参数、操作步骤、常见问题等。否则过一段时间自己都忘了怎么操作。

5. 关注社区

Fabric的社区很活跃。有问题可以在社区提问。也可以关注社区的动态。了解新的版本和新的特性。很多坑社区里已经有人踩过了。可以参考他们的解决方案。

九、写在最后

Fabric是一个功能强大但是复杂度很高的联盟链框架。用它做企业级项目。确实会踩很多坑。但是只要理解了它的设计理念。掌握了基本的操作和最佳实践。这些坑都是可以避免的。

这篇文章总结了我一年多踩过的16个坑。每个坑都是亲身经历。希望能帮到正在做Fabric开发的你。让你少走弯路。

当然Fabric还在快速发展。很多坑在新版本中已经被修复或者优化了。这篇文章基于的是2021年的版本。如果你用的是更新的版本。有些坑可能已经不存在了。具体情况还要看你用的版本。

最后用一句话结束本文:"Fabric很复杂。但是复杂的背后是强大的功能和灵活性。只要踩过了这些坑。它就能帮你构建可靠的企业级联盟链应用。"希望每一个Fabric开发者都能顺利完成项目。推动区块链技术的落地和发展。