2013年1月31日

Mac 一定要學的螢幕抓圖技巧,Screenshot cheat sheet for Mac OS X

使用 Mac OS X 快速擷取螢幕畫面

經常使用 MacBook 做簡報、寫網誌,會需要抓取螢幕畫面;但是要怎麼擷取才漂亮呢?

* Windows 使用者可以安裝「greenshot」,這是免費好用的抓圖工具。

Mac OS X 內建的 Screen Shot 熱鍵超好用,不需要安裝其他軟體,就能滿足各種快速抓圖的需求。
  • Command + Shift + 3
    抓取整個螢幕畫面並儲存到桌面
  • Command + Shift + 4
    選擇一個畫面區域後儲存到桌面
  • Command + Shift + 4、放開、再按空白鍵
    選取一個視窗後儲存到桌面
  • Command + Control + Shift + 3
    Command + Control + Shift + 4
    Command + Control + Shift + 4、放開、再按空白鍵
    功能同上;但多一個 Control 鍵,會儲存到剪貼簿而不直接存檔

如果要抓取整個視窗畫面,多按一個空白鍵切換成視窗選取模式,這樣就不會抓到視窗以外的內容,而且抓圖後還會自動將背景設為透明化、並加上陰影,效果真的非常棒!

對於進階使用者,想要在程式或 Shell Script 中自動抓圖,則可以搭配 Mac OS X 內建的「screencapture」指令:

# 直接抓取整個畫面存檔
screencapture ~/screenshot.png

# 抓取單一視窗畫面
screencapture -w ~/screenshot.png

# 抓取單一視窗畫面、背景不要加陰影
screencapture -ow ~/screenshot.png

其他參數可以參考:

  -c         force screen capture to go to the clipboard
  -C         capture the cursor as well as the screen. only in non-interactive modes
  -d         display errors to the user graphically
  -i         capture screen interactively, by selection or window
               control key - causes screen shot to go to clipboard
               space key   - toggle between mouse selection and
                             window selection modes
               escape key  - cancels interactive screen shot
  -m         only capture the main monitor, undefined if -i is set
  -M         screen capture output will go to a new Mail message
  -o         in window capture mode, do not capture the shadow of the window
  -P         screen capture output will open in Preview
  -s         only allow mouse selection mode
  -S         in window capture mode, capture the screen not the window
  -t<format> image format to create, default is png (other options include pdf, jpg, tiff and other formats)
  -T<seconds> Take the picture after a delay of <seconds>, default is 5
  -w         only allow window selection mode
  -W         start interaction in window selection mode
  -x         do not play sounds
  -a         do not include windows attached to selected windows
  -r         do not add dpi meta data to image
  -l<windowid> capture this windowsid
  -R<x,y,w,h> capture screen rect
  files   where to save the screen capture, 1 file per screen

2013年1月29日

Usersnap 類似 Google Feedback 網站使用者意見回饋的雲端服務,支援螢幕擷圖與塗鴉

Usersnap http://usersnap.com/
Google Feedback 提供網站使用者意見回饋的友善功能;現在的網站功能愈來愈複雜,而瀏覽器又五花八門,所以各種 BUG 有賴好心的使用者幫忙回報問題。但是只靠文字描述不容易把問題說清楚,所以 Google Feedback 提供擷取網站畫面的功能,讓使用者將有問題的地方標示清楚,方便網站管理者追蹤問題的原因。


儘管有許多人期待 Google 能將 Feedback 服務開放 API,讓網站經營者能夠直接利用現成的模組,可惜的是目前並沒有這樣好康。

Usersnap 是一個專門提供意見回饋雲端服務的平台,只要註冊就能幫自己的網站加上友善的意見回饋功能。目前的收費是從  $16 USD/月起。它提供塗鴉(螢光筆標示)、網站畫面擷圖、便利貼等功能,並且可以整合開發者常用的專案相關工具如 Basecamp、Evernote 及 JIRA 等。

Usersnap
http://usersnap.com/


2013年1月28日

Grails 網站整合 Facebook 帳號登入的 Facebook Auth plugin 介紹

Grails 是以 SpringSource 的 Spring Framework 為基礎,所以在整合權限控管的部分,首選當然就是 Spring 公司自家的 Spring Security 解決方案。

Grails + Spring Security 可以輕鬆完成:
  1. 網站的登入驗證機制
  2. 以角色(Role)為基礎的群組權限控管
  3. 整合其他 3rd party 提供的 OpenID 或 OAuth 帳號驗證
  4. 提供 Switch User 功能。例如:管理者可先以 admin 帳號登入,再免密碼直接切換成 user1 的帳號。

目前在 Grails Plugins 列表中,Spring Security Core 的排名高居 Top 3,顯示有大量 Grails 開發者採用,算是可以信賴的套件。

Spring Security Core plugin for Grails

安裝 Spring Security Core 的方法是在 BuildConfig.groovy 加入以下 Plugin dependency 宣告。

compile ":spring-security-core:1.2.7.3"

其餘的步驟在官方文件有詳細說明。

加上 Spring Security 的好處,就是可以簡單地利用 @Secured 的標記(annotations)控制 Controller/Action 的存取權限。例如只允許已登入的使用者存取 /user/profile 這個網址:

class UserController {
    @Secured(['ROLE_USER'])
    def profile() {
        // profile action
    }
}

另外 Grails 的 Spring Security 系列套件還提供:

雖然 Grails + SpringSecurity 對 3rd party 驗證的機制,不像 Node.js 的 Everyauth 那樣豐富;但如果你只是單純想讓網站加上 Facebook 帳號的整合,目前已經可以滿足這項需求。

在不久前,我們在設計新專案 CodeCanaan 時,就直接跳過內建註冊功能的實作,而採用 Facebook 登入讓使用者更方便。但是 Grails 的 Spring Security Facebook Auth plugin 是由 Open Source 開發者貢獻的子專案,一直存在許多 Bug 不定時發生。幸好目前 Facebook Auth 專案的維護者 Splix 相當盡責,在我們團隊不斷地回報 issue 後,他很認真地幫我們修正這些問題;所以到目前最新的 0.11 版已經算是相當穩定。

Spring Security Facebook Auth plugin for Grails
https://github.com/splix/grails-spring-security-facebook

安裝 Facebook Auth plugin 也很容易,只要在 BuildConfig.groovy 加上宣告。

compile ":spring-security-facebook:0.11"

再參考 Splix 提供的說明文件範例程式碼,就能幫網站加上 Facebook 帳號登入驗證機制。

目前 Facebook Auth plugin 提供四種整合機制:
  1. redirect - use standard server side authorization
  2. transparent - use transparent cookie based authorization
  3. cookieDirect - use manual cookie based authorization
  4. json - use JSON authorization

其中 redirect 模式是我們最終採用的模式,這個模式實作 Server-side Login 的架構。


雖然 Server-side Login 的實作難度比較高,但是 Facebook Auth plugin 已經解決掉困難的部份,只要直接設定成 redirect 模式就能使用。

使用 redirect 模式的優點有:
  1. 在同一個瀏覽器下,已經登入 Facebook 的使用者,可以自行選擇是否要登入 Grails 做的網站;可以同時登入 Facebook、再以其他帳號登入網站。
  2. 在網站的登出動作,不會影響到已經登入的 Facebook 帳號。
  3. 相容 Spring Security 的 Switch User 功能。

由於 Facebook Auth 只提供 Login 驗證的整合機制,如果想要進一步存取 Facebook 使用者的資料,就必須搭配 Spring Social Facebook 的函式庫。

Facebook 官方早已停止發展自己的 Java 的函式庫,所以在 Facebook Developers 頁面中, Java 的支援只列出 3rd party 的 BlackBerry 與 Spring Social。由於 SpringSource 在 Java 開發社群中,已經有舉足輕重的地位,因此在 Grails 眾多套件的搭配選用上,我們以 Spring 相關的套件為優先考慮的項目。

2013年1月26日

Ubuntu Linux Server 設定 GMail 為系統預設電子郵件服務

Ubuntu Linux Server 預設以 Exim4 作為電子郵件伺服器軟體,只要簡單的設定,就能搭配 GMail 使用,省去維護郵件伺服器的麻煩。

先安裝 Exim4 伺服器與 mailutils 郵件工具。

sudo apt-get update
sudo apt-get install exim4 mailutils

接下是設定 Exim4,使用 smarthost + GMail 作為外部 SMTP 服務。

sudo dpkg-reconfigure exim4-config

參考以下設定方法:

接著是一串繁瑣的設定過程,但其實設定內容很簡單,重點在 smtp.gmail.com::587 這邊要設定正確。
  1. 請選擇最符合您的需求的郵件伺服器之設定類型。
    • 使用 smarthost 來傳送郵件;並藉由 SMTP 或是 fetchmail 來接收郵件 (mail sent by smarthost; received via SMTP or fetchmail)
  2. 系統郵件名稱 (mail name):
    • 自行輸入已註冊的網域名稱(例如 yourhostname.com)
  3. 在有 SMTP 連線傳入時,要進行監聽的 IP 位址 (listen on for incoming SMTP connections)
    • 127.0.0.1
  4. 要進行接收的其它郵件位址 (Other destinations for which mail is accepted)
    • 保留空白
  5. 要替哪些主機進行郵件轉寄 (Machines to relay mail for)
    • 保留空白
  6. 外寄郵件時所使用的 smarthost 的 IP 位址或主機名稱 (Machine handling outgoing mail for this host)
    • smtp.gmail.com::587
  7. 是否在外送郵件中隱藏本機的郵件名稱 (hide local mail name in outgoing mail)
    • 否 (No)
  8. 是否保持最小的 DNS 查詢量 (don’t keep number of DNS-queries minimal)
    • 否 (No)
  9. 本機郵件的傳送方式
    • 存放在 /var/mail 裡的 mbox 格式
  10. 是否將設定檔分散成較小的檔案 (split configuration into small files)
    • 否 (No)
  11. root 及 postmaster 的郵件代收者
    • 輸入系統中指定的使用者帳號(多位使用者以空白字元分隔)

設定 GMail 密碼

因為 Gmail 需要帳號密碼登入後,才有寄信的權限;先編輯 /etc/exim4/passwd.client 加入設定,格式如下。

*:username:password

重新啟動 Exim4 

sudo service exim4 restart

測試發信

使用 mail 指令測試從 Server 寄出郵件。

echo '郵件內容' | mail -s '信件標題' yourname@gmail.com

檢查 LOG 記錄

如果寄信過程發生錯誤,可以在 maillog 記錄檔查詢。

tail -n 20 /var/log/exim4/mainlog

2013年1月23日

開啟 Ubuntu Linux Server 的自動系統安全更新與通知

Ubuntu Server 提供自動升級更新的功能,需要的套件有 unattended-upgrades(自動更新)與 apticron(郵件通知)。

安裝:

sudo apt-get install unattended-upgrades apticron

通常 unattended-upgrades 套件預設已經安裝,但如果第一次安裝時沒有選擇打開自動更新,可以利用 dpkg-reconfigure 重新設定。

sudo dpkg-reconfigure unattended-upgrades

選擇 Yes 啟用自動更新。


修改 apticron.conf 的信箱:

vim /etc/apticron/apticron.conf

改成用來接收通知的信箱。

EMAIL="your@email.com"

之後每次有重要系統升級,除了自動更新套件,還會以電子郵件通知管理者。


使用 tmux 與 tmuxifier 打造 Console 開發環境(比 screen 更棒)

對於 Mac OS X 與 Linux 開發者來說,直接在 Console(或 Terminal)下使用 Command-line 完成工作,才是最高效率的王道。

若要同時可以操作多個 shell,古老但管用的 screen 工具可以派上用場。執行 screen 指令後,使用 [Ctrl+a, S] 可以建立垂直分割的畫面,再用 [Ctrl+a, <TAB>] 切換到第二個畫面,以 [Ctrl+a, c] 就可以建立第二個 shell。

screen 垂直分割

但是如果想要水平分割,就只有某些版本的 screen 可以做到。對於現在的寬螢幕來說,不能水平分割實在很不方便。

更好的替代方案是改用 tmux 工具,它可以輕鬆做到水平分割。

Ubuntu / Debian 安裝方式

sudo apt-get install tmux

Mac OS X + MacPorts 安裝方式

sudo apt-get install tmux

執行 tmux


tmux 會建立一個 server,在 Terminal 執行一次 tmux 指令後,就可以再用 tmux + 參數操作。

例如建立垂直分割:

tmux split-window

執行後會建立新的分割畫面(pane),並自動開啟一個新的 shell。


要在兩個畫面之間切換,需要先按 Ctrl + b 再用上下左右按鍵選擇畫面。

如果已經習慣 screen 的 Ctrl + a,可以參考這篇將熱鍵設定成 Ctrl + a。一般的鍵盤要用同一隻手按 Ctrl + b 比較不容易,所以建議重設這組熱鍵。

接下來再建立一個新的水平分割,加上 -h (horizontal)指令。


每次都要下這些指令很麻煩,所以建議將常用的指令寫成 script,例如建立 tmux-workspace.sh,並將 tmux split-window 等指令都放進去,日後只要直接執行 script 就能自動開啟慣用的工作畫面。

tmux 也提供 layout 的定義,只要按下「Ctrl+a <ESC> 1」,數字 1~5 共有五組預設 layout 可選,可以依照 layout 定義的畫面配置方式重新排列。


更多 tmux 用法可參考這些文章。
  1. 進化版 screen - tmux
  2. tmux cheat sheet
  3. Switching to tmux
  4. Tmux 教學 + Screen 到 Tmux 的無痛轉換

用 tmux 還要搭配 tmuxifier 這個工具,可以讓工作畫面的建立更加方便。

使用 git clone 安裝 tmuxifier

git clone https://github.com/jimeh/tmuxifier.git ~/.tmuxifier

在 ~/.profile 加入一行設定,讓 tmuxifier 指令自動列入 $PATH 環境變數。

[[ -s "$HOME/.tmuxifier/init.sh" ]] && source "$HOME/.tmuxifier/init.sh"

接下來先檢查是否有 $EDITOR 變數。

echo $EDITOR

如果沒有設定,或想要修改,一樣把設定寫到 ~/.profile。

export EDITOR=vim

這邊指定用 vim 當成預設編輯工具。

重新啟動 shell 讓設定生效。

接下來,可以開始建立 tmuxifier 的視窗設定。

tmuxifier new-window example

這個指令會打開預設編輯器(vim),就可以編輯 example 這個新視窗定義的 script。

    # 可以直接指定某專案的路徑作為預設 Shell 的 Working Directory

    window_root "~/project/example"

    # 設定標題
    new_window "Example"

    # 先建立水平分割 50% 寬度
    split_h 50

    # 後建立垂直分割 50% 高度
    split_v 50

    # 分別在編號 0~2 三個畫面跑指令
    run_cmd "vim" 0
    run_cmd "date" 1
    run_cmd "htop" 2

    # 將游標切換到畫面 0
    select_pane 0

    # 因為主畫面 0 已經進入 VIM,可以對它送出編輯或操作指令
    send_keys "iI Love Vim"

定義好之後先儲存視窗設定。

打開視窗前需要先進入 tmux。

tmux

進入 tmux 之後再利用 load-window 指令打開定義的視窗。

tmux load-window example


所以 tmuxifier 可以很方便地依照個人使用習慣,將打造開發環境所需的畫面配置及功能,先寫在視窗定義裡,日後只要用 load-window 就能快速建立工作環境。

之後想要修改 window 的設定,則利用 edit-window 指令。

tmuxifier edit-window example

以我的 Grails 開發環境來說,使用的視窗定義如下:

  window_root "~/project/codecanaan"                                                                                                                        
  new_window "CodeCanaan"                                                                                                                                  
  split_h 45                                                                                                                                                
  split_v 40                                                                                                                                                
  run_cmd "vim" 0                                                                                                                                          
  run_cmd "grails" 1                                                                                                                                        
  run_cmd "htop" 2                                                                                                                                          
  select_pane 0                                                                                                                                            
  send_keys "\t"                                                

這組設定可以快速建立三個畫面,分別執行 vim、grails、htop 指令,並且利用 \t 打開 Vim Command-T 所提供的檔案搜尋功能,方便在工作環境啟動後,可以快速選擇想要編輯的檔案。


還有最重要的功能,就是 tmux 與 screen 一樣都可以重新 attach 尚未結束的 session。對於有架設 Linux 或租用 VPS 的開發者,只要在主機上利用 tmux 建立好開發環境,就可以隨時 detach 然後結束遠端連線;當下次需要重新上線工作,只要再 attach 就能重新回到繼續運行的畫面。

這個操作流程大概是這樣:
  1. 遠端 ssh 連線登入主機。
  2. 執行 tmux。
  3. 工作完成一段落後,按 Ctrl + b(或 a),再輸入 :detach 離開 tmux。
  4. 這時候已經打開的 tmux 與畫面中的程式仍然在背景運作。
  5. 結束 ssh 連線,收工,睡覺。

回復工作狀態的方法是:
  1. 重新連線 ssh 登入遠端主機。
  2. 使用 tmux attach 指令重新接上 session。
  3. 繼續工作!

結論:tmux 讓你再也回不去了!

免費 Cyberduck 跨平台、支援眾多協定的網路檔案傳輸工具

Cyberduck

Cyberduck 是一套同時支援 Windows 與 Mac OS X 的檔案傳輸工具,它提供 FTP 與 SFTP(SSH Secure File Transfer),對於經常需要將檔案上傳到 Server 的使用者,這是一個簡單方便的圖形化工具。

除了一般的檔案傳輸,Cyberduck 還提供利用 CDN 加速傳遞檔案的功能,它支援 Amazon CloudFront、Google Cloud Storage 與 Rackspace Cloud Files 等 CDN 服務。

如果你想要架設一個檔案伺服器,卻又不想架設伺服器或租用虛擬主機,就可以考慮租用以用多少付多少、比較不貴的 Amzon S3 服務。利用 Cyberduck 可以像操作 FTP 一樣簡單的方式,將檔案上傳到 S3 發佈,並設定存取權限;就像架設了一台容量、頻寬沒限制的檔案伺服器一樣。

不只如此,Cyberduck 還可以存取 Google Drive 上面的文件檔案,方便你管理雲端辦公室。

趕快下載 Cyberduck 充分利用你的網路頻寬吧!

Cyberduck
http://cyberduck.ch/


Download
Version 4.2.1

Dec-12-2011
Cyberduck-4.2.1.zip
Universal Binary. Mac OS X 10.5 or later required. Works with 10.7 Lion.
Version 4.2.1
Dec-12-2011
Cyberduck-Installer-4.2.1.exe
Windows XP, Windows Vista, Windows 7 or Windows 8 required.
Downloads hosted by Cacheboy CDN andRackspace.







2013年1月21日

Grails 筆記 - 輕鬆實現 JavaScript 最佳化壓縮與靜態資源 CDN 佈署

在 Grails 2.2+ 使用內建的 Resources Plugin 定義與管理 CSS、JS 資源,建議先將 Grails Resources Plugin 更新到 1.2RC2 或更新。

Grails Resources Plugin
http://grails.org/plugin/resources
runtime ":resources:1.2.RC2"
runtime ":resources:1.2.RC3"

兩個對 Resources 最佳化有幫助的必備 Plugins 分別是 Zipped 與 Cached,分別用來做壓縮與瀏覽器快取,只要安裝好就可以直接用。

Grails Rocks Plugins
http://grailsrocks.com/

Zipped Resources Plugin
http://grails.org/plugin/zipped-resources
runtime ":zipped-resources:1.0"
runtime ":zipped-resources:1.0.1"

如果瀏覽器支援 GZIP 傳輸模式,就啟用壓縮。
Transfer-Encoding header to "gzip"

在官方的 Plugins 說明上使用 1.0 版本,但其實這個 Plugin 已經有 1.0.1,主要是加上 Vary: Accept-Encoding 這個 HTTP-Header,可以讓 Proxy 及 CDN 正確處理經過壓縮的內容。

參考:http://gtmetrix.com/specify-a-vary-accept-encoding-header.html

Cached Resources Plugin
http://grails.org/plugin/cached-resources
runtime ":cached-resources:1.0"
runtime ":cached-resources:1.1"

這個套件會幫每個 .js / .css 進行 SHA-256 編碼,產生 unique 的一組 hash code 取代檔名。如此一來就能告訴瀏覽器該檔案要永久快取,因為內容如果有修改就會使用不同的檔案名。

由於會偵測檔案內容的改變,而使用不同檔名,這對 CDN 的佈署很有幫助,因為 CDN 對靜態資源有 TTL(Time-To-Live)的問題,使用不同檔名剛好是可用的解決方案。

CDN Resources Plugin
http://grails.org/plugin/cdn-resources

目前 Grails 已經不需要搭配 CDN Resources Plugin,所以這邊列出來只是僅供參考;在 CDN Resources 的頁面,有關於 Cloud Front 的設定提示。

實際上新的 Grails Resources Plugin 內建 Resources Mappers "baseurl" 功能,這項設定已經足夠直接用於 CDN 的佈署。

只要在 Config.groovy 的 production 區增加兩行設定。

grails.resources.mappers.baseurl.enabled = true
grails.resources.mappers.baseurl.default = "http://cdn.yourcompany.com/static"

實際將 WAR 佈署到 server 後,就會在所有 static resources(.css / .js)加上 baseurl 的網址。

Google Closure Compiler for Grails Plugins
http://grails.org/plugin/closure-compiler
compile ":closure-compiler:0.9.1"

Closure 是 Google 出品的 JavaScript/CSS Optimizer,功能類似 YUI Compressor 或 Uglify.js 等工具;這邊是用來幫 Grails 的所有 .js 檔案做最佳化,安裝後就可以看到效果。因為 Closure 本來就是 Java-based 的工具,所以使用這個 Grails Plugins 是個不錯的選擇。

簡單說就是網站的 .js 在開發階段,不用自己執行最佳化,Grails 會自動檢查檔案結尾若不是 .min.js,就會幫你跑 Closure Compiler 將 .js 壓縮再輸出。

設定選項有最佳化層級,分成 WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS and ADVANCED_OPTIMIZATIONS.

grails.resources.mappers.googleclosurecompiler.compilation_level='SIMPLE_OPTIMIZATIONS'

但只建議用 SIMPLE_OPTIMIZATIONS,因為 WHITESPACE_ONLY 意義不大,而 ADVANCED_OPTIMIZATIONS 容易產生不能執行的 JavaScript。

設定 defaultBundle

在開發階段為了方便維護,會盡量將 .js 拆成多個檔案,用模組化的概念來寫 code。但是最後必須合併成一個或少數幾個,才能讓網頁載入更快一點。

利用 Grails Resources Plugin 可以輕鬆滿足這項需求。例如在 ApplicationResources.groovy 中加入一個 application 的模組:

     application {
         defaultBundle 'application'

         resource url: 'js/module1.js'
         resource url: 'js/module2.js'
         resource url: 'js/module3.js'
     }

在輸出成 HTML 時,module1-3.js 三個檔案會合併成一個 bundle-application.js 再輸出。當然這個合併的 .js 也會先經過 Cached / Zipped / Closure 的最佳化處理,然後再透過 CDN 佈署。

要實際測試 Grails Web App 最佳化之後的效果,可以利用 Pingdom Tools 這個免費服務。

Pingdom Tools


熟悉這些 Grails Plugins 的安裝與設定方法後,幫一個 Web App 加上相關設定,大約只要幾分鐘就能搞定,網頁載入速度的改善就可以感覺得到。

在 Pingdom 的測試結果中,Load time 從 before 的 8.06s 進步到 after 的 4.40s,平均得分進步 5 個百分點。



依照 Pingdom 給予的建議,再次調整設定,分數又進步五個百分點。


兩個強大的 HTML5 電子書閱讀器,模擬翻頁效果且開放原始碼 Turn.js 與 20thingsilearned

Turn.js
http://turnjs.com/

製作 HTML5 電子書的前端工具,使用 jQuery 1.7+,支援 Chrome 12, Safari 5, Firefox 10, IE 9 等瀏覽器版本。

原始碼(3rd release, noncommercial BSD license)
https://github.com/blasten/turn.js

(範例電子書的效果,需要付費取得 4th release 的 license 才能用;3rd release 效果相對陽春。)




20 Things I Learned Acout Browsers and The Web(瀏覽器和網路世界20大須知)
http://www.20thingsilearned.com/zh-TW/

由 Google Chrome 小組和 F-i 合作的電子書,幫助網路使用者瞭解瀏覽器與基本常識。對開發者來說,這本書吸引人的地方不在他的內容,而是它在現代瀏覽器有很流暢的翻頁閱讀效果。

原始碼(GPL v2)
http://code.google.com/p/20thingsilearned/

HTML5 Rocks - 案例研究:20THINGSILEARNED.COM 上的翻页效果
http://www.html5rocks.com/zh/tutorials/casestudies/20things_pageflip/




2013年1月20日

讓 Ubuntu 的 VIM 程式碼的配色變好看

長久以來 VIM 一直是我的好朋友,不過因為個人太懶的因素,對 VIM 的配色並沒有太苛刻的要求,只要字看得清楚就夠了。直到最近每天寫 Code 時間長達十多個小時,面對大量 VIM 的文字編輯,只好講就一下顏色。

就讓我們一步步來看 Ubuntu 的 VIM 怎麼從素顏到上彩妝吧!

素顏的  Ubuntu + VIM

:syntax on
打開彩色模式之後

編輯設定組合,取消系統佈景指定的色彩、將色彩組合改成「XTerm」

Default 的配色終於比較像樣一點了

到 VIM Color Scheme Test 挑喜歡的配色
http://vimcolorschemetest.googlecode.com/svn/html/index-java.html

這邊用 256-jungle 示範

wget http://vimcolorschemetest.googlecode.com/svn/colors/256-jungle.vim
mkdir -p ~/.vim/colors
mv 256-jungle.vim ~/.vim/colors

另外測試一下 terminal 的色彩

echo $TERM
tput colors
export TERM=xterm-256color

切換成 256-jungle 配色

:colorscheme 256-jungle

灰色的底我不喜歡
所以偷改 256-jungle.vim
將背景直接改成純黑

hi Normal       ctermfg=253         ctermbg=black         cterm=None

上一張跟範例的圖片還是不一樣
因為要設定背景模式

:set bg=light

雖然最後還是沒有跟範例的顏色一模一樣,但至少已經比較看得順眼啦!

直接將以上的設定寫在 ~/.vimrc :

    syntax enable
    colorscheme 256-jungle
    set bg=light

上述把 Gnome Terminal 的配色改成「XTerm」,可以讓原本深藍色看不清楚的 Comment 文字比較容易閱讀,但是 XTerm 的深藍顏色太亮,對於有些 Console 工具像是 irssi,使用深藍色為底的文字背景,就會因為背景太亮。折衷的作法是將 Gnome Terminal 的色彩組合改回「Linux 主控臺」,再透過 .vimrc 將 Comment 文字前景色換掉。以下是將 Comment 改成深青色(darkcyan)的效果,註解文字變得比較容易看清楚。

hi Comment ctermfg=darkcyan

Ubuntu Linux KVM 虛擬機器維護與 Guest OS 文字介面安裝

上次的筆記是關於 KVM 虛擬化伺服器的建置,免費的虛擬化解決方案中,KVM 虛擬機器的執行效能相當好,只要配置足夠的記憶體、使用固態硬碟,就能輕鬆將伺服器一台變多台。

關於 KVM 與其他虛擬化軟體的比較。

目前 Ubuntu 除了可以容易安裝 KVM 所需的工具套件外,也有寫得算清楚的使用說明。

https://help.ubuntu.com/community/KVM/

為充分利用資源有限的硬體資源,所以在 Host 上並不安裝圖形化桌面環境,只透過 command-line 進行維護。

先安裝 virsh 的套件。

sudo apt-get install libvirt-bin

利用 virsh 連到 KVM Host 進行維護。

virsh --connect qemu:///system

使用 list --all 列出所有虛擬機器。

virsh list --all

輸出範例。

 Id Name                 State
----------------------------------
  1 vm1              running
  3 vm2              running

維護指令包括:

virsh shutdown vm1
virsh destroy vm1
virsh start vm1
virsh suspend vm1
virsh resume vm1

安裝 virtinst 套件,用於自動建立 VM 並安裝 Guest OS。

sudo apt-get install virtinst

使用 virt-install 指令建立名稱「vm3」的虛擬機器,設定記憶體 1024MB、單顆 CPU、硬碟容量 20GB,並指定從 http://tw.archive.ubuntu.com/ubuntu/dists/precise/main/installer-i386/ 位置自動安裝作業系統,如此一來就不需要先下載 .iso 檔案。

sudo virt-install --connect qemu:///system -n linuxvm -r 1024 --vcpus=1 --disk path=/var/lib/libvirt/images/linuxvm.img,size=20 --os-type linux --os-variant ubuntuprecise --location http://tw.archive.ubuntu.com/ubuntu/dists/precise/main/installer-i386/ --accelerate --network=bridge:br0 --hvm --nographics --network=network:default \ --extra-args="auto text console=tty1 console=ttyS0,115200"

等待開機程式載入,就會進入 Ubuntu Linux Server 純文字的安裝模式。
Ubuntu Linux 12.04 LTS in Console Text-based Installation

Ubuntu Linux 12.04 LTS in Console Text-based Installation


在等待虛擬機器建置過程,可利用 htop 方便觀察主機狀態。

sudo apt-get install htop
htop

若需要重新連上虛擬機器的 Console:

virsh console linuxvm

刪除虛擬機器的步驟。

virsh destroy linuxvm
virsh undefine linuxvm
virsh vol-delete --pool default linuxvm.img

第二種快速自動化安裝作業系統的方法,可以使用 ubuntu-vm-builder 或 vmbuilder 指令。

sudo apt-get install ubuntu-vm-builder python-vm-builder

使用 ubuntum-vm-builder 的範例。

sudo ubuntu-vm-builder kvm precise --addpkg vim --mem 1024 --libvirt qemu:///system

使用 vmbuilder 的範例(+ 進階參數設定)。

先切換成 root 身分。

sudo su -

切到 libvirt 的 images 資料夾下。

cd /var/lib/libvirt/images

查看 vmbuilder 可用的選項:

vmbuilder kvm ubuntu --help

執行 vmbuilder 加上參數指定選項設定。

vmbuilder kvm ubuntu \
--domain=kvm \
--dest=linuxvm \
--arch=i386 \
--hostname= linuxvm \
--mem=1024 \
--cpus=1 \
--user=kyle \
--pass=reverse \
--bridge=br0 \
--ip=192.168.0.101 \
--mask=255.255.255.0 \
--gw=192.168.01. \
--dns=8.8.8.8 \
--iso=/var/lib/libvirt/images/ubuntu-12.04.1-server-i386.iso \
--suite=precise \
--components='main,universe,restricted' \
--addpkg=vim \
--addpkg=build-essential \
--addpkg=openssh-server \
--libvirt=qemu:///system

結論:KVM + Ubuntu Server 建置虛擬化伺服器有優異的效能,而容易在全文字的 Console 介面下操作,甚至包括安裝作業系統都在純文字模式中進行,對於經常需要遠端連線操作的管理者,即使是利用速度很龜又不穩的 3G 網路,也可以輕鬆維護虛擬系統(建議搭配 mosh 讓 ssh 連線比較順)。

2013年1月17日

Foundation 3 優秀的 Reponsive 前端框架

Foundation 3 Responsive Front-end Framework

ZURB 是家擁有 14 年網站設計經驗的公司,他們的前端開發框架「Foundation」是一個開放原始碼專案,提供現代網站開發所需的 Prototyping、Grid System、Responsive Design,對平板與智慧型手機的小尺寸螢幕,有很棒的支援。ZURB 使用 SASS 設計網站布局的 CSS3 樣式,因此網頁視覺設計師可以很容易進行外觀的客製。

Foundation 可以拿來和 Twitter Bootstrap、BluePrint、Skeleton 等前端框架做比較,如果還沒決定網站要使用哪一種前端框架,不妨也將 Foundation 列入考慮項目。

與 Bootstrap 相比,Foundation 的 Grid System 較有彈性,也提供比較多範例版型可供 Wireframing 參考;但 UI 元件的數量就不如 Bootstrap 豐富。

已經有開發者將 Bootstrap / Foundation 2-3 / Skeleton 的優缺點比較詳列出來,請參考這篇「Responsive CSS Framework Comparison」。

Twinkle 讓 Java Swing 程式也有漂亮的 Growl-like 系統通知訊息顯示 from SwingFX

SwingFX - Twinkle
Beautiful desktop notifications.

現在的桌面應用程式或網站很多都用 Growl 風格的系統通知訊息,也就是在桌面角落彈出一個漂亮的訊息,然後過幾秒後又自動消失。

Twinkle 是一個以 Swing 為基礎開發的套件,它讓 Java Swing 程式也能有 Growl-like 的訊息通知設計。

SwingFX
http://www.swingfx.ch/

Twinkle @GitHub
https://github.com/spreiter301/Twinkle

使用 Twinkle 只要簡短的幾行程式碼,可以參考:
http://static.swingfx.ch/twinkle/QuickStart.java

SwingFX 的網站還有提供 Java Web Start 的範例,可以立即測試 Twinkle 的效果。

使用 Gradle Application Plugin 快速建立容易發佈的 Java 應用程式

Gradle 內建的「Application Plugin」,是網路教學文章比較少介紹;但是對 Java GUI 程式開發者來說,它是個不能不知道的好工具。

Modern Java 開發者有很多工具可以幫忙建置打包專案,包括 Ant、Maven 及目前最棒的 Gradle 等。利用 Gradle 內建的 Java 與 Jar Plugin,可以很容易將 Java 原始碼編譯,並且進行打包成 JAR 檔的工作。

但是在發佈之前,還有些事情要做:

  1. 建立 Windows / Linux 與 Mac OS X 可直接執行的 Script / Batch 檔案,包括正確尋找 JAVA_HOME 路徑、使用正確的 CLASSPATH 執行 JAR 檔案。
  2. 將相關的相依函式庫套件(.jar)也一併打包,壓縮成 ZIP 檔,方便客戶端一次取得所有需要的檔案。
有 Gradle Application Plugin 的幫忙,這些需求可以輕鬆搞定。

使用方法很簡單,在 build.gradle 加入兩行設定:

apply plugin:'application'
mainClassName = "org.gradle.sample.Main"


其中 mainClassName 是進入主程式要啟動的類別名稱,就是包含 static void main(String args) 的那個 Class。

然後在 console 執行:

gradle distZip

就會自動產生一個 AppName.zip 檔案。

使用 unzip 將這個檔案解壓縮,可以發現它包含兩個資料夾:

bin/
lib/

其中 lib 放置 Java 程式所需的相關 JAR 檔案,而 bin 則放置 Application Plugin 產生的 Shell Script(for Linux and Mac OS X)與 Windows Batch 執行檔。

對客戶端而言,只要執行 bin 裡面執行檔,就能正確啟動 Java 程式。

2013年1月16日

Grails 2.2 安裝 Local Plugin 的方法

Grails 2.2 若使用 install-plugin 安裝 Local Plugin 的 ZIP 檔案,會出現 Dependency Error。

以 spring-security-facebook 這個 Plugin 為例。

git clone git://github.com/splix/grails-spring-security-facebook.git
cd grails-spring-security-facebook
grails package-plugin

可以產生:

grails-spring-security-facebook-0.10.3.zip

不過在自己的專案中,使用 install-plugin 會發生錯誤。

grails install-plugin ../grails-spring-security-facebook/grails-spring-security-facebook-0.10.3.zip

在這個討論串有說明原因:

http://jira.grails.org/browse/GRAILS-9006

錯誤訊息包含:

Environment set to development.....
:: problems summary ::
:::: WARNINGS
::::::::::::::::::::::::::::::::::::::::::::::
:: UNRESOLVED DEPENDENCIES ::
::::::::::::::::::::::::::::::::::::::::::::::

目前解決方法,是利用 maven-install 先安裝 Plugin 到 Local Maven Repository。

在 plugin 資料夾下,先做 maven-install。

*建議先改 SpringSecurityFacebookGrailsPlugin.groovy 的版號,例如用 0.10.3rc 這樣。

grails maven-install

就會將打包好的檔案保存到 ~/.m2。

先在專案中,grails-app/conf/BuildConfig.groovy 確認有 mavenLocal() 這個 repositories 設定。

然後在 plugins 設定區增加 dependency。

plugins {
    compile ":spring-security-facebook:0.10.3rc"
}

在 Grails 2.2.x 之後的版本,已經不建議用 install-plugin 方案安裝。取代的方式就是在 BuildConfig.groovy 設定 Grape Style 的 dependency 宣告。

另外,打包 Plugin 還牽涉到 Grails 版本問題。如果專案和外部 Plugin 用不同的 Grails 版本,建議在打包 Plugin 時,先利用 GVM Tools 將 Grails 版本切換成 Plugin 原指定的版本,這樣可以避免很多建置階段的問題。

解決 Grails Domain Date + MySQL 發生錯誤 Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp


假設有個 Domain Class 的定義:

class Book {
    Date publish
}

其中 publish 用來儲存發佈日期,所以在資料庫會有:

名稱為 book 的 DB Table
名稱為 publish 的 Column(DATETIME)

但是在資料被建立時,MySQL 會自動在缺少日期設定、又是 NOT NULL 的日期欄位,自動填入「0000-00-00 00:00:00」這個時間。

在 Hibernate 取出資料時,由於這個不正確的時間值轉換成 Timestamp 會發生失敗,所以就會噴出錯誤如下:

2013-01-16 20:40:53,443 [ajp-bio-8009-exec-1] ERROR util.JDBCExceptionReporter  - Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp

解決的方法不難,就是再 JDBC Connection String 加上參數設定。

zeroDateTimeBehavior=convertToNull


建立可以直接執行的 Grails WAR 檔案

Grails 是 Java EE 的 MVC Framework,提供大量的 Plugins 可供快速開發,撰寫中小型應用程式非常簡單方便。

如果想做一個迷你型的 Web App,讓使用者下載後可以再自己的電腦上執行;過去的作法可能是:
  1. 請使用者安裝 Tomcat 或 Jetty 伺服器軟體
  2. 提供 WAR 檔請使用者下載到伺服器的 deploy 位置

為了讓使用者更方便,我們還可以將 Tomcat/Jetty + WAR 全部打包好,讓使用者下載、解壓縮後就能立即執行。

但是最近發現一個相當有趣的 Grails Plugin,叫做「War Exec Plugin」。使用方式如下:

    grails install-plugin war-exec

然後幫專案產生 WAR 檔案。

    grails dev war

就可以得到 target/MyApp.war。

這個動作和一般產生 WAR 檔並無差異,但是使用 War Exec Plugin 產生的 WAR 已內建 Jetty Embedded Web Server,所已可以直接利用 java -jar 指令執行,而不需要佈署到 Tomcat 或獨立的 Jetty 伺服器。

    java -jar target/MyApp.war

相關連結

2013年1月15日

使用 AES 演算法加密字串,以 Groovy / Java 快速實作


Java 內建 AES 演算法的 API,所以在 Groovy 程式中,實際不到十行程式碼,就能完成加密或解密字串的處理。

為了把加密結果轉成十六進位,我們使用 commons-codec 提供的 HEX 物件。當然在 Groovy 只要使用 Grab / Grapes 就可以輕易自動載入需要的函式庫檔案。

    @Grab('commons-codec:commons-codec:1.7')
   
    import javax.crypto.*
    import javax.crypto.spec.*
    import org.apache.commons.codec.binary.*
   
    String text = "I Love Taiwan"
   
    //設定金鑰與演算法
    def key = new SecretKeySpec("0123456789012345".bytes, "AES")
    def c = Cipher.getInstance("AES")
   
    //加密
    c.init(Cipher.ENCRYPT_MODE, key)
    e_text = new String(Hex.encodeHex(c.doFinal(text.getBytes("UTF-8"))))
   
    //解密
    c.init(Cipher.DECRYPT_MODE, key)
    text = new String(c.doFinal(Hex.decodeHex(e_text.toCharArray())))

@作者 lyhcode 有多年 Groovy 及 Grails 開發經驗,歡迎到 Groovy Taiwan( http://facebook.com/groovy.taiwan/ )交流分享。

2013年1月14日

Grails 好用的 LinkGenerator 與 MimeUtility 隱藏版 Helper

Grails 2.x 之後的版本帶來兩個好用的 Helper,可惜在官方文件沒有太多介紹,算是隱藏版的功能。

### LinkGenerator ###

一般來說,產生 Grails 的連結有幾種方式:
  1. <g:link ... />
  2. <g:resource ... />
  3. ${createLink(...)}
  4. ${resource(...)}

但有些特殊網址不容易透過這種標準方式產生,但很該死的在舊版 Grails 並沒有方便的標準方法,可以拿到「Base URL」,例如「http://compnay.com/app」這種!

雖然透過 request 物件,也可以自己將 URL 組合出來;但是不免還是要懷疑,一個 Web Framework 怎麼連這麼基本的東西都沒有?!

Grails 2.x 之後可以利用 LinkGenerator 幫忙,在 Controller / Service 程式中,可以定義一個 grailsLinkGenerator 變數來取得此物件實例(透過 Injection 方式)。

    class XxxController {
        def grailsLinkGenerator // Injection
    }

如此就能在程式中存取其方法:

    grailsLinkGenerator.contentPath
    grailsLinkGenerator.serverBaseURL
    grailsLinkGenerator.link ...
    grailsLinkGenerator.resource ...

特別是在設計 TagLib 時,LinkGenerator 就有很多用處了。

### MimeUtility ###

這是用來取得 Mime Types 的物件,雖然 Grails 內建能辨別的 Mime Types 並不多,但至少可以依循這個標準的介面來擴充。

使用方式同樣是透過 Injection,

    class XxxController {
        def grailsMimeUtility // Injection
    }

以下是幾種使用範例。

    log.info grailsMimeUtility.knownMimeTypes
    log.info grailsMimeUtility.getMimeTypeForExtension('html')
    log.info grailsMimeUtility.getMimeTypeForURI('http://example.com/test.html')

多作者共筆以 Markdown 編輯,使用 Mou, Pandoc, XeTex 輕鬆製作 PDF 電子書 Mac OS X

最近和技術夥伴共同編寫一些教學文件,「共筆」一直是我們覺得麻煩的問題。雖然 Google Doc 有還不錯的所視即所得+多人協作功能,但編出來的文件真是其貌不揚。而其他編出來排版效果好的軟體,在協作的功能就實在別多想了。

雖然在上個年度我們研發「ContPub(目前正在內部整修中)」平台,就是試圖想解決多人協作電子書的問題。但是以 reStructuredText 為基礎的文字編輯,目前並沒有太多「所視即所得」的套件可以選配,對需要依賴看到結果才算數的作者來說,這一直是個難解的問題,因為把整份電子書文件提交給 ContPub 後端的幕後排版主機處理,需要耗掉大量時間而且難以除錯。

目前我們自己的文字編輯團隊,採用折衷的作法,選擇以 Markdown 為基礎的工具,搭配各自可以在自己的電腦 Preview 的工具,讓電子書的編輯工作更順利一些。

因為 Markdown 本身是純文字格式,很容易做 diff / merge 處理,所以只要搭配 GitHub 作版本控制,就可以讓多為作者共同編輯幾份文件,並容易解決編輯衝突問題。這對平常很習慣用 git 的開發者來說,就是一小片蛋糕而已。

在文字編輯器的選擇上,剛好 Mac OS X 下有個 Mou 免費文字編輯軟體,它支援自動 refresh 的預覽,以及文字編輯區可放大標題顯示的 syntax highlight,所以還算得上是作者能接受的「所視即所得」。在右邊的即時預覽區會跟著編輯區的捲動移動預覽範圍,這是使用瀏覽器做成的功能,Mou 提供 CSS 設定可以修改預覽區的樣式,只要將 font-size 與 line-height 加大,就已經很接近中文預覽需要的效果。


使用 Pandoc + XeTex 進行 PDF 幕後排版輸出,Pandoc 可以將 Markdown 文件轉為 LaTeX 格式,再交由 XeLaTeX 轉檔成 PDF,中文排版的部份需要一些 tuning,這部份只要修改 default.latex 設定即可達成。


搭配 Makefile 就可以讓轉檔作業全部自動化,例如加上 watchr 自動監視文字檔的修改,每次有更新就自動進行幕後轉檔,如此一來就能讓每位作者都能輕鬆預覽自己完成的輸出結果。

最後就可以合併每位作者完成的結果(文件原始碼 + 原始圖片 + PDF 預覽檔)…如果需要更好的排版品質,就需要在最終修訂完成後,直接針對 LaTeX 檔案修改了。雖然從 Markdown 自動轉檔成 PDF 的品質,還沒辦法達到理想的水準;但是花費同樣時間,可以比 WORD 有更好的效果、更容易編輯,而且也保留了容易批次處理的圖片原始檔。

2013年1月13日

[筆記] Ubuntu Linux 使用 apt-get 指令移除軟體並清理遺留的垃圾

在 Ubuntu 下移除某個軟體套件,使用的指令是 apt-get remove,例如:

    sudo apt-get remove texlive-full

但由於先前安裝此套件,會一併自動安裝相依套件(dependencies),所以需要再用 autoremove 清理。

    sudo apt-get autoremove

或是在 remove 時加參數:

    sudo apt-get remove --auto-remove

但是這樣還不夠乾淨,因為預設的 remove 行為,會保留一些設定檔之類的遺物。所以需要用 purge 的方式移除。針對單一套件使用 purge 方式徹底移除:

    sudo apt-get purge texlive-full



    sudo apt-get remove --purge texlive-full

在使用 autoremove 時可以加上 --purge 參數,同時徹底移除套件。

    sudo apt-get autoremove --purge

對於先前用 autoremove 或 remove 或其它方式移除,但還沒經過 purge 徹底移除的套件,使用 dpkg 指令可以列出清單:

    dpkg -l | grep ^rc

其中 ^rc 代表行首以 rc 標示開頭,這是只有 remove 沒有 purge 的意思。

要批次移除這些被標為 rc 的套件,可以配合 grep + awk 指令。

    dpkg -l | grep ^rc | awk '{ print $2 }'

指令組合後即可批次徹底移除這些殘留套件。

    sudo apt-get purge `dpkg -l | grep ^rc | awk '{ print $2 }'`

如此,就可以讓系統稍微乾淨一點!

使用 mysqldump, crontab, s3cmd 自動化異地備份資料庫到 Amazon S3 雲端儲存

過去 Linux 系統的維護,對於重要的資料庫備份,不外乎是增加本地備份用的硬碟、網路儲存系統(NAS),最麻煩且成本最高的是異地備份。在雲端儲存大行其道的時代,Amazon S3 也成為系統管理者備份資料的好工具。

目前有許多新的 NAS 產品,也提供同步備份到 Amazon S3 的服務;因為操作較簡單適合一般使用者,請自行尋找合適的 NAS 解決方案(參考)。

這篇文章是利用 Shell Script 的方式,自動將 MySQL 資料庫備份到 Amazon S3,適合自行架設或租用 VPS Linux 主機的系統管理者。

測試環境為 Ubuntu Linux 12.04 LTS

### 測試 mysqldump 指令 ###

建立一組備份資料用的 MySQL 帳號 USER 並設定為 NO PASSWORD、只限從 localhost (主機)連線。

將 DB_NAME 資料庫備份到 DB_NAME.sql 的指令:

    mysqldump -u USER DB_NAME > DB_NAME.sql

如果執行成功(使用者權限正確),DB_NAME.sql 會包含資料庫完整 structure 與 data。

### 使用 gzip 壓縮備份檔 ###

先確認 gzip 工具已安裝。

    sudo apt-get install gzip

壓縮檔案。

    gzip DB_NAME.sql

執行完成後會產生 DB_NAME.sql.gz(並移除 DB_NAME.sql)。

### 加上日期標記 ####

為了區分不同時間點的備份檔,使用 date 指令產生日期。

    date +%Y%m%d%H%M%S

這個指令會產生日期+時間的一串文字:20130113132718。

為了重複利用,以 Shell 變數儲存日期標記。

    set stamp=`date +%Y%m%d%H%M%S`; echo $stamp

### 結合以上操作 ###

將備份、壓縮變成一行指令。

    stamp=`date +%Y%m%d%H%M%S`; mysqldump DB_NAME > /tmp/DB_NAME-$stamp.sql && gzip /tmp/DB_NAME-$stamp.sql

### 使用 s3cmd 備份檔案 ###

先開通 Amazon AWS 的帳號及 S3 服務,取得 ACCESS_KEY 與 SECRET_KEY。

安裝 s3cmd 工具。

    sudo apt-get install s3cmd

先設定 S3 存取權限(access_key, secret_key)。

    s3cmd --configure

先建立 Bucket(S3 儲存空間)。

    s3cmd mb s3://BUCKET_NAME

通常 Bucket 名稱使用自訂的網域,例如(s3.company.com)。

上傳一的檔案。

    s3cmd put DB_NAME.sql.gz s3://BUCKET_NAME/backup

瀏覽 S3 的檔案。

    s3cmd ls s3://BUCKET_NAME/backup/

取回檔案。

    s3cmd get s3://BUCKET_NAME/backup/DB_NAME.sql.gz DB_NAME.sql.gz

### 組合成備份指令 ###

先測試指令是否正確運作。

    stamp=`date +%Y%m%d%H%M%S`; mysqldump DB_NAME > /tmp/DB_NAME-$stamp.sql && gzip /tmp/DB_NAME-$stamp.sql && s3cmd put /tmp/DB_NAME-$stamp.sql.gz s3://BUCKET_NAME/backup/

檢查檔案備份結果。

    s3cmd ls s3://BUCKET_NAME/backup/

將指令存為 Script (backup.sh)檔。

--------- /home/USER1/backup.sh ---------
#!/bin/bash
stamp=`date +%Y%m%d%H%M%S`; mysqldump DB_NAME > /tmp/DB_NAME-$stamp.sql && gzip /tmp/DB_NAME-$stamp.sql && s3cmd --no-progress put /tmp/DB_NAME-$stamp.sql.gz s3://BUCKET_NAME/backup/
--------------------- END ----------------------

設定執行權限。

    chmod a+x backup.sh

先執行一次測試備份程式。

    ./backup.sh

### 設定 crontab 工作排程 ###

定時執行 backup.sh 程式,使用 crontab 即可辦到。

修改 crontab 設定(使用個人喜歡的編輯器)。

    crontab -e

在最行一行加入:

0 3 * * * /home/USER1/backup.sh > /dev/null 2>&1

固定每日凌晨三點,自動執行資料庫備份程式(後面 redirect 到 /dev/null 是為了避免 crontab 將訊息以郵件通知)。

@作者 lyhcode 是熱血程式設計師,喜歡分享 Linux 作業系統與自由軟體的使用技巧,本文歡迎轉載請註明出處。

觀點:開發很棒的軟體...五個成功秘訣分享(中譯摘要)

Building Great Software...5 Cool Tips For Success!
【原文】
Building Great Software...5 Cool Tips For Success!
http://www.loggly.com/blog/2012/03/you-know/
by Brian Schroeder

作者 Brian 是任職 Loggly 網路公司的開發者。 

丟掉「做這個會很酷」的點子
If you start with "you know what would be cool?", kill the idea.

這聽起來有點刺耳,但是工程師天生就是容易被很酷的技術吸引,例如新的程式語言與工具帶來很棒的特性:Redis, MongoDB, RabbitMQ, Python, Ruby, Clojure, Scala, Node.js 都是很棒的技術,當你用很新奇酷炫的技術做軟體,別人也會覺得你超級酷。但是千萬別忘記:開發軟體是為了做出「有用」的東西而非「酷」。

旨在一切從簡
Aim for simplicity.

當你準備寫下段程式碼,從簡單的開始,別在腦海裡想些複雜而遠超過所需的東西。找出對「你」而言可以最簡單容易達成目標的方法,別去用那些你不會做的。

可以簡單但不能隨便
The simplest solution isn't always best.

有時候用不好的類別繼承方式或耍小手段的演算法,可能是解決問題最輕鬆的方法。但這樣做無疑是在挖洞兼埋地雷,日後發生問題肯定粉身碎骨。要避免差勁的作法,即使看起來很簡單;有時需要用較複雜一點的作法,同時想辦法把複雜度降低。

想要的功能不一定需要
Don't build more than you need.

有些功能看起來很誘人,當你開始想要把每樣東西都加到軟體裡,請再多思考幾次,如果想不出實際的好理由,做出這些功能可能只是想要而非需要。

想遠一點
Think long-term.

乍看之下這點和前面幾項有衝突,如果要以簡單、滿足當前需要為目標,要怎麼把日後的狀況也考慮進來呢?這裡指的是「計畫」要有長遠的眼光,大處著眼,小處著手。

2013年1月12日

s3cmd 檔案傳輸速度調校筆記

在 Linux 與 Mac OS X 的開發環境,我使用 s3cmd 這個工具,將完成的檔案佈署發佈到 S3 Bucket。

s3cmd tool
http://s3tools.org/s3cmd

在 Ubuntu Linux 及 Mac OS X + MacPorts 下安裝 s3cmd 很容易。

sudo apt-get install s3cmd



sudo port install s3cmd

然後設定 AWS 的 SECRET KEY 就可以開使用。

因為這個工具透過 Web Service 存取 AWS / S3,新版本在速度上有設限制。由於最近使用頻率很高,但傳輸速度慢的問題實在造成很大困擾 : )

我的檔案大小 75MB。

$ du -h target/codecanaan.war
75M target/codecanaan.war

網路頻寬則是 HINET 光世代固定制 50M / 20M。

若以預設值上傳,真是等到天荒地老...

$ s3cmd put -P target/codecanaan.war s3://s3.xxxxxx.com/apps/
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 1 of 5, 15MB]
 15728640 of 15728640   100% in  107s   142.89 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 2 of 5, 15MB]
 15728640 of 15728640   100% in  106s   144.39 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 3 of 5, 15MB]
 15728640 of 15728640   100% in  110s   139.12 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 4 of 5, 15MB]
 15728640 of 15728640   100% in  109s   140.87 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 5 of 5, 14MB]
 15473658 of 15473658   100% in  104s   145.20 kB/s  done
Public URL of the object is: http://s3.xxxxxx.com.s3.amazonaws.com/apps/codecanaan.war

在設定檔 ~/.s3cfg 找到速度慢的兇手:

recv_chunk = 4096
send_chunk = 4096

上傳檔案只要調整 send_chunk,設定成 4096 * 16 = 65536

recv_chunk = 4096
send_chunk = 65536

調校後,速度真是天差地遠阿!

$ s3cmd put -P target/codecanaan.war s3://s3.xxxxxx.com/apps/
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 1 of 5, 15MB]
 15728640 of 15728640   100% in   13s  1163.89 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 2 of 5, 15MB]
 15728640 of 15728640   100% in   13s  1148.22 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 3 of 5, 15MB]
 15728640 of 15728640   100% in   14s  1032.15 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 4 of 5, 15MB]
 15728640 of 15728640   100% in   12s  1273.37 kB/s  done
target/codecanaan.war -> s3://s3.xxxxxx.com/apps/codecanaan.war  [part 5 of 5, 14MB]
 15473658 of 15473658   100% in   18s   805.14 kB/s  done
Public URL of the object is: http://s3.xxxxxx.com.s3.amazonaws.com/apps/codecanaan.war

預設會將大型檔案切割成每塊(chunk part) 15MB 的大小,會讓速度沒辦法拉到應有水準,這問題可以加上 --multipart-chunk-size-mb=100 解決。

$ s3cmd put --multipart-chunk-size-mb=100 -P target/codecanaan.war s3://s3.xxxxxx.com/apps/
target/codecanaan.war -> s3://s3.lyhdev.com/apps/codecanaan.war  [1 of 1]
 78388218 of 78388218   100% in   56s  1345.77 kB/s  done
Public URL of the object is: http://s3.xxxxxx.com.s3.amazonaws.com/apps/codecanaan.war

增加 send_chunk 的值可以讓傳輸更快,但是設定太高會有反效果,容易導致傳輸失敗(或速度不增反減)。

2013年1月11日

Jenkins 使用 IRC Plugin 讓專案 build 訊息自動發佈到聊天室

我們的新專案使用 GitHub 進行原始碼版本控管,並且採用 Jenkins 進行持續整合(CI, Continuous Integration);團隊成員則使用 IRC 頻道聊天室進行即時的線上討論。

前一篇「GitHub 使用 IRC Service Hook...」我們說明了利用 GitHub Hook 服務,自動將專案 Commit 的訊息,利用 IRC 發送聊天訊息通知所有成員。

當然在原始碼 PUSH 到版本控制系統後,下一步就是利用持續整合平台,進行專案的 auto build / test / deploy 等動作;我們選擇目前最強的 Jenkins 作為專案管家。目前我們在 Grails 專案每次 Commit 後,就讓 Jenkins 自動進行 test-app 的任務。

利用 Jenkins 提供的 IRC Plugin,每次開始及結束 build 階段時,都會把狀態利用 IRC 聊天室發佈訊息。

Jenkins 的 Plugin 真是包山包海,只要安裝這個「Jenkins IRC Plugin」就搞定。


比較麻煩的是設定的部份,花費好一番功夫才讓 Jenkins 可以正確連上 IRC 頻道。


在設定正確的情況下,儲存設定後,Jenkis 就會在背景建立一個 IRC 連線,以設定中指定的 Nickname 登入聊天室。

不過搭配 FreeNode IRC 伺服器使用時,剛開始遇到無法正常登入的情況,後來幫 Jenkins 註冊一組專用的 FreeNode Nickname 後,同時使用 Nickname / Password 就可以順利登入。另外是在 Channel 設定的後方有 Notification only,建議要勾取。

關於 FreeNode 使用 NickServ 註冊專屬匿稱的方法,請參考上一篇教學的末段。

[筆記] 使用 Node.js 撰寫 IRC Client / Chat Bot 聊天機器人

IRC(Internet Relay Chat)是歷久彌新的網路聊天室協定,相信開發者一定都不陌生。

Node.js 可以幹很多事,當然也可以拿來寫 IRC 聊天機器人;這篇筆記簡單分享出步測試的結果。

先找個自己喜歡的 IRC Client,登入 IRC 伺服器(如 FreeNode),建立一個測試的聊天室頻道(Channel),方便測試。

連線資訊範例:

   server: irc.freenode.net
   port: 6667
   channel: #testmynodeirc
   nickname: ilovenode

使用 node-irc 套件,用 npm 搞定。

    npm install irc

建立 client.js 程式檔,開始寫 code。

首行先 require 所需的 irc module。

    var irc = require('irc');

建立新連線,將結果存到 client 變數。

    var client = new irc.Client('irc.freenode.net', 'BOTNAME', {
        channels: ['#testmynodeirc'],
    });

再來是使用 Node.js Event-based 設計程式有趣的地方,利用一個 callback function 實作回答的功能。

    client.addListener('message', function (from, to, message) {
        client.say(to, message);
    });

這樣就完成了很蠢的第一支機器人實作,不管對方傳送什麼聊天訊息,都會把一模一樣的聊天訊息丟回去 : )

    node client.js

參考 bot 的範例

在 Ubuntu 下使用 nvm 安裝 Node.js 0.4.12 版本

因為測試某些 Node 程式的需求,需要安裝早期的 Node.js 0.4.12 版本;系統需要同時存在多個版本,這時最好的方案就是選擇 NVM(Node Version Manager)方式安裝。

先裝 curl

sudo apt-get install curl

再利用 curl 安裝 NVM

curl https://raw.github.com/creationix/nvm/master/install.sh | sh

裝好後重新登入,或者手動執行 nvm.sh。

. ~/.nvm/bin/nvm.sh

再來就能使用 nvm 指令,先列出遠端檔案伺服器提供的 Node 版本。

nvm ls-remote

選擇安裝 v0.4.12 版。

nvm install 0.4.12

build 過程會遇到缺少套件問題,先補裝套件。

sudo apt-get install build-essential libssl-dev

再重新安裝一次。

nvm install 0.4.12

裝好後用 use 切換指定版本。

nvm use 0.4.12

測試版本。

node --version

出現正確版號就代表安裝完成了。

Ubuntu 12.04 安裝 KVM 虛擬化筆記

最近打算在 Ubuntu Server 上增加幾個 Virtual Machine,用於 Jenkins 持續整合(CI, Continuous Integration)測試環境的佈署。因為 CI 在獨立的虛擬機器下運作,比較容易分別設定不同的開發軟體版本,避免太多衝突帶來困擾。

安裝套件

sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils virt-viewer virt-manager bridge-utils

設定 bridged network(讓虛擬機器可以取得對外 IP)

sudo vim /etc/network/interfaces

將對外連線的網路裝置 eth0(或 eth1)改成 br0:

# auto eth0
auto br0

# iface eth0 inet static
iface br0 inet static

保留 eth* 原有的 address、netmask、gateway 等設定,在下方加上 bridge 相關設定:

bridge_ports eth1
bridge_stp off
bridge_fd 0
bridge_maxwait 0

重新開機或重新啟動網路介面:

sudo reboot


sudo /etc/init.d/networking restart

檢查是否有 br0

ifconfig | grep br0

在 Ubuntu Desktop 或 Mac OS X (加裝 XQuartz)使用 ssh -X 連線到 server。

ssh -X user@hostname

第一次使用時,需要先將使用者帳號加入 libvirtd 這個群組,編輯 /etc/group 設定如下:

libvirtd:x:117:使用者帳號

修改群組儲存後,需要重新登入才會生效。

檢查硬體是否支援虛擬化技術

cat /proc/cpuinfo

flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms

如果處理器支援虛擬化,flags 項目會包含 vmx(Intel)或 svm(AMD)標示。

但是處理器支援,並不代表 BIOS 選項有開啟。可以使用 kvm-ok 指令,查詢是否正確啟用。

sudo kvm-ok

如果

sudo kvm-ok

如果 CPU 支援虛擬化,但 BIOS 未啟用相關設定(如 Intel(R) Virtual Technology 設定),則會顯示以下訊息。

INFO: /dev/kvm does not exist
HINT:   sudo modprobe kvm_intel
INFO: Your CPU supports KVM extensions
INFO: KVM (vmx) is disabled by your BIOS
HINT: Enter your BIOS setup and enable Virtualization Technology (VT),
      and then hard poweroff/poweron your system
KVM acceleration can NOT be used

如果 BIOS 已正確啟用硬體支援虛擬化技術,則會顯示以下 ok 訊息。

INFO: /dev/kvm exists
KVM acceleration can be used

使用 virt-manager 管理虛擬機器

透過 X11 forwarding 的 SSH 連線到 server 執行 virt-manager,或是在 Ubuntu Desktop 安裝 virt-manager 並設定 remote connection。


預設的儲存方式是 Image-based,也就是在現有的磁碟系統上增加磁碟映像檔;如果需要更好的磁碟效能,則可以用 LVM。

利用 system-config-lvm 簡化 LVM 設定。

sudo apt-get install system-config-lvm


在 virt-manager 的 Edit / Connection Details / Storage 可以增加 LVM Storage 設定。

使用 virt-manager 建立新的虛擬機器,開始安裝作業系統。


接下來,Linux Server 一台可以當多台用了 : )

參考資料

http://sealmemory.blogspot.tw/2012/03/ubuntu-linux-kvm.html
http://www.howtoforge.com/virtualization-with-kvm-on-ubuntu-12.04-lts
http://vitobotta.com/setting-up-kvm-lvm-virtual-machine-host/
http://www.linux-kvm.org/page/Networking
lyhcode by lyhcode
歡迎轉載,請務必註明出處!