歷史的痕跡

當你在撰寫一隻程式的時候,你腦中會有與該程式相關的背景知識,這是你透過瞭解這隻程式的過程中獲取而來的寶貴資料。當你要讓這隻程式產生變化之時,你得要從另外一個角度來觀看,從一個陌生人的角度,觀察這隻程式產生的變化,對這個陌生人而言有什麼意義!

例如你想要依照不同的資料做不同的處理,而你深刻的理解這兩種狀態的差異性,但!對這陌生人可不然~所以你需要留下可被追尋的痕跡,因為你在創造歷史,而你得告訴後人,為何要做這樣的決策,你可以試著用各種方式給予暗示。

註解,變數名稱,函式名稱~等等,這些可以具有意義的紀錄點~在這些地方留下深刻的印記。


<form><input type="text" name="name" /></form>

//type 1

if( $name == 'apple' || $name == 'orange') {
$db->insert('fruit', array('name', $name));
}
else if( $name == 'dog' || $name == 'cat') {
$db->insert('animal', array('name', $name));
}

//type 2

if( $name == 'apple' || $name == 'orange') {
   $type = 'fruit';
}
else if( $name == 'dog' || $name == 'cat') {
   $type = 'animal'
}
$db->insert($type, array('name', $name));

透過多命名一個稱為 $type 的變數,讓未來看見這隻程式的人,可以清楚的知道,name 有分成兩種 type ……是吧?!。。。

reverse proxy

reverse proxy ,proxy 伺服器,可以將外部連線導入到內部網路的 web 伺服器,搭配 nat 可以隱藏內部網站,如果 load blancer 效果~
只是效能可能會卡在入口站的 網路 或 效能~

apache

<VirtualHost *:80>
     ServerName apple.tw
     ProxyRequests Off
     ProxyPreserveHost On
     ProxyPass / http://192.168.8.10/
     ProxyPassReverse / http://192.168.8.10/
 </VirtualHost>

nginx

   proxy_redirect     off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_max_temp_file_size 0;

    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;

    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;

    server {
        listen  80;
        server_name apple.tw;
        location / {
          proxy_pass http://192.168.8.10/;
        }
    }

用 ab 實際測試 apache 跟 nginx 的差異 ,在我的環境下都超慢的,感覺是虛擬機的設定有問題,

只是在近端網路測就比較正常了,且在 -c Number of multiple requests to make 越高的情況下, nginx 的表現竟然反而比較好,在低的情況下就都差不多。

好像是 catch 設定的問題..每次測都有點不一樣。

nginx and django

nginx (Engine X ) 是比 Apache 小巧快速的網頁伺服器,設定上相對沒有那麼強大與複雜。

Apache 是採用行程池運作比較消耗資源,而 nginx 則是 event based,不會依照 request 生成 process or thread。

下載網址:http://nginx.org/en/download.html

只是操作起來比較不熟悉,跟 apache 用 service 的方式比較不同,所以比較不親和一點…但是相對來說設定的細節都比較容易

設定檔在 /etc/nginx.conf

nginx 當初是為了 reverse porxy 所設計的,所以在 r-proxy 上理當應該比 apache 為更適當的選擇[1]


$ nginx # 啟動

$ nginx -t # 檢查設定檔格式是否正確

$ nginx -s [stop|reload|...] # 送訊號給正在執行的 nginx

可以用 fastcgi 搭配 django 運作,

可以額外 include 一個 django 的設定檔,內容如下:

server {
        listen  80;
        server_name server.com;
        location / {
            fastcgi_pass unix:/home/www/server.sock;
#           fastcgi_pass 127.0.0.1:8000;
            include     fastcgi.conf;
            access_log  /var/log/nginx_django.log;
        }
}

然後用 django 內建的 server 跑 fastcgi 模式,就能讓 django 跟 nginx 接起來囉。

$ kill `cat /home/www/server.pid`
$ python ./manage.py runfcgi method=threaded \
          socket=/home/www/server.sock pidfile=/home/www/server.pid

這邊指定用 thread 的方式跑,然後把 socket 建在該檔案位置,用在重開的時候要用,這個 socket 位置對應到上面的 nginx 設定的 socket 位置,
也可以跑在某個 port 上面去對應,只是用檔案的方式好像比較安全?!..我也不太懂=_=
另外 django 內的 fastcgi.conf 內要注意一點:

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

<strong>fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;</strong>
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

<strong>fastcgi_param  PATH_INFO          $fastcgi_script_name;</strong>

粗體的設定是 django url 在 route 會用來判斷的變數要設定對。
然後在專案內的 setting.py 的裡面加上 FORCE_SCRIPT_NAME=”/”
原因跟上面 route 路由規則有關,否則網址倒頁的時候會出問題。 參考資源:

nowjs 伺服器(Server)建立函式,用戶端(Client)呼叫,即時系統

githubhttp://nowjs.com/

這個新的 module 做了一件有趣的事,由於 node.js 在伺服器寫 js 已經蠻酷的,進一步應該很多人都會聯想到,要怎麼在伺服器跟瀏覽器上共用已經寫過的 js 函式。

也有些人提出了一些方法來做,可以做一些簡單的判斷來做目前環境是瀏覽器或是伺服器來做不同的處理。

而這個 nowjs 主要主打的是在伺服器寫一個 function,你可以在瀏覽器端呼叫到,已經頗有趣的以外,呼叫到能幹麼呢?

主要就是傳訊息,你可以直接在 client 端呼叫伺服器的函式,並同時在伺服器呼叫一個函式,等同於呼叫 client 端的函式,達到廣播到所有使用者端的效果,其實基於web socket 就能達到這個效果,但能想出這個介面並設計出來也還頗有新意的。

跟之前有 lib 做到 php 在伺服器端建立 ajax 的概念有點類似,想要簡化 ajax 要寫 js 對某些人所帶來的[[困擾]],但這個實現我看起來覺得蠻失敗的..

但這概念搬到 nodejs 的世界來反而有不一樣的出發點,因為這邊沒有在想說這是件麻煩,而是達到用 js 做到跨前後端的假象…

但要小心要是做的太漂亮,反而容易讓新手搞不懂前後端的分別了…其實 nodejs 對 web 新手來講應該不是一個好玩具…

這部份未來倒是可以發展一下…讓開發變得更適合新手應該比較容易推廣

範例:

//server
var everyone = require("now").initialize(httpServer);
//建立一個函式 供 client 呼叫 , 並呼叫一個 client 的函式
everyone.now.distributeMessage = function(message){
  everyone.now.receiveMessage(this.now.name, message);
};
//client
<script type="text/javascript" src="http://localhost:8080/nowjs/now.js"></script>

<script type="text/javascript">
  $(document).ready(function() {
    now.name = 'mlwmlw';
    now.distributeMessage('hello');
  //設計一個函式讓 server 可以呼叫= =?
    now.receiveMessage = function(name, message) {
        alert(name + ':' + message);
    };
});

以下是官方教學影片…

參考資源: