Hyperledger Fabric Orderer节点启动
Orderer 节点启动通过 orderer
包下的 main() 方法实现,会进一步调用到 orderer/common/server
包中的 Main()
方法。
核心代码如下所示。
// Main is the entry point of orderer process
func Main() {
fullCmd := kingpin.MustParse(app.Parse(os.Args[1:])) // "version" command
if fullCmd == version.FullCommand() {
fmt.Println(metadata.GetVersionInfo())
return
} conf := config.Load()
initializeLoggingLevel(conf)
initializeLocalMsp(conf) Start(fullCmd, conf)
}
包括配置初始化过程和核心启动过程两个部分:
- config.Load():从本地配置文件和环境变量中读取配置信息,构建配置树结构。
- initializeLoggingLevel(conf):配置日志级别。
- initializeLocalMsp(conf):配置 MSP 结构。
- Start():完成启动后的核心工作。
整体过程
核心启动过程都在 orderer/common/server
包中的 Start() 方法,如下图所示。
Start() 方法会初始化 gRPC 服务需要的结构,然后启动服务。
核心代码如下所示。
func Start(cmd string, conf *config.TopLevel) {
logger.Debugf("Start()")
signer := localmsp.NewSigner()
manager := initializeMultichannelRegistrar(conf, signer)
server := NewServer(manager, signer, &conf.Debug) switch cmd {
case start.FullCommand(): // "start" command
logger.Infof("Starting %s", metadata.GetVersionInfo())
initializeProfilingService(conf)
grpcServer := initializeGrpcServer(conf)
ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server)
logger.Info("Beginning to serve requests")
grpcServer.Start()
case benchmark.FullCommand(): // "benchmark" command
logger.Info("Starting orderer in benchmark mode")
benchmarkServer := performance.GetBenchmarkServer()
benchmarkServer.RegisterService(server)
benchmarkServer.Start()
}
}
包括两大部分:
- gRPC 服务结构初始化;
- gRPC 服务启动。
gRPC 服务结构初始化
包括创建新的 MSP 签名结构,初始化 Registrar 结构来管理各个账本结构,启动共识过程,以及创建 gRPC 服务端结构。
核心步骤包括:
signer := localmsp.NewSigner() // 初始化签名结构
manager := initializeMultichannelRegistrar(conf, signer, tlsCallback) // 初始化账本管理器(Registrar)结构
其中,initializeMultichannelRegistrar(conf, signer)
方法最为关键,核心代码如下:
func initializeMultichannelRegistrar(conf *config.TopLevel, signer crypto.LocalSigner, callbacks ...func(bundle *channelconfig.Bundle)) *multichannel.Registrar {
// 创建操作账本的工厂结构
lf, _ := createLedgerFactory(conf) // 如果是首次启动情况,默认先创建系统通道的本地账本结构
if len(lf.ChainIDs()) == 0 {
logger.Debugf("There is no chain, hence we must be in bootstrapping")
initializeBootstrapChannel(conf, lf)
} else {
logger.Info("Not bootstrapping because of existing chains")
}
//初始化共识插件,共识插件负责跟后台的队列打交道
consenters := make(map[string]consensus.Consenter)
consenters["solo"] = solo.New()
consenters["kafka"] = kafka.New(conf.Kafka.TLS, conf.Kafka.Retry, conf.Kafka.Version, conf.Kafka.Verbose) // 创建各个账本的管理器(Registrar)结构,并启动共识过程
return multichannel.NewRegistrar(lf, consenters, signer, callbacks...)
}
利用传入的配置信息和签名信息完成如下步骤:
- 创建账本操作的工厂结构;
- 如果是新启动情况,利用给定的系统初始区块文件初始化系统通道的相关结构;
- 完成共识插件(包括
solo
和kafka
两种)的初始化; multichannel.NewRegistrar(lf, consenters, signer)
方法会扫描本地账本数据(此时至少已存在系统通道),创建 Registrar 结构,并为每个账本都启动共识(如 Kafka 排序)过程。
说明:Registrar 结构(位于 orderer.common.multichannel
包)是 Orderer 组件中最核心的结构,管理了 Orderer 中所有的账本、共识插件等数据结构。
创建 Registrar 结构并启动共识过程
NewRegistrar(lf, consenters, signer)
方法位于 orderer.common.multichannel
包,负责初始化链支持、消息处理器等重要数据结构,并为各个账本启动共识过程。
核心代码如下:
existingChains := ledgerFactory.ChainIDs()
for _, chainID := range existingChains { // 启动本地所有的账本结构的共识过程
if _, ok := ledgerResources.ConsortiumsConfig(); ok { // 如果是系统账本(默认在首次启动时会自动创建)
chain := newChainSupport(r, ledgerResources, consenters, signer)
chain.Processor = msgprocessor.NewSystemChannel(chain, r.templator, msgprocessor.CreateSystemChannelFilters(r, chain))
r.chains[chainID] = chain
r.systemChannelID = chainID
r.systemChannel = chain
defer chain.start() // 启动共识过程
else // 如果是应用账本
chain := newChainSupport(r, ledgerResources, consenters, signer)
r.chains[chainID] = chain
chain.start() // 启动共识过程
}
chain.start()
方法负责启动共识过程。以 Kafka 共识插件为例,最终以协程方式调用到 orderer.consensus.kafka
包中的 startThread()
方法,将在后台持续运行。
func (chain *chainImpl) Start() {
go startThread(chain)
}
startThread()
方法将为指定的账本结构配置共识服务,并将其启动,核心代码包括:
// 创建 Producer 结构
chain.producer, err = setupProducerForChannel(chain.consenter.retryOptions(), chain.haltChan, chain.SharedConfig().KafkaBrokers(), chain.consenter.brokerConfig(), chain.channel)
// 发送 CONNECT 消息给 Kafka,如果失败,则退出
sendConnectMessage(chain.consenter.retryOptions(), chain.haltChan, chain.producer, chain.channel) // 创建处理对应 Kafka topic 的 Consumer 结构
chain.parentConsumer, err = setupParentConsumerForChannel(chain.consenter.retryOptions(), chain.haltChan, chain.SharedConfig().KafkaBrokers(), chain.consenter.brokerConfig(), chain.channel)
// 配置从指定 partition 读取消息的 PartitionConsumer 结构
chain.channelConsumer, err = setupChannelConsumerForChannel(chain.consenter.retryOptions(), chain.haltChan, chain.parentConsumer, chain.channel, chain.lastOffsetPersisted+1) // 从该链对应的 Kafka 分区不断读取消息,并进行处理过程
chain.processMessagesToBlocks()
主要包括如下步骤:
- 创建到 Kafka 集群的 Producer 结构并发送 CONNECT 消息;
- 为对应的 topic 创建 Consumer 结构,并配置从指定分区读取消息的 PartitionConsumer 结构;
- 对链对应的 Kafka 分区中消息的进行循环处理。这部分更详细内容可以参考 Orderer 节点对排序后消息的处理过程。
gRPC 服务启动
初始化 gRPC 服务结构,完成绑定并启动监听。
// 初始化 gRPC 服务端结构
server := NewServer(manager, signer, &conf.Debug) // 创建 gRPC 服务连接
grpcServer := initializeGrpcServer(conf) // 绑定 gRPC 服务并启动
ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server)
grpcServer.Start()
其中,NewServer(manager, signer, &conf.Debug)
方法(位于 orderer.common.server
包)最为核心,将 gRPC 相关的服务结构进行初始化,并绑定到 gRPC 请求上。分别响应 Deliver() 和 Broadcast() 两个 gRPC 调用。
// NewServer creates an ab.AtomicBroadcastServer based on the broadcast target and ledger Reader
func NewServer(r *multichannel.Registrar, _ crypto.LocalSigner, debug *localconfig.Debug) ab.AtomicBroadcastServer {
s := &server{
dh: deliver.NewHandlerImpl(deliverSupport{Registrar: r}),
bh: broadcast.NewHandlerImpl(broadcastSupport{Registrar: r}),
debug: debug,
}
return s
} 来源:https://github.com/yeasy/hyperledger_code_fabric/blob/master/process/orderer_start.md
Hyperledger Fabric Orderer节点启动的更多相关文章
- hyperledger fabric各类节点及其故障分析 摘自https://www.cnblogs.com/preminem/p/8729781.html
hyperledger fabric各类节点及其故障分析 1.Client节点 client代表由最终用户操作的实体,它必须连接到某一个peer节点或者orderer节点上与区块链网络通信.客户端 ...
- hyperledger fabric各类节点及其故障分析
1.Client节点 client代表由最终用户操作的实体,它必须连接到某一个peer节点或者orderer节点上与区块链网络通信.客户端向endorser提交交易提案,当收集到足够背书后,向排序服务 ...
- 7.搭建hyperledger fabric环境及启动——2019年12月12日
2019年12月12日13:05:16 声明:从网络中学习整理实践而来. 1.介绍fabric Fabric 是一个面向企业应用的区块链框架,基于 Fabric 的开发可以粗略分为几个层面: 1. 参 ...
- Hyperledger Fabric的test-network启动过程Bash源码详解
前言 在基于Debian搭建Hyperledger Fabric 2.4开发环境及运行简单案例中,我们已经完成了Fabric 2.4的环境搭建及fabric-samples/test-network官 ...
- Hyperledger Fabric网络节点架构
Fabric区块链网络的组成  区块链网络结构图 区块链网络组成 组成区块链网络相关的节点 节点是区块链的通信主体,和区块链网络相关的节点有多种类型:客户端(应用).Peer节点.排序服务(Orde ...
- 死磕hyperledger fabric源码|Order节点概述
死磕hyperledger fabric源码|Order节点概述 文章及代码:https://github.com/blockchainGuide/ 分支:v1.1.0 前言及源码目录 Orderer ...
- 基于docker的 Hyperledger Fabric 多机环境搭建(上)
环境:ubuntu 16.04 Docker 17.04.0-ce go 1.7.4 consoul v0.8.0.4 ======================================= ...
- Centos7 HyperLedger Fabric 1.4 生产环境部署
Kafka生产环境部署案例采用三个排序(orderer)服务.四个kafka.三个zookeeper和四个节点(peer)组成,共准备八台服务器,每台服务器对应的服务如下所示: kafka案例网络拓扑 ...
- Hyperledger Fabric 入门 first-network 搭建
1.准备环境: 安装git.docker.curl.go [root@test_vonedao_83 fabric]# git --version git version 1.8.3.1 [root@ ...
随机推荐
- openfaas 简单试用
1. 安装 faas-cli 参考以前文章,或者使用官方的shell脚本 2. 简单例子 mkdir rong cd rong faas-cli new rong --lang python / ...
- ORACLE系统表大全
下面全面是对Oracle系统表的一些介绍: 数据字典dict总是属于Oracle用户sys的. 1.用户: select username from dba_users; 改口令 alter user ...
- bzoj 4671 异或图——容斥+斯特林反演+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 考虑计算不是连通图的方案,乘上容斥系数来进行容斥. 可以枚举子集划分(复杂度是O(Be ...
- 微信H5支付 EasyWechat
其中如果想在一个laravel中使用多个不同主题的支付账户,可以在方法实例对象时,将对应的参数进行修改配置. 其中小程序支付,已得到验证. 1.公众号支付等资格申请 2.公众号对应的支付商户主体申请 ...
- 【转】jmeter压力测试
jmeter压力测试 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域, 是压力测试的首选软件 ...
- Python 列表笔记
列表解析 squares = []for i in range(1,11): square = i**2 squares.append(square)print squares ########## ...
- java输入月份,年份,显示对应月份的天数,
总结:1,输入月份,年份,这需要用Scanner 2.我们已知道12个月份的天数,有30天,31天 3.判断闰年 用switch -case-break语句 4.注意不要忘了写break;判 ...
- php中的list方法
list 栗子一: <?php $info = array('coffee', 'brown', 'caffeine'); // 列出所有变量 list($drink, $color, $pow ...
- PCB上 如何显示 汉字
原理图上有汉字,那如何在PCB上显示汉子呢 ? 而不至于显示乱码 按如下操作 ,双击乱码 ,进入设置模式 设置好后,显示的字体样式.
- StarkSoft题库管理系统
一.功能介绍 1.自定义试题库管理系统目录.难易程度,题型,知识库等. 2.试题录入. 3.强大的试题编辑功能,并与通常应用编辑工具有共通. 4.灵活的试卷构造功能,用户可自定 ...