群件很強大也很重要。如果需要,可以購買一個群件系統。或者可能是一個集群 —— 有一個使用了 RAID 的專用的數據庫服務器,以及磁帶備份的保證,還有單獨的機器來運行界面。為什麼?當然是因為它更可靠,而且可以根據負載擴展!
不過,您可能不會處理非常多的調度任務,以至於需要使用消耗大量內存的應用程序。可能只是需要某種基於 Web 的日程表界面,以及核查需要做的項目的能力。
可能並不需要 30 兆字節大小的類庫、由一組本體專家(ontologists)來設計對象模型,或者依賴 15 個其他軟件包。這裡是我的目標:盡可能只使用系統附帶的功能來運行那些應用程序。
業務的第一個步驟
首先,需要確保老機器可以運行某個 Web 服務器和某些 CGI 腳本。方便的是,我們的機器已經擁有了一個 Web 服務器,其根位於 /var/www/htdocs.檢查配置文件(/etc/apache/httpd.conf),可以發現默認把 ExecCGI 和 Includes 都關閉了 —— 不過我想把它們打開,讓我的 Web 頁面華麗而生動。
之後的 Options 那一行是相關的設置。我添加了 ExecCGI 和 Includes 選項。如果沒有服務器端解析的文件的支持,Includes 不會做什麼事情;在 httpd.conf 中有一些注釋掉的行將完成此任務。我去掉了這三行的注釋(但仍讓那些真正的注釋保持被注釋):
[...]
AddHandler cgi-script .cgi
#
# To use server-parsed Html files
#
AddType text/html .shtml
AddHandler server-parsed .shtml
[...]
完成後,執行 apachectl restart,讓 Apache 重新加載其配置文件。為節約以 root 身份登錄的時間,可以將 /var/www/htdocs 的所有者設置為您的個人帳號。我這樣做了,而且還刪除了在線手冊和默認的索引頁。
在計算機科學中有一句諺語,“百分之十的工作可以解決百分之九十的問題”。就此想法,我為這個應用程序制作了一個首頁草稿,囊括了這個程序預期的主要工作:
Yo! Do the dishes.
現在只需要測試 CGI 處理。我的測試叫做 env.cgi,並不大,但是很實用:
#!/usr/bin/perl -w
use Env;
use CGI;
print "Content-Type: text/plain\n\n";
foreach $k (sort keys %ENV) {
print "$k: $ENV{$k}\n";
}
exit 0;
您會注意到,我實際上並沒有使用 CGI 模塊;之所以引用它,是為了確保它已經安裝。將它放在適當的位置,我可以確認 CGI 腳本正在運行。我將機器在網絡上命名為“crate”,所以,對 http://crate/env.cgi 的訪問結果如我所想:
[...]
REMOTE_ADDR: 205.166.146.66
REMOTE_PORT: 62594
REQUEST_METHOD: GET
REQUEST_URI: /env.cgi
SCRIPT_FILENAME: /var/www/htdocs/env.cgi
SCRIPT_NAME: /env.cgi
SERVER_ADDR: 205.166.146.93
SERVER_ADMIN: [email protected]
SERVER_NAME: crate.plethora.net
SERVER_PORT: 80
SERVER_PROTOCOL: HTTP/1.1
那非常有利於調試 —— 它發現我那部分有一個錯誤。我忘記去修改 httpd.conf 中的 ServerAdmin 行了。很容易修改。您的用戶名不存在。請走開。
安全性是早期出現的問題之一。您不會希望讓所有人都可以留下關於午餐所有者的危險記錄。進入訪問控制。
這需要對 httpd.conf 進行更多修改,允許 .htAccess 文件限制對站點的訪問。那表示要向允許訪問列表中添加“Limit AuthConfig”,覆蓋頂層配置文件。
接下來需要一個 .htaccess 文件。從這裡開始:
AuthUserFile /var/www/htpasswd
AuthGroupFile /dev/null
AuthName "Roommates Only"
AuthType Basic
require valid-user
htpasswd 文件並不是以普通形式存在於文檔樹中。那樣做是有目的的;不能為攻擊者創造有利條件。可以使用 htpasswd 命令初始化 htpasswd 文件:
# htpasswd -c ./htpasswd seebs
New passWord:
Re-type new password:
Adding password for user seebs
-c 選項讓 htpasswd 創建一個新文件。當創建另外的用戶時不要使用它;否則,只有最新的用戶才能夠登錄。完成後,嘗試訪問頁面將會要求輸入口令。給出用戶名和密碼,然後就能進入了。 $REMOTE_USER 將被設置為用戶名,以使得腳本可以知道誰在使用它們。
我不喜歡漫長的告別
於是,您可以登錄進入。不能登錄出去 —— 出於未知的原因,多數浏覽器通常不允許刷新所請求的用戶名/口令組合的內存。可以刷新 cookies,可以刷新緩存 —— 但是浏覽器可能仍然認為它知道您要做什麼。
所以,如果登錄到公用的計算機,那麼在離開之前一定要關閉整個浏覽器。否則,人們可能碰巧會看到您的家務雜事列表,而不是他們自己的,這樣就會出笑話了。如果這確實是個問題,那麼可使用 cookies.
盡管如此,這使得系統允許用戶使用他們自己的用戶名登錄,對於讓用戶添加記錄來說就足夠了。只要有添加記錄的途徑!
室友記錄
實現此目標的基本概念很簡單:公開地張貼有時間標記的消息,用戶可以讀取。 Berkeley msgs 工具剛好是所需的復雜程度(也就是說,幾乎根本就不難)。每個文件將包含一個名稱、一個時間標記以及一些文本。系統將向用戶顯示特定時間段的消息,或者將用戶最後一次訪問之後張貼的消息顯示給他們。
要讀取的消息的數目應該暫時不重要,所以我將使用最簡單的所有文件格式:目錄中的全部文件,每個文件中,第一行是一個時間標記和一個用戶名,然後是一些文本。這甚至不需要為文件准備數據庫;文件系統的靈活性就足夠了。(您可能會問我為什麼不直接使用文件系統中的時間標記;答案是我並不相信它,因為粗心的用戶會破壞它。我的很多目錄中所有的文件都擁有相同的時間標記。)我確實需要某種類型的數據庫,用於用戶以及他們的最近的時間標記,所以每個用戶都將擁有一個數據文件,現在其中包含有一個時間標記。
整個項目很小,只使用一個 CGI 腳本就可以借助 Perl 的標准 CGI 模塊來實現。目標是折衷所需附加代碼(盡可能少)以及所需開發時間(盡可能短)。在本例中,系統所附帶的功能是足夠的。
/var/www/msgs 是一個新目錄,用於保存消息(以數字命名的文件)和用戶記錄(使用 .htaccess 文件中給出的用戶名作為文件名)。CGI 腳本會識別自身,執行被請求的動作,並展現出相當簡單的界面;它所需要的只是一些按鈕和一個文本區域。 為了表示尊敬,這個腳本命名為 msgs.cgi.
開發過程中涉及了一些設計方面的考慮。
甚至不需要去解析日期,因為在大部分情況下可以簡單地讓用戶使用按鈕(最近 24 小時、上一周、自上一次訪問,以及所有消息)。
以數字為名稱的文件可以簡單地由內置的 glob 來識別,它能夠方便地整理文件。不過,如果數字的位數發生了變化,整理就會發生錯誤,所以要給出前導的零。腳本並沒有精心地去分辨主題,而只是為每條消息的第一行使用了 H3 標簽。程序假定輸入消息的全部 HTML 都是沒有惡意的。如果室友沒有足夠的幽默感,那麼用戶在寫入時應該仔細檢查。
這個腳本非常短小,只有 2K 多一點。不過,它也有潛在的開銷,因為 CGI 庫實際上很大。但是相對於更大的系統,它還是非常小的,而且它提供了一個適當的途徑讓用戶張貼消息並讓其他人方便地進行查看。
圖 1. 盡管針對室友的記錄的實現方法發生了變化,但其基本特性沒有發生變化
可能以後會開發某些方法來指定時間范圍或搜索函數。最好也要有刪除較老消息的方法。雖然如此,相對於貼在冰箱上的淡黃色便箋,這是一個可靠而實際的創新。
誰知道 Sam 去哪兒了?
偶爾室友的問題會是他們到底去哪裡了。我並不是要討論,當要付房租或者分擔公共費用時,某些人卻不得不離開房間 —— 而只是說某個人,比如一個朋友,打電話過來問“您知道他在哪兒嗎?”或者“您知道他什麼時候回來嗎?”
要說有什麼不同之處,那麼就是這個腳本更短小,寫起來更簡單。遵循相同的基本方法:只需要創建名字為用戶名的文件,其中包含有時間標記、可能要離開多少小時以及簡短描述。然後,每找到這樣一個文件,打印一個簡要描述。
“I'm back!”按鈕會刪除那個文件,因為可能人們並不需要知道您曾經 在哪兒(如果有意外,這有助於證明您不是幫凶)。與之相對照,能知道某人曾經要去哪裡是 有用的,所以文件不會因為變成老文件而被刪掉。
我覺得一個好的、簡單的群組日程安排軟件非常類似於 Harry Potter 叢書中 Weasley 的起居室裡的那個時鐘。它有九個黃金指針,每個上面刻有一個家庭成員的名字。邊緣上沒有數字,而是標記為位置和狀態 —— 家、工作、學校、旅行、走失、致命危險,等等。(還有一個廚房時鐘,它有一個指針以及“time for this”和“you're late”標記。)
日程計劃任務
所需要的最後一件事情是日程計劃。我們如何處理家務事的常規提示?輪到誰來洗衣服?輪到誰來涮碗?不需費力就可以定期地安排這些任務。
處理垃圾可能對每個人來說都是瑣碎的工作,但是我們所需要的只是張貼公開提示的某種方法。現在您應該對此有了一些想法。當然是使用另外一個腳本以及它自己的自定義數據庫文件。
只是目前還不需要它。這個項目的難點在於調度任務。要編寫能夠表達類似於“every Thursday is trash night”或“someone needs to do the dishes every night”等想法的代碼一點都不簡單。
不過這些代碼已經編寫好了,叫做 cron.我們所需要的只是公布消息的某種途徑。可以知道,為本月項目的第一部分已經編寫的消息程序,可以正確地滿足我們的要求。為消息目錄賦與寫權限(例如,root 有令人羨慕的特權),嘗試這個命令:
$ REMOTE_USER=bob /var/www/htdocs/msgs.cgi
"action=Post Message" "message=Test message"
現在,去查看那些消息。很酷,不是嗎? 已經能夠通過運行命令添加新消息,也就是說 cron(可以根據日程安排運行命令)滿足了我們全部的需求。
有一個小型的 Web 界面來創建這些任務可能會更好,但是由於這些東西很少修改,所以可能並不需要。這將處理所有需要常規提示的任務。不需要常規提示的任務可以手工輸入,或者使用 at(1) 設置為在適當的時候輸入。
總結與說明
本月支出為 $0,這非常好。沒有進行任何下載,只是要在本地進行一些輸入。應用程序有一些簡單,但是它們能完成應該做的事情,而且代價低廉。
進一步講,它們足夠簡單,能方便地更新。最大的弱點是安全性;沒有投入任何精力來保護這些程序不受最常見入侵的危害。其中一方面原因是,在大部分情況下那不是個大問題。
不過,如果您計劃與懂技術的室友一起使用這些,那麼有很多種方法可以讓程序更加安全。例如,如果不允許通過命令行運行 msgs.cgi 腳本,那麼需要考慮使用另外的方法來調度任務。(實際上有一個非常簡單的方法,就是使用命令行浏覽器以及精心構造的 URL,這些留給讀者去練習)。
古老的機器 的下一篇文章:使用 Web 頁開燈。可用的 x10 硬件和 Linux 驅動程序使得我們能夠完成所有那些有用的事情,比如在起床前半小時打開咖啡壺(coffee maker)。