Category Archives: 分享

Python SCSS與Compass/Blueprint輕鬆整合

身為網頁的開發者,相信在寫CSS時總會覺得少了什麼,很多風格明明都只差了一兩句,就得複製貼上或是重寫好幾次,此時你會想說如果有個import或是繼承CSS樣式的語法就好了、如果能夠訂義變數然後在CSS語法裡做加減乘除就好了,而事實上這些SCSS與SASS都可以幫你做到,它是一種將CSS擴充的一種語言,先用SCSS或SASS寫好網頁的排版,接著再用工具將其編譯成CSS檔 取此官網的例子,例如你可以這樣寫 $blue: #3bbfce; $margin: 16px; .content-navigation { border-color: $blue; color: darken($blue, 9%); } .border { padding: $margin / 2; margin: $margin / 2; border-color: $blue; } 事先定義好變數,然後在裡面使用,這還只是小小的功能之一,它還可以繼承、引入,比起直接寫CSS方便了許多 搭配上Compass/Blueprint的CSS框架,寫起來更是輕鬆愉快,想要重設CSS嗎? 很簡單 @import “compass/reset” @include blueprint-global-reset; @import “compass/reset” 是指引入compass/rest這個模組,然後@include blueprint-global-reset;是指將SCSS的語法片段插入此處,如此一來就輕鬆地重設了CSS,然而,這只不過是小菜一盤 想要採用CSS3,但是又對於-moz、-webkit、-ms … … Continue reading

Posted in Python, 中文文章, 分享 | Tagged , , , , , , , | 1 Comment

新世紀通訊函式庫 – ZeroMQ

2012年就快到了,離2015年第三次衝擊也快到了,聽不懂我在說什麼就算了,跟主題沒什麼關聯,在介紹主角之前,我總喜歡描述一下主角的背景 欲上雲端,必先分散 這幾年,雲端炒得正熱門,愛跟風的台灣人當然也不能錯過,不管是賣主機的聲稱他們是做雲端的,連賣房子的也稱他們的是雲端,哪天就連在路邊看見雲端雞排都請不要大驚小怪,因為那簡直和奈米光觸媒雞排一樣有異曲同工之妙,然而口口聲聲說雲端,但前陣子iPhone4S預購就給了各家電信商一個大巴掌,他們的網頁伺服器都在一瞬間被大量擁入的使用者塞暴了,更別說其中還有不乏自家推出雲端服務的電信商,說真的,連分散運算的基本功都做不到,跟人家雲什麼端? 你說是吧? 但今天的主角不在於雲端是什麼,或是什麼才算真正的雲端之類的無聊話題,今天的主軸是分散式運算,因為要達到規模的運算和高可得性就一定要扯到分散式的運算,而分散式運算一直以來都不是什麼簡單的議題,最麻煩的就要算是溝通上的問題了,如果你有 三個節點之間想要進行溝通,該怎麼做? 你說簡單,直接串在一起不就好了? 好吧,或許你只有固定的三個節點,這好辦,但是要是你有更多的節點呢? 考慮一下十個節點、一百個節點,光想像就能知道,隨著節點的增加,他們之間的連線數量呈指數在成長,不光是連線本身的問題,連這些節點要如何知道對方的存在以及管理都是相當麻煩的問題 中央集權 光想就令人頭皮發麻,為了解決這樣的問題,一個經典的模式被設計且大量使用,那就是所謂的 Broker (掮客),也有稱Message Queue、Message bus等,簡單的概念,就是所有節點都連向中間的訊息交換伺服器,而溝通都透過這個中央的交換中心來進行,節點與節點之間無需去在意到底誰在和我溝通,只需要在意訊息的種類和內容即可   雖然這樣的模式解決了一些問題,但同時也引入了新的問題,分散式系統的頭號公敵 – 單點失效,正因為所有節點都依賴著這個中間的掮客幫忙轉送訊息,這也意味著當掮客網路斷線、當機等等意外的發生,都會讓整個系統陷入停擺的狀態,除此之外還有另一個嚴重的問題,就是當節點數量增加,掮客的工作量也會一直往上升,在無法擴增的情況下會造成整個系統的擴展性受到限制,效能也會因為掮客受限制 各自為政 正因為中央集權造成了問題,所以有人提出了各自為政來解決問題,可以想見的,在分散式的系統裡,並不是所有的節點都需要和所有人進行溝通,他們通常只需要和特定的節點溝通,舉個例子,假設你設計的是一個多媒體檔案的處理系統,在第一個節點可能做的是Hash,用來產生該檔案的唯一識別編號,節點二做的是轉檔,節點三做的是儲存,節點四做的是歸檔,那麼你需要的就只是這樣的結構,如果以物件導向的設計模式來看,我們稱這樣的結構為責任鏈   再看另一個例子,如果我們是氣象局,想發佈各種天氣的消息,那麼你需要的是一個伺服器,讓大家去訂閱他們有興趣的主題,這樣的結構以物件導向的觀點來看就叫做觀察者模式,與我們先前見到的Broker做的是一樣的事情,然而在這裡的重點在於該伺服器只負責發佈天氣消息,並不參與訊息的交換 整體的概念就是各自有不同的子系統,我們透過通訊的方式將它們串在一起,這樣做有個好處就是效能好,再來就是設計得當的話,某子系統雖然停擺,但不會影響到所有的系統 各自為政的代價 雖然各自為政的做法有其好處,但相對的也有它的代價,光是通訊的協定就是很腦人的問題,考慮一下各種不同的子系統間該用什麼協定來溝通,連線中斷了怎麼處理,負載平衡? 這些問題都要花相當大的心力來解決 而在不同的環境下,使用不同的通訊方式都各有好處,使用TCP/IP的話,不管你的節點在同一台機器或是遠端,都可以連線,缺點是在同一台機器會有一定的效能耗損,而且遇到廣播的訊息,同樣的訊息被傳送N次,就沒有UDP廣播來得划算,如果節點是在同一台機器上溝通,使用IPC的方式效率好,如果是在同一個thread裡,那麼分享記憶體的方式最快,IPC反而會拖慢速度,正因為有各種不同的考量,使得想要達成高效率的分散式系統是一件困難的事情 是主角登場的時候了 – ZeroMQ 講了半天,ZeroMQ到底是做什麼用的? 簡單的來說,它是一套網路通訊函式庫,用來解決上面所提到的問題,考慮一下上面所提到的物件導向設計模式,你想,即然那樣的模式一再出現,為什麼我們不能將這些常見的通訊方式變成可以輕易重覆使用的形式? ZeroMQ所做到的即是如此,它將常見的通訊方式定義成不同行為的socket,讓你可以輕易地重覆使用這些樣式去組出強健的分散式系統 老樣子 Hello world.. 不! 是Hello baby … Continue reading

Posted in 中文文章, 分享 | Tagged , , , , , , , , , , , , , | 8 Comments

那些台灣軟體產業所缺少的 – 自動化測試

你是否有計算過,你在寫專案的過程中,測試過了多少次的程式? 我想是沒有,我也沒有,但是你是否有曾想過,或是感覺過,隨著專案的膨漲,你要測試的項目也跟著變多了? 這是理所當然的事情,當專案小,測試還算很輕鬆,因為程式的功能不外乎就那幾樣,一轉眼就測完了,常見的寫程式流程會像這樣 撰寫新功能 測試新功能 當然,也有修正bug的情況 修正bug 測試bug 如此一直循環,當你寫了新功能,理所當然地會去測試新功能,看是否如你預期地執行,那舊功能呢? 或許你記憶力不錯,在寫新功能的同時,想到先前某個舊功能是依賴現在改的東西,這麼一改可能會造成舊的功能出問題,於是你也順便測了一下舊的功能,當程式還小 撰寫新功能 測試新功能 測試舊功能 嘿,不怎麼樣吧? 只佔了開發時間的三分之一,好吧那如果有更多的舊功能要測呢? 撰寫新功能 測試新功能 測試舊功能 測試舊功能 測試舊功能 …. 發現了沒有? 隨著你的專案越來越大,如果要確保整個系統所有的功能都是正常運作的,無可避免地,在你修改程式之後要測試的項目會越來越多 這表示你每寫一行新程式的成本增加了,身為以減低成本為傲的島國 國民: 台灣人…,你說,簡單! 不要測舊功能不就好了? 是的,我想這可能就是最常見的情況,不要測試舊功能理所當然地,每寫一行的程式成本都保持一樣很低,但這代表著舊程式可能出錯的風險也跟著增加了,當你喜滋滋地覺得你幫公司省了成本,結果在一個月後因為舊程式缺乏測試,因改動了核心的部份造成舊的功能將所有資料外洩,公司損失慘重,這就是不重視軟體品質的後果 舉真實生活上發生過的例子,PTT曾經有過改程式未經好好地測試,造成每個人都能以管理員的權限登入的事情,知名的檔案同步平台Dropbox,也曾經發生過因為認證的程式改版有bug,造成任何人都可以登入別人帳號的事,我也有曾聽聞一些網站因為工程師為了測試方便,把認證的函數暫時改成 function authenticate(user_id, password) { return true; // do authentication here // … Continue reading

Posted in 中文文章, 分享, 嘴砲, 資訊安全 | Tagged , , , , , , | 5 Comments

那些台灣軟體產業所缺少的 – 版本控制系統

這幾年來,多多少少接觸了不少業界的人,雖然我自己還不算有真正待過業界太久,但是這期間看到不少業界的現象都令我挺驚訝的,例如在聊天時提到你們公司用的版本控制系統是什麼,有很多人都會回答 「那是什麼?」,一直以來這些在國外的主流開發環境都基本常識或是標準配備的東西台灣業界居然很多都連有那樣的工具存在都不知道,或著是對於某些東西有錯誤的認知,所以我想大略提一下常見的幾個問題 版本控制系統 我想這是最常見的毛病,很常發現很多公司在開發軟體時從來都不使用版本控制系統,最誇張的狀況就是管它三七二十一直接修改   除此之外,常見的土法鍊鋼有聽說過資料夾複製,然後將資料夾名稱命名為版本1之類的方法,高級一點還有搭配Excel來記錄改過了什麼之類的 更進階的還有多人共同開發,還架了FTP來放這些檔案 但這些都有很大的問題,而且其會遇到的問題都正好是版本控制系統所要解決的,所以到底是什麼樣的問題非用版本控制系統不可? 首先,用資料夾copy有個很大的問題,一來是copy的過程很容易出錯,而且更糟的是出的錯很難發現,你怎麼從資料夾的內容來判斷這到底是哪個版本? 最常見的做法就是回想你到底在哪個版本改了什麼,然後去看對應的位置,是否有那些改動,但你有可能記得嗎? 要是程式不是你改的呢? 因此依賴資料夾名稱來得知檔案的版本是極度不可靠的做法,再者,如果你不幸改到錯誤的版本,辛辛苦苦改了半天,才發現改到舊版本了,那你要如何把你改的和正確的版本合在一起? 如果你只改了三行,這還好辦,但如果你改了三百行,那該怎麼辦? 用Excel來記錄改動的事項和版本一樣不會有幫助 那多人開發使用FTP來分享檔案呢? 老天,事情更慘了,原先只是你自己的開發,自己改錯了就算了,如今變成多人開發,有時出問題還不是你改的,這樣想好了,FTP上有個檔案 hello.py 今天張三載回去改了,變成 hello.py (張三版) 不幸的是,王五在張三上傳回FTP之前,也載回來改,變成 hello.py (王五版) 接著,張三把它的檔案上傳了,所以FTP上的檔案變成了 hello.py (張三版) 然後好戲發生了,王五也把它改的東西上傳了,所以FTP上的檔案被蓋掉,變成 hello.py (王五版) 發生了什麼事? 張三改的版本被蓋掉了,你可以想見張三在demo給老闆看時發現改的地方被蓋掉了,翻過辦公桌衝過去揍王五的情景了嗎? 像這樣還只是最簡單的情境,以這類土法鍊鋼的方式,還有太多太多預料不到的複雜情況會發生,什麼? 那你說,如果我們規定每人都得把資料夾以自己的名稱命名,加上版號,再上傳,這樣就不會錯了吧? hello_project-王五-rev123/ 拜託,何苦呢 ? 版本控制系統就是用來解決這些問題而開發出來的,學一套新工具有這麼難嗎? 常見的理由可能會有什麼沒時間學、不信任工具等等,事實上那些都不是理由,只要是程式碼的開發,都得使用版本控制系統,現在已經是2011年,如果你的軟體開發沒有使用版本控制系統,我說這不叫落後,這是原始 用了版本控制系統,最重要的好處是 你可以安心地放膽去改程式 … Continue reading

Posted in 中文文章, 分享, 嘴砲 | Tagged , , , | 9 Comments

淺談區域性 (locality)

在設計不同的網路服務系統時,為了能夠有擴展性,通常都會設計成分散式的架構,然而除了架構上的設計,如何部署也是很重要的事,其中有個很重要的議題叫做區域性,因為沒有統一或明確的翻譯慣例,所以以英文來說明較為精確,在這裡指的區域性英文為locality,對於這個議題最近有一點心得 所以,回到主題,到底什麼是區域性? 簡單的來說,就是存取資料或資源時,很常存取或是相關的資料放在一起、或很近的地方的特性,舉個實例,例如假設我們有關於某個使用者的資料,但是使用者相關的資料分散在全球不同的資料庫裡,這時我們就會說,這資料庫的區域性不好,以圖來表示,我們假設使用者的資料分散在美西的DB1、美中的DB2和美東的DB3,而使用者在西雅圖要存取這些資料,就得走很遠的距離到三個很遠的地點存取資料 反言之,如果關於這使用者的資料,都存在離使用者很近的點,而且也都在同樣或是很接近的資料庫裡,那麼存取起來就會較快,這樣一來我們就可以說這樣的資料儲存方式它的區域性比較好,我們假設把同一使用者相關的資料都放在相近的地方,以圖為例,都放在加洲,這樣一來同樣是存取使用者的資料,其中所花的傳輸距離成本就遠比上一個例子來得少,反應速度也會因此較快 一般而言,區域性是越強越好,但是也有例外,那就是當考慮到可得性(availability)的時候,這樣的特性是指資料或資源隨時都可取得的機率高低,如果當我們把雞蛋放在同一個籃子裡,也就是資料都放在同樣的Datacenter裡,一但這個Datacenter對外的網路中斷,或是甚至遇到不可預料的災難時,那麼那些資料都會因此而無法取得,所以除了考慮到存取時的區域性,當資料有一定重要程度時,可得性也是很重要的考量,所以某些情況下,資料分散也是必要的 然而,區域性就表面看來,似乎只要將常用的、相關的資料都放在一起好像就能達成,然而經過仔細思考會發現其實並不是只有這樣,還有需要考慮到存取資料的距離,還有存取要求本身的高低階,在這篇文章我想分享的就是主要在於思考關於區域性設計上的一些理論的心得 請求的相依性與粒度 我發現並不是所有的情況下不佳的地區性都一定會嚴重影響到存取的效能,像是請求的相依性其實對於延遲的影響就非常大,如果說所有的情求都不能同時處理,一定得要上一個完成才能完成下一個的話,這樣一來就會造成每個request的請求都要額外花費一次連線的延遲成本,可以參考下圖 很明顯的,左邊的情況,傳輸距離所造成的影響,會是 請求數量 * (運算成本 + 延遲成本) 右邊的情況是 (請求數量 * 運算成本) + 延遲成本 因此光是請求是否能同步處理,並且是否有前後相依,就會造成相當大的差別,如果請求的數量越多,這樣的成本差距就越大,左邊的例子我們以NoSQL或是 SQL的請求為例子,通常下一道請求都是基於上一道請求的資料而決定的,如果說任務被拆散成很零碎的多道請求,像是有些key-value based的NoSQL資料庫,因為沒有高階的查詢指令,必然會有大量的請求,如此一來如果NoSQL資料庫放在很遠的地方,就會造成光是這之間的傳輸成本就會高得嚇人,而以SQL來看,因為可以盡可能地將多道SQL濃縮為少數幾道查詢,因此同樣的傳輸成本對於SQL資料庫來說,傳輸的成本造成的影響會小一點 而右邊的情況,通常是大量的資料傳輸,例如影音串流,因為上一筆資料無關下一筆資料,以這種情況來看,傳輸的距離不會是太大的問題,只有一開始會有的傳輸延遲 心得 一些簡單的心得就是,當請求是相依的,如果數量不大,那麼其實傳輸的延遲是可以被忽視的,又或著是大量連續的資料傳輸,距離的影響是較小的,如果不考慮連線的品質問題的話,但是如果是有相依特性的請求,數量又大的話,最好資料庫的部署要越接近越好,否則光是連線的延遲成本就相當驚人,就算你的NoSQL資料庫再怎麼快,也沒有任何幫助,甚至會比SQL資料庫還要慢

Posted in 中文文章, 分享 | Tagged , , , , | Comments Off on 淺談區域性 (locality)

我的open source專案整理列表

從很久以前,我就覺得open source是一件很酷的事,覺得能夠免費讓大家用自己心血的結晶真的是件很了不起的事,因此我自己除了使用了不少的open source資源,也一直希望自己也能夠多少有點貢獻,所以在過去多年中確實也有寫了一些open source的專案,雖然都不大,但都很多都是我自己會用到的工具,雖然以前可能有寫過一些介紹,但其實還有不少是沒有介紹過的,會寫open source專案其實多少就是希望有人能使用,而隨著時間久了,我自己會在看到時才想起原來我有寫過這個專案,所以想說弄篇文章來整理一下我所做過的open source專案 Python HGE HGE以前是一款商用的2D遊戲引擎,後來開源,因為我覺得他的引擎挺簡單好用的,重點是有硬體加速,不像SDL純軟體算圖很慢,所以想說把它移植到Python,於是就用Boost.Python寫了一個專案,完成度大約7~8成,裡面有些比較難處理的部份還沒弄好,但主要功能大多都已經可以使用 專案網址: http://code.google.com/p/python-hge/ Gluttony Glottony是一個用來分析Python函式庫在PyPi上的相依情況,主要是有一次我安裝TurboGears時遇到其中一個package的伺服器似乎掛掉了,整個進度就因為那個檔案載不了而無法進行,因此我覺得或許這種相依的情況也是選工具時重要的考量,於是就寫了這樣的工具 專案網址: https://bitbucket.org/victorlin/gluttony Po translator 這是一個用來將.PO檔中的內容透過Google自動翻譯的工具,主要是因為我自己的網站有中文版,想翻成簡體中文,手動一個一個實在太花時間,於是就寫了一個這樣的工具,不過目前有個缺點是當送的量太多,會被Google擋掉一陣子的樣子 專案網址: https://bitbucket.org/victorlin/po_translate Apply firewall iptable幾乎是所有用Linux主機多少都會用到的服務,但是在重設iptable的過程中,難免有時會不小心擋掉自己,如果是遠端登入就麻煩大了,主機在美國也碰不到,只有遠端重開機一條路可走,為了解決這問題,我做這個小工具,可以讓設定iptable像是切換螢幕解析度一樣,會有一段時間讓你確認,沒反應的話會自動取回更動前的設定 專案網址: https://bitbucket.org/victorlin/apply_firewall Correct pycountry 這是一個pycountry的fork,主要是因為pycountry引用ISO裡的國家名稱,但大家都知道台灣的名稱被ISO亂訂,看了心情就不是很爽,所以就fork出一個專案然後改掉裡面的名稱部份 專案網址: https://bitbucket.org/victorlin/correct_pycountry Middleman Middleman是一個基於gevent的簡單網頁proxy,主要是我自己寫來抓論文用的,不過現在已經沒在使用,middleman的名稱主要是取自middleman attack 專案網址: https://bitbucket.org/victorlin/middleman/ Logy 一個簡易的中央日誌記錄用的網頁服務,目前沒有繼續開發的打算 專案網址: https://bitbucket.org/victorlin/logy Loso … Continue reading

Posted in 中文文章, 分享 | Tagged , | 8 Comments

Zero-downtime service migration

When I am running my website, now.in, I did encounter a trouble.  That is, when there is a bug in the production server, then I need to restart them.  Sounds fine, right? Just to restart a server.  Yes, for most … Continue reading

Posted in English Articles, Python, Unix-Like, 分享 | Tagged , , , , | 1 Comment

無停機服務遷移

一直以來在營運now.in都有一個令人困擾的問題,就是每當伺服器更新或是出現問題時,就得關掉重開,雖然說大部份的伺服器我在設計上都做成重開也沒有關係,但有少部份一但重啟就會造成使用者斷線,參考下面這張伺服器狀態的圖 圖中被切斷的山峰都是伺服器重啟的時候,無疑的這對使用者來說是不好的體驗,對於一般網頁HTTP這類stateless的伺服器來說重啟是無所謂,但串流伺服器就不一樣,因此最近我在思考如何解決這樣的問題,首先想到的是伺服器重開的原因,不外乎有幾種 部署新版的程式 為了修正BUG 記憶體用量過高 重新讀取執行環境,例如ulimit -n,也就是檔案數量的限制大小 從主機A移到主機B 以Python的伺服器來說,如果只是單單只是為了部署新版的程式,Python有個reload函數可以重讀整個module,因此可以設個管理用的後門用來重載模組,但是這樣做有個問題,就是已經產生的instance還是一樣,其實說穿了等於是重新執行那個module,如果只是簡單的改版還好,但複雜的改版就可能牽扯到太多因素難以透過這樣來更新,而除此之外,很多重開的因素像是記憶體用量過高,或著執行的環境參數改變,這些都無可避免的一定得建新的process,至於從A主機移到B主機,基本上是難以避免的一定得重啟伺服器,除非有某個前端的伺服器保持連線,後端的伺服器進行交移工作才有可能,而主機轉移的狀況其實很少出現,因此這篇文章要探討的是如何辦到同一臺機器內的服務轉移 方法 最大的問題就在於,連線中的socket該如保持住連線,最簡單的想法就是建立新的process,將目前的連線交給新的process,新的process接手完所有的連線開始運作後舊的process就能終止了,當然所謂的連線還包函了服務的狀態,我們在者裡稱之為 CSD (Connection State Descriptor),大致想法如下面圖片所示 首先Process A是正在運行的process,而Manager是負責控制遷移的process 此時Manager啟動了要負責接手的Process B 接著Manager通知A將連線狀態傳送給Process B,B接手後繼續提供服務,並且告知接收完成 在確定B能夠接手服務並且正確執行後,這時Manager就能將A中止,走到這裡服務就算是完整地移交了,中間沒有任何間斷 技術層面問題 – Socket的轉移 這樣的做法理論上看起來確實可行沒錯,但是最主要有技術上的問題得解決,就是如何將socket,或著是file descriptor轉移到另一個process,在我找過相關的資料後知道目前有兩個方法 child process 這個方法主要是因為child process在生成後會繼承parent process的file descriptor,但是缺點就是只限於child process,如果我們想將服務移交給另一個完整的獨立process這個方法就會行不通,因此使用上會有很多限制 sendmsg 另一個方法就是unix domain的socket有提供一個函數叫sendmsg,可以將file descriptor轉移到任何process,這樣一來實用性就比child process高很多,於是我決定採用此方法 簡易的實作 … Continue reading

Posted in Python, 中文文章, 分享 | Tagged , , , , , , , | 7 Comments

Logy – a central logging system for Python

I’m glad to announce my new open source project:Logy. Logy is a simple lightweight central logging system for Python. When do you need a central logging system?  Well, when you have many servers online, and they are running different python … Continue reading

Posted in English Articles, 分享 | Tagged , , | 1 Comment

Po translate – automatic translation tool for .PO files

It is kinda hateful to translate .PO files from Traditional-Chinese to Simplified-Chinese, most of the meanings are identical but different in simplified word or traditional word.  It is not a very difficult to translate.  But however, it is still an … Continue reading

Posted in English Articles, Python, 分享 | Tagged , , , , , , | 1 Comment