# 同步服务部署文档 ## 设计方案 子链合约部分我们介绍为了保证子链与主链did 状态数据库一致,我们需要以块为最小单位进行同步迁移。所以我们得到以下同步服务流程: 1) 同步服务监听主链区块 2) 同步服务解析主链区块,并检查是否存在在关注列表的 did topic,存在进入第三步,否则丢弃并回到第一步 3) 同步服务按照主链区块中交易顺序构建 did event 数据 list 4) 同步服务将整理的主链中某个块的 event 数据打包,调用同步合约进行上链操作 5) 子链 did 同步合约将同步服务的 event 数据解包并写入链上 ## 部署流程 ### 硬件配置 | 配置 | 最低配置 | 推荐 | |-----|-------|-------| | CPU | 1.5Hz | 2.4Hz | | 内存 | 8G | 16G | | 核心 | 4核 | 8核 | | 带宽 | 2Mb | 10Mb | ### 合约部署 本服务应用前提需要两条 ChainMaker 链,请自行部署搭建,主链安装DID合约,子链安装DID同步合约。 主链DID合约在:[DID合约](https://git.chainweaver.org.cn/chainweaver/did/did-contract/-/tree/master/standard-did) DID同步合约在:[DID同步合约](https://git.chainweaver.org.cn/chainweaver/did/did-contract/-/tree/v1.2.0_subchain/standard-did) > 可下载已编译好的文件[同步合约](https://git.chainweaver.org.cn/chainweaver/did/did-contract/-/releases/v1.2.0_sc)进行部署,或根据服务器配置自行编译后部署 请将以上两个合约安装到对应的ChainMaker链上。 ### docker 方式部署 #### 软件依赖 | 名称 | 版本 | 描述 | |----------------|----------|------------| | docker | 18+ | 运行服务 | | docker-compose | v1.26+ | docker部署工具 | > 注: > > - 确保已有一个运行中的Docker,版本建议为18或更高。 > - 已安装docker-compose命令行工具,用于docker- compose.yml的部署。 > - 确保可以从长安链镜像仓库hub-dev.cnbn.org.cn拉取镜像。 #### 创建etc目录,准备配置文件: 配置文件目录结构如下: ```shell did-sync ├── docker-compose.yml └── etc ├── config.yaml # 服务配置文件 ├── mainchain_user.key # 主链 SDK 客户端用户交易签名私钥 ├── sdk_config_mainchain.yml # 主链 SDK 配置文件 ├── sdk_config_subchain.yml # 子链 SDK 配置文件 └── subchain_user.key # 子链 SDK 客户端用户交易签名私钥 ``` 1. 主链 sdk 配置文件:sdk_config_mainchain.yml 2. 子链 sdk 配置文件:sdk_config_subchain.yml 3. 服务配置文件:config.yaml 配置项如下,请根据注释自行调整 > 需确认以下部分: > 1、syncContract部分:主链did合约名称,若有特殊要求(明确知道需同步数据起止区块高度)可自行配置,默认将同步所有; > 2、主子链配置文件路径,子链同步合约名称是否正确。 ```yaml system: env: test db-type: sqlite # 日志配置 zap: # 日志输出级别 level: debug # 日志格式, json 格式 或者 console format: console # 日志输出前缀 prefix: "[did-sync]" # 日志输出路径 path: ./logs/service.log # 是否显示代码行号 show-line: true # 是否打印到控制台 log-in-console: false # 监听主链did合约信息 syncContract: # 主链DID合约名称 name: "DID" topic: #设置为空表示监听当前合约下的所有event # - "SetDidDocument" # - "SetTrustRootList" # - "RevokeVc" # - "AddBlackList" # - "DeleteBlackList" # - "AddTrustIssuer" # - "DeleteTrustIssuer" # - "Delegate" # - "RevokeDelegate" # - "SetVcTemplate" # - "VcIssueLog" # - "DisableVcTemplate" # - "EnableVcTemplate" # 如果结束高度设置为-1,则一直同步 endHeight: -1 # 开始同步 主链区块高度 startHeight: 0 # 子链配置信息 subCmSdk: # DID 同步合约名称 contractName: "DIDSub" chainConfig: sdkPath: "./etc/sdk_config_subchain.yml" chainId: "chain_sub_test" # 主链配置信息 mainCmSdk: chainConfig: sdkPath: "./etc/sdk_config_mainchain.yml" chainId: "chain_main_test" ``` #### 准备 docker-compose.yml 文件 可自行拉取服务镜像: ```shell docker pull hub-dev.cnbn.org.cn/opennet/did-sync:v1.2.0_qc ``` docker-compose.yml 文件内容如下: ```yaml services: did-sync: image: hub-dev.cnbn.org.cn/opennet/did-sync:v1.2.0_qc container_name: did-sync volumes: - ./etc:/did-sync/etc - ./logs:/did-sync/logs - ./data:/did-sync/data restart: always ``` #### 使用 `docker-compose` 命令部署资源定义文件到 docker: ```shell docker-compose -f ./docker-compose.yml up -d ``` #### 验证部署检查容器状态: ```shell docker ps | grep did-sync ``` 返回结果如下,则表示启动成功。 ```shell CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cedf2c8beaf3 hub-dev.cnbn.org.cn/opennet/did-sync:v1.2.0_qc "./did-sync" 4 seconds ago Up 3 seconds did-sync ``` 若未成功启动可查看docker容器日志检查原因: ```shell docker logs did-sync ``` #### 查看服务日志: ```shell cat ./logs/service.log ``` 返回结果如下,则表示启动成功。 ```shell ======== _____ _____ _____ _____ | __ \_ _| __ \ / ____| | | | || | | | | |_____| (___ _ _ _ __ ___ | | | || | | | | |______\___ \| | | | '_ \ / __| | |__| || |_| |__| | ____) | |_| | | | | (__ |_____/_____|_____/ |_____/ \__, |_| |_|\___| __/ | |___/ ======== Service Name: DID Sync Service Version: v1.2.0_qc Build Time: 2024-08-15 08:07:41 Git Commit: v1.2.0_qc(a8d35d9d) Start Time: 2024-08-15T16:44:30+08:00 Now Time: 2024-08-15T16:44:30+08:00 2024-08-15 16:44:30.878 [INFO] [did-sync] did-sync/main.go:64 Starting did sync service ``` #### 停止服务: ```shell docker-compose -f ./docker-compose.yml down ``` 若要清空数据请删除 logs目录及 etc 目录下的 sqlite.db 本地数据库文件 ### k8s 部署方式 #### 软件依赖 | 名称 | 版本 | 描述 | |-----------|----------|------------------| | docker | 18+ | 拉取镜像使用 | | k8s | v1.18+ | 服务 Kubernetes 集群 | | kubectl工具 | 与k8s集群匹配 | | > 注: > > - 确保已有一个运行中的 Kubernetes 集群,版本建议为v1.18或更高 > - 已安装并配置`kubectl`命令行工具,用于与 Kubernetes 集群交互 > - 确保可以从长安链镜像仓库 hub-dev.cnbn.org.cn 拉取镜像 #### 将镜像载入k8s的work节点 项目方准备一个公网可访问的Docker镜像仓库,用于存储DID微服务的镜像。在后续运行部署流程时会自动拉取,如果Kubernetes所在环境无法访问互联网,需要手动载入Docker镜像到Kubernetes的Worker节点,执行如下命令: ```shell # 手动载入Docker镜像,找个能连hub-dev.cnbn.org.cn的服务器 docker pull hub-dev.cnbn.org.cn/opennet/did-sync:v1.2.0_qc # 保存文件到本地 docker save -o did-sync-v1.2.0.tar hub-dev.cnbn.org.cn/opennet/did-sync:v1.2.0_qc # 自行上传文件 did-sync-v1.2.0.tar 到Kubernetes的Worker节点服务器 # Kubernetes的Worker节点服务器载入镜像 docker load -i did-sync-v1.2.0.tar #查看是否载入成功 docker images | grep hub-dev.cnbn.org.cn/opennet/did-sync # 若显示如下说明成功 hub-dev.cnbn.org.cn/opennet/did-sync v1.2.0_qc cdf19ec76c3a 2 hours ago 190MB ``` #### 准备 deployment.yaml 配置文件 配置文件目录结构如下: ```shell did-sync └── deployment.yaml ``` deployment.yaml 文件内容如下,请自行修改 ConfigMap 配置相关内容: > 注: > > - config.yaml 为服务配置文件,请确认简单主链did合约信息、同步合约名称和主子链配置(sdk_config文件路径)是否正确 > - *.key 文件为用户私钥,sdk_config.yml 文件为链 SDK 配置文件 请确保内容正确 ```yaml apiVersion: v1 kind: ConfigMap metadata: creationTimestamp: null name: did-sync-configmap data: # 服务配置 config.yaml: |+ system: env: test db-type: sqlite # 日志配置 zap: # 日志输出级别 level: debug # 日志格式, json 格式 或者 console format: console # 日志输出前缀 prefix: "[did-sync]" # 日志输出路径 path: ./logs/service.log # 是否显示代码行号 show-line: true # 是否打印到控制台 log-in-console: false # 监听主链did合约信息 syncContract: # 主链DID合约名称 name: "DID" topic: #设置为空表示监听当前合约下的所有event # - "SetDidDocument" # - "SetTrustRootList" # - "RevokeVc" # - "AddBlackList" # - "DeleteBlackList" # - "AddTrustIssuer" # - "DeleteTrustIssuer" # - "Delegate" # - "RevokeDelegate" # - "SetVcTemplate" # - "VcIssueLog" # - "DisableVcTemplate" # - "EnableVcTemplate" # 如果结束高度设置为-1,则一直同步 endHeight: -1 # 开始同步 主链区块高度 startHeight: 0 # 子链配置信息 subCmSdk: # DID 同步合约名称 contractName: "DIDSub" chainConfig: sdkPath: "./etc/sdk_config_subchain.yml" chainId: "chain_sub_test" # 主链配置信息 mainCmSdk: chainConfig: sdkPath: "./etc/sdk_config_mainchain.yml" chainId: "chain_main_test" mainchain_user.key: | -----BEGIN PRIVATE KEY----- MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgelqvKuVT3RMtKqC3 ZCJI4Tac8tYkS50erVjLPe+rhBegCgYIKoEcz1UBgi2hRANCAARe9ivpYoa0yirj VPmCAm8XYbqhuj2RWdPhTr81/B15t/0Zp/oL0g48l4vWp/89X3n9S94g2VIYECbN VpYRWCRs -----END PRIVATE KEY----- sdk_config_mainchain.yml: | chain_client: # 链ID chain_id: "chain_main_test" # 客户端用户交易签名私钥路径 user_sign_key_file_path: "./etc/mainchain_user.key" # 客户端用户交易签名私钥密码(无密码则不需要设置) # user_sign_key_pwd: "123" # 签名使用的哈希算法,和节点保持一直 crypto: hash: SM3 auth_type: public # 同步交易结果模式下,轮询获取交易结果时的最大轮询次数,删除此项或设为<=0则使用默认值 10 retry_limit: 20 # 同步交易结果模式下,每次轮询交易结果时的等待时间,单位:ms 删除此项或设为<=0则使用默认值 500 retry_interval: 500 # txid配置项:默认支持TimestampKey,如果开启enableNormalKey则使用NormalKey enable_normal_key: false nodes: - # 节点地址,格式为:IP:端口:连接数 node_addr: "127.0.0.1:12391" # 节点连接数 conn_cnt: 10 rpc_client: max_receive_message_size: 100 # grpc客户端接收消息时,允许单条message大小的最大值(MB) max_send_message_size: 100 # grpc客户端发送消息时,允许单条message大小的最大值(MB) send_tx_timeout: 60 # grpc 客户端发送交易超时时间 get_tx_timeout: 60 # rpc 客户端查询交易超时时间 sdk_config_subchain.yml: | chain_client: # 链ID chain_id: "chain_sub_test" # 客户端用户交易签名私钥路径 user_sign_key_file_path: "./etc/subchain_user.key" # 客户端用户交易签名私钥密码(无密码则不需要设置) # user_sign_key_pwd: "123" # 签名使用的哈希算法,和节点保持一直 crypto: hash: SM3 auth_type: public # 同步交易结果模式下,轮询获取交易结果时的最大轮询次数,删除此项或设为<=0则使用默认值 10 retry_limit: 20 # 同步交易结果模式下,每次轮询交易结果时的等待时间,单位:ms 删除此项或设为<=0则使用默认值 500 retry_interval: 500 # txid配置项:默认支持TimestampKey,如果开启enableNormalKey则使用NormalKey enable_normal_key: false nodes: - # 节点地址,格式为:IP:端口:连接数 node_addr: "127.0.0.1:12395" # 节点连接数 conn_cnt: 10 rpc_client: max_receive_message_size: 100 # grpc客户端接收消息时,允许单条message大小的最大值(MB) max_send_message_size: 100 # grpc客户端发送消息时,允许单条message大小的最大值(MB) send_tx_timeout: 60 # grpc 客户端发送交易超时时间 get_tx_timeout: 60 # rpc 客户端查询交易超时时间 subchain_user.key: | -----BEGIN EC PRIVATE KEY----- MHcCAQEEIMiaCfztbtenIgNHKjqFHtgJy9B3cyWVLIfM0bFn86pUoAoGCCqGSM49 AwEHoUQDQgAEjXCPDCb9TjjPCKDSo85EDRr7El79ZpWR9xeu9zMidwDcF3U4Zt1u AudJ3nLiANAxRsKqPmXIiAu5kOF9Svrd8Q== -----END EC PRIVATE KEY----- --- apiVersion: apps/v1 kind: Deployment metadata: name: did-sync spec: replicas: 1 selector: matchLabels: app: did-sync template: metadata: labels: app: did-sync spec: containers: - name: did-sync image: hub-dev.cnbn.org.cn/opennet/did-sync:v1.2.0_qc volumeMounts: - name: config-volume mountPath: /did-sync/etc volumes: - name: config-volume configMap: name: did-sync-configmap ``` #### 部署到 Kubernetes 集群 使用`kubectl apply`命令部署资源定义文件到 Kubernetes 集群: ```shell kubectl apply -f ./deployment.yaml ``` 验证部署检查Pod状态,确保 DID 同步服务已成功启动并运行: ```shell kubectl get pods | grep did-sync ``` 返回结果如下,1/1则表示微服务有一个实例,启动成功1个pod实例。 ```shell NAME READY STATUS RESTARTS AGE did-sync-xxxxx-xxx 1/1 Running 0 2s ``` 若未成功启动可查看 k8s pod检查原因: ```shell # 查看pod详情 kubectl describe pod did-sync-xxxxx-xxx # 查看pod日志 kubectl logs did-sync-xxxxx-xxx ``` 服务启动后进入服务查看运行日志: ```shell # 进入服务pod kubectl exec -it did-sync-xxxxx-xxx -- /bin/sh # 查看日志 tail -f ./logs/service.log ``` #### 停止服务: ```shell kubectl delete -f ./deployment.yaml ```