# 多机部署
## 概述
通过本文你将可以搭建起长安链多节点集群,并使用命令行工具/管理台完成长安链多机部署。
通过源码搭建长安链并且上链查数据需要以下步骤,本文将一一演示
- 命令行创建集中式多节点链
- 命令行创建分布式多节点链
- 管理台创建集中式多节点链
- 启动多节点集群
- 使用CMC工具安装、调用、查询一个合约
- 使用GO SDK验证合约
- 使用管理台验证合约
## 环境依赖
请查看:[【快速入门】](../tutorial/通过命令行工具启动链.md)
## 多机部署
> 部署按照`PermissionedWithCert`模式进行搭建
|名词 | 说明 |
| --- |--------------------------------|
| 多机 | 多台机器部署同一条链 |
| 集中式 | 使用不同根证书在一个服务器(组织)上生成各个节点、组织、用户证书 |
| 分布式 | 使用不同根证书在不同服务器(组织)上生成各个节点、组织、用户证书 |
### 命令行多机部署-集中式
> 适用于`Linux`、`MacOS`
> 代码部署、编译参考通过命令行搭建链
##### 证书生成
```bash
# 进入脚本目录
$ cd ../scripts
# 生成单链4节点集群的证书和配置
$ ./prepare.sh 4 1
begin check params...
begin generate certs, cnt: 4
input consensus type (0-SOLO,1-TBFT(default),3-HOTSTUFF,4-RAFT,5-DPOS):
input log level (DEBUG|INFO(default)|WARN|ERROR):
enable docker vm (YES|NO(default))
begin generate node1 config...
begin generate node2 config...
begin generate node3 config...
begin generate node4 config...
# 查看生成好的节点证书和配置
$ tree -L 3 ../build/
../build/
├── config
│ ├── node1
│ │ ├── certs
│ │ ├── chainconfig
│ │ ├── chainmaker.yml
│ │ └── log.yml
│ ├── node2
│ │ ├── certs
│ │ ├── chainconfig
│ │ ├── chainmaker.yml
│ │ └── log.yml
│ ├── node3
│ │ ├── certs
│ │ ├── chainconfig
│ │ ├── chainmaker.yml
│ │ └── log.yml
│ └── node4
│ ├── certs
│ ├── chainconfig
│ ├── chainmaker.yml
│ └── log.yml
├── crypto-config
│ ├── wx-org1.chainmaker.org
│ │ ├── ca
│ │ ├── node
│ │ └── user
│ ├── wx-org2.chainmaker.org
│ │ ├── ca
│ │ ├── node
│ │ └── user
│ ├── wx-org3.chainmaker.org
│ │ ├── ca
│ │ ├── node
│ │ └── user
│ └── wx-org4.chainmaker.org
│ ├── ca
│ ├── node
│ └── user
└── crypto_config.yml
```
#### 修改节点内部chainmaker.yml文件
> 修改`build/config/nodeN`中所有的`chainmaker.yml` 如:`build\config\node1\chainmaker.yml`
```bash
net:
provider: LibP2P
listen_addr: /ip4/0.0.0.0/tcp/11301
seeds:
- "/ip4/127.0.0.1/tcp/11301/p2p/QmeSqRL6N4ZB4YwYho4eBXX3YzHZbtjTh2jashqLZmSPw7"
- "/ip4/127.0.0.1/tcp/11302/p2p/QmNwkeUaJ4153by2Uf1GDsjHw9W25B8gRjkruoMuCjAGdB"
- "/ip4/127.0.0.1/tcp/11303/p2p/QmcTJ231F9gTwrNGK8Pm4raSZLWLD1GR7Ura8YoEdeBzMr"
- "/ip4/127.0.0.1/tcp/11304/p2p/QmSAqwDyHDo9RqTB75ZkKiyRGh1T1onHgJdnXhQKxp79Sx"
```
将net.seeds下 `/ip4/127.0.0.1/tcp/11301/p2p/QmeSqRL6N4ZB4YwYho4eBXX3YzHZbtjTh2jashqLZmSPw7` 修改为部署机器的ip/域名和port
```bash
eg:
- "/ip4/192.168.0.1/tcp/11301/p2p/QmeSqRL6N4ZB4YwYho4eBXX3YzHZbtjTh2jashqLZmSPw7"
- "/dns/cm-node1.com/tcp/11301/p2p/QmeSqRL6N4ZB4YwYho4eBXX3YzHZbtjTh2jashqLZmSPw7"
```
#### 编译及安装包制作
- 生成证书(prepare.sh脚本)后执行`build_release.sh`脚本,将编译`chainmaker-go`模块,并打包生成安装,存于路径`chainmaker-go/build/release`中
```bash
$ ./build_release.sh
$ tree ../build/release/
../build/release/
├── chainmaker-v2.0.0-wx-org1.chainmaker.org-20210406194833-x86_64.tar.gz
├── chainmaker-v2.0.0-wx-org2.chainmaker.org-20210406194833-x86_64.tar.gz
├── chainmaker-v2.0.0-wx-org3.chainmaker.org-20210406194833-x86_64.tar.gz
├── chainmaker-v2.0.0-wx-org4.chainmaker.org-20210406194833-x86_64.tar.gz
└── crypto-config-20210406194833.tar.gz
```
#### 启动节点
- 通过scp复制节点到部署的机器上,进入部署机器进行解压,然后启动节点内部`bin`目录下`start.sh`脚本
```bash
$ scp ./xxx.tar.gz username@ip:/路径
$ tar -zxvf xxx.tar.gz
$ cd xxx/bin && ./start.sh
```
- 若需要关闭节点,在部署机器上的节点bin目录下启动`stop.sh`脚本:
>
> ```bash
> $ ./stop.sh
> ```
#### 查看节点启动使用正常
- 查看进程是否存在
```bash
$ ps -ef|grep chainmaker | grep -v grep
25261 2146 4 19:55 pts/20 00:00:01 ./chainmaker start -c ../config/wx-org1.chainmaker.org/chainmaker.yml
```
- 查看端口是否监听
```bash
$ netstat -lptn | grep 1230
tcp6 0 0 :::12301 :::*
```
- 检查节点是否有`ERROR`日志
```bash
# 进入节点部署的位置
$ cd /data/multiMachineDeployment/hainmaker-v2.2.1-wx-orgN.chainmaker.org
$ cat bin/panic.log
$ cat log/system.log
$ cat log/system.log |grep "ERROR\|put block\|all necessary"
```
### 命令行分布式多机部署
> 适用于`Linux`、`MacOS`
> 代码部署、编译参考通过命令行搭建链
##### 证书生成, 修改节点内部chainmaker.yml文件
```bash
# 进入脚本目录
$ cd ../scripts
```
- 执行4次证书生成操作
```bash
# 生成次单链节点集群的证书和配置
$ ./prepare.sh 1 1
begin check params...
begin generate certs, cnt: 1
input consensus type (0-SOLO,1-TBFT(default),3-HOTSTUFF,4-RAFT,5-DPOS):0
input log level (DEBUG|INFO(default)|WARN|ERROR):
enable docker vm (YES|NO(default))
begin generate node1 config...
# 移出对应的config文件
$ mv chainmaker-go/build/config /data/tmp/node1/
$ mv chainmaker-go/build/crypto_config /data/tmp/node1/
```
- 进入到文件生成位置`/data/tmp/`,将4次文件生成的`chainmaker.yml(chainmaker-go/build/config/node1)`进行整理,收集各个节点下的seeds,合并成一个,修改对应的ip和port,并放置全部部署机器上
```bash
net:
provider: LibP2P
listen_addr: /ip4/0.0.0.0/tcp/11301
seeds:
- "/ip4/127.0.0.1/tcp/11301/p2p/QmeSqRL6N4ZB4YwYho4eBXX3YzHZbtjTh2jashqLZmSPw7"
# 修改之后
net:
provider: LibP2P
listen_addr: /ip4/0.0.0.0/tcp/11301
seeds:
- "/ip4/192.168.0.170/tcp/11301/p2p/QmaMxoZbUaxeMSaSY5fsaUx9KFg9wJcQAcnSUxFtxGhMAv"
- "/ip4/192.168.0.171/tcp/11302/p2p/QmVRbLmQHcPU2oWpgubespZoL1gw7Z1UktRHnTiX7ENXnD"
- "/ip4/192.168.0.172/tcp/11303/p2p/QmSvgJ6UKJVasKZkbtu1xBnDfRPoY9wPmUWgWPY8PoSHRE"
- "/ip4/192.168.0.173/tcp/11304/p2p/QmNcjPyjZ1jRAwEj6uZ34pZGQ5jVtUBAd6hJt99YySwcJL"
```
#### 编译及安装包制作
- 复制之前移出的配置文件到对应的`config`和`crypto_config`到`chainmaker-go/build`目录下
- 执行`build_release.sh`脚本,将编译`chainmaker-go`模块,并打包生成安装,存于路径`chainmaker-go/build/release`中
```bash
# 移出对应的config文件
$ cp -R /data/tmp/node1/config chainmaker-go/build/config
$ cp -R /data/tmp/node1/crypto_config chainmaker-go/build/crypto_config
```
```bash
# 移出对应的config文件
$ cp chainmaker-go/script
$ ./build_release.sh
$ tree -L 1 chainmaker-go/build/release
├── chainmaker-v2.2.1-wx-org.chainmaker.org
├── chainmaker-v2.2.1-wx-org.chainmaker.org-20220728121113-x86_64.tar.gz
└── crypto-config-20220728121113.tar.gz
```
#### 启动节点
- 通过scp复制节点到各个机器上,启动节点内部`bin`目录下`start.sh`脚本
```bash
$ scp ./xxx.tar.gz username@ip:/路径
$ tar -zxvf xxx.tar.gz
$ cd xxx/bin && ./start.sh
```
#### 关闭节点
- 若需要关闭节点,在部署机器上的节点bin目录下启动`stop.sh`脚本:
```bash
$ ./stop.sh
```
### 管理台多机部署-集中式
#### 构建组织、节点、用户证书
- 申请4个组织证书、4个节点证书、4个用户证书
#### 创建链
- 新建链, 选择多机部署
#### 部署链
- 对链进行下载
- 将链部署到机器上
```bash
# 进入下载目录
$ cd download
# 同步链到部署机器上
$ scp chain1.zip root@192.168.0.170:/data/multiMachineDeployment
...
# 进入链当前目录
$ ssh root@192.168.0.170
$ cd /data/multiMachineDeployment
# 解压
$ unzip chain1.zip
# 进入当前部署机器的节点,启动当前节点
$ cd cd release/wx-org1.chainmaker.org-node1/bin/ && sh start.sh
```
## 功能验证
为了验证所搭建的链功能是否正常,可以通过`cmc`命令行工具或`sdk`的单元测试用例来进行验证。
### cmc命令行工具验证
请参看:[【命令行工具】](../dev/命令行工具.md)
### go sdk验证
#### 下载go sdk源码
> 在`chainmaker-go`工程同级目录,执行下面命令获取`go sdk`
```bash
$ git clone -b v2.2.1 https://git.chainmaker.org.cn/chainmaker/sdk-go.git
```
#### 关联证书
> 将通过`prepare.sh`工具生成的`crypto-config`目录,软连接到`sdk-go/testdata`目录
```bash
$ cd sdk-go/testdata
# 这里我们使用新生成的用户证书,请先将testdata已有的crypto-config移除
$ /bin/rm -rf crypto-config
# 软连接使用prepare.sh脚本生成的证书目录
$ ln -s ../../chainmaker-go/build/crypto-config/ .
```
#### 配置修改
> 修改sdk单元测试使用的配置文件:`sdk-go/testdata/sdk_config.yml`
根据需要修改节点地址:
```yml
nodes:
- # 节点地址,格式为:IP:端口:连接数
node_addr: "127.0.0.1:12301"
```
如果证书路径有调整,修改对应的证书路径配置:
```yml
# 客户端用户私钥路径
user_key_file_path: "./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key
# 客户端用户证书路径
user_crt_file_path: "./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt"
# 客户端用户交易签名私钥路径(若未设置,将使用user_key_file_path)
user_sign_key_file_path: "./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.key"
# 客户端用户交易签名证书路径(若未设置,将使用user_crt_file_path)
user_sign_crt_file_path: "./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.crt"
```
#### 执行存证合约example
该单测会进行存证合约的部署、调用和查询。
```bash
$ cd sdk-go/examples/user_contract_claim
$ go run main.go
```
看到success或OK等类似输出,说明功能验证成功。
### 管理台验证
请查看:[【管理台】](../tutorial/通过管理台启动链.md)
如果需要配置自拉起方式启动,请参考:[【自拉起服务】](../operation/自拉起服务.md)