網頁

2012年11月19日 星期一

在 windows 上面建立 android 開發環境 (eclipse adt + ndk)

因為有一隻熊太笨了,要編 android 的程式卻苦於沒有環境,所以這裡簡單記錄一下 android 開發環境(on Windows)的建造過程。

1.) 首先,你會需要 jdk。

2.) 然後安裝 Eclipse CDT。

3.) 在 Eclipse 裡面安裝 ADT(選 Help->Install New Software, Work with 填入 https://dl-ssl.google.com/android/eclipse/ 
    然後選 Developer Tools 跟 NDK Plugin)。

4.) 重新啟動 Eclipse 後會要你安裝 android sdk。

5.) 安裝 NDK。

6.) 下載需要的 cocos2d-x。

7.) 安裝 TortoiseSVN
然後來測試是否能夠編譯 C++ Project:

1.) 開啟 Eclipse,選 File->New->Project ,選 Android Project from Existing Code

2.) 選一個 Cocos2ds-X 的 Sample 匯入成 Project (這裡是 TestCpp)

3.) 會看到 Cocos2dxActivity cannot be resolved to a type 有三個錯誤,暫時解法是把 Cocos2d-X 目錄
中的 
    cocos2dx/platform/android/java 也 import 成一個 project。

4.) 在 TestCpp Project 上面按右鍵,選 Properties,找裡面的 Builders。

5.) 按 New 新增一個 Builder,然後路徑選 NDK 裡面的 ndk-build.cmd。

6.) 把 tab 切到 environment,新增 NDK_MODULE_PATH 變數,後面給兩個值 
    C:\android\cocos2d-2.0-x-2.0.4;C:\android\cocos2d-2.0-x-2.0.4\cocos2dx\platform\third_party\android\prebuilt 
    中間用分號隔開

7.) 建立完成後把 NDKBuilder 推到最上面

8.) Project -> Build Project 就會開始編譯。



更詳細的圖文請參考:這裡

UPDATE: 遇到 The import org.cocos2dx.lib cannot be resolved    錯誤的話,把  cocos2d-2.0-x-2.0.3/cocos2dx/platform/android/java 也 import 進來就好了,參考

2012年10月18日 星期四

HTC One X 斷電後進入 bootloader

昨天想把 unlock 過且刷過第三方韌體的 HTC One X 給 ruu 回原廠韌體(必須要重新 lock),結果遇到幾個問題,卡了好幾個小時,簡單記錄如下。

1) 本來想先 restore backup ,回到當初剛 root 完的狀態,但不知道為何卻一直卡在 One 的那個 load 畫面,那是處於 fastboot 失效且無 adb 的狀態,然後用三鍵斷電重開卻又無法進入,持續 bootloop。

解法:這是按法的問題,在三鍵強制斷電重開的時候,似乎馬上接著只按volum down 並不會偵測到。而應該改成三鍵重開按完,下面三個按鍵燈閃爍時先放掉 volum up,然後過一下子再放開 power ,即可進入 bootloader 。

2) 找不到快速的 ruu 載點,不是要註冊收費就是很慢

後來在 htcruu 找到.exe,然後在 這裡 找到 2.17 的台版 ruu。

3) ruu 更新一直失敗,卡在錯誤的 bootloader

這裡有兩個原因,一個是要用 fastboot oem readcid 對照看看抓的版本是不是一樣,我本來抓 Asia-TW 但後來發現手上版本都是 TWM,瞎忙了一陣子。

然後用 fastboot getvar all 看一下
E:\OneX\Android\Tools1.26>fastboot getvar all
(bootloader) version: 0.5a
(bootloader) version-bootloader: 1.12.0000
(bootloader) version-baseband: 1.1204.104.14
(bootloader) version-cpld: None
(bootloader) version-microp: None
(bootloader) version-main: 2.17.709.2
(bootloader) serialno: HT258W1A0919
(bootloader) imei: 353043057600408
(bootloader) product: endeavoru
(bootloader) platform: HBOOT-T30S
(bootloader) modelid: PJ4610000
(bootloader) cidnum: HTC__621
(bootloader) battery-status: good
(bootloader) battery-voltage: 3848mV
(bootloader) devpower: 59
(bootloader) partition-layout: None
(bootloader) security: on
(bootloader) build-mode: SHIP
(bootloader) boot-mode: FASTBOOT
(bootloader) commitno-bootloader: None
(bootloader) hbootpreupdate: 2
(bootloader) gencheckpt: 0
all: Done!
finished. total time: 0.827s 

注意當中的 HBoot Version ,這裡的版本如果比 ruu 裡面就的話就會報 bootloader 錯誤。 解決方是參考mobile01 上的 (8/23) One X RUU回復/Recovery/OTA相關教學 自己做一個專屬的 ruu 來就 ok 了。


2012年10月12日 星期五

在 hicloud 遭遇的狀況

最近因為遇到一些問題,所以開始 survey 往雲端發展的環境,目前在 hicloud 降價之後,價格到具有競爭力的階段(之前是 In/Out 合併計算,每 GB NTD 15,降價後只算 Out,每 GB NTD 3),目前待了一個月左右,有一些有點麻煩的問題。

由於線上是 VM 環境(vmware),所以資源共用是一件很合理的事情,但如果當我們的 VM 跟其他大戶放在一起,便會有很恐怖的事情發生。

圖中可以看到,Disk I/O 忽然在 12 點過後就進入瘋狂的 busy 狀態,在這個狀態下大部份的 CPU Time 都跑去做 IO Wait,所以 Load Average 莫名飆高,而整個跟 Disk 有關的動作都完全被卡死。

這個狀態持續了快 18 個小時,最後在連續三張 Ticket 以及好幾次電話之後才解決。

如果是一般的 Web Application,那只會暫時慢一下,沒有太大影響。但由於我的 Socket Server 是直接呼叫 MySQL C API ,在這裡則會直接 blocking,然後就會 Out of Service。

在這種 workload 都還算 micro 的狀況底下就出這種包,實在是有點誇張。

PS: 在當時,連一個大概十萬筆有 Index 的資料,下去做 query 限制三十筆輸出,都可以花上 20 多秒鐘?! 這不會太誇張嗎?

所以當時對 ext4 的檔案系統有稍微調整一下。

1: 取消 access time 更新
2: 延長 write-back 的時間

(參考)

# 把 /etc/fstab 加上 noatime 跟 data=writeback

tune2fs -o journal_data_writeback /dev/sdaX

UUID=9ee7afff-654d-123c-b936-fe96354bec0c /               ext4    errors=remount-ro,noatime,data=writeback 0       1
# /etc/sysctl.conf 加上延長 writeback 時間

vm.dirty_writeback_centisecs = 360000


本來想把 ext4 的 journal 關掉,但是看了看好像不妥,尤其是需要 unmount/fsck ,我又是 root partition ,就放棄了。

看來目前能做的就是

1) 盡力讓 Database 有效率(快)一點,把不用的資料丟進 archive
2) 想辦法讓 server 對 MySQL 的存取變成 Asynchronous I/O,就算 MySQL 塞住也不要 blocking。
3) 求神拜佛希望 cloud 環境不要再出狀況了 (嘆)

2012年10月11日 星期四

在 Blogger 上用 Google Code Prettify 顯示程式碼

blog 荒廢了好長一段時間,還是習慣 wordpress 裡面 rich editor 的寫作方式,但是實在是受不了自己 maintain 機器那種一陣子爆炸一次之後就再那邊焦頭爛額的慘劇,但 wordpress.com 裡面的客製化域名又是年費計算,感覺不太爽,所以索性把 blog 移到 blogger 上來。

遇到的第一個問題就是貼 code 的部份,印象中在 zeroplex 那邊有看過,本來跟他問是用什麼方法貼的,但三更半夜的誰有閒情逸致待在電腦前呢,大概只有 ㄐㄒㄈ資深工程師 還在公司埋頭苦幹吧?

Google 了一下看到了 在 Blogger 文章中利用 CSS Block 及 Google Code Prettify 顯示程式碼這篇文章,照著做也確實是可以運作的,而且當中的 background image 偷偷從 zeroplex 那邊偷了 base64 encode的 gif 直接藏在 template 中也挺方便, 不過 onLoad 放在 <body> 中會造成整頁一直卡住 Loading 的問題,會讓網頁速度拖慢,有點討厭。

剛剛又稍為找了一下發現在 stackoverflow 裡面的這篇解答提供了一個比較方便的解法,也不需要改動太多的 template code,作法如下:

先把自己想要的 Design 給選好,然後進到 Blogger 的 Design 頁面選[編輯HTML]在 <head> 後面貼這段:

<link href="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" language="javascript" src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js"></script>
<script type="text/javascript" language="javascript" src="http://google-code-prettify.googlecode.com/svn/trunk/src/lang-css.js"></script>
<script type="text/javascript">
    document.addEventListener('DOMContentLoaded',function() {
        prettyPrint();
    });
</script>
然後進到 自訂->進階-> Add CSS,加入這段:

pre.code {
  display: block; /* fixes a strange ie margin bug */
  font-family: Courier New; 
  font-size: 10pt; 
  overflow:auto; 
  background: #f0f0f0 url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAASwCAYAAAAt7rCDAAAABHNCSVQICAgIfAhkiAAAAQJJREFUeJzt0kEKhDAMBdA4zFmbM+W0upqFOhXrDILwsimFR5pfMrXW5jhZr7PwRlxVX8//jNHrGhExjXzdu9c5IiIz+7iqVmB7Hwp4OMa2nhhwN/PRGEMBh3Zjt6KfpzPztxW9MSAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzB8HS+J9kUTvzEDMwAAAABJRU5ErkJggg==) left top repeat-y;
  border: 1px solid #ccc;
  padding: 10px 10px 10px 21px;
  max-height:200px;
  line-height: 1.2em;
}
之後只要用 <pre class="code prettyprint">要顯示的 code</pre> 就可以顯示了。

Happy Blogging !

2012年9月11日 星期二

ubuntu 筆記

最近因為某些原因,所以開始測試國內的雲端環境,挑選的是中華電信的 hiCloud 服務,前面一些跌跌撞撞的紀錄就不多說了;簡單講,本來選了以為會比較好用的 CentOS 結果卻非常不順手,用了三天毅然決然把環境換為 ubuntu,直接 apt-get update 然後 do-release-upgrade -d 把原來的 ubuntu 10.04 升到 12.04 。玩了一陣子下來,果然順暢多了。
但是卻發現 hiCloud 目前無法自己製作 image deploy,所以只好把該記的記下來。
下面就是一些重新演練的環境紀錄,供以後參考。

基本環境設定


先安裝 sshd、vim、screen

apt-get install openssh-server
apt-get install vim
apt-get install screen

設定目前機器的網路環境

vim /etc/network/interfaces
iface lo inet loopback
auto lo

auto eth1
iface eth1 inet dhcp

改成
iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1

升級系統


大致上是 apt-get update , apt upgrade 就可以解決。 一開始我是會用 apt-get 的 mirror 功能讓他自動依區育去挑 mirror,方法為在 /etc/apt/source.list 的最前面加上
deb mirror://mirrors.ubuntu.com/mirrors.txt precise main restricted universe multiverse
deb mirror://mirrors.ubuntu.com/mirrors.txt precise-updates main restricted universe multiverse
deb mirror://mirrors.ubuntu.com/mirrors.txt precise-backports main restricted universe multiverse
deb mirror://mirrors.ubuntu.com/mirrors.txt precise-security main restricted universe multiverse
但不幸遇到 tw.archive.ubuntu.com 掛掉的問題的話,就到 官方mirror列表找自己的地區然後是Up to date的,這裡我是選國網自由軟體實驗室的mirror,然後把 /etc/apt/source.list 改成
#

# deb cdrom:[Ubuntu-Server 12.04.1 LTS _Precise Pangolin_ - Release amd64 (20120817.3)]/ dists/precise/main/binary-i386/
# deb cdrom:[Ubuntu-Server 12.04.1 LTS _Precise Pangolin_ - Release amd64 (20120817.3)]/ dists/precise/restricted/binary-i386/
# deb cdrom:[Ubuntu-Server 12.04.1 LTS _Precise Pangolin_ - Release amd64 (20120817.3)]/ precise main restricted

#deb cdrom:[Ubuntu-Server 12.04.1 LTS _Precise Pangolin_ - Release amd64 (20120817.3)]/ dists/precise/main/binary-i386/
#deb cdrom:[Ubuntu-Server 12.04.1 LTS _Precise Pangolin_ - Release amd64 (20120817.3)]/ dists/precise/restricted/binary-i386/
#deb cdrom:[Ubuntu-Server 12.04.1 LTS _Precise Pangolin_ - Release amd64 (20120817.3)]/ precise main restricted

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://free.nchc.org.tw/ubuntu/ precise main restricted
deb-src http://free.nchc.org.tw/ubuntu/ precise main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://free.nchc.org.tw/ubuntu/ precise-updates main restricted
deb-src http://free.nchc.org.tw/ubuntu/ precise-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://free.nchc.org.tw/ubuntu/ precise universe
deb-src http://free.nchc.org.tw/ubuntu/ precise universe
deb http://free.nchc.org.tw/ubuntu/ precise-updates universe
deb-src http://free.nchc.org.tw/ubuntu/ precise-updates universe

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
deb http://free.nchc.org.tw/ubuntu/ precise multiverse
deb-src http://free.nchc.org.tw/ubuntu/ precise multiverse
deb http://free.nchc.org.tw/ubuntu/ precise-updates multiverse
deb-src http://free.nchc.org.tw/ubuntu/ precise-updates multiverse

## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb http://free.nchc.org.tw/ubuntu/ precise-backports main restricted universe multiverse
deb-src http://free.nchc.org.tw/ubuntu/ precise-backports main restricted universe multiverse

deb http://security.ubuntu.com/ubuntu precise-security main restricted
deb-src http://security.ubuntu.com/ubuntu precise-security main restricted
deb http://security.ubuntu.com/ubuntu precise-security universe
deb-src http://security.ubuntu.com/ubuntu precise-security universe
deb http://security.ubuntu.com/ubuntu precise-security multiverse
deb-src http://security.ubuntu.com/ubuntu precise-security multiverse

## Uncomment the following two lines to add software from Canonical's
## 'partner' repository.
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu precise partner
# deb-src http://archive.canonical.com/ubuntu precise partner

## Uncomment the following two lines to add software from Ubuntu's
## 'extras' repository.
## This software is not part of Ubuntu, but is offered by third-party
## developers who want to ship their latest software.
# deb http://extras.ubuntu.com/ubuntu precise main
# deb-src http://extras.ubuntu.com/ubuntu precise main
如果覺得太麻煩,網路上有自動產生器可以用。

建構網頁環境

安裝網頁伺服器(Lighttpd)

apt-get install lighttpd

安裝資料庫(MySQL)

apt-get install mysql-server

安裝 php

apt-get install php5-fpm

安裝 phpmyadmin

apt-get install phpmyadmin

將 php5-fpm 改成 unix-socket

vim /etc/php5/fpm/pool.d/www.conf

* 找到以下將 listen 換成 php5-fpm.sock *

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses on a
;                            specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
;listen = 127.0.0.1:9000
listen = /tmp/php5-fpm.sock
vim /etc/lighttpd/conf-enabled/15-fastcgi-php.conf

* 將 lighttpd 的 fastcgi module 改成跑 fpm sock *

fastcgi.server += ( ".php" =>
        ((
                "socket" => "/tmp/php5-fpm.sock",
                "broken-scriptfilename" => "enable"
        ))
)

遭遇錯誤

需要MDB2

Failed opening required 'MDB2.php':
解法
apt-get install php-mdb2

需要DataObject

Failed opening required 'DB/DataObject.php':

解法

pear install DB_DataObject
pear install MDB2_Driver_mysqli

需要php5-geoip

[plugin] modifier 'geoip_country_code_by_name' is not implemented:

解法
apt-get install php5-geoip

安裝開發環境

安裝GCC

apt-get install gcc 

安裝G++

apt-get install g++

安裝GDB

apt-get install gdb

安裝 GMake

apt-get install make 

安裝subversion

apt-get install subversion

安裝 Google Protobuf

apt-get install protobuf-compiler libprotobuf-dev

安裝 Boost C++ Library

apt-get install libboost-all-dev

安裝 Poco C++ Library

apt-get install libpoco-dev

安裝 MySQL C API 

當出現錯誤訊息找不到 mysql.h:
apt-get install libmysqlclient-dev

安裝 CMake

apt-get install cmake 

安裝 samba

apt-get install samba
pdbedit -a USERNAME

設定 ulimit

vim /etc/security/limits.conf 
*               soft    core            -1
*               soft    data            33554432
*               soft    fsize           -1
*               soft    memlock         -1
*               soft    nofile          40960
*               soft    rss             -1
*               soft    stack           524288
*               soft    cpu             -1
*               soft    as              -1
*               soft    locks           -1
root            hard    core            100000

設定 core dump filename

echo "%e.core.%s.%t"> /proc/sys/kernel/core_pattern

永久寫入 vim /etc/sysctl.conf
kernel.core_pattern=%e.core.%s.%t 

換掉 default editor

update-alternatives --config editor

備份與還原 

安裝進度條

每次當我們在 unix-like 上執行某些操作,例如傳檔案、壓縮、解壓縮,總是很難知道現在還要等多久,所以可以透過pv 這支程式幫我們顯示進度條。
apt-get install pv

備份資料庫

mysqldump -u username -p --add-drop-table --create-options --routines --default-character-set=utf8 DATABASE_NAME | pv | bzip2 -cq9 | pv > BACKUPFILENAME.sql.bz2

還原資料庫

pv BACKUPFILENAME.sql.bz2 | bunzip2 > BACKUPFILENAME.sql
pv BACKUPFILENAME.sql | mysql -u username -p DATABASE_NAME

雜七雜八

看目前裝了什麼套件,類似FreeBSD 裡的 pkg_info

dpkg-query -Wf  '${Installed-Size}\t${Package}\n' | sort -n
或是
sudo sed -ne '/^Package: (.*)/{s//1/;h;};/^Installed-Size: (.*)/{s//1/;G;s/n/ /;p;}' /var/lib/dpkg/status | sort -rn

2012年2月24日 星期五

到底是 programmer 還是雜耍工

有感:程式設計師在除錯的時候就像偵探一樣,必須鉅細靡遺的抽絲剝繭。

這一個禮拜幾乎都在做偵探在做的事情。起因是有個 flash 在測試環境連 amfPhp 的 Server 測試起來都沒啥問題,一到線上環境就會莫名其妙的亂卡。卡的時間還很詭異的都是五的倍數。

於是第一個當然就是懷疑線上跟開發環境的版本問題啦。
所以一開始就把 lighttpd 版本,換呀換, php 版本換呀換,結果問題還是存在。

那不然應該就是,線上的 load 過高?可是圖表看起來一切都還好阿。於是一連串由可能懷疑的都懷疑了。先是懷疑 fastcgi process spawn 的速度,然後又懷疑是不是 fastcgi handler,所以也換了好幾種 fastcgi 的模式,也用了 php內建的 php-fpm ,結果依然照舊。

後來發現這個恐怖的 amfphp 竟然會一直抽插 lighttpd ,每個 rpc call 都要 connect 一次,於是開始覺得會不會是 lighttpd 的 fastcgi handler 不夠力,會 queue 住,之後發現也不是,然後又開始懷疑該不會是 socket 有問題吧.....。

到最後能調的都調過了,其他網頁的速度也明顯的加快許多,可是還是一樣,莫名其妙會卡。

好吧,那應該不是 server 的問題了,乖乖的抽絲剝繭看看吧。

所以就乖乖的進 php 裡面用,「夾擠法」去找出到底卡在哪。最後發現卡在兩個點,一個是在 amfphp 的 auth 模組,一個是在 class 模組。

trace 進 auth 模組裡面發現裡面有用到 session ,不會吧,難道這種流量 io 就撐不住了嗎?於是把 php 的 session 丟到 ramdisk ,情況依舊。後來找到 session 相關的問題有人提到session lock 要注意。 我也乖乖的改了,還是一樣。

後來跟 clark 討論的時候他看了看程式碼,蹦了一句話,那應該是每次用完 session 就先強制 close 掉就好。於是我又乖乖跑回去改 code ,結果還是卡。就當一籌莫展的時候無意間看到,咦?auth 模組真的不會卡了耶!所以 session lock 莫名的就被修好了。到這裡已經用了三天。

之後又繼續 trace class 模組,到最後發現產生的地方在 new 物件的地方花費很久,這就束手無策百思不得其解了好一陣子。不會要我對線上環境 gdb 吧?這根本沒搞頭阿。不小心被我找到一個東西:http://xdebug.org/,這東西真是太銷魂了阿。

一丟進去,就算是線上環境也還好,馬上就可以看到是卡在哪裡。

class 模組馬上看到是在兩個點,跑進去追根究柢後,一個是 pear 的問題,一個卡在 mysqli 的 connect ,一量馬上發現,原來問題是出在 mysql slave ,都顧著調 master ,結果是 slave 的 connect 有時候會卡。

還好,找到問題,收工。

但是那堆 pear 還是沒辦法解決阿......哀嚎中。