使用rsync部署Hexo部落格 | Tony's toy blog
Hexo擁有強大的插件系統,在部落格建構的各個環節都有各種各樣的插件來滿足不同的需求,對于部署部落格這個過程來說也不例外。本部落格由于使用了雲伺服器和獨立的域名,不依賴于github,最後使用nginx直接通路生成的html内容,綜合考慮後選擇采用rsync進行部署。
什麼是rsync
rsync是linux系統下的資料鏡像備份工具,可通過LAN/WAN快速同步多台主機間的檔案。rsync使用所謂的“rsync算法”來使本地和遠端兩個主機之間的檔案達到同步,這個算法隻傳送兩個檔案的不同部分,而不是每次都整份傳送,是以速度相當快。
CentOS系統預設安裝了rsync,使用指令rsync --version來檢視版本。此外windows也有相應的移植比如cwRsync和 Cygwin。
rsync的幾種傳輸方式
為了更好地表達指令的格式,一些替代符号的意義如下:
- [options] :附加的指令選項
- [user]:用于操作的使用者名
- [host]:遠端主機位址或主機名
- [src]:源檔案的路徑
- [dest]:目标檔案的路徑
主機本地傳輸
Rsync不僅可以遠端同步資料,還可以本地同步資料(類似于cp),但不同于cp或scp的一點是,rsync不像cp/scp一樣會覆寫以前的資料(如果資料已經存在),它會先判斷已經存在的資料和新資料有什麼不同,隻有不同時才會把不同的部分覆寫掉。
使用的指令格式如下
rsync [options] [src] [dest]
使用rsync認證協定進行傳輸
網上大多數的rsync使用教程都是在描述使用rsync認證協定進行傳輸。在傳輸沒有建立之前,這種形式有server和client的概念,server端需要啟動一個rsync守護程序(daemon/service),等待接受client發起的連接配接。一旦連接配接建立,Client(用戶端)/Server(伺服器)的這兩個角色的差别,就被Sender(發送者)/Receiver(接收者)所取代。
對于移植到windows的rsync軟體來說,你可能會發現有server版本和client版本,但是server和client都是可以主動進行”推送“的。這個概念對于初次接觸rsync的人員來說比較容易混淆。
使用的指令格式如下
rsync [options] [user]@[host]::[src] [dest] # 拉取遠端檔案
rsync [options] [src] [user]@[host]::[dest] # 推送本地檔案
使用遠端shell進行操作
rsync也支援本地主機借助ssh和rcp等工具使用遠端shell和遠端主機進行通信。使用這種形式進行傳輸則不需要任何一方開啟守護程序,另外要注意rsync本身的配置檔案rsync.conf并不會在這種形式下起作用。
使用的指令格式如下
# 注意差別在于兩個':'還是一個:"
rsync [options] [user]@[host]:[src] [dest] # 拉取遠端檔案
rsync [options] [src] [user]@[host]:[dest] # 推送本地檔案
使用遠端shell臨時啟動rsync daemon
通過遠端shell也能臨時啟動一個rsync daemon,這不同于使用rsync協定,它不要求遠端主機上事先啟動rsync服務,而是臨時派生出rsync daemon,它是單用途的一次性daemon,僅用于臨時讀取daemon的配置檔案,當此次rsync同步完成,遠端shell啟動的rsync daemon程序也會自動消逝。使用時要求options部分必須明确指定”–rsh”選項或其短選項”-e”。
rsync常用參數
rsync的參數非常多,詳細請參考相關文檔以及本身的help指令。這裡僅列出一下比較常用的選項:
-v, --verbose 詳細模式輸出
-q, --quiet 精簡輸出模式
-c, --checksum 打開校驗開關,強制對檔案傳輸進行校驗
-a, --archive 歸檔模式,表示以遞歸方式傳輸檔案,并保持所有檔案屬性
-r, --recursive:遞歸到目錄中
-z, --compress 對備份的檔案在傳輸時進行壓縮處理
--delete 删除DST中SRC沒有的檔案
--ignore-errors 忽略IO錯誤
--rsync-path=PATH 指定遠端伺服器上的rsync指令所在路徑資訊
--remove-source-files:要求删除源端已經成功傳輸的檔案
-o, --owner:保持owner屬性
-g, --group:保持group屬性
--chmod=Dg+s,ug+w,Fo-w,+X 指定傳輸後的檔案權限
文法為[D|F][ugo][+-][rwxs],表示為目錄(D)和檔案(F)增加(+)減少(-)權限
最常用的選項組合是”avz”,即壓縮和顯示部分資訊,并以歸檔模式傳輸。另外從windows傳輸到linux系統時,控制檔案權限的--chmod也是非常有用的。
插件hexo-deployer-rsync
這個插件的位址為https://github.com/hexojs/hexo-deployer-rsync,安裝還是非常便捷容易的,但是和其他很多Hexo插件一樣,使用說明少之又少。對于不熟悉rsync的使用者來說,初次使用很容易找不到頭緒,到底是使用rsync的什麼形式進行傳輸?如果是rsync協定那麼本機作為server還是遠端伺服器作為server?…這還是在基于了解rsync的傳輸方式之後才能想到的問題,如果不了解rsync的基礎更是一頭霧水,總之很惡心。
由于多種使用方式的存在,以及當時網上能查到的相關内容非常之爛,翻遍了各個文章,還嘗試在本機啟動了一個rsync server,弄得一團糟。
源碼
很煩,最後沒法了直接看這個插件的源碼,沒想到源碼短到隻有50行。這裡就直接貼一下。
'use strict';
var chalk = require('chalk');
var spawn = require('hexo-util/lib/spawn');
var pathFn = require('path');
module.exports = function(args) {
if (!args.host || !args.user || !args.root) {
var help = '';
help += 'You should configure deployment settings in _config.yml first!\n\n';
help += 'Example:\n';
help += ' deploy:\n';
help += ' type: rsync\n';
help += ' host: <host>\n';
help += ' user: <user>\n';
help += ' root: <root>\n';
help += ' port: [port] # Default is 22\n';
help += ' delete: [true|false] # Default is true\n';
help += ' args: <rsync args>\n';
help += ' verbose: [true|false] # Default is true\n';
help += ' ignore_errors: [true|false] # Default is false\n\n';
help += 'For more help, you can check the docs: ' + chalk.underline('http://hexo.io/docs/deployment.html');
console.log(help);
return;
}
if (!args.hasOwnProperty('delete')) args.delete = true;
if (!args.hasOwnProperty('verbose')) args.verbose = true;
if (!args.hasOwnProperty('ignore_errors')) args.ignore_errors = false;
var params = [
'-az',
process.platform === 'win32' ? pathFn.basename(this.public_dir) + '/' : this.public_dir,
args.user + '@' + args.host + ':' + args.root
];
if (args.port && args.port > 0 && args.port < 65536) {
params.splice(params.length - 2, 0, '-e');
params.splice(params.length - 2, 0, 'ssh -p ' + args.port);
}
if (args.verbose) params.unshift('-v');
if (args.ignore_errors) params.unshift('--ignore-errors');
if (args.delete) params.unshift('--delete');
if (args.args) params.unshift(args.args);
return spawn('rsync', params, {verbose: true});
};
可以看到最終這個插件就隻是調用了一下rsync指令,剩下的都是指令内容的拼接。
為了更加清晰得說明問題,把這個插件的配置參數也貼出來
host: Address of remote host
user: Username
root: Root directory of remote host
port: Port
delete: Delete old files on remote host
args: Rsync arguments
verbose: Display verbose messages
ignore_errors: Ignore errors
源碼簡析
按照代碼順序解釋如下:
- host、user、root這三個參數必填,否則将會列印You should configure deployment settings in _config.yml first! ...提示你輸入必填參數。
- delete預設為true,verbose預設為true,ignore_errors預設為false
- 建立參數集合,固定使用-az這兩個參數;根據平台擷取部落格public目錄的路徑;拼裝遠端目錄路徑
- 參數集合判斷加入端口、ssh
- 判斷增加verbose、ignore_errors、delete選項對應參數
- 使用組裝好的參數調用rsync指令
很明顯就是要去使用ssh遠端shell進行操作,是以隻要本機和伺服器都裝上rsync即可,不需要啟動daemon程序。
使用注意
對于windows系統來說有幾個需要注意的點。
推薦使用cwRsync,貌似是要收費,但是你懂的。注意要安裝client版本,使用server版本可能會出現報錯,原因與ssh指令有關,可以發現client版本bin目錄下自帶了一個ssh.exe。因為插件直接執行rsync指令,是以安裝完成後還需要把安裝目錄添加到系統環境變量中,這樣才能直接使用。
此外由于軟體本身是linux移植過來的,在填寫路徑的時候無法識别類似 d:\\dir\\public 的win風格路徑格式,cwRsync使用 /cygdrive/d/dir/public 的格式來讀取win路徑下的内容。