项目的环境配置化

发布包往往依赖于一些环境配置,比如项目的数据库连接地址等, 在现在的云方案中,有etcd/condf,Apollo等方案,以相对独立的方式对配置进行管理。但对于传统项目,配置文件经常与Jar、War等文件,或与源代码在同一目录下进行管理。

传统项目的配置文件通常有以下三种。

  1. 编译参数选择,通过编译时指定不同的参数,将源代码中不同的配置文件打包至二进制文件。
  2. 线上文件目录指定。二进制文件固定读取某一指定目录下的配置文件。
  3. 二进制文件替换配置。由于Java工程下的Jar、War实际结构是zip包,而且其配置文件是明文文本文件。所以,对于此类伪二进制目标文件,可以先采用解压包,替换二进制文件,再封装包的方式进行配置更新。该方式即可达到配置文件更新的目的,又可以保证测试环境和生产环境的二进制包的一致性。

建立配置模板文件、配置文件

在config库中,根据项目名称samples,建立 以下文件:

---
# file: projects/samples/vars/main.yml
# configure_files选项,其指定配置文件列表。系统将从main,prod,uat等文件中所获得变量文件,对src模板文件进行替换,生成实际的配置文件,最后替换jar包中的dest文件。

hellowar:
tomcat:
service_name: "tomcat-hellowar"
port: 8080
configurations_files:
- { src: "{{ project_dir }}/hellowar/config.properties.j2", dest: "WEB-INF/classes/config.properties" }
# file: projects/samples/hellowar/config.properties.j2
# 一个测试的配置

config.site.name={{ config.site.name }}
---
# file: projects/samples/vars/prod.yml
# 生产环境的变量值

config:
site:
name: "I am a production site"
---
# file: projects/samples/vars/uat.yml
# UAT环境的变量值

config:
site:
name: "I am a test site"

Ansible文件

---
# 用Ansible文件将上述配置连接起来。注意增加: role: app.config; configurations_files: "{{ hellowar.configurations_files }}" 即可。

- hosts: "&samples:hellowar"
pre_tasks:
- name: include Globals
include: "{{ playbook_dir }}/../includes/global_vars.yml"
tags: "always"
vars:
project_name: "samples"
roles:
- role: app.config
- role: app.war
vars:
type: "tomcat"
vars:
project_name: "samples"
service_name: "{{ hellowar.tomcat.service_name }}"
workspace: "{{ app_root }}/war/{{ service_name }}"
container:
type: "tomcat"
service_name: "{{ service_name }}"
jdk_home: "{{ jdk8_home }}"
warfile: "hello.war"
TARGET_FILE: "hello-0.0.1-SNAPSHOT.war" #this file path will be replace by jenkins
war_unachive: false
target_type: "war"
configurations_files: "{{ hellowar.configurations_files }}"
service:
name: "{{ service_name }}"
port: "{{ hellowar.tomcat.port }}"

详细工作原理可以阅读 app.war 中的源代码。

加密配置管理

基于安全考虑,生产服务器中的数据库密钥、付费业务的Key/Value对,通常应该进行保密处理,不应该将明文暴露在Config代码库中。Ansible的变量文件可以通过Vaults工具进行加密管理。

另一个好的建议是对公用资源的管理,如数据库、缓存等。 运维应按照业务需要、资源配置需求,对公用资源进行分组管理。开发人员无需了解实际的资源连接IP、密码等细节,只需要了解组名、以及该类型资源下存在的键即可。

以MySQL配置为例,说明配置组和加密配置使用:

---
# file: configs/vaults/test.yml

mysql:
group_sample:
host: 192.158.31.100
port: 3306
user: root
password: "password"

文件定义了 mysql 的sample组。 其键包括 host、port,password等。

在应用的配置模板文件中,按照应用的格式要求,填写资源.组.键即可:

server:
sql:
# 开发环境
host: {{ mysql.group_jkt.host }} # 192.158.31.100
port: {{ mysql.group_jkt.port }}
username: {{ mysql.group_jkt.user }}
password: {{ mysql.group_jkt.password }}

建立加密的prod配置文件

$ cd configs/vaults
$ ansible-vault create prod.yml
New Vault password:
Confirm New Vault password:

输入密钥文件,回车之后,会进入vi编辑页面。 填入与test.yml文件相同的结构和正确的密码,保存。 特别注意,在配置文件更新时,要保证prod和test环境的同步,prod环境缺少配置键而到时上线失败。

查看prod.yml应形如如下内容:

$ cat prod.yml
$ANSIBLE_VAULT;1.1;AES256
6466356161366165386166393136336233
3762383566393964366661313962636264

该文件仅能通过ansible-vault edit prod.yml ,并输入密码后再次进行编辑。无密码之人是无法对文件进行查看和修改的。所以,放心的将prod.yml加入到git版本库进行管理。

还有一个步骤,你需要将这个密钥告诉Ansbile发布机。登录到发布机后,修改ansbile.cfg文件,增加行:

vault_password_file = ~/.ansbile/vault_password_file

创建~/.ansbile/vault_password_file文件,并将密钥明文写入到文件中。

DevOps下的角色及工作流

角色说明

角色职能
admin
管理员
对自动化部署系统进行系统管理、插件管理、编译节点建设、用户及权限管理。 对Jenkins使用的密钥进行管理。
sa
发布配置工程师
建立Jenkins编译任务(Build job)、发布任务(Publish Job)
scm
运维配置工程师
建立配置文件模板、配置文件参数,编写自动运维剧本
dev
开发工程师
编写代码、提交至SCM。
test
测试工程师
按顺序进行测试、准生产、生产各环境的发布、测试、审核审批
master
DevOps架构师
设计并实现DevOps的架构、流程、角色、规范,选择并应用各DevOps工具,指导全员融入DevOps体系

角色权限表 – Jenkins

RoleOverallCredentialsManage ownershipAgentJobPipelineRunViewSCM
adminAllAllAllAllAllAllAllAllAll
devNoneNoneNoneBuild, CancelDeploy to test (Automatically)NoneNoneNone
qaNoneNoneNoneBuild, CancelTestPassDeploy to uat&prodNoneNoneNone
scmCreate, Update, ViewALLNoneConfigureand All for test usageAll for test usageAllNoneNone
saCreate, Update, ViewNoneALLNoneNoneNoneNoneNone

启用角色管理插件

进入Jenkins管理页面,配置全局安全配置, 选择 Role-Based Strategy,保存。在保存前,先备份Jenkins Home下面的config.xml文件,当权限配置出错时,会导致管理员登录不进去。此时还原config.xml文件即可解决。

配置全局角色、项目角色

然后开始按上述权限表进行配置,进入Jenkins系统管理 -> Manage and Assign Roles -> Manage Roles, 通过新增,勾选,得到如下图所示的全局角色表、项目角色表。

建立用户,并授权角色

使用OpenLdap,添加用户。

Jenkins开启Role-Based Strategy组件之后,不接受OpenLdap的角色属性,因此,Jenkins内部权限应迁移到Manage and Assign Roles中进行配置。

进入系统管理 -> Manage and Assign Roles -> Global roles -> User/group to add -> 添加用户邮箱 -> 然后勾选对应角色

进入系统管理 -> Manage and Assign Roles -> Item roles -> User/group to add -> 添加用户邮箱 -> 然后勾选对应的项目组

其他与职能角色相关的任务

SA / SCM:

  1. 管理playbooks部署代码,负责项目及工程配置
  2. 管理 configs/prod 的配置代码修订
  3. 在Jenkins中发布playbooks库
  4. 在Jenkins中发布configs生产库
  5. 维护Jenkins的项目、工程文件。[SA/Dev]

Admin:

  1. 管理角色、用户、角色赋权
  2. 管理整体Jenkins配置

Dev:

  1. 维护业务代码
  2. 维护业务Config。由于生产配置库使用加密存储,Configs/Prod的配置,特别是涉及到密码的配置,由SA管理。
  3. 发起Pipeline编译过程,完成从编译、测试环境发布、测试过程,进入UAT发布准备阶段。

Test:

  1. 承接Dev的测试环境,共同完成测试验证工作。
  2. 确认发布UAT环境
  3. 验收UAT环境
  4. 发布PROD环境
  5. 验收PROD环境

新建项目和工程

为了管理方便,在DevOps中将系统分级为两层,项目、工程。 在演示用例中,我们建立一个项目,samples, 里面包含若干工程,hellowar, hellojar, hellohtml等。

以hellowar为例,建立Tomcat项目的自动化部署。

关于hellowar

hellowar是一个简单的tomcat项目,源代码可以在gikoluo/java-tomcat-example-app找到。部署成功后,访问项目首页,会得到一个WEB页面: hello world。

Jenkins项目框架

 HOME  #根
|-- samples #项目名
| |-----builds #这里放置编译任务
| |---- hellowar
| |---- hellojar
| |---- hellowar #这是一个带有pipeline的发布任务
| |---- hellojar
|-- sa #SA项目,用于管理DevOps环境及设备
|---- playbooks 这是一个发布+ant编译的项目。

对于工程,我们把编译和发布分离,一个pipeline中仅关联一次编译,这样有助于减少编译次数,并保证各环境下的部署内容一致。

Playbook项目框架

ROOT
|-- samples #项目名
|-- 22-tomcat8.yml #基础包。用数字作为前缀,表明依赖的先后顺序。
|-- hellowar.yml #工程包。以工程为名。

配置文件结构

ROOT
|-- projects
| |-- samples
| | |-- vars
| | | |-- main.yml #通用配置
| | | |-- uat.yml #环境特殊配置,比如环境IP,数据库IP等
| | |-- hellowar #应用配置模板文件,可以使用vars中的变量
| | | #在发布时进行变量替换。
| | | |-- application.xml

Tomcat基础包部署文件

---
# filename: 22-tomcat8.yml

- hosts: "&samples:hellowar"
become: True
become_user: root
pre_tasks:
- name: include Globals
include: "{{ playbook_dir }}/../includes/global_vars.yml"
vars:
project_name: "samples"
roles:
- app.tomcat
vars:
project_name: "hellowar"
service_name: "{{ hellowar.tomcat.service_name }}"
jdk_home: "{{ jdk8_home }}"
tomcat_version: '8.5.38'
tomcat_env_catalina_home: "{{ opt_root }}/{{ service_name }}/"
tomcat_redis_filename: "apache-tomcat-{{ tomcat_version }}.tar.gz"
tomcat_default_override_uri_encoding: UTF-8
tomcat_service_allow_restart: true
system_type: "systemd"
tomcat_instances:
- name: "{{ service_name }}"
service_name: "{{ service_name }}"
service_file: "{{ service_name }}"
port_ajp: 8009
port_connector: "{{ hellowar.tomcat.port }}"
port_redirect: 8443
port_shutdown: -1
path: "{{ opt_root }}/{{ service_name }}"
tomcat_service_allow_restart: true
tomcat_default_override_uri_encoding: UTF-8

项目部署文件

---
# filename: hellowar.yml

- hosts: &samples:hellowar
pre_tasks:
- name: include Globals
include: "{{ playbook_dir }}/../includes/global_vars.yml"
tags: "always"
roles:
- role: app.config
- role: app.war
vars:
type: "tomcat"
vars:
project_name: "samples"
service_name: "{{ hellowar.tomcat.service_name }}"
workspace: "{{ app_root }}/war/{{ service_name }}"
container:
type: "tomcat"
service_name: "{{ service_name }}"
jdk_home: "{{ jdk8_home }}"
warfile: "hello.war"
TARGET_FILE: "hello-0.0.1-SNAPSHOT.war" #this file path will be replace by jenkins
war_unachive: false
target_type: "war"
configurations_files: "{{ hellowar.configurations_files }}"
service:
name: "{{ service_name }}"
port: "{{ hellowar.tomcat.port }}"

服务器设备配置

#filename: uat/samples

[jdk8]
192.168.10.50 default_link=1

[hellowar]
192.168.10.50

[samples:children]
hellowar

配置文件

---
#repo: configs
#filename: configs/projects/vars/main.yml

hellowar:
tomcat:
service_name: "tomcat-hellowar"
port: 8080
configurations_files: []
log:
home: "{{ log_root }}/tomcat-hellowar"
level: INFO

提交并在Jenkins中发布Playbooks,configs代码

进入发布机,将项目的设备资源及环境进行初始化

ansible-playbook jkt/22-tomcat7.yml -i $INVERNTORY
ansible-playbook jkt/crm.yml -i $INVERNTORY --tags=setup
ansible-playbook jkt/appserver.yml -i $INVERNTORY --tags=setup

配置Jenkins

在Jenkins WEB页面中,如上框所示的目录架构,新建文件夹任务,samples; 再建立文件夹任务builds。

建立hellowar工程,类型为maven项目,配置如下:

源代码: https://github.com/gikoluo/java-tomcat-example-app.git
Build:
ROOT POM: pom.xml
Goals and options: compile war:war
归档成品: target/hellowar.war

保存,编译,等待hellowar.war编译完成

在samples内,建立任务hellowar,类型为 流水线。配置如下:

Prepare an environment for the run: True
Properties Content内填入以下内容:

PROJECT_NAME=samples
SERVICE_NAME=hellowar
BUILD_JOB=${PROJECT_NAME}/builds/hellowar
TARGET_FILE=target/hellowar.war
AUTO_BUILD=true

流水线: Pipeline srcipt from SCM
GIT, Repositories: https://github.com/gikoluo/devops-utils.git
脚本路径: src/jenkinsfile/common/Jenkinsfile.groovy

  • Prepare an environment for the run: 为EnvInject提供的功能,将Properties Content的语法为Key/Value变量,申明内容将注入到全局变量,供Jenkins脚本使用。注意,内容中,不允许有注释。
    • PROJECT_NAME/SERVICE_NAME: 填项目、工程名称。
    • BUILD_JOB: 填上文建立的Maven项目名。形如${PROJECT_NAME}/builds/hellowar。
    • TARGET_FILE: 填BUILD_JOB中编译归档的文件名,注意带上路径。
    • PLAYBOOK: 填写Playbook名称,如不存在则将使用 ${PROJECT_NAME}/${SERVICE_NAME}。
    • AUTO_BUILD: true/false 。 #是否每次发布时都自动执行编译。默认True。
  • 流水线: gikoluo/devops-utils 提供了一些标准通用的流水线文件,可以直接使用,可以获得源代码滞后,将文件内容直接复制到流水线定义里。

保存,构建。顺利的话,你将得到一个如图所示的Pipeline:

确认发布UAT之后,将进入验收阶段。 在浏览器中键入: http://192.168.10.50:8080/hello/ , 得到Hello World。确认UAT验证完成。

接下来继续通过Pipeline,确认Production发布、Production验收阶段,完成上线的全部流程。

新增目标服务器

在完成服务器的上架工作后,对服务器进行初始化配置。

在Ansible发布机配置的章节,已经进行过类似的操作了。 这里作为运维新机器上架的操作,再列一次。

在机器建立之初,首先得通过项目属性,了解机器的用途。获得以下属性:

  • 项目组: samples。 项目组为服务组,或者一个工作组。可以共享部署配置。
  • 服务名:hellowar。 服务名为一个可独立部署的服务。
  • 环境:UAT。
  • 设备IP:192.168.10.50
  • 服务环境: Tomcat8
  • JAVA环境:JDK8
  • 服务类型:放置在Tomcat下的War服务包

建立机器配置

$ cd playbooks
$ vi uat/samples
[jdk8]
192.168.33.100 default_link=1

[hellowar]
192.168.33.100

[samples:children]
hellowar

提交代码到GIT,然后在Jenkins WEB界面中执行SA/playbooks发布操作,将更新推送到发布机。

进入到发布机中进行目标的Ansible推送操作。

ssh ANSIBLE-UAT

export IP=192.168.33.100
export INVERNTORY=uat
export KEY_PATH=~/.ssh/agent/id_rsa
#注入公钥
ansible-playbook setups/10-installkey.yml -i $INVERNTORY -l "$IP" --private-key=$KEY_PATH
#建立统一的初始化环境
ansible-playbook setups/00-setup.yml -i $INVERNTORY -l "$IP"
#安装JDK8
ansible-playbook setups/01-oracle-jdk8.yml -i $INVERNTORY -l "$IP"
#安装Tomcat
ansible-playbook samples/22-tomcat8.yml -i $INVERNTORY
#初始化项目框架
ansible-playbook samples/23-hellowar.yml -i $INVERNTORY --tags=setup

关于如何写sample/*.yml, 在下一篇文章中会介绍。

Ansible发布机

上接Jenkins部署,现在分别在三个环境下,构建三台Ansible发布机器,机器将作为Jenkins的部署节点。
现在将Jenkins机器作为临时的Ansible节点,分别推送三个环境的Ansible部署机器的安装工作。
以UAT环境为例,操作如下

建立Playbook发布项目

进入Jenkins:
新建任务,添加文件夹,任务名: SA;
进入SA目录,新建任务,添加自由风格的软件项目,任务名: playbook,配置如下:

项目类型: 自由风格的软件项目
描述: 将Absible Playbooks 发布到 发布机
源码管理: git, Repository URL: https://github.com/gikoluo/playbooks2.git
构建:Invoke Ant
Ant version: ant or default
Target: build
构建后操作:
Send build artifacts over SSH
SSH Server: 192.168.10.45
Transfers Set:
Source file: dist/playbooks.tar.gz
Remote directory: playbooks/
Exec command: cd /data/playbooks && tar zxvf playbooks.tar.gz && rm playbooks.tar.gz
Flatten files: TRUE

SSH Server: 192.168.33.10
Transfers Set:
THE SAME AS BELOW.

SSH Server: 10.0.1.12
Transfers Set:
THE SAME AS BELOW.

归档成品:
用于存档的文件: dist/playbooks.tar.gz

保存,然后发布, 检查日志输出、目标文件夹代码是否正常。

安装Ansible

#进入Jenkins机器
$ ssh jenkins
#安装pip & ansbile。 通过pip安装可以保证ansible的版本较新。
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py
$ pip install ansible
#克隆ansible剧本
$ cd /data
$ git clone https://github.com/gikoluo/playbooks2.git playbook
$ git clone https://github.com/gikoluo/ansible-config.git configs
#配置IP
$ cd playbooks
$ vi uat/sa

[ansible]
192.168.10.45
[jdk8]
192.168.10.45 default_link=1

#将Jenkins登录公钥注入部署机器
$ export IP=192.168.10.45
$ export INVERNTORY=uat
$ export KEY_PATH=~/.ssh/agent/id_rsa
$ ansible-playbook setups/10-installkey.yml -i $INVERNTORY -l "$IP" --private-key=$KEY_PATH #如果使用证书登录,使用本行
$ ansible-playbook setups/10-installkey.yml -i $INVERNTORY -l "$IP" -kK #如果使用密码登录,可以使用本行,输入密码和SUDO密码
$ ssh $IP ip a #测试是否可直接登录成功,如果返回正常,则说明安装密钥正常。
#将Jenkins登录公约注入部署机器
$ ansible-playbook setups/00-setup.yml -i $INVERNTORY -l "$IP" #初始化机器环境
$ ansible-playbook provo/01-ansible.yml -i $INVERNTORY -l "$IP" #安装Ansible
$ ansible-playbook setups/01-oracle-jdk8.yml -i $INVERNTORY -l "$IP" #安装JDK环境,将Ansible机器作为Jenkins节点时需要
$ ansible-playbook setups/01-open-jdk8.yml -i $INVERNTORY -l "$IP" #或安装openJDK环境,将Ansible机器作为Jenkins节点时需要

将发布机器配置为Jenkins节点

进入Jenkins -> 系统管理 -> 节点管理 -> 新建节点 -> 填写下方配置后保存。

节点名称:ansible-uat
节点类型:固定节点
远程工作目录: /data/playbooks
主机: 192.168.10.45
Credentials: 自行配置私钥

保存后,Jenkins会自动启动节点服务。如启动失败,可根据日志检查问题。

部署其他节点

与上方操作相同,完成三台发布机初始化工作,在JENKINS节点中分别命名为ANSIBLE-TEST,ANSIBLE-UAT,ANSIBLE-PROD。

Jenkins部署

使用Docker部署

$ git clone https://github.com/gikoluo/devops-jenkins.git
$ cd devops-jenkins
$ docker-compose up

使用K8S部署

$ git clone https://github.com/gikoluo/devops-jenkins.git
$ cd devops-jenkins
$ kubectl apply -f jenkins-home-pvc.yaml
$ kubectl apply -f jenkins-deployment.yaml
$ kubectl apply -f jenkins-service.yaml

传统部署

$ yum install jenkins

安装组件

微服务部署时,组件已经完成部署。传统部署模式下,需要手动运行以下脚本安装组件。

 
$ export JENKINS_USER_ID=luochunhui
$ export JENKINS_API_TOKEN=123456
$ export JENKINS_SERVER=http://192.168.30.200:8080/
$ cd devops-jenkins
$ wget "${JENKINS_SERVER}jnlpJars/jenkins-cli.jar"
$ xargs java -jar jenkins-cli.jar -s $JENKINS_SERVER install-plugin $i < plugins.txt

OpenLdap管理

一、服务器部署

使用DockerComposer部署

$ git clone https://github.com/gikoluo/openldap
$ cd openldap
$ docker-compose up

使用K8S部署

$ git clone https://github.com/gikoluo/openldap
$ cd openldap
$ kubectl apply -f openldap-etc-pvc.yaml
$ kubectl apply -f openldap-lib-pvc.yaml
$ kubectl apply -f openldap-deployment.yaml
$ kubectl apply -f openldap-service.yaml

# Check services
$ kubectl get deployments openldap
$ kubectl get services openldap
$ kubectl describe services openldap
$ kubectl get pods

# Open a temporary port to manage
$ kubectl port-forward openldap-XXXXXX-XXXX 8389:389

使用Helm部署

helm install --name openldap -f helm.yaml stable/openldap

使用传统Yum部署

详细流程参见页面: https://linuxtechlab.com/openldap-complete-guide-install-configure

$ yum install openldap-server

二、管理使用

验证:

$ ldapsearch -x -W -D 'cn=Manager,dc=greenlandfinancial,dc=com' -b "" -s base
Enter LDAP Password:
# extended LDIF
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: ALL
#

#
dn:
objectClass: top
objectClass: OpenLDAProotDSE

# search result
search: 2
result: 0 Success
numResponses: 2
numEntries: 1

使用ApacheDirectoryStudio进行管理

从 https://directory.apache.org/studio/ 下载并安装ADS。 适用于MAC,Windows,Linux。

新建LDAP连接,使用以下配置:

Hostname: 127.0.0.1
Port: 389
Encryption method: No encryption
Provider: Apache Directory LDAP Client API
BindDN or user: cn=Manager,dc=greenlandfinancial,dc=com
Bind password: password set in deploy

建立组织和用户结构

建立组织结构,结果按图示:

ou=inner         #内部产品
- ou=jenkins #某产品,也用来管理用户和产品之间权限管理
ou=people #用户列表
- cn=luochunhui@greenlandfinancial.com #用户

管理用户和组关系

在需要的授权的组中,增加member属性,其值为用户的DN地址。示例如下图:

十二月读书简报

《咨询学》- 余阳明 

简评: 读完了第一章,放弃。写得太马克思了。

《成为百万美元咨询师》- 艾伦*韦斯 第四版

本书对咨询师如何成为更优秀地咨询师地指导,本身文字具有很强的咨询性质。比如一些要点:放弃底部15%;强调结果和效果;一分钟精确阐述自己地价值等等。其中1%解决方案也挺富有哲理。本书的语句,精辟短小,可以作为咨询师进行语言摘录的重要来源。

《区块链平台调研与分析报告》

《区块链平台调研与分析报告》 – FISCO-BCOS/Wiki

〇、概要

本文从8个维度,包括架构、核心技术组件、应用功能、技术能力、安全机制、适用性、开发及工具、维护支持能力,围绕Ethereum、Fabric、Corda、BCOS 4个区块链技术平台展开分析。

四个区块链平台介绍

  • Ethereum:以太坊,最早提出,可建立去中心化应用
  • Fabric:超级账本
  • Corda:是一个分布式账本;第二,Corda是一个去中心化数据库;第三,Corda是一个“受区块链启发的”技术平台
  • BCOS:名字取至BlockChainOpenSource,是深圳前海微众银行股份有限公司、上海万向区块链股份公司、矩阵元技术(深圳)有限公司三方共同研发并且完全开源的区块链底层技术平台。

一、架构

  • 数据层:数据链式结构、数字签名、哈希函数、非对称加密等算法和技术。主要实现了网络数据存储、账户和交易的实现与安全两个功能。
  • 网络层:P2P网络机制、数据传输机制和数据验证机制,实现网络节点的连接和通讯。
  • 共识层:封装网络节点的各类共识机制算法。常见:Pow、PoS、BFT等。
  • 激励层:实现代币的发行和分配。激励遵守规则的节点、惩罚不规则节点。
  • 合约层:封装脚本、算法、智能合约,赋予账本可编程的特性。
  • 应用层:各类应用场景和案例,如DAPP。

架构灵活性

  • Ethereum:分片机制,未实现。
  • Fabric:松耦合设计,将共识机制、身份验证等组件模块化;支持不同主体间交易的多通道结构,提升业务隔离、安全性方面。
  • Corda:共识机制设计为可插拔的独立性服务。通过独立服务(验证使用,不必证明合法)提高了扩展性、分账系统的兼容性和算法敏捷性。
  • BCOS:共识算法采用插件化设计,实现在多个联盟链里使用不同的共识机制,参与到同一个联盟链的所有节点必须采用同一种共识配置。

节点分类

  • Ethereum:从Pow到PoS共识,依据资产的多寡分配记账权重,更好的利用计算资源
  • Fabric:验证节点、非验证节点。通过授权和证书管理节点。
  • Corda:普通节点、公证节点(有效性共识、金融凭证流运行和签发)、管理节点。
  • BCOS:共识节点和观察节点。共识节点参与运算,成为记账者,观察节点只同步数据。

二、核心技术组件

共识机制

  • Ethereum:PoW+PoS混合机制
  • Fabric:主要为PBFT。
  • Corda:一般选择BTF为公证算法,也可以使用Raft。
  • BCOS:PBFT、Raft作为联盟链的共识算法,参与到联盟链的所有节点必须选用同一种共识配置。

通讯/P2P技术

  • Ethereum:标准加密货币协议,“幽灵”协议的最基础部门
  • Fabric:Google PRC,功能包括双向流,流控制,多路复用要求。能与网络基础设施结合,包括防火墙,代理服务器以及安全保护,提供点对点的多路传送的定义
  • Corda:AMPQ/1.0消息中间件,适合嵌入式应用。TLS加密协议。
  • BCOS:AMOP系统,联盟链内区块链节点,无论是共识节点还是观察节点,均可使用AMOP进行通讯。

存储

  • Ethereum:使用Merkle树存放交易散列。区块头记录状态快照。但回收剔除的历史区块的方法,特别是其存储方式,存在争议,主要争议点为历史数据会导致数据中心点。
  • Fabric:同Ethereum
  • Corda:数据仅存储在合约执行者的节点。
  • BCOS:支持分组多副本方式存储,支持分布式数据存储,企业可使用现有分布式存储方法,如数据仓库、数据库集群等。

计算效率

Ethereum、Corda的交易可被并行验证以提高计算效率

  • Ethereum:通过分区解决合约持久化问题和分区间并行, 但尚未实现。
  • Fabric:低效率
  • Corda:因为存储仅在合约执行节点,因此计算可并行。
  • BCOS:利用集群化、分片机制,使交易按一定的规则互相隔离,可被并行处理,且数据量可以通过垂直切分的方式,分布存储在不同的存储设备上,以满足性能和容量平行扩容的需求。

三、应用功能

身份认证

  • Ethereum:匿名身份认证。
  • Fabric:数字证书,基于PKI。
  • Corda:数字证书。存在全网身份服务节点。
  • BCOS:数字证书。使用CA证书准入机制。

账户设计

  • Ethereum:余额账户机制。
  • Fabric:无代币,可以通过ChainCode实现本币发行和账户功能。
  • Corda:无余额,所有余额通过UTXO计算得出。
  • BCOS:无代币。

私钥保护

  • Ethereum:用户本地存储
  • Fabric:用户本地存储
  • Corda:证书与私钥绑定
  • BCOS:采用加密机,与节点分离存储

智能合约

  • Ethereum:图灵完备,采取合约和共识相连
  • Fabric:Docker计算
  • Corda:JVM运行。交易、智能合约、流架构。
  • BCOS:运用Solodity合约开发语言。同Ethereum。

监管相关功能

  • Ethereum:公有链特性,监管可接入,但身份匿名,监管接入意义不大
  • Fabric:监管机构可按照规定规则来审计全部或部分总账分录,利用密钥的层级赋予权限,审计员通过“基于时间的证书”来获得总账查看权限
  • Corda:许可、运营
  • BCOS:支持监管部门和审计部门作为特殊节点接入,同步数据。提供可监管、可审计的数据接口

特权机制的实现

特权机制主要包括两类:暂停、回滚或者取消交易;改正数据。

  • Ethereum:无。理论上可“隐性地”实现暂停、回滚或取消交易以及改正数据的特权,采用硬分叉、反向交易方式。
  • Fabric:同上
  • Corda:同上
  • BCOS:BCOS可以针对特定的业务场景,制定特定的权限集合,如监管方可以是联盟链的规则制定者和实施者,通过参与准入审核,智能合约编写、部署和升级,以及事前中后的检测和干预对业务实施监管。

四、技术能力

吞吐量

  • Ethereum:当前交易限制在10TPS或者更低。
  • Fabric:1000TPS或更高
  • Corda:与交易复杂程度正相关。总吞吐量与Fabric相当
  • BCOS:数千TPS,并支持平行扩展

确认时间

  • Ethereum:确认时间12秒左右。
  • Fabric:3-6秒确认交易
  • Corda:实时
  • BCOS:1秒出块,出块即达成共识

可用性

  • Ethereum:PoW提供较高的灵活性和可用性。
  • Fabric:记账节点必须在线提供服务而不能推出网络,三分之一的节点停机将变得不可用
  • Corda:节点必须自身保证
  • BCOS:PBFT共识与Fabric一直;Raft超过1/2数量时网络不可用

五、安全机制

从总体上看,理想的隐私保护策略,如零知识证明、同态加密等大都基于较为复杂的密码学技术,目前在各平台实际应用中有待进一步完善并丰富应用场景。

六、平台适用性

  • Ethereum:Ethereum可利用图灵完备的智能合约,适应金融应用、物联网、供应链管理、社交网络、去中心化自治组织(DAO)、预测市场等场景。
  • Fabric:Fabric具备了多通道的架构设计以及共识节点的独立性,可以在保证平台上交易多方隐私性的同时,提高共识节点的效率,从而在技术上推动区块链和分布式账本技术在跨行业应用场景中的应用,使其可满足金融服务、供应链管理、智能制造、文化娱乐、医疗健康、社会公益、教育就业等领域的应用。
  • Corda:Corda定位为面向非公有链的场景,其架构设计如可插拔的共识算法、灵活可配的节点权限、凭据流概念的引入,使得Corda更接近于受监管的金融机构的应用。
  • BCOS:PBFT共识与Fabric一直;Raft超过1/2数量时网络不可用。
  • 与外部数据对接的角度上看,Ethereum、Fabric、Corda和BCOS在架构上均预留了身份、策略、数据、过程等应用模块,

七、开发及工具

编程语言

  • Ethereum:Go、C++、Python,通过编译器转成EVM语言。Solidity为首选。
  • Fabric:容器技术,支持Go、Java。
  • Corda:Java,Koltin,也支持SQL。原则上DApp支持JVM任何语言。
  • BCOS:支持C++,Java,Python,Javascript,Go。

配套开发工具

  • Ethereum:技术文档。Solidity语言。
  • Fabric:Fabric项目源码。
  • Corda:DorDapp-template,Samples。
  • BCOS:源码、SDK工具包。

接口完备程度

  • Ethereum:8545端口,JSON RPC API接口,可执行WEB3库的各种指令。
  • Fabric:灵活可扩展的模块,提供API接口,即插即用。
  • Corda:流程实时监控和展示接口,预留SQL,支持通用API接口。
  • BCOS:对业务层提供接口服务,HTTPS服务端口,JSON编码。SDK面向区块链底层功能接口的调用;SDK也面向业务,提供业务级别的接口。

智能合约的可编辑性

  • Ethereum:用户可创建自己的包含任意逻辑的合约。
  • Fabric:理论上Docker支持任何语言,但Docker架构存在资源消耗难以测定、通用性方面的问题。
  • Corda:可使用任何与JVM兼容的语言。
  • BCOS:支持Solidity,计划支持JVM。

八、维护支持能力

版本升级维护

  • Ethereum:主要由 Ethereum 基金会来负责运行,且有明确规划:Frontier(前沿)、Homestead(家园)、Metropolis(大都会)和Serenity(宁静)。
  • Fabric:由 Linux 基金会发起创建的,联盟主要成员来自大型金融机构、大型 IT 企业、大型咨询机构等不同的利益体,具备强大的资金和技术能力。源于IBM。
  • Corda:由 R3 CEV 联盟组织开发,其成员主要来自于全球知名的金融机构。
  • BCOS:BCOS由微众银行、万向区块链、矩阵元共同开发,有专业开发团队进行研发和维护。BCOS升级原则上保证向下兼容。BCOS平台借鉴COBIT模型,形成了一个三维治理体系结构,包括治理准则(Business Requirements)、治理对象(Resources)、及治理过程(Processes)。

九、总结表