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

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

mybatis映射器配置小结

《mybatis映射器配置小结》本文详解MyBatis映射器配置,重点讲解字段映射的三种解决方案(别名、自动驼峰映射、resultMap),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定... 目录select中字段的映射问题使用SQL语句中的别名功能使用mapUnderscoreToCame

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

MySQL8 密码强度评估与配置详解

《MySQL8密码强度评估与配置详解》MySQL8默认启用密码强度插件,实施MEDIUM策略(长度8、含数字/字母/特殊字符),支持动态调整与配置文件设置,推荐使用STRONG策略并定期更新密码以提... 目录一、mysql 8 密码强度评估机制1.核心插件:validate_password2.密码策略级

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达