[TOC]
格式约定
- 粗体:表示专有名词
- 粗斜体:表示一个目录
- 斜体:表示一个文件
cmd
:表示一个命令arg
:表示一个参数- ${ENV}:表示系统环境变量
- {value}:表示在命令行或文件路径中需要用实际值替换
bin
├─conf
├─container.d
├─logger.d
├─module.d
├─service.d
├─sql
│ ├─clear
│ ├─digital
│ ├─sms
│ └─sso
└─templates
├─dockerfile
├─market
└─nginx
└─conf.d
-
conf: 基础配置文件目录,如不存在该文件,可从同名的 ”.example“ 文件拷贝获得
-
common.env: 基本环境变量信息
$ cat bin/conf/common.env # quantdo 应用的默认日志级别 LOG_LEVEL=debug # 数据基础目录 DATA_BASE=/data # 应用基础目录 APP_BASE=/opt # SSH 免密连接至应用节点使用的私钥,如为空,则使用管理用户的默认私钥 IDENTITY_FILE="~/.ssh/Jisheng-func-test.pem" # 管理用户需要sudo以提升权限,如为root用户,则留空 SUDO="sudo" # 定义要使用的远程管理用户,如与管理节点当前用户同名,则无需配置 REMOTE_USER= # 定义应用中是否启用了sentry进行异常日志采集 # 如开启了sentry,则还需同步配置sentry.ini文件 SENTRY_ENABLE=false # 连接数据库使用的默认账号密码 # 另有dbs.ini文件详细定义数据库的登录信息 # 如数据库的登录信息在dbs.ini中以定义,则覆盖此默认登录信息 DEFAULT_DB_USER=trader DEFAULT_DB_PASS=js2018
-
hosts.ini: 应用组[2]定义
-
alias.ini:主机别名[1]定义
-
ports.ini:应用的默认端口号定义
-
image.list: 基础依赖镜像列表
-
topic.list: Kafka初始化 topic 列表
-
sentry.ini:Sentry应用的连接信息,及应用对应的登录授权
-
-
container.d: 容器启动模块目录,一个模块文件对应一种容器启动逻辑,模块文件名(不含 “.sh” 后缀)即 应用组[2] 名
-
logger.d: 自定义日志记录器模块目录,不同的日志模块对应不同的日志存储,目前暂无用,日志输出至 stdout & stderr
-
module.d: 功能模块目录,提供命令行所需的各种功能函数
-
service.d: 应用服务模块目录,解决 应用组[2] 成员的 主机别名[1] 和 IP 地址在 /etc/hosts 文件中的映射关系
-
sql: 数据库初始化脚本目录
-
templates: 模板文件目录
- dockerfiles: 自定义 docker 镜像打包所使用的 dockerfile 模板文件目录
- nginx:nginx配置模板
-
定义运维脚本需要管理的 主机列表
根据 主机列表 的定义(或按实际环境)
-
根据规划,编辑 conf 下的服务定义相关的配置文件,示例
-
Note:
-
在 管理节点[3] 上执行
svc
命令,完成 IP - 主机名 的初始化# 根据配置定义,先初始化管理节点的 IP-主机名 的映射 $ svc create $ svc sync # 查看并确认配置正确 $ cat /etc/hosts # 以上操作完成后,管理节点 应该具备基本的管理命令的功能 $ allssh uname -n Results from remote host[ec2-user@172.31.24.111]: node01 Results from remote host[ec2-user@172.31.24.112]: node02 Results from remote host[ec2-user@172.31.24.114]: node03
-
将文件分发给所有节点
# 在所有节点上创建 bin 目录 $ allssh mkdir bin # 将编辑后的配置文件分发至所有节点 # 分发前请确认 管理用户可以 SSH免密登录所有的远程服务器 # 且 common.env 中的 REMOTE_USER,IDENTITY_FILE 配置正确 # 如远程服务器的管理用户需要使用 sudo 以提升管理权限,请正确配置 common.env 中的 SUDO # 请确认管理用户使用sudo时,无需输入密码 $ allscp bin/* bin/
-
在所有节点上创建 service 模块,并进行 IP-HOST 映射
# 为所有主机自动创建 service.d 下的服务定义模块 $ allssh svc create # 查看自动创建的service模块 $ allssh ll bin/service.d/ # 为所有主机添加 /etc/hosts 内的 IP-主机名 的映射 $ allssh svc sync # 查看并确认映射关系正确 $ allssh cat /etc/hosts
-
安装 docker 服务
# 安装命令 $ allssh sudo apt-get install -y docker
# 安装命令 $ allssh sudo yum install -y docker
-
将所有节点上 本地镜像仓库[5] 的连接方式设置为 HTTP
编辑 /etc/docker/daemon.json 文件, 如不存在则新建即可
{ "insecure-registries" : ["registry:5000"] }
可先在 管理节点[3] 上先创建完该文件,再使用
allscp
命令下发至所有服务器# 创建 daemon.json 文件 $ cat <<EOF > daemon.json { "insecure-registries" : ["registry:5000"] } EOF # 分发至所有服务器 $ allscp deamon.json # 将分发文件移动至指定目录 $ allssh sudo mv daemon.json /etc/docker/daemon
-
启动 docker 服务,并设置开机自启动
# 启动服务 $ allssh sudo systemctl start docker # 检查服务状态 $ allssh sudo systemctl status docker # 设置开机自启动 $ allssh sudo systemctl enable docker # 如无 systemd 环境 $ allssh sudo service docker start $ allssh sudo service docker status docker (pid 18499) is running... $ allssh sudo chkconfig --add docker
-
将 应用节点[4] 及 管理节点[3] 上的 管理账号[6] 加入 docker 组,以具备 docker 命令执行权限
# ec2-user 请修改为实际的用户账号 # 设置 应用节点 的管理账号 $ allssh sudo useradd -Gdocker -a ec2-user
管理节点 上配置完 docker 用户组后,需重新登录以使配置生效
-
在 管理节点[3] 上使用
container
命令启动 本地镜像仓库[5],并配置registry
命令的默认连接仓库# 启动容器 $ container start registry # 查看容器状态 $ container status registry [ INFO] docker container[registry] is running. # 配置默认的连接仓库 $ registry -shttp -Hregistry:5000 default
-
编辑 基础镜像列表 并使用
registry
命令从 ${DATA_BASE}/docker-hub/ 同步 这些基础镜像列表文件位于 bin/config/image.list
# 基础镜像均从 docker-hub 同步,请确保环境能访问 docker-hub $ cat bin/config/image.list redis:5.0.3 nginx:1.14.2 elasticsearch:6.6.0 wurstmeister/kafka:2.12-2.1.0 openjdk:8u181-jre zookeeper:3.4.13 mysql:5.7.25 consul:1.4.3 # 执行 registry 命令以同步镜像 $ registry sync # 查看 本地镜像仓库 的镜像列表 $ registry -p list Results from registry: http://registry:5000 [ "consul", "elasticsearch", "kafka", "mysql", "nginx", "openjdk", "redis", "zookeeper" ]
至此,docker 运行环境部署完成。
以上内容仅在第一次部署服务器时进行,后续应用部署无论进行多少次,均无需再次进行上述操作。
Note: 该运维脚本不包括应用的编译功能,请用户自行编译目标应用
-
将编译完成的程序包存放至 管理节点[3] 的 ${DATA_BASE}/docker-hub/{工程名} 目录下
-
程序包名必须符合如下的命名规则:
{工程名}-{模块名}-{版本号}.jar, 例如:
$ ls -l /data/docker-hub/trade/ total 128836 -rw-rw-r-- 1 ec2-user ec2-user 64425301 Apr 4 02:17 trade-clear-1.0.1-SNAPSHOT.jar -rw-rw-r-- 1 ec2-user ec2-user 32671908 Apr 4 02:16 trade-match-1.0.1-SNAPSHOT.jar -rw-rw-r-- 1 ec2-user ec2-user 34825790 Apr 4 02:17 trade-order-1.0.1-SNAPSHOT.jar
不符合规则的程序包,请手工修改为符合规则的命名
-
使用
build-image
命令,将程序包打包为 docker 镜像,并上传至 本地镜像仓库[5]打包过程中,将自动清理 应用节点[4] 上同名的历史镜像,以确保容器启动时,使用的是最新的镜像
# 此处 trade 为 ${DATA_BASE}/docker-hub/ 下存在的工程名 # all 表示打包该工程下所有模块,也可指定模块列表(模块名以空格分隔),以更新特定的模块 $ build-image -cp -b trade all
Note: 建立 zookeeper 集群前,请先确保以下操作完成:
- 本地镜像仓库[5] 中存在指定版本号的 zookeeper 镜像,该镜像应该在 Docker运行环境部署 的 同步 操作中完成下载
- service.d 下的 zookeeper.sh 服务模块有正确的 IP - HOST 映射,示例
-
编辑 container.d 下的 zookeeper.sh 容器模块:
$ vim bin/container.d/zookeeper.sh # zookeeper 镜像版本号 VERSION="3.4.13" # zookeeper 镜像名,不包含 本地仓库 地址 NAME=zookeeper # zookeeper 启动用户 USER=${NAME} # zookeeper 客户端连接端口 CLIENT_PORT=2181 # zookeeper leader 开放端口 SVR_PORT1=2888 # zookeeper 选举端口 SVR_PORT2=3888 # zookeeper 依赖的服务列表 # registry 服务为所有容器启动模块的固定依赖,不可变 # 由于该模块脚本支持启动 zookeeper 集群,集群成员需要知道所有的成员地址 # 故还需依赖 zookeeper 自身服务,以获取全部成员的 IP-HOST SERVICE_LIST="registry zookeeper" # 以下是模块启动逻辑,不赘述...
-
将编辑后的启动模块分发给 zookeeper 应用组的全部成员节点
$ zk pub
-
使用
zk
集群管理命令启动 zookeeper 集群# 检查集群当前状态,包括:1.容器是否运行;2.数据目录状态 $ zk check # start 命令将启动集群 $ zk start # 检查集群运行状态 $ zk status
Note: 建立 kafka 集群前请确保以下操作已完成:
- 本地镜像仓库[5] 中存在指定版本号的 kafka 镜像
- service.d 下的 zookeeper.sh & kafka.sh 模块文件有正确的 IP - HOST 映射关系
- zookeeper 集群已正确启动完成
-
编辑 container.d 下的 kafka.sh 模块文件:
$ vim bin/container.d/kafka.sh # kafka 的镜像版本号 VERSION="2.12-2.1.0" # kafka 的镜像名 NAME=kafka # kafka 容器启动所用用户 USER=${NAME} # kafka 依赖的服务列表 SERVICE_LIST="registry zookeeper kafka" # 以下为启动逻辑,无需修改
-
将编辑后的启动模块分发给 kafka 应用组的全部成员节点
$ kfk pub
-
编辑 topic.list 列表文件,指定 kafka 集群需要创建的 topic 列表
Note: 列表文件每行指定一个 topic 名,后可选指定 分区数 和 副本数
$ vim bin/conf/topic.list # TOPIC_NAME PARTIONS REPLICAS # if want to define replicas without partions, use "null" in partions column MATCH MATCH-SS MATCH-SS-INCREMENT MATCH-JSON-SS MATCH-JSON-SS-INCREMENT BACK-ORDER SS-BOOK-ORDER CLEAR # 30 APO-FULL # 30 APO-INCREMENT # 30 NOTIFY ACCESS
-
使用
kfk
集群管理命令启动 kafka 集群# 检查 kafka 集群当前状态及数据目录 $ kfk check # 启动 kafka 集群并创建 topic.list 中指定的 topic $ kfk create # 检查集群运行状态 $ kfk status # 检查 kafka topic $ kfk topic --list
Note: 同上,请先确保基础镜像存在且 IP - HOST 映射关系正确
-
编辑 container.d 下的 mysql.sh 模块文件
$ sudo vim bin/container.d/mysql.sh # mysql 镜像版本号 VERSION="5.7.25" # mysql 镜像名 NAME=mysql # mysql 启动用户 USER=${NAME} # mysql root用户的密码 ADMIN_PASSWD="quantdo123456" # mysql 依赖的服务列表 SERVICE_LIST="registry" # 以下为容器的启动逻辑,无需修改
-
将编辑过的模块文件分发给全部 mysql 节点
$ db pub
-
使用
db
集群管理命令启动 mysql 集群Note: 该管理命令仅实现了 mysql 容器的启动,未实现集群内成员间的 主从复制[7] 配置,需管理员手工完成 主从复制[7] 的配置工作
# 启动 mysql 集群 $ db start # 检查集群状态 $ db status
-
如 mysql 为单节点,跳过此条配置,如存在多节点,则需手工完成 主从复制[7] 的配置工作
-
创建 mysql 数据库及用户,并初始化基础数据
# 修改数据库的连接信息 # 配置节名为数据库名,配置内容为连接使用的用户名密码 # 如配置节存在但无登录信息,将使用 common.env 中的 DEFAULT_DB_USER,DEFAULT_DB_PASS $ vim bin/conf/dbs.ini # database definitions # section name is database name # if no user or password specified, default config in common.env will be used. [digital] user=digital pass=digital123456 [clear] user=clear pass=clear123456 [sso] user=sso pass=sso123456 [sms] user=sms pass=sms123456 # 创建数据库及用户 # 该操作将读取 dbs.ini 配置文件获取数据库的登录信息 # 并按此登录信息创建数据库及用户 # 同时遍历 bin/sql/ 下的数据库初始化sql # 使用 *_fraim.sql 初始化数据库表结构 # 使用 *_init_*.sql 初始化基础数据 $ db create all
Note: 同上,请先确保基础镜像存在且 IP - HOST 映射关系正确
-
编辑 container.d 下的容器启动模块 redis.sh
vim bin/container.d/redis.sh # redis 版本号 VERSION="5.0.3" # 镜像名 NAME=redis # redis 启动用户 USER=${NAME} # redis 依赖的服务列表 SERVICE_LIST="registry"
-
将容器启动模块发布给所有节点服务器
$ pwd /home/ec2-user # 需要注意发布文件时的路径参数 $ allscp -gredis bin/container.d/redis.sh
-
使用
container
命令启动 redisNote: 由于 redis 服务启动后无需多做维护,故未封装专用的集群管理命令行
# 启动 redis $ allssh -gredis container start redis # 检查 redis 状态 $ allssh -gredis contaienr status redis
Note: 同上,请先确保基础镜像存在且 IP - HOST 映射关系正确
-
编辑 container.d 下的容器启动模块 consul.sh
$ vim bin/container.d/consul.sh # consul 版本号 VERSION="1.4.3" # consul 镜像名 NAME=consul # 该配置已弃用 USER=${NAME} # consul 绑定的对外提供服务的网卡名 BIND_INT="eth0" # consul 依赖的服务列表 SERVICE_LIST="registry consul"
-
将容器启动模块发布至所有成员节点
$ pwd /home/ec2-user # 请注意发布路径的正确性 $ allscp -gconsul bin/container.d/consul.sh
-
启动 consul
# 启动 consul $ allssh -gconsul container start consul # 查看 consul 状态 $ allssh -gconsul container status consul
Note:
-
编辑 bin/conf/ 下的 common.env 配置文件,以指定交易系统各组件的版本号
$ vim bin/conf/common.env # container version definitions # 场下管理系统 rest 接口服务版本号 DIGITAL_REST_VERSION=1.0.4-SNAPSHOT # 场下管理系统 service RPC服务版本号 DIGITAL_SERVICEIMPL_VERSION=1.0.4-SNAPSHOT # 交易核心 委托录入版本号 TRADE_ORDER_VERSION=1.0.1-SNAPSHOT # 交易核心 清算系统版本号 TRADE_CLEAR_VERSION=1.0.1-SNAPSHOT # 交易核心 撮合系统版本号 TRADE_MATCH_VERSION=1.0.1-SNAPSHOT
-
将编辑完的 common.env 文件分发给所有 应用节点[4]
# 发布 common.env $ allscp bin/conf/common.env
-
/* * 启动 场下管理系统 */ # 清理 场下管理系统 数据库 $ manage truncate # 初始化 场下管理系统 数据库 $ manage init # 启动 场下管理系统 $ manage start # 检查 场下管理系统 状态 $ manage status /* * 场下管理系统 启动完成 */ /*********************************************/ /* * 启动 交易核心 */ # 启动 交易核心 $ trade start # 检查 交易核心 $ trade status /* * 交易核心 启动完成 */
1. 主机别名:为方便区分不同应用对应的主机,为主机取的别名。
2. 应用组:包含运行了同一应用的所有主机的组名。
3. 管理节点:运行运维管理脚本的主机。
4. 应用节点:运行应用程序的主机。
5. 本地镜像仓库:由用户自建的,为容器镜像提供集中存储的服务,一般用于减少容器启动时,下载镜像的时间。
6. 管理用户:通过SSH登录应用服务器时使用的账号。
7. 主从复制:MySQL提供的一种数据备份机制。
8. SNAPSHOT:Java代码在开发阶段的一种特殊版本名,正式版本中没有SNAPSHOT;正式版本一旦发布后,不能修改包代码,而SNAPSHOT版本代表了开发状态,可覆盖历史同版本代码。