星期日, 10月 18, 2009

PHP 裡抓出當月的第一天第一秒鐘,以及下個月的第一天第一秒鐘 (也就是當月最後一秒的後一秒)

PHP 時嘗試了不少方法,看起來這個方法是比較簡單的:
function getMonthPeriod()
{
# 用台北時間計算
date_default_timezone_set('Asia/Taipei');

# 取出本月的第一天
$beginTime = mktime(0, 0, 0, date('n'), 1);

# 取出下個月的第一天
$endTime = strtotime('+1 month', $beginTime);

return array($beginTime, $endTime);
}

星期二, 7月 21, 2009

Squid based reverse proxy tuning

這兩天測試的感想。

不管怎麼 tune,軟體要先選對,不然 tune 起來就很悶了...

Lusca 是改自 Squid 2。Squid 2 因為很多人使用過很長一段時間,所以有很穩定的 codebase (先不管是不是 dirty hack 堆出來),Lusca 則是在 Squid2 的 codebase 下改善效能,用了一年多 (之前 Lusca 的專案名稱叫做 Cacheboy),的確很穩定。

Squid 3 對 CPU 的使用率低很多,但就我自己用的感覺,在 reqs/sec 很高的時候穩定性不太好。另外因為 Squid 3 改寫了很多東西,所以有些重要的功能反而不見了。(像是 cache_peer 的 monitorurl 設定)

雖然 Lusca 在 high reqs/sec 時 CPU usage 高很多,但就目前的 CPU 應該都夠用。就目前其中一台 E5345,上面跑 250reqs/sec 大約吃單顆 30% CPU usage。

比較需要特別提出來的是,在 reqs/sec 很高時,accesslog 寫入反而會變成效能的瓶頸。在 Lusca 可以使用 logdaemon 解決 (這個功能 merge 回 Squid 3.1 了):
access_log daemon:/home/logs/squid/access.log squid
cache_store_log daemon:/home/logs/squid/store.log
logfile_daemon /usr/local/squid/libexec/logfile-daemon
這樣 write log 就不會使 Lusca 卡住而反而造成 CPU bound。

星期四, 7月 09, 2009

修正 mod_fastcgi 在 threading 環境下會 coredump 的 bug

PIXNET 我們是用 Apache 2.2 MPM worker + mod_fastcgiPHP,但從以前就發現 httpd 會自己死掉,雖然 parent httpd 會再把他叫起來,但會造成已經連上的 connection 斷線。

昨天花了一個下午的時間追這個 bug,後來發現是 mod_fastcgi 使用 getgrgid()getpwuid() 的原因造成的,這兩個 function 在 FreeBSD 上並不是 thread-safe function,在 Open Group 的文件也說明這兩個 function 不需要 thread-safe。

所以這兩個 function 必須用 getgrpid_r()getpwuid_r() 改寫。

除了把 patch 送到 FastCGI mailing list 上讓人確認外,這邊也放一份好了:
--- fcgi_util.c.orig    2009-07-08 17:16:29.816884000 +0800
+++ fcgi_util.c 2009-07-09 08:43:09.222180000 +0800
@@ -268,13 +268,17 @@
/* Get the user membership for the file's group. If the
* uid is a member, check the group bits. */
{
- const struct group * const gr = getgrgid(statBuf->st_gid);
- const struct passwd * const pw = getpwuid(uid);
+ char buf[1024], buf2[1024];
+ struct group gr, *r;
+ struct passwd pw, *r2;

- if (gr != NULL && pw != NULL) {
- char **user = gr->gr_mem;
+ getgrgid_r(statBuf->st_gid, &gr, buf, sizeof(buf), &r);
+ getpwuid_r(uid, &pw, buf2, sizeof(buf2), &r2);
+
+ if (r != NULL && r2 != NULL) {
+ char **user = r->gr_mem;
for ( ; *user != NULL; user++) {
- if (strcmp(*user, pw->pw_name) == 0) {
+ if (strcmp(*user, r2->pw_name) == 0) {
if (mode & R_OK && !(statBuf->st_mode & S_IRGRP))
return "read not allowed by group";
if (mode & W_OK && !(statBuf->st_mode & S_IWGRP))
@@ -445,8 +449,9 @@
{
#ifndef WIN32

+ char buf[1024];
struct passwd *pw;
- struct group *gr;
+ struct group gr, *r;

if (fcgi_wrapper == NULL)
return NULL;
@@ -467,14 +472,14 @@
s->username = s->user;

s->gid = gid;
- gr = getgrgid(gid);
- if (gr == NULL) {
+ getgrgid_r(gid, &gr, buf, sizeof(buf), &r);
+ if (r == NULL) {
return ap_psprintf(p,
"getgrgid() couldn't determine the group name for gid '%ld', "
"you probably need to modify the Group directive: %s",
(long)gid, strerror(errno));
}
- s->group = ap_pstrdup(p, gr->gr_name);
+ s->group = ap_pstrdup(p, r->gr_name);

#endif /* !WIN32 */

星期一, 5月 25, 2009

mod_blocking

最近寫出來幾個東西,其中一個是 apache module,目前命名為 mod_blocking。在 apache 2.2 worker MPM (multi-threading 環境) 下透過 .htaccess 設定阻擋可能的攻擊行為。(像是灌票,或是衝人氣)

寫這個東西時學習到 libmemcached 的用法,以及目前 libmemcached 在 multi-threading 環境下的限制。另外熟悉 apr 的用法,不過比較可惜的是 apr 的 license 使得無法用他開發軟體。再來就是複習 multi-threading 環境要注意的資源共用問題。

第一個版本的 mod_blocking 已經暫時告一段落,不過裡面有大量的 PIXNET only code,還要再找時間慢慢把這些 hard 的部份改寫成變數讀入... 另外已知我使用 libmemcached 的方式會 memory leak,不過速度還可以接受,就暫時不管他了...

星期六, 5月 23, 2009

造輪子

當 scale 愈來愈大的時候就很明顯感覺到 open source 的技術不夠用,有很多東西要自己開發。在找方向時會看到很多公司都在造輪子...

像是 Google 很早就造了 Chubby,分散式且高可靠度的 lock service,被用在 GFSBigTable 裡 (這兩個也是造出來的輪子)。Yahoo 把造 Hbase 的人找進去,把 Search 的架構轉換過去,Amazon 也造了 Dynamo,被用在購物車與 Amazon Web ServicesFacebook 造了 Cassandra 把搜尋功能換上去。

所以這陣子也得開始造輪子了。所有的東西都是一層疊一層,想要土法煉鋼建出高樓大廈是不可能的,一定得每層都很穩定。

星期六, 2月 07, 2009

startup 與 copy

37signals 上的「Why you shouldn't copy us or anyone else」這篇文章提到 startup 的事情,在工作時遇過許多人後特別有感覺。

其實只是學校裡已經用到爛「知其然不知其所以然」的觀念,只是大多數的人沒有把這件事情練成直覺而身體力行:(上面那篇文章裡提到的段落)
Here’s the problem with copying: Copying skips understanding. Understanding is how you grow. You have to understand why something works or why something is how it is. When you copy it, you miss that. You just repurpose the last layer instead of understanding all the layers underneath.
還蠻有感觸的文章。

星期日, 2月 01, 2009

新的 Gearmand

在「FreeBSD 上的 Gearmand」提到了用 C 重寫的 Gearmand,實際測試發現還是有一些問題:



worker 的 CPU 會愈吃愈兇,看起來是 pooling 的 bug 造成的。所以後面就先換回 p5-Gearman-Server 了。

過年放假...

這個年過的真不舒服,發生了一些鳥事情 XD

機房某個機櫃的 400KVA 的排插 (110V),上面只接了四台 1U 伺服器,過年期間跳電了... 事後量測發現上面有 9.4A (低於負載值不少,但比預期的高了許多),因為這組排插是大約半年前新加的,可能是排插問題,打算請機房換一隻...

懷疑某組 NAT server 有問題,造成連某個站台一直不順,後來決定換成 pfSense,用過 pfSense 的介面後突然有「當初幹麼買 hardware NAT server」的想法,結果換完後問題還是沒解決,看起來是外部站台有問題,白做不少功。

過完年後有一堆 paper work 要處理,想到就頭痛...