前言

Hyperledger Fabric无系统通道启动及通道的创建和删除中,我们已经完成了以无系统通道的方式启动 Hyperledger Fabric 网络,并将链码安装到指定通道。但目前为止,实验中的 orderer 服务都是通过单独的排序组织来维护且只有一个,那能不能不要排序组织而使用普通组织来运行维护多个 orderer 服务呢?当然是可以的,本文将在之前的实验基础上,启动一个没有 orderer 组织的 Fabric 网络,网络中包含三个组织且每个组织运行维护着一个 Raft 协议的 orderer 节点,最后成功在其上部署运行链码。

背景介绍

实验准备

本文网络结构直接将 Hyperledger Fabric无系统通道启动及通道的创建和删除 中创建的 3_RunWithNoSystemChannel 复制为 4-1_RunOrdererByOneself (建议直接将本案例仓库 FabricLearn 下的 4-1_RunOrdererByOneself 目录拷贝到本地运行)。默认情况下,所有命令皆在 4-1_RunOrdererByOneself 根目录下执行,在开始后面的实验前按照以下命令启动基础实验网络(主要修改为删除 orderer 组织相关配置):

  1. 设置环境变量 source envpeer1soft
  2. 启动CA网络 ./0_Restart.sh

本实验初始 docker 网络为:

本文工作

以无排序组织的方式启动 Hyperledger Fabric 网络,其中包含三个组织—— soft 、 web 、 hard , 每个组织都运行维护着一个 peer 节点和一个 orderer,并使用 osnadmin 工具通过 ordereradmin 服务使 orderer 加入这两条通道(实验代码已上传至:https://github.com/wefantasy/FabricLearn4-1_RunOrdererByOneself 下):

运行端口 说明
council.ifantasy.net 7050 council 组织的 CA 服务, 为联盟链网络提供 TLS-CA 服务
soft.ifantasy.net 7250 soft 组织的 CA 服务, 包含成员: peer1 、 admin1
peer1.soft.ifantasy.net 7251 soft 组织的 peer1 成员节点
orderer1.soft.ifantasy.net 8251 soft 组织的 orderer1 服务
orderer1.soft.ifantasy.net 8252 soft 组织的 orderer1 服务的 admin 服务
web.ifantasy.net 7350 web 组织的 CA 服务, 包含成员: peer1 、 admin1
peer1.web.ifantasy.net 7351 web 组织的 peer1 成员节点
orderer1.soft.ifantasy.net 8351 web 组织的 orderer1 服务
orderer1.soft.ifantasy.net 8352 web 组织的 orderer1 服务的 admin 服务
hard.ifantasy.net 7450 hard 组织的 CA 服务, 包含成员: peer1 、 admin1
peer1.hard.ifantasy.net 7451 hard 组织的 peer1 成员节点
orderer1.soft.ifantasy.net 8451 hard 组织的 orderer1 服务
orderer1.soft.ifantasy.net 8452 hard 组织的 orderer1 服务的 admin 服务

实验步骤

配置文件

  1. 修改配置文件 compose/docker-compose.yaml ,删除所有关于 orderer 组织的配置,并新增 hard 组织相关容器和普通组织的 orderer 容器:
  hard.ifantasy.net:
container_name: hard.ifantasy.net
extends:
file: docker-base.yaml
service: ca-base
command: sh -c 'fabric-ca-server start -d -b ca-admin:ca-adminpw --port 7050'
environment:
- FABRIC_CA_SERVER_CSR_CN=hard.ifantasy.net
- FABRIC_CA_SERVER_CSR_HOSTS=hard.ifantasy.net
volumes:
- ${LOCAL_CA_PATH}/hard.ifantasy.net/ca:${DOCKER_CA_PATH}/ca
ports:
- 7450:7050
peer1.hard.ifantasy.net:
container_name: peer1.hard.ifantasy.net
extends:
file: docker-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.hard.ifantasy.net
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_ADDRESS=peer1.hard.ifantasy.net:7051
- CORE_PEER_LOCALMSPID=hardMSP
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.hard.ifantasy.net:7051
volumes:
- ${LOCAL_CA_PATH}/hard.ifantasy.net/registers/peer1:${DOCKER_CA_PATH}/peer
ports:
- 7451:7051 orderer1.soft.ifantasy.net:
container_name: orderer1.soft.ifantasy.net
extends:
file: docker-base.yaml
service: orderer-base
environment:
- ORDERER_HOST=orderer1.soft.ifantasy.net
- ORDERER_GENERAL_LOCALMSPID=softMSP
- ORDERER_GENERAL_LISTENPORT=8251
volumes:
- ${LOCAL_CA_PATH}/soft.ifantasy.net/registers/orderer1:${DOCKER_CA_PATH}/orderer
ports:
- 8251:8251
- 8252:8888
- 8253:9999 orderer1.web.ifantasy.net:
container_name: orderer1.web.ifantasy.net
extends:
file: docker-base.yaml
service: orderer-base
environment:
- ORDERER_HOST=orderer1.web.ifantasy.net
- ORDERER_GENERAL_LOCALMSPID=webMSP
- ORDERER_GENERAL_LISTENPORT=8351
volumes:
- ${LOCAL_CA_PATH}/web.ifantasy.net/registers/orderer1:${DOCKER_CA_PATH}/orderer
ports:
- 8351:8351
- 8352:8888
- 8353:9999 orderer1.hard.ifantasy.net:
container_name: orderer1.hard.ifantasy.net
extends:
file: docker-base.yaml
service: orderer-base
environment:
- ORDERER_HOST=orderer1.hard.ifantasy.net
- ORDERER_GENERAL_LOCALMSPID=hardMSP
- ORDERER_GENERAL_LISTENPORT=8451
volumes:
- ${LOCAL_CA_PATH}/hard.ifantasy.net/registers/orderer1:${DOCKER_CA_PATH}/orderer
ports:
- 8451:8451
- 8452:8888
- 8453:9999
  1. 修改配置文件 config/configtx.yaml源文件太长在此不贴,其主要修改内容为:

    • 每个组织 MSP 下增加本组织维护的 OrdererEndpoints 配置:

    • Orderer 配置下修改 orderer 服务的地址:

    • Profiles 配置下修改排序节点的维护组织为 softMSPwebMSPhardMSP

    • 必须有一个组织 MSP 的 Policies 中的 ReadersWritersRule 值为 member ,文末会有解释:

  2. 各组织的环境变量文件中添加 orderer 服务的管理证书环境变量,以 envpeer1soft 为例:

export ORDERER_CA=$LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem
export ORDERER_ADMIN_TLS_SIGN_CERT=$LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1/tls-msp/signcerts/cert.pem
export ORDERER_ADMIN_TLS_PRIVATE_KEY=$LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1/tls-msp/keystore/key.pem
  1. envpeer1soft 复制为 envpeer1hard 作为 hard 组织的环境变量,其内容为:
export LOCAL_ROOT_PATH=$PWD
export LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgs
export DOCKER_CA_PATH=/tmp
export COMPOSE_PROJECT_NAME=fabriclearn
export DOCKER_NETWORKS=network
export FABRIC_BASE_VERSION=2.4
export FABRIC_CA_VERSION=1.5
echo "init terminal hard"
export FABRIC_CFG_PATH=$LOCAL_ROOT_PATH/config
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="hardMSP"
export CORE_PEER_ADDRESS=peer1.hard.ifantasy.net:7451
export CORE_PEER_TLS_ROOTCERT_FILE=$LOCAL_CA_PATH/hard.ifantasy.net/assets/tls-ca-cert.pem
export CORE_PEER_MSPCONFIGPATH=$LOCAL_CA_PATH/hard.ifantasy.net/registers/admin1/msp export ORDERER_CA=$LOCAL_CA_PATH/hard.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem
export ORDERER_ADMIN_TLS_SIGN_CERT=$LOCAL_CA_PATH/hard.ifantasy.net/registers/orderer1/tls-msp/signcerts/cert.pem
export ORDERER_ADMIN_TLS_PRIVATE_KEY=$LOCAL_CA_PATH/hard.ifantasy.net/registers/orderer1/tls-msp/keystore/key.pem

注册用户

在注册脚本 1_RegisterUser.sh 中删除 orderer 组织账户并添加三组织排序服务的 msp 账户和 tls-msp 账户,默认密码与账户名相同:

登录账户

在登录脚本 2_EnrollUser.sh 中删除 orderer 组织相关内容并添加三组织排序服务的 msp 账户和 tls-msp 账户,如 soft 组织下新增登录 orderer1 的代码:

echo "Enroll Orderer1"
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pem
export FABRIC_CA_CLIENT_MSPDIR=msp
fabric-ca-client enroll -d -u https://orderer1:orderer1@soft.ifantasy.net:7250
# for TLS
export FABRIC_CA_CLIENT_MSPDIR=tls-msp
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pem
fabric-ca-client enroll -d -u https://orderer1soft:orderer1soft@council.ifantasy.net:7050 --enrollment.profile tls --csr.hosts orderer1.soft.ifantasy.net
cp $LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1/tls-msp/keystore/*_sk $LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1/tls-msp/keystore/key.pem
mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1/msp/admincerts
cp $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/registers/orderer1/msp/admincerts/cert.pem

创建通道并加入

在执行上述脚本后,在脚本 3_CreateChannel.sh 中创建通道并使所有节点加入:

  1. 启动 peer 和 orderer 容器:
docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d peer1.soft.ifantasy.net peer1.web.ifantasy.net peer1.hard.ifantasy.net
docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d orderer1.soft.ifantasy.net orderer1.web.ifantasy.net orderer1.hard.ifantasy.net

此时本实验所有容器启动完成:



2. 创建通道文件 testchannel

configtxgen -profile OrgsChannel -outputCreateChannelTx $LOCAL_ROOT_PATH/data/testchannel.tx -channelID testchannel
configtxgen -profile OrgsChannel -outputBlock $LOCAL_ROOT_PATH/data/testchannel.block -channelID testchannel
  1. soft 组织的 orderer 服务加入通道:
source envpeer1soft
osnadmin channel list -o orderer1.soft.ifantasy.net:8252 --ca-file $ORDERER_CA --client-cert $ORDERER_ADMIN_TLS_SIGN_CERT --client-key $ORDERER_ADMIN_TLS_PRIVATE_KEY
osnadmin channel join -o orderer1.soft.ifantasy.net:8252 --channelID testchannel --config-block $LOCAL_ROOT_PATH/data/testchannel.block --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
osnadmin channel list -o orderer1.soft.ifantasy.net:8252 --ca-file $ORDERER_CA --client-cert $ORDERER_ADMIN_TLS_SIGN_CERT --client-key $ORDERER_ADMIN_TLS_PRIVATE_KEY
  1. web 组织的 orderer 服务加入通道:
source envpeer1web
osnadmin channel list -o orderer1.web.ifantasy.net:8352 --ca-file $ORDERER_CA --client-cert $ORDERER_ADMIN_TLS_SIGN_CERT --client-key $ORDERER_ADMIN_TLS_PRIVATE_KEY
osnadmin channel join -o orderer1.web.ifantasy.net:8352 --channelID testchannel --config-block $LOCAL_ROOT_PATH/data/testchannel.block --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
osnadmin channel list -o orderer1.web.ifantasy.net:8352 --ca-file $ORDERER_CA --client-cert $ORDERER_ADMIN_TLS_SIGN_CERT --client-key $ORDERER_ADMIN_TLS_PRIVATE_KEY
  1. hard 组织的 orderer 服务加入通道:
source envpeer1hard
osnadmin channel list -o orderer1.hard.ifantasy.net:8452 --ca-file $ORDERER_CA --client-cert $ORDERER_ADMIN_TLS_SIGN_CERT --client-key $ORDERER_ADMIN_TLS_PRIVATE_KEY
osnadmin channel join -o orderer1.hard.ifantasy.net:8452 --channelID testchannel --config-block $LOCAL_ROOT_PATH/data/testchannel.block --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
osnadmin channel list -o orderer1.hard.ifantasy.net:8452 --ca-file $ORDERER_CA --client-cert $ORDERER_ADMIN_TLS_SIGN_CERT --client-key $ORDERER_ADMIN_TLS_PRIVATE_KEY
  1. 将通道文件复制到各组织资产目录下:
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/soft.ifantasy.net/assets/
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/web.ifantasy.net/assets/
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/hard.ifantasy.net/assets/
  1. 各组织 peer 节点加入通道:
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/soft.ifantasy.net/assets/
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/web.ifantasy.net/assets/
cp $LOCAL_ROOT_PATH/data/testchannel.block $LOCAL_CA_PATH/hard.ifantasy.net/assets/

部署测试链码

在执行上述脚本后,在脚本 4_TestChaincode.sh 中安装链码并调用执行:

  1. 各组织安装测试链码:
source envpeer1soft
# peer lifecycle chaincode package basic.tar.gz --path asset-transfer-basic/chaincode-go --label basic_1
peer lifecycle chaincode install basic.tar.gz
peer lifecycle chaincode queryinstalled
source envpeer1web
peer lifecycle chaincode install basic.tar.gz
peer lifecycle chaincode queryinstalled
source envpeer1hard
peer lifecycle chaincode install basic.tar.gz
peer lifecycle chaincode queryinstalled
  1. 设置链码 ID 环境变量:
export CHAINCODE_ID=basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718
  1. soft 组织批准链码:
source envpeer1soft
peer lifecycle chaincode approveformyorg -o orderer1.soft.ifantasy.net:8251 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --version 1.0 --sequence 1 --waitForEvent --init-required --package-id $CHAINCODE_ID
peer lifecycle chaincode queryapproved -C testchannel -n basic --sequence 1
  1. web 组织批准链码:
source envpeer1web
peer lifecycle chaincode approveformyorg -o orderer1.web.ifantasy.net:8351 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --version 1.0 --sequence 1 --waitForEvent --init-required --package-id $CHAINCODE_ID
peer lifecycle chaincode queryapproved -C testchannel -n basic --sequence 1
  1. hard 组织批准链码:
source envpeer1hard
peer lifecycle chaincode approveformyorg -o orderer1.hard.ifantasy.net:8451 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --version 1.0 --sequence 1 --waitForEvent --init-required --package-id $CHAINCODE_ID
peer lifecycle chaincode queryapproved -C testchannel -n basic --sequence 1

注意,这里各组织批准链码时的 -o 参数可以指定任意一个 orderer 服务



4. 检查链码批准情况:

peer lifecycle chaincode checkcommitreadiness -o orderer1.soft.ifantasy.net:8251 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --version 1.0 --sequence 1 --init-required
  1. 测试调用链码:
source envpeer1soft
peer lifecycle chaincode commit -o orderer1.soft.ifantasy.net:8251 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --init-required --version 1.0 --sequence 1 --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE
peer lifecycle chaincode querycommitted --channelID testchannel --name basic -o orderer1.soft.ifantasy.net:8251 --tls --cafile $ORDERER_CA --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE
peer chaincode invoke --isInit -o orderer1.soft.ifantasy.net:8251 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE -c '{"Args":["InitLedger"]}'
sleep 3
peer chaincode invoke -o orderer1.soft.ifantasy.net:8251 --tls --cafile $ORDERER_CA --channelID testchannel --name basic --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE -c '{"Args":["GetAllAssets"]}'

常见错误

  1. 没有领导节点
Error: failed to send transaction: got unexpected status: SERVICE_UNAVAILABLE -- no Raft leader

上述错误归结起来就是 orderer 之间没有选出领导节点,此时应该检查:

  • 网络中 orderer 节点的数量是否为 2n+1 个,否则可能无法完成选举
  • 各 orderer 容器的 ORDERER_GENERAL_LOCALMSPID 配置是否正确,必须为自身所属组织的 MSPID
  • 检查 configtx.yaml 中各组织的 Policies 配置是否正确
  1. 排序节点之间无法通信
2022-04-09 05:32:07.086 UTC 0032 ERRO [orderer.consensus.etcdraft] logSendFailure -> Failed to send StepRequest to 3, because: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 172.19.0.10:8451: connect: connection refused" channel=syschannel node=1

上述错误的原因是 orderer 节点间无法通信, 此时应该检查 configtx.yaml 中相关的 orderer 地址是否正确。这里有个大坑:所有 configtx.yaml 文件内的 orderer 相关配置的端口必须设置为容器内 ORDERER_GENERAL_LISTENPORT 的监听端口,而不是容器外的映射端口,假如 orderer 容器配置如下图, configtx.yaml 中的 orderer 端口必须为 7050 而不能填 8251 (所以为了避免冲突,强烈建议这两个端口设置成一样的 8251)。

  1. peer 节点之间无法通信
Error: timed out waiting for txid on all peers
2022-04-10 02:57:37.135 UTC 00a1 WARN [peer.blocksprovider] DeliverBlocks -> Got error while attempting to receive blocks: block from orderer could not be verified: implicit policy evaluation failed - 0 sub-policies were satisfied, but this policy requires 1 of the 'Writers' sub-policies to be satisfied channel=testchannel orderer-address=orderer1.soft.ifantasy.net:8251

错误原因是没有操作权限,通常是 configtx.yaml 中的策略问题,在本实验中如果三个组织的 Policies 都设置为下列内容则会触发本错误:

Policies:
Readers:
Type: Signature
Rule: "OR('softMSP.admin', 'softMSP.peer', 'softMSP.client')"
Writers:
Type: Signature
Rule: "OR('softMSP.admin', 'softMSP.client')"
Admins:
Type: Signature
Rule: "OR('softMSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('softMSP.peer')"

此时需要将任意组织(比如 web)的 ReadersWritersRule 改为 menber 即可解决,解决后实验各步骤结果符合预期:

Policies:
Readers:
Type: Signature
Rule: "OR('webMSP.member')"
Writers:
Type: Signature
Rule: "OR('webMSP.member')"
Admins:
Type: Signature
Rule: "OR('webMSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('webMSP.peer')"

至于为什么会导致如此尚未发现,猜测是普通组织的策略与排序节点所需要的策略存在冲突,因此建议排序服务独立于普通组织。

Hyperledger Fabric无排序组织以Raft共识算法启动多个Orderer服务、多组织共同运行维护Orderer服务的更多相关文章

  1. Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务、TLS组织运行维护Orderer服务

    前言 在实验Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务.多组织共同运行维护Orderer服务中,我们已经完成了让普通组织运行维护 Orderer 服务,但是 ...

  2. raft共识算法

    raft共识算法 分布式一致性问题 如果说,服务器只有一个节点,那么,要保证一致性,没有任何问题,因为所有读写都在一个节点上发生.那如果server端有2个.3个甚至更多节点,要怎么达成一致性呢?下面 ...

  3. Raft共识算法详解

    Raft共识算法 一.背景 拜占庭将军问题是分布式领域最复杂.最严格的容错模型.但在日常工作中使用的分布式系统面对的问题不会那么复杂,更多的是计算机故障挂掉了,或者网络通信问题而没法传递信息,这种情况 ...

  4. 【翻译】Raft 共识算法:集群成员变更

    转载请注明出处:https://www.cnblogs.com/morningli/p/16770129.html 之前都在集群配置是固定的(参与共识算法的server集合)假设下讨论raft.在实践 ...

  5. Hyperledger Fabric无系统通道启动及通道的创建和删除

    前言 在Hyperledger Fabric组织的动态添加和删除中,我们已经完成了在运行着的网络中动态添加和删除组织,但目前为止,我们启动 orderer 节点的方式都是通过系统通道的方式,这样自带系 ...

  6. Hyperledger Fabric 1.0 学习搭建 (五)--- 启动Fabric多节点集群

    5.1.启动orderer节点服务 上述操作完成后,此时各节点的compose配置文件及证书验证目录都已经准备完成,可以开始尝试启动多机Fabric集群. 首先启动orderer节点,切换至order ...

  7. Raft 共识算法

    转载请注明出处:https://www.cnblogs.com/morningli/p/16745294.html raft是一种管理复制日志的算法,raft可以分解成三个相对独立的子问题: 选主(L ...

  8. Fabric2.2中的Raft共识模块源码分析

    引言 Hyperledger Fabric是当前比较流行的一种联盟链系统,它隶属于Linux基金会在2015年创建的超级账本项目且是这个项目最重要的一个子项目.目前,与Hyperledger的另外几个 ...

  9. Hyperledger Fabric 部署在多个主机上

    前言 在实验Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务.TLS组织运行维护Orderer服务中,我们已经完成了使用提供 TLS-CA 服务的 council ...

随机推荐

  1. .net core 配置Swagger 摆脱PostMan,你值得拥有这样的api调试方式

    废话不多说直接来看 第一步: 安装nuget包:Swashbuckle.AspNetCore.Swagger Swashbuckle.AspNetCore.SwaggerGen Swashbuckle ...

  2. K8S原来如此简单(六)Pod调度

    我们前面部署的pod调度取决于kube-scheduler,它会根据自己的算法,集群的状态来选择合适的node部署我们的pod. 下面我们来看下如何来根据我们自己的要求,来影响pod的调度. 定向no ...

  3. linux命令管道工作原理与使用方法

    一.管道定义 管道是一种两个进程间进行单向通信的机制.因为管道传递数据的单向性,管道又称为半双工管道.管道的这一特点决定了器使用的局限性.管道是Linux支持的最初Unix IPC形式之一,具有以下特 ...

  4. 项目可以怎么规范Git commit ?

    通常情况下,commit message应该清晰明了,说明本次提交的目的,具体做了什么操作.但是在日常开发中,大家的commit message都比较随意,中英文混合使用的情况有时候很常见,这就导致后 ...

  5. 从零开始,开发一个 Web Office 套件(14):复制、粘贴、剪切、全选

    这是一个系列博客,最终目的是要做一个基于 HTML Canvas 的.类似于微软 Office 的 Web Office 套件(包括:文档.表格.幻灯片--等等). 博客园:<从零开始, 开发一 ...

  6. Redis常见问题及其场景问题

    假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以 某个固定的已知的前缀开头的,如果将它们全部找出来?   使用 keys 指令可以扫出指定模式的 key 列表. 对方接着追 ...

  7. Hibernate学习一:Hebinate入门以及一些小问题

    1:Hebinate框架的简述: Hebinate框架主要用用在javaee开发中的dao层设计,实现对数据库的crud等操作, Hibernate的底层通过jdbc实现,通过对jdbc的封装,实现对 ...

  8. mac 安装shell

    https://blog.csdn.net/weixin_41937552/article/details/108565705

  9. requests库获取图片响应流进行转发

    遇到了一个问题,使用requests进行转发 requests响应流的时候,出现各种问题,问题的描述没有记录,不过Debug以下终于解决了问题.......下面简单的描述解决方案 response = ...

  10. MyISAM Static 和 MyISAM Dynamic 有什么区别?

    在 MyISAM Static 上的所有字段有固定宽度.动态 MyISAM 表将具有像 TEXT, BLOB 等字段,以适应不同长度的数据类型. MyISAM Static 在受损情况下更容易恢复.