tag:blogger.com,1999:blog-92153501406152088282024-03-05T15:54:04.757+08:00ScrumFall MasterVanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.comBlogger37125tag:blogger.com,1999:blog-9215350140615208828.post-22206098825026981862020-04-05T11:00:00.004+08:002020-04-05T11:00:52.154+08:00redis 的 cache stampede之前就大概有稍微看了一下 cache stampede 的文章,也大概知道了 xfetch 這個東西,<br />
但是一直都沒有仔細下去看,因為覺得問題不大,<br />
<br />
直到剛好看到這篇<br />
<br />
<a href="https://kkc.github.io/2020/03/27/cache-note/">https://kkc.github.io/2020/03/27/cache-note/</a><br />
<br />
<br />
裡面大概講到幾種避免的方式:<br />
<br />
<ol>
<li>弄個 cronjob/worker 定期去更新,這就犯了一個常見的問題。</li>
<ol>
<li>cache 到底是 cache 還是 storage?</li>
<li>如果是 cache,那他應該是 on demand 的才對吧?</li>
<li>cache fail 了,程式應該要知道怎麼 fallback!</li>
<li>既然是兩個地方都要處理同樣的邏輯,程式的架構是寫死在一個地方,還是寫成 component?</li>
</ol>
<li>lock 機制</li>
<ol>
<li>當大家同時遇到某個 cache expire 了,就用 lock 來搶吧!</li>
<li>所以只有搶到 lock 的那個 request 可以真的 query db,其他的就在那邊 sleep!</li>
<li>那要等多久?等到天荒地老?要不要設定一個 timeout?如果 timeout 到了,還是沒辦法從 redis 拿到資料該怎麼辦?一樣大家進去操 db?</li>
</ol>
<li>xfetch 機制</li>
<ol>
<li>會在 query db 的時候把要花多久存下來(aka delta),之後在每次要 get cache 的時候,一次把 cache value/ttl & delta 都拿出來,先比對 delta 如果 >= ttl 的話,就預先做一次 query db,然後把資料存回來。</li>
<li>那如果同時好幾個人都 get cache,然後大家都要去 query db 呢?</li>
<li>xfetch 用了一個 random 來判斷!</li>
<li>沒錯,用 random,所以最差就是大家一起死,不然就是等到大家都 cache expire 了,再一起死!</li>
</ol>
</ol>
<div>
這些方法,聽起來都好像可以,但是真的實作起來,其實都還是怪怪的。</div>
<div>
<br /></div>
<div>
<ol>
<li>cron job 如果程式架構可以,要處理的 hot spot 也夠明確,的確能立即解決問題!</li>
<li>但是在 cloud 的時代,每個 instance 都應該是沒有狀態在上面,也不應該在上面跑 cronjob 才對。不然大家都一起跑,還不是一樣大家都戳一次!</li>
<li>lock 好像也很好,但是在很多 instance 很多 process 的狀況下,該怎麼 lock 呢?</li>
<li>有的人會說,redis 有 redlock,對,的確可以用,不過就算 lock/unlock 的時間點抓得夠好,還是會有其他的 request 在那邊等的狀況發生(不過原本 request 在等,有可能是 query db,所以無論如何都在等,無所謂)</li>
<li>xfetch 看起來是比較聰明的,但是蠢就在,他用 random 去判斷誰該做事,random ㄟ,random ㄟ!沒有更聰明的?</li>
</ol>
<div>
<br /></div>
</div>
<div>
經過一段沈思跟試驗實作之後,我覺得真正簡單又可以動的版本應該是這樣的:</div>
<div>
<br /></div>
<div>
<b>xfetch + lock</b></div>
<div>
<b><br /></b></div>
<div>
要提前 query db,但是又要想辦法讓同時間只有一個 query db 的動作!</div>
<div>
<br /></div>
<div>
那要怎樣做到這些事情?</div>
<div>
要感謝 redis 後來有 server side lua 了,可以讓你在 redis 裡面先做一些判斷,</div>
<div>
client 只要一個 packet 就可以拿到他要的結果!</div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-28754361290237549922019-06-26T20:54:00.000+08:002019-06-26T20:55:06.382+08:00[FreeBSD] UEFI boot loader with http support最近 FreeBSD 的 uefi boot loader 加上了 http protocol 的支援,<br />
<br />
但是剛出來的 code,總是有點 bug,而不幸的是,我剛好踫上了!<br />
<br />
make world; make kernel; reboot 之後,機器就卡在 boot loader 的過程,<br />
因為是 load boot loader 階段,所以連進去 boot loader 去 bypass 的機會都沒有。<br />
<br />
更難堪的是,跑在小機器上,M2 規格只有一個,不可能裝另外一個 SSD,然後把原本的掛上去偷天換日。<br />
<br />
所以想了一下,大概就是用 bootable cd,開起來之後進去 shell 裡面去處理。<br />
<br />
因為現在其實很少人會還有燒錄機這種東西,而我也討厭用 usb 去 boot,<br />
所以 N 年前就在同事建議之下,買了拉麵外接盒 (<a href="https://24h.pchome.com.tw/prod/DRAB5S-A9005B1NK">https://24h.pchome.com.tw/prod/DRAB5S-A9005B1NK</a>)<br />
可以直接將 iso 丟進去,讓他模擬成 bootable cd,很環保。<br />
<br />
下面是一些步驟,是為了以後遇到同樣的問題,我自己會忘記而記錄下來的。<br />
<br />
<br />
<ul>
<li>用 install cd 開機之後,dialog 選 shell,然後用 root login。</li>
<li>dmesg 看一看,可以查到自己的硬碟在哪個裝置上(我的機器上是 nvd0)</li>
<li>gpart show nvd0</li>
<ul>
<li>可以列出這個硬碟上面有哪些 partition。</li>
<li>我是把系統都裝在 zfs 上。</li>
<li>理論上第一個應該是 efi,第二個是 freebsd-boot,第三個是 freebsd-swap,第四個就是 freebsd-zfs 了。</li>
</ul>
<li>再來就是用 gpart 來安裝 boot loader</li>
<ul>
<li>gpart bootcode -b /boot/pmbr -p /boot/loader.efi -i 2 nvd0</li>
<li>index 是 2 的原因是, 1 => efi, 2 => freebsd-boot</li>
</ul>
<li>重開機,boot loader 就是比較舊版本的那個了。</li>
</ul>
<br />
<br />
Ref: <a href="https://ashish.blog/2018/06/freebsd-uefi-boot/">https://ashish.blog/2018/06/freebsd-uefi-boot/</a><br />
<br />Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-15323980625620070742017-05-09T10:32:00.002+08:002017-05-09T11:09:19.721+08:00[elixir] 打包以前一直都是用 exrm + exrm_rpm 做 elixir project 的 release manager,<br />
<br />
但是最近因為改用 aws,同事又偏好 ubuntu (aws 上面不是應該直接用 amazon linux 嘛?)<br />
所以得用 exrm + exrm_deb 來打包,<br />
<br />
<br />
無奈 exrm & exrm_deb 在 hex.pm 上面的版本都太舊,<br />
搭配著 elixir 1.4 都有一堆 warning,<br />
然後 exrm_deb 生出來的 deb 無法安裝,一直都會有 conffile 的問題,<br />
自己試著解,還是沒辦法搞定。<br />
<br />
觀察一下,exrm 的作者其實心力都不在 exrm 上了,他自己又搞了一套叫<br />
distillery 的 package,功用也是作 release manager,<br />
然後別人也幫他弄了一個 distillery_packager,宣稱可以產出 deb/rpm。<br />
玩弄了一下,生出來的 deb 沒有問題,systemd & upstart script 都幫你處理好,<br />
理論上裝上去就可以直接用。<br />
<br />
PS: distillery_packager 宣稱 deb/rpm 都支援,但是實際上只有 deb,rpm 還在等待有緣人送 patch。Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-23179751233980577122016-10-24T00:00:00.001+08:002016-10-24T00:02:29.040+08:00Apache Traffic Server & Varnish Cache 之我見. (Part 2)上一篇忘了講,大部分的人弄 proxy,架構應該都是像下面這樣弄的:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIRbR-m6oSa_jeX_64FSYcC5k32a-bC5oYsFvzWcBm61NH5qlhieFeb7qpyfXhboLT3O5289PTs-BRjTZ1MLQJmtkh8rzxQrxriiVAri0O6QZ3kf052mhyphenhyphenResqWx_Yf2azeRiE9oAXE3RX/s1600/mps_cdn_bad.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIRbR-m6oSa_jeX_64FSYcC5k32a-bC5oYsFvzWcBm61NH5qlhieFeb7qpyfXhboLT3O5289PTs-BRjTZ1MLQJmtkh8rzxQrxriiVAri0O6QZ3kf052mhyphenhyphenResqWx_Yf2azeRiE9oAXE3RX/s400/mps_cdn_bad.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
流量由 l4 load balancer 導入,可能用 round robin 或者是一般的 hash 將流量散到各台去,這樣會有幾個問題可能發生:<br />
<br />
<ol>
<li>如果是 round robin,任意一個 url 都可能導到任意一台,假設我有 100 台 storage,如果很不幸的每次都是導到沒有 cache 的某台 storage,這樣對 Origin Server 就是一百次的 request,並沒有真的解決問題。</li>
<li>如果是用一般的 hash,全部的機器都健康的時候,hash 都維持得很好,cache hit 也可能都會不低,但是一但某台機器掛點,會重新 re hash,原本養的 cache 全都報銷了。</li>
</ol>
<div>
再講回 Apache Traffic Server,其實它源自 Inktomi 的 proxy server,設計精良,當年被 yahoo 併購之後,yahoo 只看到 inktomi 的搜尋部分業務,其他的東西都被冷凍起來,後來有人挖寶之後,發現了 inktomi proxy server,一用之後驚為天人,轉身變成 Yahoo Traffic Server,並且大量部署在 yahoo cdn 上。</div>
<div>
<br /></div>
<div>
不過後來可能因為政策改變,yahoo 內部自行研發了 uff 這套原本想要取代 yts 的 proxy server,所以將 Yahoo Traffic Server 在 2009 年捐給 Apache Project,原本一些在內部做 yts 研發的人員,大部分也同時成為 apache committer 來改善 Apache Traffic Server。</div>
<div>
<br /></div>
<div>
後來的後來,由於 uff 最主要的開發者離職,Apache Traffic Server 在 open source 社群中大量被改善效能,原本只能跑在 32bits 的環境,也改成對 64bits 相容。所以後來 Yahoo 又將 cdn 相關的 solution 改回來 Apache Traffic Server。</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
剛才講到 Apache Traffic Server 設計精良,內部對於 thread/event/network 都有各自的 processor,像是 carp 做 health check 的部分,就是丟給 event processor,然後會去呼叫 thread/network 相關的 processor 做更低階的處理,最後再透過 callback 之類的將最終狀態丟回原本的 caller。</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
讓我整個卡住的部分,其實就是在這邊,怎麼樣看,他都應該幫我開一個 tcp connection 出去,但是程式判斷的地方,他會先判斷 thread event type,如果不是他要的,就直接不處理,等到 event timeout 之後,就會去 callback 原本的 caller 來做後續的處理。可是我找不到任何的地方去決定 thread event type 呀!!!</div>
<div>
<br /></div>
<div>
因為我的 c++ skill 實在太差,在卡住三四天之後,覺得這樣下去不行,雖然手上有最終解決方案,就是 Apache Traffic Server cluster,但是終究是要 deprecated 的東西。所以我就開始找尋下一個替代方案,nginx 不行,因為 proxy mode 比較厲害的東西都被放在 nginx plus 裡面。那 varnish 呢?以前稍微試用過的經驗並不好。不過市面上可以用的 proxy 幾乎沒有了,每一套宣稱自己多厲害多厲害的 proxy,終究就只是很單純的 proxy,很多連自己對 client request/response, origin server request/response 都沒辦法額外處理。更不要講 performance 了。</div>
<div>
<br /></div>
<div>
在抱著試試看以及捧個人場的心情下,試用了一下 varnish cache,為什麼說捧個人場?因為 varnish 是 phk@freebsd.org 最近這十年來的力作,他幾乎都沒有再碰 kernel development,全心全力的做 varnish cache 的開發。</div>
<div>
<br /></div>
<div>
varnish cache 有下列幾個我覺得很棒的地方:</div>
<div>
<ol>
<li>bsd-2 clauses license,去他媽的 gpl。</li>
<li>沒有設定檔,一些參數都用 cli 方式傳進去,然後如果不會寫 vcl 也沒關係,backend server 相關資訊一樣可以用 cli 傳進去。</li>
<li>vcl 很簡單,會寫簡單 perl 的人都會。</li>
<li>vcl 不是直譯式處理,而是在 start-up 的時候,直接轉譯成 c code,馬上 compile 成 .so,varnishd load .so 起來處理,只要專心做好自己想要判斷的事情就好,memory leak/performance issue 等相關的事情完全不要理會。</li>
<li>builtin vcl function 不夠用的話,可以自己寫 vmod 來擴充 function。</li>
<li>log 什麼鬼的,varnish 全部都扔到 shared memory 去,另外有一隻 varnishlog 會從 shared memory 讀資料之後寫黨,所以什麼 log rotate 之類的事情,不用 kill -HUP varnishd,服務完全不會中斷。</li>
<li>reload vcl 之類的也是可以 online 做,一樣服務不會中斷。</li>
<li>相關的 utility 做得非常好,varnishadm/varnishstat 之類的,幾乎都是商業等級的水準。</li>
<li>內建 health check,可以做到失敗幾次才會算真的失敗這類的情境。</li>
<li>支援各種 director,可以簡單應付各種場景。</li>
<ul>
<li>fallback</li>
<li>hash</li>
<li>round robin</li>
<li>random</li>
<li>shard</li>
</ul>
</ol>
<div>
不過 varnish 現在對我而言有一個瑕不掩瑜的缺點,雖然這個也可以用另外的程式做掉,但還是會覺得有點不舒服,那就是,他不支援 ssl,https 之類的要自己處理,這對於之後的 ios 可能會是個問題。</div>
</div>
<div>
<br /></div>
<div>
總之,varnish 算是簡單就達到我想要的功能,理論上會直接拿來使用。而 Apache Traffic Server 也不是完全沒有優點的,只是不會寫他的 plugin 的話,出廠預設的功能,其實是很難滿足需求。</div>
<div>
<br /></div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-46673993017901819142016-10-23T00:16:00.001+08:002016-10-23T00:21:18.136+08:00Apache Traffic Server & Varnish Cache 之我見. (Part 1)最近因為任務需要,需要自己弄一套 proxy/cache 的系統。<br />
<br />
至於為什麼要自己弄?<br />
<br />
<ol>
<li>當地國際頻寬貴,如果能在當地弄一份 static replica,可以省下很多錢。</li>
<li>但是在偏遠的地方自己弄 storage,光想營運成本就很高,尤其每樣都要做 HA 的時候,成本跟硬碟幾乎都是一路 * 2 * 3 上去。</li>
<li>既然不能搞 storage,那弄一份 cdn 總可以吧,基本上解決 20% 的 content,就省掉了 80% 的 cost。</li>
<li>cdnetwork 之類的,幾乎都沒有在當地有 edge server。</li>
<li>所以即使用了 cdnetwork,還是要走國際頻寬出去,一樣貴。</li>
</ol>
<div>
原本想像中的架構如下:</div>
<div>
<ol>
<li>最前面擋台 l4 load balancer,將流量 round robin 散到下面的 l7 load balancer 上。</li>
<li>l7 load balancer 理論上會用 Apache Traffic Server 加上自己寫的 plugin,將前面進來的 request,透過 consistent hash 算過之後,平均導到後面的 storage 上面。</li>
<li>consistent hash 只是個說法,重點是每台 l7 load balancer 自己要維護一份後面的 storage 的健康狀況表。</li>
<li>storage 相對起來簡單,但是要能根據後面 Origin Server 的不同產生不同的 header 之類的,例如如果 Origin Server 是 S3,要能自動生出 s3 request header。</li>
<li>這樣做的好處在於,如果其中一台 l7 load balancer 壞掉,起碼有一台可以撐住。而後端的 storage,也會因為 l7 load balancer 已經用 consistent hash 算過,固定的 url 會送往固定某台,cache hit rate 會拉高,Origin Server 假設是 300T 好了,每台 storage 基本上可以只是部分就好,一旦任意一台 storage 壞掉,起碼可以先將 request 由隔壁來分擔,而不是全部養好的 cache 就全部掛光。</li>
</ol>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia2vqdwWYX8623SuLiyySHfEtuGqIcFNbCV8NGff2S6ORAJE5iLBIzm2Dj9L1aCmWXamEgAqsWI2TNBHQ660Xes0rzSY3_nWfJ3zPvhZpa_QvSMfyN3wjexO564XgN1Auvu-mfPWMX461e/s1600/cdn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia2vqdwWYX8623SuLiyySHfEtuGqIcFNbCV8NGff2S6ORAJE5iLBIzm2Dj9L1aCmWXamEgAqsWI2TNBHQ660Xes0rzSY3_nWfJ3zPvhZpa_QvSMfyN3wjexO564XgN1Auvu-mfPWMX461e/s640/cdn.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
剛才講到會用 Apache Traffic Server 來實做這些東西,為什麼呢?<br />
<br />
<ol>
<li>畢竟我也是 ex-yahoo 呀。</li>
<li>畢竟我也摸了好一陣子的 yts & uff 呀。</li>
<li>畢竟我也是受到<b>業界知名的嫩哥</b>的薰陶。</li>
</ol>
<div>
Consistent Hash 就用 google 提出的 Jump Consistent Hash,而後端機器健康程度,要就是 plugin 自己開個 thread 定期去維護,不然就是透過 lmdb or mmap file 之類的,讓另外一支程式來幫你維護。</div>
<div>
<br /></div>
<div>
plugin 寫了一半,看到其實 Apache Traffic Server 有 cluster 的功能,看起來大方向其實跟我想做的雷同,只是方法不同。</div>
<div>
ats cluster 的做法是,根本不分 l7 load balancer 還是 storage,全部都是 storage,只是一個 request 近來,會先查查自己肚子裡面有沒有 hit,沒有就發 udp multicast 出去問隔壁的有沒有人有 hit,有就直接抓來往 client 送。</div>
<div>
<br /></div>
<div>
諮詢嫩哥對於 ats cluster 的看法之後,他說 "cluster? 快要 deprecated 了呀" "現在你要用 carp 啦!"</div>
<div>
<br /></div>
<div>
carp 是什麼呢? 是 yahoo 針對這類的需求開發出來的一個 ats plugin,並且已經有送 pull request 給 ats 了,目標是在下一個版本的 ats 會包含這個 plugin。</div>
<div>
想嚐鮮的可以先到 https://github.com/ericcarlschwartz/trafficserver/tree/TS-4723/plugins/experimental/carp 去查看。</div>
<div>
<br /></div>
<div>
既然 yahoo 都這麼有心,放出了方案給大家用,似乎不去試試看,好像還頗對不起 MM 的。</div>
<div>
<br /></div>
<div>
carp 光看設計,其實頗不錯的,health check 幫你做,也做 consistent hash,基本上我想要的他都做到了。很棒,立馬抓來 compile,load 進 ats 來試試看。</div>
<div>
<br /></div>
<div>
嗯嗯, 問題不大,最大的問題頂多是不會動而已!</div>
<div>
<br /></div>
<div>
對,他不會動,仔細查了一下相關的 code,寫法都是對的,但是他就是不會動!</div>
<div>
<br /></div>
<div>
好吧,一路追下去好了,TSContCreate,TSContSchedule,TSNetConnect 看起來每一樣都對呀!</div>
<div>
<br /></div>
<div>
不對,為什麼 TSNetConnect 裡面只要是 carp 要做 health check 的 connection,他就是直接不處理,然後最後等到 timeout?</div>
<div>
<br /></div>
<div>
喔,原來是 thread type 不對他就不處理呀!可是從頭到尾都沒有一個地方可以讓我自己決定要用哪種 thread 呀!</div>
<div>
<br /></div>
<div>
這個部分大概就卡了我三四天!!!</div>
<div>
<br /></div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-38159365209010700982016-03-23T14:50:00.002+08:002016-03-23T14:50:48.074+08:00[Elixir] 安裝 erlang + elixir + phoenix frameworkelixir 是架構在 erlang vm 上的語言,所以在開發程式之前,第一件事就是把 erlang 裝起。<br />
<br />
<br />
<br />
<ul>
<li>Linux</li>
<ul>
<li>由於個人使用習慣,平常我個人都用 FreeBSD,linux 我大概只用 rhel/centos。</li>
<li>rpm 可以在 <a href="https://www.erlang-solutions.com/resources/download.html">Erlang Solutions</a> 下載,不過這個版本會順便將 wxGtk 也裝起來,個人並不喜歡。</li>
<li>可以使用 rabbitmq 做好的 <a href="https://github.com/rabbitmq/erlang-rpm/releases">zero dependencies rpm</a>。</li>
</ul>
<li>FreeBSD</li>
<ul>
<li>透過 ports,直接到 lang/erlang 下面 make install 就好了。</li>
</ul>
</ul>
<div>
裝好了 erlang,下一步就是把 elixir 也裝好。</div>
<div>
<ul>
<li>Linux</li>
<ul>
<li>我不確定有哪一個 distribution已經內建 elixir,但是同樣的 <a href="https://www.erlang-solutions.com/resources/download.html">Erlang Solutions</a> 有 package,但是只有給 debian/ubuntu 的而已。</li>
<li>所以直接到 <a href="https://github.com/elixir-lang/elixir/releases">elixir 的 github</a> 下載,解開之後打個 make install 就裝好了。</li>
</ul>
<li>FreeBSD</li>
<ul>
<li>一樣很簡單,到 lang/elixir 下面 make install 就裝好了。</li>
</ul>
</ul>
<div>
裝好 elixir 之後,基本上會有兩個東西會不停地在開發過程被用到:</div>
</div>
<div>
<ul>
<li>mix - project management tool,任何你在開發過程會用到的工具或者流程,都會透過 mix 這一個 command 來執行,另外也可以自行編寫 mix task 擴充功能。</li>
<li>iex - interactive elixir shell,就是一個 elixir shell,一些簡單的想法可以直接在 iex 裡面實現及驗證。</li>
</ul>
<div>
再來就是安裝 phoenix framework,這東西有點像是蛋跟雞一樣,你要有 phoenix 的 mix task,才能夠建立一個 phoenix project,但是你也要先有相關的 package 安裝好了,才能有 phoenix mix task 能夠被使用。不過沒問題,elixir & phoenix team 都幫你想好了,透過 mix archive.install 就可以把 phoenix 裝好。</div>
</div>
<div>
<br /></div>
<div>
<div>
<pre nbsp="" style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9rr7Eeih02VPWPZiS2ElsMuz2FLZKfNj95ADpDSGWIu18rLC-1AfVgGlkWa_aobAAkd-9dY4vXd-owT3S0IIV4OJ9YGTG1DfZFHvQszPg4C5wfMSHe8H_SzCTFdAcoOA-CdfxNzQ4p6nm/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> mix archive.install https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez </code></pre>
</div>
<div>
</div>
</div>
<div>
<br /></div>
<div>
裝好 phoenix 之後,打 mix -h 就可以發現多了一個 mix phoenix.new 的 task 可以用。</div>
<div>
也可以打一下 'mix phoenix.new -h' 來看看相關參數。</div>
<div>
<br /></div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-4234583992445826012016-03-10T15:52:00.003+08:002016-03-10T15:52:53.314+08:00[Elxir] 為什麼要用 elixir 呢?開始的開始,其實我是先知道 erlang 這個語言的。<br />
<br />
大約在 2007/2008 左右,那時候應該還是在 erlang 13.x 的版本,我忘記我從哪邊知道這個語言,一直想好好學好它,也買了書來看。<br />
<br />
但是大概是 perl/php 這類語言的餘毒,讓我在學習 functional language 的路上沒能好好走完。<br />
雖然一直都沒學好,不過我都還是持續在關心著 erlang,尤其這中間很多公司,都用了 erlang 做一堆神經病等級的產品,例如 whatsapp,例如 cowboy 等等。<br />
<br />
而 elixir 這個架構在 erlang vm 上的語言,我大概是兩三年前在 erlang 的社群略有耳聞,但是由於之前對於 erlang 一直學不好的心理因素,就一直忽視他。<br />
<br />
那到底是什麼樣的機緣,又讓我再度擁抱 erlang 甚至開始學習 elixir 呢?應該是因為工作需要吧!因為一些先天上的限制,軟體的 dependencies 其實是困擾的所有的開發人員,尤其是開發電信機房裡面的服務。<br />
<br />
一開始我們選擇的 golang,寫起來簡單,相關的 unit test 都具備了,但是又似乎少了點什麼,如果程式因為任意原因死掉了,你必須自己監控,必須自己想辦法。即使 golang 有了 static link 這個降低 dependencies 的好處,但那還是不夠呀。<br />
<br />
所以大約在去年七月,經過一些評估之後,我重回了 erlang/elixir 的懷抱:<br />
<br />
<ul>
<li>ecosystem 完善</li>
<ul>
<li>有 hex.pm 這一個 package management site,任何人寫的東西都可經由這個網站發布,也可以輕易的跟 project 結合。</li>
<li>elixir 內建了 mix 這一個 project management tool,任何開發期需要的東西,都可以透過這個工具去呼叫,也可以自己寫 mix task 來把複雜的事情變簡單。</li>
</ul>
<li>otp</li>
<ul>
<li>Open Telecomm Platform</li>
<li>erlang 內建 otp,因為 erlang 就是為了交換機而被發明的語言,所以他很多特性,都是為了電信業而產生。</li>
<li>而 otp 本身就有很多先進的設計,就是為了確保服務儘可能地沒有 downtime,例如 supervisor 可以檢控 process,當他掛掉會自動重新叫起來。例如 code hot swap 可以讓 daemon 持續服務,但是瞬間將版本升級。</li>
</ul>
<li>async</li>
<ul>
<li>在 erlang 裡面,每一個 app 都是獨立的一個 erlang process,彼此用 message passing 溝通,所以要寄信,直接將相關資料扔給寄信的 process 即可,前端的 web 可以繼續服務。</li>
</ul>
<li>no side effect</li>
<ul>
<li>也由於資料並沒有 lock 這類的問題,所以儘可能地降低 side effect。</li>
</ul>
<li>接近人類思考模式</li>
<ul>
<li>erlang 說真的我還是沒認真寫過,但是 elixir 幾乎已經接近人類思考模式了,人並不會做一件事情,只有一個 function 然後裡面一堆 if/else,而是在最開始,就已經把很多事情直接分開。這樣的好處是,每個 function 就只做自己的事情。</li>
</ul>
<li>phoenix framework</li>
<ul>
<li>如果只有 elixir + mix 這樣的工具,其實還沒辦法好好做事,畢竟什麼東西都還是要有個漂亮的介面。</li>
<li>phoenix framework 是用 elixir 寫的 web framework,再加上 ecto 之後,資料庫什麼鬼的都抽象化了。</li>
<li>簡單的說,elixir 就像是 ruby,phoenix 就像是 ror,而依賴著 erlang 天生的高效能,可以快速地生出很棒的服務出來。</li>
</ul>
<li>exrm + rpm</li>
<ul>
<li>exrm 是一個 release tool,經過 exrm 的 task 處理過後,可以生出一個 .tar.gz 檔。</li>
<li>將這個檔案直接 copy 到機器上,解開就可以直接跑起服務。</li>
<li>像是 erlang vm 什麼的,都會在這個 .tar.gz 裡面。根本不需要預先安裝甚麼軟體。</li>
<li>但是只有 exrm 對很多人來說可能還是不夠,所以有人又替 exrm 衍生出 exrm_rpm。</li>
<li>exrm_rpm 在 exrm 的基礎上,可以在 task 的最後,把 .tar.gz 轉成一個 .rpm。</li>
<li>這個 rpm 裡面連 init.d 的 script 都有了,直接 yum install xxx.rpm,重新開機就所有服務一次到位。</li>
</ul>
</ul>
<div>
評估完,就開始將原本用 php 寫的 web tool 改用 elixir 寫,整個工作從去年八月開始,中間加入了一些 linter,code analyst tools,並在今年二月左右,將整個 unit test/integration test 都做完,最後的 code coverage 約 85%。</div>
<div>
<br /></div>
<div>
本篇為起手式,之後會開始從怎樣弄一個 elixir project 講起,到我中間有用過的工具,然後最後以包出一個 rpm 為結束。</div>
<div>
<br /></div>
<div>
(不保證什麼時候會做好。)</div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-10560235011684285142014-02-06T15:39:00.001+08:002014-02-06T15:39:37.110+08:00go + clang自從 freebsd 10.0 之後, 系統內預設的 compiler 就是 clang 了,<br />
<br />
所以用 go + cgo 寫出來的東西, 跑 go build 的時候, 會出現<br />
<br />
'exec gcc: No such file or directory'<br />
<br />
這樣的訊息,<br />
<br />
是因為 cgo 裡面直接假設大家的 compiler 都是 gcc, 所以他 hardcode 'gcc' 進去.<br />
<br />
那有解法嗎?<br />
<br />
有的.<br />
<br />
用 -ldflags 把參數傳進去.<br />
<br />
<br />
<br />
go build -ldflags '-extld clang'<br />
<br />
這樣 go 就會用 clang 去做 link 的動作了.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-30631301347361597162013-07-25T00:07:00.000+08:002013-07-25T00:07:07.102+08:00Facebook 的 hiphop-php (aka hhvm)<h2>
什麼是 hiphop-php 呢?</h2>
<div>
<br />
<ol>
<li>基本上就是 facebook 自己實作的 php runtime,再加上很多特異功能。</li>
<li>第一代叫做 HPHPc,這是一個將 php transform 成 c++ 的版本,由於因為對開發者不友善,加上每次只要 php code 有變動,就得整個重新編譯,而編譯一次得花上好幾個鐘頭,所以 facebook 在 2013/02 放棄使用這個版本。(第一代其實還包括 HPHPi,HPHPd 等衍生的特殊版本)</li>
<li>第二代叫做 HHVM,將原本的編譯改成 vm 模式,加上 <a href="http://zh.wikipedia.org/wiki/%E5%8D%B3%E6%99%82%E7%B7%A8%E8%AD%AF">JIT</a> 支援,讓 php 執行起來就跟在飛一樣快。</li>
<li><a href="http://zh.wikipedia.org/wiki/HipHop_for_PHP">wiki</a></li>
</ol>
<br />
<h3>
那 hhvm 有什麼特異功能呢?</h3>
</div>
<div>
<ol>
<li>基本上他就是一個 base on libevent 的 http server,加上 php runtime。</li>
<li>但是你想得到的一些基本 http server 該有的他都有,例如 virtual host, gzip, keepalive, rewrite, acl 等等。</li>
<li>此外,還可以扮演 proxy/rpc/static 。</li>
<li>再來它可以開一個 admin server,bind 在特定的 port 上,提供一些 server status,以及一些管理上的相關 api。</li>
<li>非常快,在我的 i7-3770k + 32G ram 的機器上,跑一隻簡單的 php,出現了接近 10000 reqs/sec 的數據,當然這會跟著你的 php 程式複雜程度而減少。</li>
<li>容易 deploy,如果 hhvm 是 static link 的話,deploy 只需要將 binary scp 到所有機器上就完成了,根本不需要管相關的 dependencies library。hhvm 在跑起來的時候,其實需要額外的 php data file,但是他用了一個很變態的方法存放這些 php data file,把它藏在 hhvm binary file 的 .text section 裡面。</li>
<li>fb 自己實作了不少特殊功能的 function,例如用 non-blocking 的方式連接 mysql。</li>
<li>還很多,我目前還在看當中。</li>
</ol>
<h3>
<br />
</h3>
<h3>
那目前有什麼做不到的?</h3>
</div>
<div>
<ol>
<li>由於還在緊密開發,所以他官方宣稱只支援到 php 5.3,並且不是所有的 php extension,都可以在 hhvm 裡面使用。</li>
<li>例如資料庫的部分,目前僅支援 mysql/sql,有些人想要 mongodb driver,目前還在殷切盼望中。</li>
<li>文件缺乏,雖然 source code 是你最要好的朋友,但是不是所有人都能看 c/c++ 去瞭解整個系統的。</li>
<li>i386/powerpc/sparc/ia64/arm 等平台都不支援,目前只支援 amd64(x86_64),arm 的話,據說不支援啦,但是某些地方有看到這個 keyword,這讓我想到之前聽到的 facebook 考慮用 arm 來當 web 的八卦。</li>
</ol>
<div>
理論上只要你用 mysql 當 database,沒用奇怪的 extension,那麼 hhvm 應該是可以直接拿來用,連 nginx/apache 等 web server 都可以不用安裝了。但是如果有用到額外的 php extension,那要就是等別人寫出對應的 hhvm extension,不然就不建議使用。(當然也可以自己下去寫看看)<br />
<br /></div>
</div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-46230944772605683872013-07-07T15:25:00.001+08:002013-07-07T22:32:38.181+08:00我也來點勵志的好了.很多的同事,一起工作久了,就會問‘你哪個大學畢業的?研究所呢?’,其實,我根本沒讀大學呀,最高學歷只有高中,還讀了三家,從省立高職日校,到省立高職夜校,最後只好認命地在私立高職的補校讀了三年,再多考一次資格考,才把高中同等學歷補齊。現在大家一直在講証照,一直講技職體系出了問題,我的經歷應該可以給技職體系的學生們一些激勵吧。那憑什麼給大家激勵?高職畢業,一張證照也沒有,在外商工作過,每天準時上下班,日子也過得舒服,這些應該當理由就夠了吧。<br />
<br />
為什麼只讀高職,為什麼不讀高中,然後大學一路讀上去?這大概得從國中時代講起,國中的時候,幾乎都沒在認真讀書,大概上輩子有燒好香,所幸成績都還不錯。我們班算是前段班,同學們幾乎都是腦袋聰明,很會玩,就是不願意認真讀書。因為這原因,所以國三的時候,我就在想,是一定要讀高中嗎?不能走不一樣的路嗎?因此決定不參加高中聯考,只參加高職及五專聯考。最後上了省立永靖高工製圖科,讀了兩三個月就沒去上課,自動退學。隔年因為朋友的原因,報名了省立北斗家商的夜校廣告科,一樣讀了兩三個月自動退學。最後是某朋友勸我,就算怎樣不喜歡讀書,起碼得把高中同等學歷補齊,以後才不會後悔。因為這個理由,所以報名了彰化的私立正德工商夜校的資訊科 [1]。為什麼會是資訊科?班上男生的說法都一樣,大家都以為資訊科女生多,結果女生就被蜂擁而至的男生們排擠掉了,反而資料處理科的女生才多。:(<br />
<br />
資訊科並沒有教太多資訊相關的東西,真的要講的話 ,隱約記得就是大易輸入法跟 8051 組合語言。輸入法對於寫程式來講,沒有太大意義,學校教輸入法,我猜大概是要大家多一樣才藝,然後比賽誰速度快。8051 組合語言,教的時候大部份的人都聽不懂,考試的時候好像也沒考,真的要實做,只要有一兩個會寫,互相 cover 就通過測驗了。<br />
<br />
講完了學歷,再來講電腦相關的經歷。最開始接觸電腦,是在國中畢業之後,白天讀永靖高工,晚上我自己跑去一家電腦公司當工讀生,在那邊認識了電腦上的啓蒙師傅。也因為他,所以開始學著架設 dial-up BBS [2]。當時的作業系統都是 MS-DOS,沒有多工, 一台 pc 同時間只能讓一個用戶撥接上來用。那時對於所謂的作業系統,我一點概念都沒有,頂多就是玩耍著 <a href="https://zh.wikipedia.org/zh-tw/QEMM">QEMM</a>,讓可用記憶體增加一點,玩耍著 <a href="http://zh.wikipedia.org/wiki/PC_Tools_(%E8%BB%9F%E9%AB%94)">pctools</a>,修改遊戲存檔,讓玩遊戲練功的時間縮短,不過也因此學習到什麼是 16 進位。<br />
<br />
當作業系統是 MS-DOS 的電腦,進入了 BBS 模式,就是等著讓別人撥接進來用,自己只能在旁邊乾瞪眼,因此問了師傅,有沒有什麼方法,可以讓很多人同時使用一台電腦?他說有種系統叫做 unix,但是他並沒真的用過,也不熟。而他自己架設的 BBS 上,是透過一個叫 <a href="http://en.wikipedia.org/wiki/DESQview#DESQview.2FX">desqview/X</a> [3] 的程式,讓一台電腦,做到簡單的多工,來達到架設多線 dial-up BBS 的目的。<br />
<br />
用 desqview/X 沒多久,OS 世代進入了 windows95,據說不需要 desqview/X 這類的程式,也可以做到多工。我突然想起 unix 這個 keyword,很想知道那到底是什麼樣的系統。當時台灣有些先進在推廣 linux,因此買了書,使用光碟安裝起自己的第一個 linux 系統,那時比較有名也比較友善的,應該是 <a href="http://zh.wikipedia.org/zh-tw/Slackware_Linux">Slackware</a> 吧,<a href="https://zh.wikipedia.org/wiki/Red_Hat_Linux">RedHat</a> 還沒出現在市場上。<br />
<br />
由於對於 linux 系統不熟,所以遇到了一些小問題的解決辦法,就是重新安裝整個系統。也因為這樣的反覆安裝,開始對於整個環境比較熟悉。既然系統比較熟悉一點了,那就學一下寫程式吧!<a href="https://zh.wikipedia.org/wiki/PHP">PHP</a> 的前身 php/fi 剛出現,因為語法跟別的語言比較起來相對簡單,就花了一些時間好好地學了一下 php/fi,然後忘了什麼原因,同時間也學著寫 <a href="http://zh.wikipedia.org/zh-tw/Perl">perl</a>。<br />
<br />
linux 用了一年多,多數時間都在摸索,剛好交大的 jdli 在推廣 FreeBSD,想說反正都一樣是 unix like 的系統,多學一點也無所謂,就順勢換到了 FreeBSD,沒想到一用成主顧,自此在自己的機器上,就很少安裝 linux 了(測試或者案例需要不算)。<br />
<br />
FreeBSD 當時的社群,非常壯大,每個人都可以直接參與,可以送自己想改的東西回去。由於年紀還輕,熱血過剩,所以想了很多想做的東西,例如 FreeBSD 在中文使用上的修正什麼的,但是 submit 幾次 patch 都沒有人理會,就自作主張的用英文寫了封信,給 jkh@ [4],問他有沒有方法,可以讓中文相關的事情有人來關注?他就問我有沒有興趣接下這個任務?我回答說‘可是我並不是那麼懂 c 呀’,他回我說‘沒問題的’,因此,在 1997 年的 11 月,正式變成了 FreeBSD.org 的一員。[5]<br />
<br />
成為 FreeBSD 的成員之後,除了持續在 BBS 上的 tw.bbs.386bsd 回答問題之外,偶爾也會寫一些跟中文相關的文章。有討論自然少不了吵架,也因為吵架,催生了 FreeBSD FAQ 繁體中文版。當時號召了好幾個 bsd 板上認識的網友,大家在空閒時間裡,將 FreeBSD FAQ 翻譯成繁體中文。因為我是 committer,也就順理成章的將這些成果變成官方的 FAQ 繁體中文版,並且直接在 FreeBSD 官方網站上就可以看到。[6]<br />
<br />
1999 年當兵,2000 年底退伍,退伍之後工作。這時,社群的一些人,開始改用 <a href="http://zh.wikipedia.org/zh-tw/IRC">IRC</a> 作為聊天以及交換資訊的途徑。最早大家用 <a href="http://en.wikipedia.org/wiki/BitchX">BitchX</a> 這個 client,同時有另外一個叫做 <a href="http://en.wikipedia.org/wiki/Irssi">irssi</a> 的 client 好像也很不錯。經過測試之後,發現 irssi 無法正確的刪除中文字。某天晚上,熬夜研究了一下這部分的 code,並參考了 <a href="mailto:clive@freebsd.org">clive@</a> 當時對於 bitchx 的一些修正,終於將這問題解決。在 irc 讓大家測試沒問題之後,寫信通知 irssi 的作者,他馬上就發佈了一個包含這個修正的版本。[7]<br />
<br />
<br />
[未完, 下次再講工作做過哪些好玩的事情吧!]<br />
<div>
<br /></div>
<div>
Ref:</div>
<ol>
<li>正德工商已經改名為正德高中,是一所綜合高中,據說升學率不算低,算是彰化不錯的私立學校了。不過真實狀況到底是怎樣,我並不清楚。</li>
<li>不是 ptt 那種 internet bbs,而是透過 modem 撥接的 bbs,當時比較代表性的,有superbbs/ra/rbbs/powerboard 等。</li>
<li>後來才知道 X 代表的就是 XWindow,在 DOS 上實作出 X server 真的是很厲害。</li>
<li>FreeBSD 的 founder,後來去蘋果當 unix 部門的主管,最近轉職到 iXSystem 當 CTO。</li>
<li>那時候好像還在正德讀第三年。</li>
<li>後來 FAQ 格式改版過很多次,由於大家工作的工作,上大學的上大學,加上我個人當兵的原因,沒有餘力跟上最新的變化。</li>
<li>irssi 後續的中文修正,是由 mhsin 接手,他同時也是修正 windows 上常用的終端程式 putty 中文相關問題的長輩。</li>
</ol>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-90813525001741126662013-06-18T21:16:00.000+08:002013-06-18T21:16:22.024+08:00perl performance tuning不知道是不是因為 aws 實在太好用,還是用的機器數量, 決定服務在大老闆心中的份量, 因此很多人覺得, performance 是不需要稍微調教的, 只要加機器, 就可以得到更多的效能, 或者會拿出大神高德納講的那句話出來當證明,<br />
<br />
"過早的最佳化, 是萬惡的根源"<br />
<br />
但是在我看來, 很多人並不是晚點才做最佳化, 而是根本<span style="color: red;">不做</span>最佳化.<br />
<br />
<br />
最近花了點時間, 看了社內某個用 mod_perl 寫出來的產品.在 4g ram 的 vmware 裡面, 只跑得出 9reqs/sec 的數據, 問問原本維護的人, 他們說這很合理呀, 他們要求即使是測試環境, 最少也給 16g ram, 才有可能跑得起來, 4g 他們覺得連跑都跑不動.<br />
<br />
<br />
花了點時間用 Devel::NYTProf 做一下 profiling, 發現每一次的 request, db access 都在最後面, 大概只佔該次 request 的 1/5 ~ 1/4 左右而已, 而前面看起來很忙, 但是都不知道在忙什麼.<br />
<br />
<br />
仔細研究 code 之後, 發現了下面幾個問題:<br />
<br />
<br />
<ol>
<li>每次 request 會先檢查 session 是否 valid, 但是檢查的 function 連續被 call 了兩次.</li>
<li>檢查 session 是否 valid 的 function, 檢查的瞬間, 會從資料庫撈出某資料, 這資料會先用 fork 某程式來取得更仔細的資料, 而這個會 fork 的 function, 從開始到結束會被 call 四次.</li>
</ol>
<div>
2. 的 code 如下.<br />
<br /></div>
<pre>my $encode = encode_base64($plain_text);
my $r = `perl decode_base64.pl "$encode" | xxxxx`;
</pre>
<div>
<br /></div>
<div>
<br />
$plain_text 是從資料庫出來的資料, 先用 encode_base64 編碼, 再帶進去 fork perl 出來的 decode_base64.pl 解成 plain_text, pipe 給 xxxxx.<br />
<br />
decode_base64.pl 是一隻 perl script, 只做一件事情, 從 @ARGV 收參數, 然後 decode_base64 之後, print 到 stdout.<br />
<br />
<br />
這, 是喝到多醉, 才會寫出這種 code? 因為它其實可以簡化成<br />
<br />
my $r = `echo "$plain_text" | xxxxx`;<br />
<br />
少 fork perl 這種大傢伙, 會減少很多時間的, 另外, 這個 function 會 fork 幾次? 答案應該是 24 次, (shell + perl + xxxxx) * 4 * 2 = 24, 每一個 request 先 fork 24 隻程式出來, 其中包括八次是 perl, 是能得到多少效能?<br />
<br />
那, 可以完全避免掉 fork 嗎? 答案是可以的, xxxxx 這是社內其他人寫的東西, 機器上看起來只有 binary, 那拿的到 source code 嗎? 沒有理由不行呀, 拿到 source code 之後, 改寫成 perl XS, 理論上就可以完全避免掉 fork 了.<br />
<br />
<br />
將 1. 2. 的部分避免掉之後, 再做一次 benchmark, 得到了 45reqs/sec 的數據, 這已經是 500% 的 improve, 而這只是最基本的避免 fork 而已, 是不是還有其它招式可以加速? 當然有, 只是要見招拆招.<br />
<br />
<br />
<br />
附註:<br />
<br />
<ol>
<li>http://cdn.oreillystatic.com/en/assets/1/event/45/Understanding and Optimizing your Code with Devel__NYTProf Presentation.pdf</li>
<li>這是 perl DBI 作者的簡報, 他同時也是 Devel::NYTProf 的作者.</li>
<li>簡報裡面提到不少 tuning 的概念, 都非常的棒.</li>
<li>最後已經在計較 subroutine 傳參數進去, 是否要 unpack 的效率了.</li>
<li>有的時候, 如果可以找到相同功能的 perl module, 但是是用 xs 改寫過的, 測試沒問題就儘量用, 速度上差很多 (前提是該 module 沒 bug)</li>
</ol>
<br />
<br /></div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-29977473033848898672013-05-10T11:24:00.000+08:002013-05-10T11:24:08.380+08:00go and elf rpath<link href="http://syntaxhighlighter.googlecode.com/svn/trunk/Styles/SyntaxHighlighter.css" rel="stylesheet" type="text/css"></link>
<script language="javascript" src="http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shCore.js">
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCpp.js'/>
<script language="javascript">
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
</script>
某社後來都強制得對 binary 加上 rpath, 為了系統安全的原因.<br />
<br />
那怎樣在 go 裡面檢查 binary file 的 rpath ?<br />
<br />
用 debug/elf 呀.<br />
<br />
--
<br />
<pre class="Cpp" name="code">package main
import (
"fmt"
"debug/elf"
)
func main() {
f, err := elf.Open("/bin/ls")
if err != nil {
panic(err)
}
rpath, err := f.DynString(elf.DT_RPATH);
fmt.Printf("%s\n", rpath)
}
</pre>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-22481527620313259042013-01-29T21:00:00.001+08:002013-01-29T21:01:26.887+08:00pecl-solrpecl-solr 是一個 php 的 extension, 用 curl & libxml2 處理從 <a href="http://lucene.apache.org/solr/">solr</a> 吐回來的資料,<br />
資料的格式可能是 xml, json 或是 serialize 過的 php array string.<br />
<br />
<br />
這幾天在看 freebsd 的 <a href="http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/173574">pr</a>, 發現寫 pecl-solr 的這群人非常的天才,<br />
即使他們全部都有 @php.net 的帳號.<br />
<br />
<br />
首先, 用 curl 去 solr 拉 search result, 如果格式是 xml 的話,<br />
再用 libxml2 處理 search result, 轉成 php array.<br />
(以上都是在 extension 裡面呼叫, 所以都是用到 c 的 function)<br />
<br />
<br />
但是 build 出來的 solr.so 並沒有 link 到 libcurl & libxml2.<br />
往上追到 Makefile, 發現根本沒有 "-lcurl -lxml2" 等 keyword,<br />
<br />
Makefile 是透過 configure 產出的,<br />
那是不是 configure 的時候出了什麼問題?<br />
<br />
也不是, config.log 怎樣看都是對的,<br />
有抓到 curl & libxml2 的 library & header file, 判斷都是對的.<br />
<br />
configure 是透過 phpize 讀取 config.m4 產生的.<br />
那 config.m4 有沒有問題?<br />
<br />
config.m4 在 curl 判斷上, 將 -lcurl 的定義放進了 CURL_SHARED_LIBADD<br />
<br />
最後會用 PHP_SUBST 來把要 link 的 library 放進 Makefile 裡面,<br />
但是他的 config.m4 裡面是這樣的.<br />
<br />
PHP_SUBST(SOAP_SHARED_LIBADD)<br />
<br />
你明明是 solr extension, 為什麼要用 SOAP 這名字?<br />
並且為什麼上面寫的是 CURL_SHARED_LIBADD,<br />
<br />
第一, 名字寫錯了, 第二, 就算寫錯, 兩個寫的一樣也是兜的起來,<br />
<br />
這樣怎麼可能會去 link 到對的 library?<br />
<br />
<br />
然後又發現 pecl-solr 有一些 unit test, 跑了一下,<br />
錯誤訊息裡面說我沒有裝 php curl extension.<br />
<br />
code 怎樣看都是直接 call libcurl 的 c function, 為什麼要我裝 php curl extension?<br />
<br />
再繼續看 php_solr.c 發現他在裡面 require 了 php curl & libxml2 extension.<br />
<br />
<br />
真相大白, 為什麼在 runtime 的時候都不會有問題?<br />
<br />
因為很白痴的要求一定要裝 php curl & libxml2, 所以不會發生 undefined symbol 的問題,<br />
<br />
但是這不是脫褲子放屁嗎?<br />
<br />
<br />
php-curl 大家用得比較多, 但是 php-libxml2 在我所知道的人裡面, 很少人直接 call 這個,<br />
pecl-solr 只是直接 call c function, 為什麼要 require php-libxml2 extension?Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-44884568065203734182013-01-09T23:33:00.004+08:002013-01-09T23:33:50.485+08:00工程師想要什麼?<div dir="ltr" style="text-align: left;" trbidi="on">
我們組最近有個需求, 想要監控 mysql 各個 table 的 row size,<br />
<br />
直接讓某台 cron 機器, 開 mysql connection 到各台 mysql 讀 INFORMATION_SCHEMA 是最直覺的,<br />
<br />
也有同事說, 讓 mysql server 自己讀自己的 INFORMATION_SCHEMA,<br />
讓別人透過 http 來讀 json 就好, 但是這樣可能就得跑一下 apache 之類的.<br />
<br />
後來我研究了一下, 公司內部本來就有一個 package, 可以透過 http 提供 mysql 各項的 metrics,<br />
<br />
原本想要稍微修改這個 package, 讓我們想要提供的資料可以套用進去,<br />
<br />
更深入研究之後, 發現這個 package 的 desc 寫著 mysql status framework,<br />
<br />
Framework 唷, 真厲害, 而他真的就是一套用 perl 寫的簡單 framework,<br />
<br />
用了 AnyEvent::HTTPD 做前端, 用了內部的 dbm 當 storage,<br />
只要繼承他的 perl module, 寫一些 callback function,<br />
就可以把怎樣搜集資料, 以及 http handler 都搞定,<br />
<br />
立馬就寫了一下, 大概不到一百行就搞定我們要的功能,<br />
也不會有 performance impact,<br />
<br />
因為往 mysql 的 query 都不是即時的,<br />
是透過 collector 每多久查一下, 寫到 storage,<br />
前端的 AnyEvent::HTTPD 收到 request, 往 storage 查, 馬上就吐出去.<br />
<br />
<br />
簡單, 好用, 又讓我覺得很爽.<br />
<br />
工程師想要的是什麼? 就是這種偶然遇到的小 hack 得到的喜悅呀.</div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-5178556776609031222012-11-14T10:58:00.002+08:002012-11-14T11:11:09.956+08:00php spl_autoload<div dir="ltr" style="text-align: left;" trbidi="on">
這兩天在 CI report 上, 一直回報某個 php class not found 的錯誤, 但是怎樣看,<br />
<div>
那個 class 確實是有被 require 到, 只是用 get_declared_classes() 是看不到的,</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
現在很多 php framework, 或者 developer 都會叫人不要再用 require_once() 了,</div>
<div>
大概也是這種原因吧.</div>
<div>
<br /></div>
<div>
不要再用 require_once(), 那要用什麼? 答案就是 spl_autoload.</div>
<div>
<br /></div>
<div>
用法其實很簡單, 宣告一個 register function,</div>
<div>
<br /></div>
<div>
<br />
function _autoload($class) {<br />
include $class . '.php';<br />
}<br />
<br />
spl_autoload_register('_autoload');<br />
<br />
然後把這東西放在 auto_prepend_file 裡面, 就會在每個 request 進來的時候幫你把東西 load 進來了.<br />
<br />
--<br />
update: 要注意的是, class name ($class) 要跟檔名一樣, 剛才就遇到同事寫的<br />
<br />
class name 是 getXXXX, 但是 filename 是 GetXXXX, 這樣他會抓不到.</div>
</div>
Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-35690204452158216412012-06-25T11:50:00.003+08:002012-06-25T11:50:56.524+08:00traffic server with srv lookup.lwhsu@ 後來又跟我重新講了一次 update.tw.freebsd.org 的狀況,<br />
<br />
他是希望 proxy 在往後抓資料之前, 先查一次 dns srv record, 才決定到底該往哪台抓.<br />
<br />
原本的想法是, 應該寫個 plugin 在 remap 之前作一下這事,<br />
<br />
不過在查詢相關資料的時候, 意外的發現, 其實 ats 本身就可以做了,<br />
<br />
code 就在那邊, 不過相關設定跟文件都沒有講的很清楚,<br />
<br />
唯一的缺點是, 似乎不會按照 priority 去決定哪台,<br />
<br />
--<br />
CONFIG proxy.config.srv_enabled INT 1<br />
<br />
在 record.config 中加上這行, remap.config 中把要 remap 的 target 改成要查的 hostname,<br />
重跑 ats 就可以了.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-51849722137354194072012-06-11T16:06:00.002+08:002012-06-11T20:56:52.033+08:00使用 trafficserver 建立 mirror 的 FreeBSD portsnap site.某長輩說目前的 portsnap.tw.freebsd.org 用 squid 跑, 某些原因, 要定期去清 cache,<br />
<br />
我就想說, 那到底能不能直接用 trafficserver 來直接替換 squid, 單純跑 reverse proxy 呢?<br />
<br />
答案是 ok 的, 雖然 traffic server 單純跑 reverse proxy 並不能顯示他的強項.<br />
<br />
<br />
<br />
1: 在 www/trafficserver 下面打個 make install, 目前版本是 3.0.4 (stable)<br />
<br />
2: 在 /etc/rc.conf or /etc/rc.conf.local 加上 "trafficserver_enable=YES"<br />
<br />
3: 修改 /usr/local/etc/rc.d/trafficserver, 把 command & procname 裡面的 traffic_server 換成 traffic_manager<br />
<br />
這邊的理由是, traffic_server 並不能用 root 跑, 因為程式裡面會檢查,<br />
但是不用 root 跑, 他又不能 bind 在 port 1024 以下.<br />
解法就是跑 traffic_manager, 讓他帶起 traffic_server, 這樣就可以必掉一些安全性問題,<br />
又讓他 bind port 80.<br />
<br />
4: 修改 /usr/local/etc/trafficserver/record.config<br />
1: CONFIG proxy.config.http.server_port INT 80 (讓 server 跑在 port 80)<br />
2: CONFIG proxy.config.http.cache.required_headers INT 0 (不管 response hearer 如何, 就是要 cache)<br />
<br />
5: 修改 /usr/local/etc/trafficserver/remap.config<br />
加上<br />
<br />
map / http://portsnap.freebsd.org/<br />
<br />
這是指定 trafficserver 的 origin server 是 portsnap.freebsd.org<br />
<br />
其實應該不應該直接 remap '/', 而是要指定整個的 http schema 的,<br />
但是因為 portsnap 會用到 fetch, 而 fetch 並不多送 host header.<br />
<br />
6: 修改 /usr/local/etc/trafficserver/storage.config<br />
把 256M 修改成想要的 cache size.<br />
<br />
7: /usr/local/etc/rc.d/trafficserver start<br />
<br />
<br />
這樣 local 就可以有一份 portsnap mirror 了.<br />
<br />
用<br />
<br />
portsnap -s 127.0.0.1 fetch 就可以作測試了.<br />
<br />
--<br />
UPDATE: 長輩說, 其實不是 portsnap 有問題, 而是 freebsd-update 會出問題, 但是其實是同一台, 所以要換就會整個一起換.<br />
<br />
remap.config 這邊又研究了一下, 發現其實是 ok 的, 因為我偷懶, 沒跟著動 dns,<br />
<br />
以 portsnap.tw.freebsd.org & update.tw.freebsd.org 這兩個 hostname 來講,<br />
<br />
remap.config 設定如下.<br />
<br />
map http://update.tw.freebsd.org/ http://update.freebsd.org/<br />
map http://portsnap.tw.freebsd.org/ http://portsnap.freebsd.org/<br />
<br />
設定好重跑 trafficserver 即可.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-46392672416450327172012-05-13T01:04:00.000+08:002012-05-13T01:08:34.691+08:00php embed or not.雖然敝社還是在 layoff 的輪迴中, 但是總是沉浸在這樣的氣氛也不好,<br />
<br />
5/24 有所謂的 hackday, 原本堅持不參加這種無聊節目的我, 剛好在 g+ 看到朋友討論 sketchup 有 embed ruby,<br />
<br />
想到了 2007 年我曾經玩耍過 embed php, 那就來拿這個來玩耍一下吧.<br />
<br />
<br />
hosted app 是 multi thread, 是所謂的 apache traffic server 的下一代, 也可以寫 plugin,<br />
<br />
所以玩法就是把 php 用 plugin 的方式, embed 進這 hosted app 裡面,<br />
<br />
掐頭掐尾, 把每次 request 中間, 要處理的資料丟進去 php runtime 處理,<br />
<br />
(其實所謂的 plugin/module 的概念都差不了太多, 就是把中間某段切出來處理呀, 只是我試著改用別種語言來搞)<br />
<br />
<br />
plugin 註冊的時候, load 進一個 php file, 裡面寫著遵守某些規範的 function,<br />
傳什麼樣的資料進去, 離開的時候, 傳什麼樣的資料出來等規範.<br />
<br />
然後就可以在每一次 request 之後, call php function 來幫你做事情.<br />
<br />
想法很完美, 大概能省的 resource 也都省掉了, code 也寫好了,<br />
<br />
基本測試也做完了, 跟差距的沒差太多, 不過一開始擔心的事情,<br />
<br />
在第二次做 concurrent connection 的時候就發生,<br />
<br />
由於敝社的 php 是 non thread, 被 embed 進 multi thread hosted app 中的時候,<br />
<br />
同時間只有一個 connection, 一切都很美好,<br />
<br />
但是只要同時有兩個 function 被 call, php runtime 一些 global variable 就會爆炸了.<br />
<br />
而即使 php 是 thread, 這問題也是會發生, 因為 php_embed 這一個 sapi 實作上的問題,<br />
<br />
他沒有把一些 global variable 切得很乾淨, 所以一定會爆炸.<br />
<br />
<br />
查了一下 php mailing list, 其實 2009 年有人遇到這樣的問題, 所以某人就實作了<br />
<br />
php_embed2, 號稱即使是 non-thread, 也一樣可以 embed 在 multi-thread hosted app 中.<br />
<br />
測試的結果, fail.<br />
<br />
Zend engine 跟我的 hosted app, 都會試著將 malloc/free 替換成他們自己的版本,<br />
<br />
然後在 php runtime init 的時候, 就爆炸了, 根本不用等到 request 處理的瞬間.<br />
<br />
所以, php embed + multi-thread hosted app FAILED.<br />
<br />
<br />
<br />
<br />
既然都 fail 了有什麼好講? 我不管, 反正就是要 embed 個什麼東西進去,<br />
手頭上幾個選項有 python, perl, lua.<br />
<br />
敝社並不養雞, 所以會寫 python 的不多, perl 很多人用,<br />
但是 default 的 perl5.8 沒有 thread, perl5.10 才有開, 但只有 32 bits binary,<br />
<br />
意思就是我得強制我的 hosted app 也跑在 32bits, 我不要呀.<br />
<br />
<br />
lua 則是聽過的人少, 會寫的更少, 不然會是最好的選擇,<br />
<br />
選項都選光了, 一樣沒有好處理的, 怎麼辦? 我話都說出去了, 要參加呀.<br />
<br />
好吧, 那 embed js 進去好了.<br />
<br />
<br />
c++ daemon 收 request, 中間轉用 js 處理一些邏輯, 最後又用 c++ 收尾,<br />
多棒呀.<br />
<br />
<br />
講到 server side js, 大家一定會想到 nodejs, 但是其實並不是 embed nodejs.<br />
因為 nodejs 目前只能寫 module 去 extend 他, 但還不接受被別人 embed,<br />
<br />
要 embed, 請找 v8.<br />
<br />
查了一下公司內的 package, v8 的版本有, 但是是 1.3.xxx, 現在 github 上的 v8 都已經 3.10.x 了, 也太老舊了吧.<br />
<br />
v8 不行, 那 spidermonkey 總行了吧?<br />
<br />
spidermonkey 有兩個版本, 1.7.0 & 1.8.5,<br />
<br />
試了一下之後, 發現這兩個版本, 雖然 api level 是基本上相容的,<br />
但是其實 1.8.x 整個 js runtime 似乎是用 c++ 整個重新實作過.<br />
<br />
我不知道誰比較好, 但是看起來 1.8.x 有把一些 jit 之類的都做出來, 好像很厲害的樣子.<br />
<br />
基本的 code 寫好, unittest 還沒做, concurrent connection 測試作過.<br />
<br />
目前的測試, 有過 js runtime 跟沒過, 大概只差了一點點.<br />
<br />
<br />
看起來是可以拿上場跟人較量了.<br />
<br />Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-38864582455644810562012-03-18T21:37:00.002+08:002012-03-18T21:40:25.313+08:00vim + clang_complete最近寫了不少 c/c++ code, 如果有 vs ide like 的 auto complete 的話, 可以少很多工.<br />
<br />
vim 下老牌的 auto complete 大概是 omni cpp complete 了吧, 不過唯一的缺點我覺得是, 要搭配 ctags 服用.<br />
<br />
<br />
前兩天在 twitter 上看人講到 clang_complete 這套, 試用之後果然考試都考一百分了, 感覺十分爽快.<br />
<br />
<br />
在 FreeBSD 下面要安裝很簡單, 首先你需要 vim with python support.<br />
<br />
<br />
1: 到 /usr/ports/editors/vim-lite 下面重新安裝 vim,<br />
make WITH_PYTHON=yes install<br />
2: 將 clang_complete clone 下來.<br />
git clone https://github.com/Rip-Rip/clang_complete.git<br />
3: 確定有裝 clang; cd /usr/ports/lang/clang; make install<br />
4: freebsd 9.0 之後, 系統預設就有 clang 了, 但是如果要更快點,<br />
這是不夠的, 因為相關 library 都被 static link 進 clang binary 中,<br />
最好是另外安裝 ports 裡面的版本.<br />
5: 到 clone 下來的 clang_complete 下面, make install 就完成了.<br />
會看到相關的 code 都被安裝到 ~/.vim 下面.<br />
6: 會感覺到慢吧? 因為他預設某些選項是關掉的,<br />
所以每次要 auto complete 的時候, 都會執行一下 clang,<br />
重新讀入所有要 parse 的 header files, 速度自然快不起來.<br />
7: 在 .vimrc 下面加行 'let g:clang_use_library=1' 吧.<br />
這會改用 libclang 做 parse 的動作, 並且將結果 cache 在記憶體<br />
裡面, 你在該次的 vim session 中, 都會使用到 cache 裡的資料.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-18089566115534796882009-10-21T10:02:00.000+08:002009-11-25T16:50:05.304+08:00freebsd + ahcimav@freebsd.org 之前將 ahci(4) import 進 freebsd source tree, 昨天在桌機上裝了一下 freebsd 8,<br /><br />順手把這個打開來用用看, 果然用起來沒問題呀.<br /><br /><br />安裝光碟, 預設還是 ata, 所以得裝完之後, 自己在 /boot/loader.conf 加上 ahci_loader="YES",<br /><br />然後修改 /etc/fstab 之後, 重開機就可以使用 ahci 了, 當然, 硬體跟 bios 都要有支援就是, 有的 bios 預設就是 ata, 要自己進去改一下,<br /><br />不然怎樣搞都還是進不了 ahci mode.<br /><br />--<br />ata 硬碟的命名是 adX, ahci 則是 adaX, 所以 fstab 得自己改過.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-83430969578959608522009-10-20T10:28:00.000+08:002009-11-25T16:50:04.638+08:00git 的 hooks由於公司內部一些東西改用 git 做版本控制, 所以現在用 git 的頻率還頗高的, <br /><br />大家共用一個 codebase 最大的缺點, 就是有人可能搞爛東西, 然後大家還不知道,<br /><br />為了預防這種事情發生, 大部分的 scm 都會有所謂的 hook, 可以在一些事情被執行前後, 做點檢查之類的事情.<br /><br />我是直接拿 git pre-commit 這個 hook, 檢查更新過的 php 的 syntax, 如果有問題直接就不給 commit,<br /><br />至於 bug, 當然是沒辦法檢查出來的.<br /><br />下面是 code, 存成 .git/hooks/pre-install, chmod u+x 一下就可以用了,<br /><br />不過比較好奇的是一般自己架設的 git server, 是可以自己處理 server side hooks, 但是 github 看起來並沒有這種機制.<br /><br /><code><br />#!/usr/bin/env php<br /><?php<br />exec( "git diff --numstat", $output );<br />$fa = array();<br />foreach( $output as $o ) {<br /> $f = explode( "\t", $o );<br /> $p = pathinfo( $f[2] );<br /> if( $p['extension'] == 'php' )<br /> $fa[] = $f[2];<br />}<br /><br />foreach( $fa as $f ) {<br /> system( "php -l $f", $result );<br /> if( $result != 0 ) {<br /> $flag = true;<br /> break;<br /> }<br />}<br />if ($flag) exit( 1 );<br />?><br /><br /></code><br />Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-33548086501651476992009-06-24T17:17:00.000+08:002009-11-25T16:50:00.220+08:00論 "php cpu 使用率不佳" 以及 php extensionpixnet 的大神貼了一篇徵才的 blog, 中間講到, "因為 php cpu 使用率不佳, 所以我們決定換成 python"...<br /><br />會說這種話, 要不就是不用功, 沒真的找出怎樣壓榨出更多 cpu 效能的辦法, 不然就是手槍打得很兇, 只會假裝自己弄了新東西很炫...<br /><br />簡單的講, facebook 大不大? yahoo 大不大? 他們都用 php 當前端顯示的 language, 你 pixnet 跟他們比, 算什麼咖?<br /><br /><br />php 作者 rasmus 自己都研究過, 一般狀況, 一個 request 進來, 到顯示完成,<br />php 本身只消耗了 10% 的 cpu, 剩下的時間, 幾乎都是等其他東西比較多, 例如資料庫, browser 端的 render 等等.<br />(<a href="http://talks.php.net/show/ntu/9)">http://talks.php.net/show/ntu/9)</a><br /><br />就算真的 cpu 使用率不佳, 總能把不佳的部份, 改用 php extension (c or c++) 來改寫, 一個在網站內最常被使用到的 function (not bif),<br />改用 php extension 方式處理的話, 速度上得提昇, 馬上就可以感覺出來.<br /><br />python 本身沒有不好, 只是把 "php cpu 使用率不佳" 這種沒有道理, 隨口胡謅的結果, 強加期望在 python 身上, 實在是罪過.<br /><br />以 yahoo 架構上來講, 重要的核心, 基本上都會有 c or c++ library, 然後會有 php extension 來封裝起來,<br /><br />一般的 web coder, 只要知道 php extension 版本的語法就好, 後面的速度跟效能, 只要 c or c++ library 升級, 馬上就得到成果.<br /><br />Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-35586836075442070542008-12-18T12:00:00.000+08:002009-11-25T16:49:53.672+08:00php ctemplate for win32昨晚突然想到, 應該弄一下 php ctemplate 的 win32 binary,<br /><br />因為 google ctemplate 原本就是 win32 ready, php 也是, 那為甚麼不順便做一下 php ctemplate php extension for win32 呢?<br /><br />測試了一下, 東西已經丟上 github 了.<br /><h2>https://github.com/vanillahsu/php-ctemplate/tree</h2><br />有需要的自己弄一份吧, binary 的話, 私下講吧.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-29378440340221258282008-12-16T10:29:00.000+08:002009-11-24T13:29:05.756+08:00pcre & pcrecpppcre 是 unix 上被使用的很頻繁的 regex library, 原本是 exim (一套 sendmail like 的 mail) 想要做 perl compatible regex library,<br /><br />最後一堆軟體都不小心有用到, php 的 preg_* 後面就是 pcre.<br /><br />最近把一個工作上, 其他同事慣用的 php template library 改成 php ext,<br /><br />為甚麼要這樣做呢?<br /><br />因為 coder & designer 已經用習慣, 叫他們改, 大概會殺人吧.<br /><br />所以只好退而求其次, 一樣用他們習慣的 rule & style 去做.<br /><br />而該 template library, 其實就是一堆 preg_match & preg_replace 組成的,<br /><br />php ext 也照圖說故事, 該用的地方就用一下.<br /><br />我是用 c++ 來改寫的, 所以一堆原本 php 的 array, 直接用 stl 就可以很快樂,<br /><br />preg_* 的 function, 也是可以直接用 pcre c function 來做,<br /><br />但是, 但是.<br /><br />google 約在 2006 年左右, 貢獻了一個 c++ binding 給 pcre, 所以如果願意的話, cpp binding 用起來更爽快點.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0tag:blogger.com,1999:blog-9215350140615208828.post-47643886214234795062008-10-06T15:21:00.000+08:002009-11-24T13:29:02.300+08:00socket with ssl昨天做 net/spserver 的修改, 把原本少弄進去的 matrixssl, gnutls, xyssl 的東西補上,<br /><br />看到 xyssl 的 sample code, 是讓一般的 tcp server & client 可以用 ssl 收發資料,<br /><br />覺得還頗簡單的, 然後又去看了一下 openssl demo code,<br /><br />我的第一印象, 就是覺得 openssl + socket 應該很難搞,<br /><br />沒想到看了一下, 還真簡單<br /><br />open socket 之後, 把 fd 用 SSL_set_fd 餵到 ssl 裡面,<br /><br />再來就用 SSL_read & SSL_write 取代原本的 read/send 就好了.<br /><br />真方便.Vanillahttp://www.blogger.com/profile/01811227327050754560noreply@blogger.com0