Skip to content
This repository has been archived by the owner on Jun 7, 2023. It is now read-only.

Latest commit

 

History

History
192 lines (146 loc) · 14.6 KB

static-server-reference.md

File metadata and controls

192 lines (146 loc) · 14.6 KB

静态服务端Reference

静态服务端是由一些脚本文件和一些可执行文件缝合而成的一个整合包(你没看错),这样的模块化设计对扩展和定制方面特别友好。静态服务端的核心文件是一个叫incremental-upload.exe的文件。这是一个工具软件,可以将本地有修改的文件增量地上传到各个地方(对象存储或是FTP),未修改的文件不会上传,可以节省带宽和时间。具体的上传过程会由incremental-upload.exe调用具体命令行来完成。这个命令行可以自由配置,也就是说只要写好了调用命令行,那么incremental-upload.exe可以将文件上传到任何地方!包括私有的服务器。

静态服务端目前仅提供了Windows x64平台的整合,如果你需要在Linux平台下使用,请过来催更一下。

incremental-upload工具

incremental-upload工具是一个开源命令行工具程序,用rust语言编写,拥有较高的执行性能和较少的内存BUG(源代码也会随可执行文件一起附赠)。同时也是静态整合包里面最核心的一个工具,负责计算文件差异,然后将新文件上传到远端,然后将旧文件删除掉。

加载不同的配置文件之后,可以实现不同服务商/协议的上传效果,目前自带了4个服务商/协议支持:

  • 阿里云对象存储
  • 腾讯云对象存储
  • 七牛云对象存储
  • FTP协议(适用于网站主机)

如果你需要增加一个新的协议或者是服务商的支持,请阅读添加服务商支持(自由化部署)章节

工作流程

incremental-upload工具的工作流程如下,先读取远端的文件结构(当然不会真的去索引远端文件,而是从一个存在于本地的状态文件(通常是tools/remote-structure.json)里读取,incremental-upload会维护这个文件的内容使其与远端一致)。在知道了远端目录的结构之后,就会与本地的目录进行对比,计算出文件差异。文件差异分4个部分:

  • 旧文件:本地不存在但远端存在的文件。需要将远端的这个文件删除,以和本地保持同步
  • 旧目录:本地不存在但远端存在的目录。需要将远端的这个目录删除,以和本地保持同步
  • 新文件:本地存在但远端不存在的文件。需要将这个文件上传到远端,以和本地保持同步
  • 新目录:本地存在但远端不存在的目录。需要在远端新建这个空目录,以和本地保持同步

这4个部分会按上面的顺序依次执行,已确保先删除目录下的文件,再删除父目录,然后先创建文件夹,再上传文件。此为,每个部分都会调用一个具体的外部命令行,若干次,去执行实际的操作。至于若干次是多少次,那就要看旧文件或者旧目录部分下有多少个新文件/旧文件了。100个新文件会调用100次上传文件的命令行。1000个旧文件会调用1000此删除文件的命令行,以此类推。

所有外部命令行调用完成之后,incremental-upload工具就会再次遍历这些文件差异,以对状态文件(也叫远端目录结构文件)进行更新(这些操作都是在程序内部的内存里完成的,此时就不会调用外部命令行了)。此时状态文件就又能和远端结构保持同步了。然后程序就执行完毕了。

其实这里面有个问题:一旦使用incremental-upload工具进行第一次上传之后,就再也不能对远端文件进行手动管理了,不然会造成状态文件里的远端文件结构和实际对不上,在执行命令行时出现文件找不到的问题,或者目录不存在的问题。如果不小心破坏这个一致性,那么就需要删除本地的tools/remote-structure.json文件和清空对应的远端目录再进行上传,以重建状态文件。

配置文件

基本功能配置

# 源目录路径(支持使用自定义变量)
# 源目录就是要上传的文件都存放所在的那个目录,通常是updater目录,这里从变量里进行读取
source-dir: $source

# 状态文件路径(支持使用自定义变量)
# 状态文件就是存储远端目录结构的文件,有了这个文件,程序就不用去实际索引远端文件了,而是直接从这个文件里进行读取,这里从变量里进行读取
state-file: $state

# 是否开启覆盖模式,开启后需要先删除后上传的文件会跳过删除步骤,仅进行上传
# 覆盖模式就是,如果文件被修改了,通常的做法是先将远端的这个文件删除,然后再上传这个文件。
# 开启覆盖模式之后,就不会删除了,而是直接走上传流程。如果你的服务商/协议不支持覆盖这种操作,请关闭这个选项
overlay-mode: true

# 是否开启快速对比模式,开启后优先对比文件修改时间,然后才是文件hash
# 开启后在计算本地文件差异时,会先看文件的修改时间,如果与远端一致,就不再检测hash。如果不一致则再检查hash判断文件是否相同
# 开启后可以极大加快检查文件差异的过程,节省不必要的IO操作,通常推荐开启
fast-comparison: true

# 是否使用本地状态文件,若与use-remote-state同时开启,则download-state不会被执行
# 用于存储远端目录结构的状态文件,是否保存到本地。推荐保存到本地,这样读取起来比较快,如果需要同时也保存到远端一份,可以开启use-remote-state。
use-local-state: true

# 是否使用远程状态文件,若与use-local-state同时开启,则download-state不会被执行
# 用于存储远端目录结构的状态文件,是否保存到远端。开启后每次更新状态文件之后,都会调用专门的命令行将状态文件上传到远端一份。
# 此选项通常是不开启的,因为每次上传消耗额外的时间和流量,除非你特别特别担心位于本地的状态文件丢失后会打破状态文件与远端实际文件结构的一致性。此时可以考虑开启此选项
use-remote-state: false

# 状态文件缩进数量
# 状态文件是以Json格式保存的,此选项用来调整Json文本的缩进数量,设置为0可以缩减文件大小,节省流量。
# 设置为2或者4会增大状态文件大小,但文件内容的可读性会提升。生产环境建议设置为0
state-indent: 0

# 命令执行时使用的并发数,有效指令:delete-file, upload-file
threads: 1

# commands节点下所有的命令执行时的工作目录,默认继承自父进程
# 此选项用来配置在执行commands节点下的目录时,子进程的工作目录,如果留空则会继承父进程的工作目录
command-workdir: tools/tencent

# 文件过滤器,使用正则表达式语法,匹配的文件才会被执行到delete-file, delete-dir, upload-file, making-dir命令中
# 若有多个过滤器,文件路径需要全部匹配才会执行delete-file, delete-dir, upload-file, making-dir命令
# 如果过滤器以!开头,则过滤器的匹配条件会被翻转。未匹配时返回true,匹配时返回false
# 文件过滤器可以过滤掉一些Logs文件或者Cache文件,这些文件不会被上传到远端,可以节省流量。如果过滤器为空,则任何文件都会被上传到远端
# 使用小提示:此选项配置好之后,可以直接打开命令行终端,在incremental-upload.exe的后面传入--test-filter参数
# 此时incremental-upload会进入过滤器测试模式,会列出所有匹配的文件路径,匹配的文件都会上传。此方法可以用于快速调试file-filters选项
file-filters: []

自定义变量配置。这里的变量仅仅是会进行简单文本替换的变量,并不是指环境变量,也不会从环境变量进行继承。

# 自定义变量定义,变量之间可以互相嵌套使用。注意不要出现环形嵌套,程序会陷入死循环的
variables:
  source: updater
  state: tools/remote-structure.json
  cli: coscli-windows.exe -c tencent.cos.yaml
  bucket: 'cos://my-default-bucket'

文件操作命令用于执行实际的远端文件管理操作:上传文件、删除文件、新建目录、删除目录等。

所有捕获的子进程(命令行)输出都是使用utf-8进行解码的,如果你的程序不是使用utf-8,则输出的文字可能是乱码(乱码不会影响程序正常运行,仅会影响人类阅读)。

子命令可以写成列表的形式来指定多个命令顺序执行,如果其中有一个命令的返回值不是0,则整个程序中断运行,并打印相关的报错信息。可以利用整个机制在start-up里检查一些python环境或者是java环境有没有安装,如果没有安装则不会执行后面的代码

# 文件操作命令
# 所有命令可用的全局变量:
#   $source:源目录的绝对路径(路径分隔符为正斜线/)
#   $workdir:工作目录的绝对路径(路径分隔符为正斜线/)
#   $source_:源目录的绝对路径(路径分隔符为反斜线\)
#   $workdir_:工作目录的绝对路径(路径分隔符为反斜线\)
#   $last-stdout:同一个子指令下面,前一个命令执行结果所捕获的标准输出流内容,首个指令无此变量
#   $last-stderr:同一个子指令下面,前一个命令执行结果所捕获的标准错误流内容,首个指令无此变量
# 每个子指令都可以写成列表的形式来执行多个步骤,比如
# start-up:
#   - echo step one now
#   - echo step two now
# 如果子命令写成上面那样的单行单行的列表,每一行的字符串都会被按空格拆分成程序名+应用程序参数的形式
# 如果写成子列表的形式,则直接使用你指定的拆分顺序,而不是由程序自动按空格拆分(多数情况下你并不需要用到该功能)
# 也可以将子命令写成列表和单行混用的形式。如果你的命令行就是单行,且不希望被自动拆分,可以在字符串最前面加一个+来避免
# start-up: # 演示混合风格
#   - echo step one now # 使用自动命令行拆分(按空格):[echo, step, one, now],其中echo是程序名,step和one是参数
#   - - echo # 使用手动命令行拆分:[echo, step one, now],其中echo是程序名,step one是参数1。now是参数2
#     - step two
#     - now
#   - +echo step three now # 禁用自动命令行拆分:[echo step three now],其中echo step three now是一个完整的文件名,后面无任何参数
commands:
  # 传输初始化命令,在有文件差异存在时,此命令最先被执行。若无文件差异,则不会被执行
  start-up: 

  # 传输清理命令,在有文件差异存在时,此命令最后被执行。若无文件差异,则不会被执行
  clean-up: 

  # 将远程状态文件下载到本地的命令,仅当开启use-remote-state且use-local-state未被开启时会被执行
  download-state: $cli cp "$bucket/$state" "$state"

  # 将本地状态文件上传到远程的命令,仅当开启use-remote-state时会被执行
  upload-state: $cli cp "$state" "$bucket/$state"

  # 删除远程文件的命令
  # 可用局部变量:$path:文件的相对路径、$path_:路径分隔符为反斜线版本的$path
  delete-file: $cli rm "$bucket/$path" --force

  # 删除远程目录的命令
  # 可用局部变量:$path:文件的相对路径、$path_:路径分隔符为反斜线版本的$path
  delete-dir: 

  # 将本地文件上传到远程的命令
  # 可用局部变量:$path:文件的相对路径、$path_:路径分隔符为反斜线版本的$path
  upload-file: $cli sync "$source/$path" "$bucket/$path"

  # 创建一个远程目录的命令
  # 可用局部变量:$path:文件的相对路径、$path_:路径分隔符为反斜线版本的$path
  making-dir: 

添加服务商支持

要添加新的服务商支持,只需要修改YAML格式的配置文件就好了,完全无需编写代码,这也是incremental-upload最大的优势。

  1. 复制腾讯云对象存储的配置文件作为模板,然后在上面进行修改:复制tools/tencent目录到tools/custom目录(只能叫custom
  2. 进入tools/custom目录,删除除了config.yml以外的其它文件。然后打开config.yml编辑配置文件
  3. 修改commands节点下的子命令,以实现对远端文件的操作
    1. start-up:执行一些初始化工作,一般留空即可
    2. clean-up:执行一些清理工作,一般留空即可
    3. download-state:下载远端的状态文件到本地,如果use-remote-state没有开启,此选项可以留空
    4. upload-state:上传本地的状态文件到远端,如果use-remote-state没有开启,此选项可以留空
    5. delete-file:删除远端文件的命令,可以使用变量$path来替换具体文件相对路径
    6. delete-dir:删除远端目录的目录,可以使用变量$path来替换具体文件相对路径
    7. upload-file:上传一个本地文件到远端,可以使用变量$path来替换具体文件相对路径
    8. making-dir:在远端创建一个空目录,可以使用变量$path来替换具体文件相对路径
  4. 其它选项可以按需修改,完成后保存关闭
  5. 删除tools/service-provider.txt文件
  6. 重新启动run.bat,然后会多出来一个叫custom的选项,输入custom的序号按下回车,此时incremental-upload就会执行你自己的上传逻辑了
  7. 当然,一般切换上传目标之后,建议一并删除tools/remote-structure.json文件,使其重建远端目录结构数据
  8. 如果你需要添加多个服务商的支持,可以在tools目录下除了添加custom目录以外的目录,并修改run.bat文件,在这个脚本照葫芦画瓢,根据前面的代码复制并修改,添加上你自己的服务商名字和选项,再次删除tools/remote-structure.json文件并启动run.bat就可以看到效果了

自由化部署

如果你不喜欢用incremental-upload一键上传。而是偏好生成好状态文件res.json之后自己处理。你可以将incremental-upload切换为仅生成状态文件的模式。

你可以将下面的代码保存到一个bat文件里,可以叫它gen.bat,然后保存关闭。

@echo off
if exist updater\res.json move /Y updater\res.json res.json > nul
tools\incremental-upload-0.0.0-windows-x64.exe --config tools\calculate-res-dot-json.yml
if exist res.json move /Y res.json updater\res.json > nul
pause

双击运行这个文件,就会仅刷新updater\res.json这个状态文件而不会执行任何上传操作了。之后你就可以把updater目录下的文件做自行处理了,无论是上传到私有服务器,还是存储空间都是没问题的。