fisco bcos用caliper0.2.0进行压力测试的安装配置

2023-11-07

一、前期环境
1. 硬件
需要外网权限
2. 操作系统
版本要求:Ubuntu >= 16.04, CentOS >= 7, MacOS >= 10.14
3. 基础软件
python 2.7,make,g++,gcc,git

sudo apt install python2.7 make g++ gcc git curl
git config --global url.git://github.com/.insteadOf https://github.com/

4. NodeJS

版本要求:
NodeJS 8 (LTS), 9, 或 10 (LTS),Caliper尚未在更高的NodeJS版本中进行过验证。

安装指南:
建议使用nvm(Node Version Manager)安装,nvm的安装方式如下:

# 安装nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash

# 若出现因网络问题导致长时间下载失败,可尝试以下命令
curl -o- https://gitee.com/mirrors/nvm/raw/v0.33.2/install.sh | bash

# 加载nvm配置
source ~/.$(basename $SHELL)rc
# 安装Node.js 8
nvm install 8
# 使用Node.js 8
nvm use 8

5. Docker

# 更新包索引
sudo apt-get update
# 安装基础依赖库
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
# 添加Docker官方GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加docker仓库
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 更新包索引
sudo apt-get update
# 安装Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io
#查看Docker版本
docker --version
#添加docker用户组
sudo groupadd docker          
#将当前用户添加至docker用户组
sudo gpasswd -a $USER docker
#更新docker用户组  
newgrp docker  
# 重启Docker服务
sudo service docker restart
# 验证Docker是否已经启动
sudo systemctl status docker               

6. Docker Compose

版本要求:>= 1.22.0

安装指南:

#有时候连接错误,多试几次就好了
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
#查看docker-compose版本
docker-compose -v

二、Caliper部署

1. 部署

#建立一个工作目录
mkdir benchmarks && cd benchmarks
#对NPM项目进行初始化
npm init -y
#安装caliper-cli
npm install --only=prod @hyperledger/caliper-cli@0.2.0
#验证caliper-cli安装成功
npx caliper --version

需要改三个配置文件

/home/echo/benchmarks/node_modules/@hyperledger/caliper-fisco-bcos/lib/fiscoBcos.js

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const {
    BlockchainInterface,
    CaliperUtils
} = require('@hyperledger/caliper-core');
const installSmartContractImpl = require('./installSmartContract');
const invokeSmartContractImpl = require('./invokeSmartContract');
const generateRawTransactionImpl = require('./generateRawTransactions');
const sendRawTransactionImpl = require('./sendRawTransactions');
const Color = require('./common').Color;
const commLogger = CaliperUtils.getLogger('fiscoBcos.js');

/**
 * Implements {BlockchainInterface} for a FISCO BCOS backend.
 */
class FiscoBcos extends BlockchainInterface {
    /**
     * Create a new instance of the {FISCO BCOS} class.
     * @param {string} config_path The absolute path of the FISCO BCOS network configuration file.
     * @param {string} workspace_root The absolute path to the root location for the application configuration files.
     */
    constructor(config_path, workspace_root) {
        super(config_path);
        this.bcType = 'fisco-bcos';
        this.workspaceRoot = workspace_root;
        this.fiscoBcosSettings = CaliperUtils.parseYaml(this.configPath)['fisco-bcos'];

        if (this.fiscoBcosSettings.network && this.fiscoBcosSettings.network.authentication) {
            for (let k in this.fiscoBcosSettings.network.authentication) {
                this.fiscoBcosSettings.network.authentication[k] = CaliperUtils.resolvePath(this.fiscoBcosSettings.network.authentication[k], workspace_root);
            }
        }
    }

    /**
     * Initialize the {FISCO BCOS} object.
     * @async
     * @return {Promise<object>} The promise for the result of the execution.
     */
    async init() {
        return Promise.resolve();
    }

    /**
     * Deploy the smart contract specified in the network configuration file to all nodes.
     * @async
     */
    async installSmartContract() {
       const fiscoBcosSettings = this.fiscoBcosSettings;
        try {
            await installSmartContractImpl.run(fiscoBcosSettings, this.workspaceRoot);
        } catch (error) {
            commLogger.error(Color.error(`FISCO BCOS smart contract install failed: ${(error.stack ? error.stack : error)}`));
            throw error;
        }
    }

    /**
     * Get a context for subsequent operations
     * 'engine' attribute of returned context object must be reserved for benchmark engine to extend the context
     *  engine = {
     *   submitCallback: callback which must be called once new transaction(s) is submitted, it receives a number argument which tells how many transactions are submitted
     * }
     * @param {String} name name of the context
     * @param {Object} args adapter specific arguments
     * @param {Integer} clientIdx the client index
     * @return {Promise<object>} The promise for the result of the execution.
     */
    async getContext(name, args, clientIdx) {
        return Promise.resolve();
    }

    /**
     * Release a context as well as related resources
     * @param {Object} context adapter specific object
     * @return {Promise<object>} The promise for the result of the execution.
     */
    async releaseContext(context) {
        return Promise.resolve();
    }

    /**
     * Invoke the given smart contract according to the specified options. Multiple transactions will be generated according to the length of args.
     * @param {object} context The FISCO BCOS context returned by {getContext}.
     * @param {string} contractID The name of the smart contract.
     * @param {string} contractVer The version of the smart contract.
     * @param {Array} args Array of JSON formatted arguments for transaction(s). Each element contains arguments (including the function name) passing to the smart contract. JSON attribute named transaction_type is used by default to specify the function name. If the attribute does not exist, the first attribute will be used as the function name.
     * @param {number} timeout The timeout to set for the execution in seconds.
     * @return {Promise<object>} The promise for the result of the execution.
     */
    async invokeSmartContract(context, contractID, contractVer, args, timeout) {
        let promises = [];
        try {
            args.forEach((arg) => {
                let fcn = null;
                let fcArgs = [];

                for (let key in arg) {
                    if (key === 'transaction_type') {
                        fcn = arg[key].toString();
                    } else {
                        fcArgs.push(arg[key].toString());
                    }
                }
                promises.push(invokeSmartContractImpl.run(context, this.fiscoBcosSettings, contractID, fcn, fcArgs, this.workspaceRoot));
            });

            return await Promise.all(promises);
        } catch (error) {
            commLogger.error(Color.error(`FISCO BCOS smart contract invoke failed: ${(error.stack ? error.stack : JSON.stringify(error))}`));
            throw error;
        }
    }

    /**
     * Query state from the ledger
     * @param {Object} context The FISCO BCOS context returned by {getContext}
     * @param {String} contractID Identity of the contract
     * @param {String} contractVer Version of the contract
     * @param {String} key lookup key
     * @param {String} fcn The smart contract query function name
     * @return {Promise<object>} The result of the query.
     */
    async queryState(context, contractID, contractVer, key, fcn) {
        try {
            return invokeSmartContractImpl.run(context, this.fiscoBcosSettings, contractID, fcn, key, this.workspaceRoot, true);
        } catch (error) {
            commLogger.error(Color.error(`FISCO BCOS smart contract query failed: ${(error.stack ? error.stack : error)}`));
            throw error;
        }
    }

    /**
     * Generate an raw transaction and store in local file
     * @param {Object} context The FISCO BCOS context returned by {getContext}
     * @param {String} contractID Identity of the contract
     * @param {Object} arg Arguments of the transaction
     * @param {String} file File path which will be used to store then transaction
     * @return {TaskStatus} Indicates whether the transaction is written to the file successfully or not
     */
    async generateRawTransaction(context, contractID, arg, file) {
        return generateRawTransactionImpl.run(this.fiscoBcosSettings, this.workspaceRoot, context, contractID, arg, file);
    }

    /**
     * Send raw transactions
     * @param {Object} context The FISCO BCOS context returned by {getContext}
     * @param {Array} transactions List of raw transactions
     * @return {Promise} The promise for the result of the execution
     */
    async sendRawTransaction(context, transactions) {
        return sendRawTransactionImpl.run(this.fiscoBcosSettings, context, transactions);
    }
}

module.exports = FiscoBcos;

/home/echo/benchmarks/node_modules/@hyperledger/caliper-fisco-bcos/lib/channelPromise.js

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const tls = require('tls');
const fs = require('fs');
const net = require('net');
const uuidv4 = require('uuid/v4');
const events = require('events');

/**
 * NetworkError exception class thrown in socket connection
 */
class NetworkError extends Error {
    /**
     *
     * @param {String} msg exception message
     */
    constructor(msg) {
        super(msg);
        this.name = 'NetworkError';
    }
}

let emitters = new Map();
let buffers = new Map();
let sockets = new Map();
let lastBytesRead = new Map();

/**
 * Parse response returned by node
 * @param {Buffer} response Node's response
 */
function parseResponse(response) {
    let seq = response.slice(6, 38).toString();
    let result = JSON.parse(response.slice(42).toString());
    let emitter = emitters.get(seq);
    if(!emitter) {
        //Stale message receieved
        return;
    }
    emitter = emitter.emitter;

    if (emitter) {
        let readOnly = Object.getOwnPropertyDescriptor(emitter, 'readOnly').value;
        if (readOnly) {
            if (result.error || result.result !== undefined ) {
                emitter.emit('gotresult', result);
            }
        } else {
            if (result.error || result.status || (result.result && result.result.status)) {
                emitter.emit('gotresult', result);
            } else {
                if (!result.result) {
                    throw new NetworkError(`unknown message receieved, seq=${seq}, data=${response.toString()}`);
                }
            }
        }
    } else {
        throw new NetworkError(`unknown owner message receieved, seq=${seq}, data=${response.toString()}`);
    }
}

/**
 * Create a new TLS socket
 * @param {String} ip IP of channel server
 * @param {Number} port Port of channel server
 * @param {Object} authentication A JSON object contains certificate file path, private key file path and CA file path
 * @return {TLSSocket} A new TLS socket
 */
function createNewSocket(ip, port, authentication) {
    let secureContextOptions = {
        key: fs.readFileSync(authentication.key),
        cert: fs.readFileSync(authentication.cert),
        ca: fs.readFileSync(authentication.ca),
        ecdhCurve: 'secp256k1',
    };

    let secureContext = tls.createSecureContext(secureContextOptions);

    let socket = new net.Socket();
    socket.connect(port, ip);

    let clientOptions = {
        rejectUnauthorized: false,
        secureContext: secureContext,
        socket: socket
    };

    let tlsSocket = tls.connect(clientOptions);

    tlsSocket.on('error', function (error) {
        throw new Error(error);
    });

    let socketID = `${ip}:${port}`;

    lastBytesRead.set(socketID, 0);

    tlsSocket.on('data', function (data) {
        let response = null;
        if (data instanceof Buffer) {
            response = data;
        }
        else {
            response = Buffer.from(data, 'ascii');
        }

        if (!buffers.has(socketID)) {
            // First time to read data from this socket
            let expectedLength = null;
            if (tlsSocket.bytesRead - lastBytesRead.get(socketID) >= 4) {
                expectedLength = response.readUIntBE(0, 4);
            }

            if (!expectedLength || tlsSocket.bytesRead < lastBytesRead.get(socketID) + expectedLength) {
                buffers.set(socketID, {
                    expectedLength: expectedLength,
                    buffer: response
                });
            } else {
                lastBytesRead.set(socketID, lastBytesRead.get(socketID) + expectedLength);
                parseResponse(response);
                buffers.delete(socketID);
            }
        } else {
            // Multiple reading
            let cache = buffers.get(socketID);
            cache.buffer = Buffer.concat([cache.buffer, response]);
            if (!cache.expectedLength && tlsSocket.bytesRead - lastBytesRead.get(socketID) >= 4) {
                cache.expectedLength = cache.buffer.readUIntBE(0, 4);
            }

            if (cache.expectedLength && tlsSocket.bytesRead - lastBytesRead.get(socketID) >= cache.expectedLength) {
                lastBytesRead.set(socketID, lastBytesRead.get(socketID) + cache.expectedLength);
                parseResponse(buffers.get(socketID).buffer);
                buffers.delete(socketID);
            }
        }
    });

    return tlsSocket;
}

/**
 * Prepare the data which will be sent to channel server
 * @param {String} data JSON string of load
 * @return {Object} UUID and packaged data
 */
function packageData(data) {
    const headerLength = 4 + 2 + 32 + 4;

    let length = Buffer.alloc(4);
    length.writeUInt32BE(headerLength + data.length);
    let type = Buffer.alloc(2);
    type.writeUInt16BE(0x12);
    let uuid = uuidv4();
    uuid = uuid.replace(/-/g, '');
    let seq = Buffer.from(uuid, 'ascii');
    let result = Buffer.alloc(4);
    result.writeInt32BE(0);
    let msg = Buffer.from(data, 'ascii');

    return {
        'uuid': uuid,
        'packagedData': Buffer.concat([length, type, seq, result, msg])
    };
}

/**
 * Clear context when a message got response or timeout
 * @param {String} uuid The ID of an `channelPromise`request
 */
function clearContext(uuid) {
    clearTimeout(emitters.get(uuid).timer);
    emitters.delete(uuid);
    buffers.delete(uuid);
}

/**
 * Return channel promise for a request
 * @param {Object} node A JSON object which contains IP and port configuration of channel server
 * @param {Object} authentication A JSON object contains certificate file path, private key file path and CA file path
 * @param {String} data JSON string of load
 * @param {Number} timeout Timeout to wait response
 * @param {Boolean} readOnly Is this request read-only?
 * @return {Promise} a promise which will be resolved when the request is satisfied
 */
function channelPromise(node, authentication, data, timeout, readOnly = false) {
    let ip = node.ip;
    let port = node.channelPort;

    let connectionID = `${ip}${port}`;
    if (!sockets.has(connectionID)) {
        let newSocket = createNewSocket(ip, port, authentication);
        newSocket.unref();
        sockets.set(connectionID, newSocket);
    }
    let tlsSocket = sockets.get(connectionID);

    let dataPackage = packageData(JSON.stringify(data));
    let uuid = dataPackage.uuid;

    tlsSocket.socketID = uuid;
    let packagedData = dataPackage.packagedData;
    let channelPromise = new Promise(async (resolve, reject) => {
        let eventEmitter = new events.EventEmitter();
        Object.defineProperty(eventEmitter, 'readOnly', {
            value: readOnly,
            writable: false,
            configurable: false,
            enumerable: false
        });

        eventEmitter.on('gotresult', (result) => {
            clearContext(uuid);
            if (result.error) {
                reject(result);
            } else {
                resolve(result);
            }
            return; // This `return` is not necessary, but it may can avoid future trap
        });

        eventEmitter.on('timeout', () => {
            clearContext(uuid);
            reject({ 'error': 'timeout' });
            return; // This `return` is not necessary, but it may can avoid future trap
        });

        emitters.set(uuid, {
            emitter: eventEmitter,
            timer: setTimeout(() => {
                eventEmitter.emit('timeout');
            }, timeout)
        });

        tlsSocket.write(packagedData);
    });
    return channelPromise;
}

module.exports = channelPromise;

/home/echo/benchmarks/node_modules/@hyperledger/caliper-fisco-bcos/lib/web3lib/web3sync.js

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const uuidv4 = require('uuid/v4');
const utils = require('./utils');
const Transaction = require('./transactionObject').Transaction;

/**
 * Generate a random number via UUID
 * @return {Number} random number
 */
function genRandomID() {
    let uuid = uuidv4();
    uuid = '0x' + uuid.replace(/-/g, '');

    return uuid;
}

/**
 * Sign a transaction with private key and callback
 * @param {String} txData transaction data
 * @param {Buffer} privKey private key
 * @param {callback} callback callback function
 * @return {String} signed transaction data
 */
function signTransaction(txData, privKey, callback) {
    let tx = new Transaction(txData);
    let privateKey = Buffer.from(privKey, 'hex');
    tx.sign(privateKey);

    // Build a serialized hex version of the tx
    let serializedTx = '0x' + tx.serialize().toString('hex');
    if (callback !== null) {
        callback(serializedTx);
    } else {
        return serializedTx;
    }
}

/**
 * get transaction data
 * @param {String} func function name
 * @param {Array} params params
 * @return {String} transaction data
 */
function getTxData(func, params) {
    let r = /^\w+\((.*)\)$/g.exec(func);
    let types = [];
    if (r[1]) {
        types = r[1].split(',');
    }
    return utils.encodeTxData(func, types, params);
}

/**
 * get signed transaction data
 * @param {Number} groupId ID of the group where this transaction will be sent to
 * @param {Buffer} account user account
 * @param {Buffer} privateKey private key
 * @param {Buffer} to target address
 * @param {String} func function name
 * @param {Array} params params
 * @param {Number} blockLimit block limit
 * @return {String} signed transaction data
 */
function getSignTx(groupId, account, privateKey, to, func, params, blockLimit) {
    let txData = getTxData(func, params);

    let postdata = {
        data: txData,
        from: account,
        to: to,
        gas: 1000000,
        randomid: genRandomID(),
        blockLimit: blockLimit,
        chainId: 1,
        groupId: groupId,
         extraData: '0x0'
    };

    return signTransaction(postdata, privateKey, null);
}

/**
 * get signed deploy tx
 * @param {Number} groupId ID of the group where this transaction will be sent to
 * @param {Buffer} account user account
 * @param {Buffer} privateKey private key
 * @param {Buffer} bin contract bin
 * @param {Number} blockLimit block limit
 * @return {String} signed deploy transaction data
 */
function getSignDeployTx(groupId, account, privateKey, bin, blockLimit) {
    let txData = bin.indexOf('0x') === 0 ? bin : ('0x' + bin);

    let postdata = {
        data: txData,
        from: account,
        to: null,
        gas: 1000000,
        randomid: genRandomID(),
        blockLimit: blockLimit,
        chainId: 1,
        groupId: groupId,
        extraData: '0x0'
    };

    return signTransaction(postdata, privateKey, null);
}

module.exports.getSignDeployTx = getSignDeployTx;
module.exports.signTransaction = signTransaction;
module.exports.getSignTx = getSignTx;
module.exports.getTxData = getTxData;

进入/home/echo/benchmarks/node_modules/@hyperledger/caliper-fisco-bcos目录,编辑该目录下的package.json文件,在"dependencies"中添加一项"secp256k1": "^3.8.0",随后在该目录下执行npm i secp256k1@3.0.0

2. 绑定

npx caliper bind --caliper-bind-sut fisco-bcos --caliper-bind-sdk latest

3. 运行基准测试

#拉取代码
git clone https://gitee.com/vita-dounai/caliper-benchmarks.git
#测试helloworld合约
npx caliper benchmark run --caliper-workspace caliper-benchmarks --caliper-benchconfig benchmarks/samples/fisco-bcos/helloworld/config.yaml  --caliper-networkconfig networks/fisco-bcos/4nodes1group/fisco-bcos.json

在这里插入图片描述

#执行Solidity版转账合约测试
npx caliper benchmark run --caliper-workspace caliper-benchmarks --caliper-benchconfig benchmarks/samples/fisco-bcos/transfer/solidity/config.yaml  --caliper-networkconfig networks/fisco-bcos/4nodes1group/fisco-bcos.json

在这里插入图片描述

#执行预编译版转账合约测试
npx caliper benchmark run --caliper-workspace caliper-benchmarks --caliper-benchconfig benchmarks/samples/fisco-bcos/transfer/precompiled/config.yaml  --caliper-networkconfig networks/fisco-bcos/4nodes1group/fisco-bcos.json

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

fisco bcos用caliper0.2.0进行压力测试的安装配置 的相关文章

随机推荐

  • otsu算法_OTSU算法详解

    OTSU是阈值分割中一种常用的算法 它可以根据图像自动生成最佳分割阈值 OTSU的核心思想是类间方差最大化 OTSU算法详解 令 表示一幅大小为 像素的数字图像中的 个不同的灰度级 表示灰度级为 的像素数 图像中的像素总数为 像素的灰度级为
  • VS2017序列号

    趁着这两天微软发布了Visual Studio 2017 安装体验了这个史上最强IDE最新版 分享一下自己的安装过程 下载地址点击这里 该版本堪称史上最大IDE 随便勾了几个选项 就要占用几十个GB的安装空间 最后果断选择了最小安装包 只要
  • uniapp中单选按钮的实现

    标签说明 radio group 单项选择器 内部由多个
  • Java核心技术卷 学习Day02

    java学习 复习 本文主要参照 Java核心技术卷 作为学习对象 第四章 对象与类 1 类 面向对象程序设计OOP 类 封装实例字段 方法 类 gt 继承 is a 依赖 uses a 聚合 has a gt 类 2 预定义类 Math
  • JAVA---抽象类和接口基础知识详解(及两者异同点)

    在本篇博客中将介绍JAVA里抽象类和接口的基础知识以及两者的异同点 在有继承和多态的基础知识上学习会更好 目录 抽象类基础知识 抽象类的定义 创建等基础 抽象类的几点说明 一 为何使用抽象方法 抽象类的几点说明 二 接口基础知识 接口的定义
  • 【Zotero高效知识管理】(1)Zotero介绍

    Zotero高效知识管理 专栏其他文章 Zotero文献管理软件的系统性教程 包括安装 全面的配置 基于众多插件的文献导入 管理 引用 笔记方法 Zotero高效知识管理 2 Zotero的安装 百度云存储配置及常用插件安装 Zotero高
  • jsp调用controller方法_SpringMVC五大核心组件及调用过程

    Spring Web MVC 五大核心组件 DispatcherServlet 控制器入口 负责分发请求 HandlerMapping 负责根据请求 找到对应的控制器 Controller 真正处理请求的控制器 ModelAndView 封
  • 用于光栅仿真的非偏振光–实例讨论

    摘要 像光栅这样的光学设备对光的偏振比较敏感 因此 在仿真中适当考虑光的偏振非常重要 在实际中 光栅有时会以非偏振光作为输入 作为两个正交偏振态的平均值 我们为您展示了如何在VirtualLab Fusion中建模这种用于光栅仿真的非偏振光
  • C语言《文件操作》事无巨细,保姆级介绍,通俗易懂

    目录 1 文件名与文件分类 2 文件操作使用 2 1文件的打开与关闭 3 文件操作函数 3 1其他文件函数 1 fseek 2 ftell 3 rewind 4 文件结束的判定 4 1被错误使用的 feof 4 2文件结束的正确判断 5 文
  • negix安装部署

    1 从nginx官网下载Nginx wget http nginx org download nginx 1 8 1 tar gz 2 解压Nginx tar zxvf nginx 1 8 1 tar gz 3 初始化配置 configur
  • OpenCV(3.4.1) Error: Assertion failed (scn == 3

    错误 OpenCV 3 4 1 Error Assertion failed scn 3 scn 4 in cv cvtColor file D Build OpenCV opencv 3 4 1 modules imgproc src c
  • vi的一些操作

    1 u可撤销操作 2 yy复制当前行 3 p粘贴复制的行 4 dd删除一行 5 xxx可以定位xxx所在位置 6 n或ngg或nG可以跳转到第n行 以下设置是临时的 只在当前vi中生效 但可将其添加在配置文件 etc virc中使每次按文件
  • STM32CubeMX的使用教程

    STM32 关于STM32CubeMX的使用 打开Cube 点击File New Project 搜索芯片型号这边选择的是STM32L071CB系列上面菜单Docs Resources可以下载数据手册程序手册等 点击Start Projec
  • DEBUG:only Tensors of floating point dtype can require gradients

    DEBUG only Tensors of floating point dtype can require gradients 解决 x V t arange 2 4 float requires grad True
  • 4_hytrix_信号量_线程池

    文章目录 Hystrix 核心特性和原理 使用 单独使用 整合 Feign 整合RestTemplate 信号量与线程隔离 线程池隔离 信号量隔离 常用配置 hystrix 使用dashboard Hystrix 核心特性和原理 熔断 连续
  • C strtok strtok_s 函数说明 按分隔符分解字符串

    1 说明 1 1 函数签名如下 char strtok char str const char delimiters 1 str 要被分解成一组小字符串的字符串 2 delimiters 包含分隔符的 C 字符串 1 2 返回值 该函数返回
  • DPDK的PMD(uio/igb_uio/vfio-pci/uio_pci_generic)

    目录 linux收包的方式 中断对性能的影响有多大 轮询对性能的提升有多大 PMD 介绍 收包对比 内核收包的弊端 DPDK 收包的优点 uio igb uio uio pci generic vfio pci igb uio IGB UI
  • MATLAB算法实战应用案例精讲-【集成算法】集成学习模型stacking(附Python和R语言代码)

    目录 前言 几个高频面试题目 1 哪种集成技术更优 什么情况下选择哪种集成技术呢
  • Java多线程技术详解(全都是细节!)

    多线程启动 线程有两种启动方式 实现Runnable接口 继承Thread类并重写run 方法 1 Thread 与 Runnable Runnable接口表示线程要执行的任务 当Runnable中的run 方法执行时 表示线程在激活状态
  • fisco bcos用caliper0.2.0进行压力测试的安装配置

    一 前期环境 1 硬件 需要外网权限 2 操作系统 版本要求 Ubuntu gt 16 04 CentOS gt 7 MacOS gt 10 14 3 基础软件 python 2 7 make g gcc git sudo apt inst