2013年8月3日 星期六

一歲的偽天龍人

night market

在台北不知不覺過了一年了,想起來也算是退伍一年,更仔細想想這一年似乎沒什麼成長?總是太餓了嗎?還是太蠢了呢?

回想起來,從萬華這邊起頭似乎很有緣分,扣除房東外,第一個跟我交談的是水電工,輕描淡寫地說住在這邊不要多想什麼,堅定正派信念,更要懂得珍惜長者。很妙地這些正不是資訊業的縮影?大家自恃著擁有搜尋引擎、開源碼,前輩們的價值以超過指數速度狂降,更別說生活上的大小事,都是先 Google 再說 :P 但一個銅板拍不響,也存在非常非常多的前輩只扛著年資討生活。

有一陣子我總想 PTT 上曾出現過的跑馬燈:「人人都想拯救世界,但是沒人幫媽媽洗碗…」,這句話含義真的很深很深。當我有機會陪家人時,發現自己也因此沒有多餘的行動力,一天總是只有那 24 小時,所以,這句話更重要的提醒是等價交換。極端點就是幫媽媽洗碗無法讓你拯救世界。

此外,想起市場規模的影響,年輕人回鄉不是壞事,以鄉村的角度是多了人力、青春活力,但以年輕人的角度來看,可能會因為缺少特別的資源而局限自己的長才,讓我想起跟一位上海 RD 聊天,他總說著有機會真的要去上海走一趟!以 Set-top box 來說,台灣最猛的頂多 400萬用戶,一年淘汰也了不起 20~40萬裝置,而每年的裝置可以養多大的公司?而大陸光一個省就超過了!這件事也讓我想起周邊一個雲端案例,用了 Hadoop/HBase 作出不錯的模組,但最後卡在台灣用量沒那麼多,真正會買單的客戶少,最後也終究遠離家鄉。這些例子或許都是特例,卻也紮實地說明了目前台灣有些東西為何如此。

經過這一年奇妙的旅程及回顧,讓我的思緒越來越清楚了。生活化的角度是要珍惜青春,但不必整天計較著付出就一定要得到什麼,卻也別忘了想要得到什麼就必須捨棄東西。

2013年8月1日 星期四

[Python] 使用 Bottle 開發簡易 CGI Prototype @ Ubuntu 12.04

Python Bottle 提供 web server 與簡易的 MVC framework 服務(或許稱不上MVC架構),且 bottle 單純只是一個 python 檔案而已,十分輕巧,姑且不論效能,但應該稱得上是個不錯的測試、製作 prototype 的好工具。

常見的簡易 Web server 用法:

$ cd /path/workdir
$ python -m SimpleHTTPServer


安裝 bottle (單純下載單一檔案):

$ wget --no-check-certificate http://bottlepy.org/bottle.py


撰寫相關程式碼(main.py):

from bottle import Bottle, request, response, run

import json
#import sqlite3
#conn = sqlite3.connect('/tmp/example.db')


app = Bottle()

@app.route('/test')
def test():
        out = { 'status': True }
        #print request.headers
        response.headers['Accept-Ranges'] = 'none'
        return json.dumps(out)

@app.route('/')
def rootTest():
        out = { 'status': True }
        out['request.url'] = request.url
        out['request.urlparts'] = request.urlparts
        out['request.fullpath'] = request.fullpath
        out['request.query_string'] = request.query_string
        out['request.script_name'] = request.script_name
        out['request.content_type'] = request.content_type
        out['request.is_xhr'] = request.is_xhr
        out['request.is_ajax'] = request.is_ajax
        out['request.auth'] = request.auth
        out['request.remote_route'] = request.remote_route
        out['request.remote_addr'] = request.remote_addr
        response.headers['X-My-Resonse-Header'] = 'none'
        return json.dumps(out)

run(app, host='127.0.0.1', port=8000)


執行:

$ python main.py
Bottle v0.12-dev server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:8000/

Hit Ctrl-C to quit.


如此就有一個包含 web server 跟簡易 APIs 可以被呼叫測試,並且不需去安裝 web server、處理 python cgi 等問題,十分方便啊。

此例執行結果:
提供 http://127.0.0.1:8000/test 位置,並回傳 {"status": true} 資料。

[Linux] 使用 C/C++ 撰寫 FastCGI 與 Nginx 設定筆記 @ Ubuntu 12.04

大概有半年了,跟 fastcgi 與 nginx 的淵源還不斷地繼續著,不過,開始更有機會真的用 C/C++ 寫 Fastcgi 啦,在此簡易筆記用法

/etc/nginx/sites-enabled/fcgidev:

server {
  listen 55688;

  root /tmp/fcgidev;
  client_max_body_size 0;

  location /fcgi {
    fastcgi_pass 127.0.0.1:55699;
    include /path/etc/fastcgi_params;
  }

  location / {
  }
}

用 C 撰寫 (https://github.com/changyy/fastcgi-study/blob/master/fcgi/main.c):

#include <stdlib.h>
#include <fcgi_stdio.h>

#define CGI_HEAD_BODY_SEPARATOR "\r\n\r\n"
#define CGI_CONTENT_TYPE_TEXT_HTML "Content-type: text/html"
#define CGI_CONTENT_TYPE_APPLICATION_JSON "Content-type: application/json"
#define CGI_WELCOME_HEAD CGI_CONTENT_TYPE_TEXT_HTML
#define CGI_WELCOME_BODY \
"<html>\
<head>\
<title>Hello FastCGI</title>\
</head>\
<body>\
<h1>Hello FastCGI</h1>\
</body>\
</html>"

int main(int argc, char** argv)
{
int count = 0;
while(FCGI_Accept() >= 0)
{
printf(
CGI_WELCOME_HEAD
CGI_HEAD_BODY_SEPARATOR
CGI_WELCOME_BODY
);
}
return 0;
}

編譯:

$ gcc -o fcgi-out main.c -lfcgi 

用 C++ 撰寫(https://github.com/changyy/fastcgi-study/blob/master/fcgicc/main.cpp):

#include <cstdlib>
#include "cgicc/Cgicc.h"
#include "cgicc/HTTPResponseHeader.h"
#include "cgicc/HTMLClasses.h"
#include "FCgiIO.hpp"

#define CGI_WELCOME_BODY \
"<html>\
<head>\
<title>Hello FastCGI</title>\
</head>\
<body>\
<h1>Hello FastCGI</h1>\
</body>\
</html>"

int main(int argc, char **argv)
{
if (argc < 2) exit(1);

FCGX_Request request;
FCGX_Init();
FCGX_InitRequest(&request, 0,0);

while(FCGX_Accept_r(&request) == 0)
{
try
{
cgicc::FCgiIO io(request);
cgicc::Cgicc cgi(&io);

cgicc::HTTPResponseHeader resp("Status:", 200, "OK");
resp.addHeader("Content-Type", "text/html");
io << CGI_WELCOME_BODY;
}
catch (std::exception const &e)
{
}
FCGX_Finish_r(&request);
}
return 0;
}


編譯:

$ g++ -o fcgi-out main.cpp FCgiIO.cpp -lfcgi -lcgicc -lfcgi++

執行:

$ spawn-fcgi -a 127.0.0.1 -n -p 55699 -F 1 -- fcgi-out /tmp

2013年7月29日 星期一

nginx worker process exited on signal 7 @ ARM & LOA

嵌入式就是這麼奇妙!nginx 在 x86 可以穩穩跑、在 ARM-based 的 linux 也能穩穩跑,但是在 LOA 上頭就是會收到 signal 7 訊號而掛掉!

最後則是想要編 debug 訊息來用,意外發現 -O0 時就一切正常了!

故,最佳化這種事,還是小心為妙。

Scripting Nginx with Lua (lua-nginx-module) 筆記 @ Linux

最近常用 nginx 開發服務,接著又碰碰 lua 的部分,十分彈性。接下來,移植到 ARM 裝置後,就開始進入 debug 模式 XD 需要追蹤一些 requests 的流向,又想到 lua 啦

nginx-test.conf

  location /lua {
    default_type 'text/plain';
    content_by_lua '
        local currtime = ngx.localtime()
        local file = io.open("/tmp/nginx_lua.log", "a");
        file:write(currtime, "\\t", ngx.var.uri, "\\n");
        file:write("\\t", ngx.var.args, "\\n");
        file:close();

        ngx.print(currtime, "\\n");
        ngx.print(ngx.var.uri,"\\n");
        ngx.print(ngx.var.args,"\\n");
        --ngx.print(ngx.var.request_body, "\\n");
    ';
  }


/tmp/nginx_lua.log:
2013-07-29 04:19:07     /lua
        a=1&b=c&d


Web:
2013-07-29 04:19:07
/lua
a=1&b=c&d


如此一來,當 request 進來時,可以查看 /tmp/nginx_lua.log 看看到底走了幾個 requests,留意項目:

  • 在 content_by_lua 中,要印出 newline 必須用 ngx.print( "\\n" ) ,但如果是在 access_by_lua_file 中,只需 ngx.print( "\n" ) 即可。
  • 註解是用 "--" 而非用 "#" 或 "//" 開頭