2、一粒云二次封装与迁移 – 二次打包

目录 运维

为了使后续的安装包可以兼容各类x86的Linux系统,选择用源码编译的方式进行安装部署。同时为了减轻工作量,将所需依赖分为2种,一种是可以直接在系统安装CD上使用包管理器安装的基础依赖,这部分依赖无论是使用网络包管理还是CD离线源都可以轻松安装上,并且不需要判断什么路径配置文件。另一种则是CD包管理不自带安装负责需要配置文件的依赖,例如mysql,redis等这部分依赖将采用源码编译的方式安装部署。

一 、整理数据包文件

经过从原系统的配置文件的收集整理,以下为所需的资源包。

MacBook-Pro package % tree -L 2
.
├── bin                   //启动脚本
│   ├── fdfs              //文件系统
│   ├── fdfs_storaged     //文件系统存储
│   ├── fdfs_trackerd     //文件系统管理
│   ├── nginx             //openresty
│   ├── nodejs            //web主进程
│   ├── redis             //缓存数据库
│   └── yliyun            //网盘主启动进程
├── common
│   ├── bin
│   └── lib
├── conf                  //配置文件
│   ├── fdfs              //文件系统配置文件
│   ├── mysql             //数据库配置文件
│   └── redis             //缓存数据库配置文件
├── fastdfs               //文件服务源码包
├── libfastcommon         //文件服务依赖
├── mysql                 //数据库源码包 
├── nodejs                //Web服务 Nodejs二进制包
├── openresty             //Web服务 Openresty源码包
├── openssl               //Openresty依赖
├── pcre                  //Openresty依赖
├── perl                  //数据库依赖
├── plugins
│   ├── freetype
│   ├── ghostscript
│   ├── imagemagick
│   ├── libjpeg
│   ├── libpng
│   ├── libreoffice
│   ├── qcad
│   └── uniconvertor
├── redis                 //缓存数据库
├── tcl                   //缓存数据库依赖
├── work                  //网盘代码
│   ├── lua
│   ├── nginx
│   └── node
├── yliyun.lic            //授权
├── yliyun.sql            //数据库结构
├── yliyun_log.sql        //数据库结构
└── zlib                  //Openresty依赖

openresty所需模块源码

MacBook-Pro openresty % tree -L 1
.
├── COPYRIGHT
├── README-win32.txt
├── README.markdown
├── bundle
├── configure
├── fastdfs-nginx-module       //文件系统模块(https://github.com/happyfish100/fastdfs-nginx-module)
├── nginx-upload-module-2.2    //下载模块(https://github.com/fdintino/nginx-upload-module)
├── patches
└── util

源码包中的mysql,fastdfs,nodejs,openresty,redis需要和原有网盘系统相符。因为这些软件在进行更新时,会对部分不完善的接口进行删除或者变更,版本有差距可能会产生bug。

二、新目录结构分配

原系统文件都存放在/opt目录下的yliyun文件中,经过第一步的分析和整理,规划一个新的目录结构来运行系统。首先将目录从/opt移动到了/usr/local目录下,所有的支持程序都将安装到此目录,例如mysql,nodejs,openresty,redis等,除了这些以外,还增加了一个yliyun目录,用来存放启动脚本,各类支持库,数据,日志,代码,缓存,授权,配置文件等数据。

/usr/local
├── mysql                 //运行数据库
│   ├── bin               //数据导入,恢复,Cli操作数据库
│   ├── data              //yliyun数据存放目录
│   ├── docs
│   ├── include
│   ├── lib
│   ├── man
│   ├── mysql-test
│   ├── scripts
│   ├── share
│   ├── sql-bench
│   └── support-files     //mysql.server,用于启动mysql
├── nodejs                //nodejs提供主要服务,包括鉴权,登录验证,UI等
│   ├── bin
│   ├── include
│   ├── lib
│   └── share
├── openresty             //主要访问入口,根据不同的访问链接匹配不同的策略
│   ├── bin
│   ├── luajit
│   ├── lualib
│   ├── nginx
│   ├── pod
│   └── site
├── redis                 //yliyun缓存数据库
│   ├── bin
│   ├── deps
│   ├── src
│   ├── tests
│   └── utils
└── yliyun                //此安装方式的特有目录
    ├── bin               //各运行环境启动脚本,或集体启动脚本
    ├── common            //支持库
    ├── conf              //各运行库集中配置点,通过软链接给各运行库提供conf
    ├── dailytemp
    ├── data              //除了mysql外其余的运行环境的数据存储,fdfs日志也在该目录下
    ├── logs              //除了fdfs分布式文件存储系统外,其余运行环境的集中日志存储
    ├── plugins           //支持库
    ├── temp              //上传文件时的临时文件存放点
    ├── work              //工作目录
    └── yliyun.lic        //授权

三、配置文件和系统代码适配

一些配置文件中可能会有类似核心优化,绝对路径之类的参数,云盘代码中也有可能会有绝对路径的存在,这些都会影响迁移后系统的正常运行。好在我们可以使用shell脚本在数兆的配置和代码文件中进行快速搜索过滤替换。

#!/bin/bash

find -name $1 | while read line
do
       number=`cat $line | grep "$2" | wc -l`;
       if [ $number -ne 0 ];then
              echo $line
       fi
done

将脚本放到需要搜索的confwork目录下,执行./xxx.sh [目标文件] [关键词] 来进行查找

MacBook-Pro work % ./find.sh "*.js" "/opt"
./node/config/app(1).js
./node/update.js
./node/node_modules/xdg-basedir/index.js
....

例如查询*.js文件中是否涉及到原先系统的绝对地址/opt,反馈中app(1).js和update.js等这些js文件涉及到了绝对路径。

这些文件在进行二次封装时就需要修改这些路径为新的路径(直接使用sed命令或者在vim中全局替换即可)。

为了清楚的知道修改了什么,哪里需要修改,需要将修改分块,分而治之。

1、Mysql配置

mysql一般配置文件都存放在my.cnf文件中,里面可以设置的参数非常多,但我们以实际为准,经过查看以下的配置需要进行变更。

[mysql]
...
socket                         = /usr/local/mysql/mysql.sock
...
[mysqld]
...
socket                         = /usr/local/mysql/mysql.sock
pid-file                       = /usr/local/mysql/mysql.pid
...
datadir                        = /usr/local/yliyun/data/mysql
log-bin                        = /usr/local/yliyun/logs/mysql
log-error                      = /usr/local/yliyun/logs/mysql/mysql-error.log
slow-query-log-file            = /usr/local/yliyun/log/mysql/mysql-slow.log
...

以上是根据(二、新目录结构分配)变更完毕的,其余不涉及IP地址之类的变更,非常简单。

2、Redis配置

redis配置文件是一个名为redis.conf的文件,只涉及到一个数据目录的指定。

...
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /usr/local/yliyun/data/redis
...

3、Fastdfs配置

Fastdfs的配置文件比较多,涉及到的有client.conf,http.conf,mod_fastdfs.conf,storage.conf,storage_ids.conf,tracker.conf

client.conf

此配置文件涉及到的文件系统客户端日志路径和tracker_server地址与端口号。后续把所有的IP地址都更改为AAAAAAAAAA,为了使安装更自动化,安装完成后只需要将AAAAAAAAAA替换为新IP地址即可。

...
# the base path to store log files
base_path=/usr/local/yliyun/data/fdfs/client

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=AAAAAAAAAA:22122

#standard log level as syslog, case insensitive, value list:
...
http.conf

无涉及

mod_fastdfs.conf

此配置文件是用来给fastdfs的Nginx模块使用的,其中涉及日志路径,tracker_server地址,还有store_path_count和对应的路径地址。store_path_count数量必须和后面的store_path数量对应,否则文件系统无法运行,store_path对应的路径也必须真实存在,否则无法正常运行。直接指定4个默认地址,在安装时自动创建即可。

...
# the base path to store log files
base_path=/usr/local/yliyun/logs/nginx
...
# FastDFS tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
# valid only when load_fdfs_parameters_from_tracker is true
tracker_server=AAAAAAAAAA:22122
...
# path(disk or mount point) count, default value is 1
# must same as storage.conf
store_path_count=4
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
# must same as storage.conf
store_path0=/yliyun_data_01
store_path1=/yliyun_data_02
store_path2=/yliyun_data_03
store_path3=/yliyun_data_04
#store_path1=/home/yuqing/fastdfs1
...
storage.conf

出现了一个比较特殊的参数work_threads,这个参数对应工作核心数,直接用BBBBBBBBBB作为参数,安装时获取cpu内核数后进行替换。其余的参数与mod_fastdfs.conf相同。

...
# the base path to store data and log files
base_path=/usr/local/yliyun/data/fdfs/storage
...
# work thread count, should <= max_connections
# work thread deal network io
# default value is 4
# since V2.00
work_threads=BBBBBBBBBB
...
# path(disk or mount point) count, default value is 1
store_path_count=4
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
store_path0=/yliyun_data_01
store_path1=/yliyun_data_02
store_path2=/yliyun_data_03
store_path3=/yliyun_data_04
...
# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=AAAAAAAAAA:22122
...
storage_ids.conf

无涉及

tracker.conf

日志路径与工作核心数。

...
# the base path to store data and log files
base_path=/usr/local/yliyun/data/fdfs/tracker
...
# work thread count, should <= max_connections
# default value is 4
# since V2.00
work_threads=BBBBBBBBBB
...

4、Openresty配置

Openresty的配置文件位置比较特殊,它是存放在work代码文件下作为lua代码的一部分。所以需要到该目录下进行配置。配置文件位置在work/lua/nginx目录下的nginx.conf

MacBook-Pro nginx % pwd && ls -lh
/xxx/xxx/package/work/lua/nginx
total 24
-rw-r--r--  1 wxx  staff    10K  7  7 23:44 nginx.conf

需要注意的是worker_processes这个参数,这个参数意思是启用几个worker进程,推荐与CPU核心数相同。不过为了自动化优化,改成BBBBBBBBBB

user  root;
worker_processes  BBBBBBBBBB;

error_log  /usr/local/yliyun/logs/nginx/error.log;
error_log  /usr/local/yliyun/logs/nginx/error.log  notice;
#error_log  logs/error.log  info;

pid        /usr/local/yliyun/logs/nginx/nginx.pid;

worker_rlimit_nofile    65535;

events {
    use       epoll;
    worker_connections    102400;
}
.....
...

另外这个文件涉及大量绝对路径需要进行修改。例如上传缓存路径,日志,luajit脚本路径等。

#各类日志
error_log  /usr/local/yliyun/logs/nginx/error.log;
error_log  /usr/local/yliyun/logs/nginx/error.log  notice;
access_log  /usr/local/yliyun/logs/nginx/access.log  main;

#pid路径,可能会涉及启动和关闭命令
pid        /usr/local/yliyun/logs/nginx/nginx.pid;

#lua包路径
lua_package_path '/usr/local/yliyun/work/lua/?.lua;/usr/local/openresty/lualib/resty/?.lua;;';

#lua文件路径
init_by_lua_file '/usr/local/yliyun/work/lua/common/init.lua';

#上传文件临时路径
upload_store /usr/local/yliyun/temp;

#网页静态文件路径
root /xxx/yliyun/work/nginx/;

#其它涉及下载权限判定之类的lua文件,都使用了绝对路径
location ~ ^/group1/M[0-9][0-9]/(.*)$ {
    access_by_lua_file /usr/local/yliyun/work/lua/download/anti_steal_check.lua;
    proxy_buffering off;
    limit_rate_after 50m;
    limit_rate 500k;
    ngx_fastdfs_module;
}
......

5、Nodejs配置

Nodejs在这个系统的占比比较高,但是主要是PM2的配置内容,其本身并不复杂。主要是PID,日志等路径的指定。

MacBook-Pro node % vim pm2.json 

    "instance_id_env": "NODE_APP_INSTANCE",
    "max_memory_restart": "256M",
    "pid_file": "/usr/local/yliyun/logs/node/socket.pid",
    "error_file": "/usr/local/yliyun/logs/node/socket-err.log",
    "out_file": "/usr/local/yliyun/logs/node/socket.log",
    "log_date_format": "YYYY-MM-DD HH:mm:ss"
  },
  {
    "name": "conv",
    "script": "/usr/local/yliyun/work/node/conv.js",
    "cwd": "/usr/local/yliyun/work/node",
    "instances": 1,
    "instance_id_env": "NODE_APP_INSTANCE",
    "max_memory_restart": "256M",
    "pid_file": "/usr/local/yliyun/logs/node/conv.pid",
    "error_file": "/usr/local/yliyun/logs/node/conv-err.log",
    "out_file": "/usr/local/yliyun/logs/node/conv.log",
    "log_date_format": "YYYY-MM-DD HH:mm:ss"
  },
  {
    "name": "update",
    "script": "/usr/local/yliyun/work/node/update.js",
    "cwd": "/usr/local/yliyun/work/node",
    "instances": 1,
    "instance_id_env": "NODE_APP_INSTANCE",
    "max_memory_restart": "256M",
    "pid_file": "/usr/local/yliyun/logs/node/update.pid",
    "error_file": "/usr/local/yliyun/logs/node/update-err.log",
    "out_file": "/usr/local/yliyun/logs/node/update.log",
    "log_date_format": "YYYY-MM-DD HH:mm:ss"
  }
]

5、启动代码配置

我将启动代码设计为,各个应用单独控制启动重启另设一个总控制来进行全部应用的同时启动和重启。

设计启动的应用分别为

fcy@MacBook-Pro bin % ls
fdfs		fdfs_trackerd	nodejs		yliyun
fdfs_storaged	nginx		redis

fdfs_storaged控制fdfs存储进程,fdfs_trackerd控制fdfs管理进程,fdfs同时控制存储和管理。其余管理对应名称的进程,另外yliyun管理全部进程。除yliyun外其余进程只需要在原有的启动脚本上重新指定新的路径即可。

#!/bin/sh

YLIYUN_HOME=/usr/local/yliyun

case "$1" in
    start)
        $YLIYUN_HOME/bin/mysqld start
        $YLIYUN_HOME/bin/redis start
        $YLIYUN_HOME/bin/fdfs_trackerd start
        $YLIYUN_HOME/bin/fdfs_storaged start
        $YLIYUN_HOME/bin/nginx start
        $YLIYUN_HOME/bin/node start
        ;;
    stop)
        $YLIYUN_HOME/bin/nginx stop
        $YLIYUN_HOME/bin/node stop
        $YLIYUN_HOME/bin/mysqld stop
        $YLIYUN_HOME/bin/redis stop
        $YLIYUN_HOME/bin/fdfs_trackerd stop
        $YLIYUN_HOME/bin/fdfs_storaged stop
        ;;
    *)
        echo "Please use start or stop as first agrument"
        ;;
esac

6、封包

将所有所需的脚本,源码配置文件,放到一个package目录中。

MacBook-Pro package % ls
bin		fastdfs		mysql		openssl		plugins		work		yliyun_log.sql
common		find.sh		nodejs		pcre		redis		yliyun.lic	zlib
conf		libfastcommon	openresty	perl		tcl		yliyun.sqls

使用tar命令打包为package.tar.gz压缩文件。