fabirc1.0商业正式版本源码解析4——配置系统

2024-06-06 18:38

本文主要是介绍fabirc1.0商业正式版本源码解析4——配置系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

fabric的配置系统是程序原始数据的来源之一,虽然简单却很重要。在阅读源码过程中对于具象化程序也很有帮助。在分析peer的具体交易工作之前,我们可以先分析一下fabric的配置系统。我们还将我们的目光聚焦在/fabric/peer/main.Go的main函数中,除了一系列mainCmd的命令操作,还有viper进行的一系列配置操作,并通过err := common.InitConfig(cmdRoot)进行了配置的初始化。

fabric索取配置的途径有:环境变量,命令行参数,各种格式的配置文件。其中以配置文件为主,环境变量和命令行参数辅助,三者可以相互作用。主要的配置文件有core.yaml,orderer.yaml等,在/fabric/sampleconfig中有示例。主要使用的配置代码集中在/fabric/core/config下。

viper简介

fabric的配置系统主要运用第三方包viper,可在github.com/spf13/viper下载。viper可以对系统环境变量,yaml/json等格式的配置文件甚至是远程配置进行读取和设置,并可以在不重启服务的情况下动态设置新的配置项的值并使之实时生效,是一个专门处理配置的解决方案。 而且,viper,眼镜蛇,称自己与cobra(见peer命令结构一文)是companion,足见使用viper的理由。

viper的基础用法如下:

//设置一个要读取的配置文件名(不包含后缀),一个viper只支持一个文件名
viper.SetConfigName("config")
//设置一个搜索配置文件的路径,viper的搜索路径可以有多个
viper.AddConfigPath("/etc/appname/")
viper.AddConfigPath(".")
//读取配置文件
viper.ReadInConfig()
//获取其中一个name项的值
viper.Get("name")
//将name的值设置为Bill
viper.Set("name", "Bill")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

viper搜索路径和文件

peer命令对core.yaml的引入也是通过viper,具体过程如下:

  • /fabric/peer/main.go中定义const cmdRoot = "core"
  • main函数中调用err := common.InitConfig(cmdRoot),该参数一路向下传递。
  • InitConfig函数在/fabric/peer/common/common.go中定义,其中调用了config.InitViper(nil, cmdRoot)viper.ReadInConfig()
  • InitViper在/fabric/core/config/config.go中定义,接收cmdRoot作为参数,最终调用了viper.SetConfigName(),也即将core设置为了配置文件名。
  • common.InitConfig(cmdRoot)中的viper.ReadInConfig()则读取了该配置文件

orderer命令则使用orderer.yaml配置文件,由viper引入,具体过程如下:

  • 在/fabric/orderer/main.go中main函数调用了config.Load()
  • Load在/fabric/orderer/localconfig/config.go中定义。该文件中定义了Prefix = "ORDERER"configName string,并在init初始化函数中将configName赋值为strings.ToLower(Prefix),即orderer,也即所用的配置文件名为orderer。Load函数新建了一个用于orderer自己的viper,并调用了cf.InitViper(config, configName),其中config参数为新建的用于orderer自身的viper,configName为配置文件名orderer
  • InitViper在/fabric/core/config/config.go中定义,最终调用了viper.SetConfigName(),也即将orderer设置为了配置文件名
  • Load随后调用了config.ReadInConfig(),读取了配置文件

InitViper

上述步骤中peer和orderer在初始化配置文件时,最终都将调用的终点指向了/fabric/core/config/config.go中定义InitViper()。下面集中分析InitViper。

  • 首先判断环境变量FABRIC_CFG_PATH是否有值,如果有值,则是手工定义了FABRIC的配置文件所在路径。参考Getting Started中关于手工设置export FABRIC_CFG_PATH=$PWD(当前目录)。

  • 若没有定义该环境变量的值,则用代码添加三个路径作为搜索配置文件的路径:当前工作目录,$GOPATH/src/github.com/hyperledger/fabric/sampleconfig,/etc/hyperledger/fabric

    • 当前工作目录,调用addConfigPath(v, “./”)添加,其内部调用的是viper.AddConfigPath()。

    • $GOPATH/src/github.com/hyperledger/fabric/sampleconfig,通过调用AddDevConfigPath(v)添加。

      • AddDevConfigPath首先调用GetDevConfigDir(),读取 GOPATHsrc/github.com/hyperledger/fabric/sampleconfigfilepath.Join GOPATH和src/github.com/hyperledger/fabric/sampleconfig,形成完整的路径并返回。
      • AddDevConfigPath接着调用addConfigPath函数,其内部调用的是viper.AddConfigPath()。
    • /etc/hyperledger/fabric。定义了OfficialPath = “/etc/hyperledger/fabric”常量,如果该路径存在,则调用addConfigPath加入该路径。
  • 调用SetConfigName()设置配置文件名,所指的的配置文件名configName是由参数传递进来的。

由经由InitViper,形成了以下viper配置:

搜索路径(二选一)

  • FABRIC_CFG_PATH指定的路径
  • ./,$GOPATH/src/github.com/hyperledger/fabric/sampleconfig,/etc/hyperledger/fabric

搜索的配置文件名

  • core —— 核心配置,供各个模块使用
  • orderer —— orderer配置,orderer使用

另外注意InitViper的第一个参数,v *viper.Viper。在InitViper函数中,无论是添加搜索路径(使用的是addConfigPath函数),还是设置要搜索的配置文件名(viper自身的SetConfigName函数),都分为全局的viper和特定的viper(也就是参数v)。最终由viper.AddConfigPath或viper.SetConfigName完成的,则是全局的,由v.AddConfigPath或v.SetConfigName完成的,则是特定的。这样就可以很方便的初始化需要单独使用viper的模块,如orderer就是单独使用一条毒蛇,其在/fabric/orderer/localconfig/config.go中的Load函数中,config := viper.New()新养了一条自己的蛇,然后将此蛇通过参数传给InitViper,cf.InitViper(config, configName)。

安全文件配置

安全配置相关的代码在/fabric/peer/main.go中没有体现,而是在/fabric/peer/node/start.go中的serve函数中才初次出现。若grpc服务中使用了TLS网络,则需要.key,.crt,.ca文件配套文件。在此简略介绍,关于TLS,将会在将来专门的文章中详细介绍。

在/fabric/peer/node/start.go中的serve函数中secureConfig, err := peer.GetSecureConfig()获取安全配置。

使用的安全配置结构为/fabric/core/comm/server.go中定义的SecureServerConfig,用于一个grpc服务端实例。 
.key,.crt,.ca文件所在的目录都是在core.yaml中定义都的tls文件夹中,当使用TLS网络时,会读取这些文件的数据到SecureServerConfig对象中。在GetSecureConfig()函数中,使用ioutil.ReadFile读取由/fabric/core/config/config.go中定义的config.GetPath(“…”)函数获取的tls路径下的相应文件。如/etc/hyperledger/fabric/tls/server.crt。

命令选项配置

以peer start命令为例,在/fabric/peer/node/start.go中startCmd()函数中,flags.BoolVarP(&chaincodeDevMode, "peer-chaincodedev", "", false,"Whether peer in chaincode development mode")设置了peer start命令的选项之一为peer-chaincodedev,用于赋值文件中的全局变量chaincodeDevMode,该变量指定了chaincode的模式。chaincode的模式在core.yaml中也有定义,chaincode.mode的值为net,为默认选项。而当执行peer start 命令时指定了选项peer-chaincodedev=true,也即将chaincodeDevMode赋值为true,在serve()函数中,就会使用viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)将chaincode的模式值设置成了dev

环境变量配置

在fabric目前的阶段,各个peer都是在容器中运行的,因此环境变量指的是各个容器中的环境变量。在各个容器的启动脚本中对容器的一些环境变量也进行了设置。在peer-base-no-tls.yaml(见源码解析1——线头)中,如peer容器中,设置了如下环境变量:

    - CORE_PEER_ADDRESSAUTODETECT=true
    - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
    - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=e2ecli_default
    - CORE_LOGGING_LEVEL=ERROR
    ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在fabric/peer/main.go中的开始,即对容器的环境变量进行了获取并设置:

    //设置了环境变量前置,在此也就是peerviper.SetEnvPrefix(cmdRoot)//将环境变量加载进来了viper.AutomaticEnv()replacer := strings.NewReplacer(".", "_")//将环境变量中的_换成.,这样就和yaml文件的配置相匹配了。//因为viper读取yaml文件所形成的配置项就是按层级并以.分隔的格式,如peer.addressviper.SetEnvKeyReplacer(replacer)

这篇关于fabirc1.0商业正式版本源码解析4——配置系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1036918

相关文章

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Jenkins分布式集群配置方式

《Jenkins分布式集群配置方式》:本文主要介绍Jenkins分布式集群配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装jenkins2.配置集群总结Jenkins是一个开源项目,它提供了一个容易使用的持续集成系统,并且提供了大量的plugin满

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法