2012/08/26

Nginx load balance

Nginx 內建的 load balance 規則有 round-robin、weight、ip_hash、fair、url_hash
但如果想更精確的把特定 request 導到特定的 server,可以自己來寫 rule。

例如想用 user id 做 despatch,下面的例子是利用 user id 的開頭第一個字元來做決定
server {
    listen 80;
    server_name www.domain.com;

    location ~* /profile/[a-m] {
        proxy_pass http://server0.domain.com;
    }

    location ~* /profile/[n-z] {
        proxy_pass http://server1.domain.com;
    }    
}

如此一來
http://www.domain.com/brian 就會導向 server0
http://www.domain.com/vicky 就會導向 server1



如果 user id 是流水號,那我們就判斷 id 的個位數字
server {
    listen 80;
    server_name www.domain.com;

    location ~* /profile/[0-9]*[02468]$ {
        proxy_read_timeout 10s;
        proxy_pass http://server0.domain.com;
    }

    location ~* /profile/[0-9]*[13579]$ {
        proxy_pass http://server1.domain.com;
    }
}

http://www.domain.com/2000 就會導向 server0
http://www.domain.com/2001 就會導向 server1



如果 request 是 http long polling,可以考慮用301 Moved Permanently 的方式讓 client 的 connection keep 在 target server,減少 nginx 的 connection 數量
server {
    listen 80;
    server_name www.my-domain.com;

    location ~* /profile/[a-m] {
        rewrite ^(.*) http://server0.domain.com$1 permanent;
    }

    location ~* /profile/[n-z] {
        rewrite ^(.*) http://server1.domain.com$1 permanent;
    }    
}

有關 location rule 可以參考:高飞鸟 – Highbird » Blog Archive » Nginx的location匹配规则

2012/08/22

在 iOS 平台加入 Flurry 廣告

Flurry

1. 註冊後,新增 Application,把 API Key 記下來

2. 建立 Ad space


3. 開始寫程式,先下載 SDK,裡面包含教學pdf 與 library
把 Flurry, FlurryAds 拖曳到 project 內

4. 在 app launch 的時候去初始化 flurry
AppDelegate.m
#import "Flurry.h"
#import "FlurryAds.h"

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
    [Flurry startSession:@"YOUR_API_KEY"];
    [FlurryAds initialize:rvc];
}

5. 在想呈現廣告的 viewController 加入程式碼
ViewController.m
#import "FlurryAds.h"

- (void)viewWillAppear:(BOOL)animated
{
    [FlurryAds isAdAvailableForSpace:@"FrontPage" view:self.view 
        size:BANNER_TOP timeout:1000];
}

6. 加入額外的 framework
  • MediaPlayer.framework
  • SystemConfiguration.framework

7. Run


參考資料
Publisher/GettingStarted/TechnicalQuickStart - Flurry
iPhoneAgent: FlurryAds Class Reference

2012/08/04

工欲善其事,必先利其器:GDB 基本教學

最基本的編譯時要加"-g",把 debugging information 編譯進去,否則印不出什麼資訊來。再來就是不要做 optimize,不然程式碼行數會對不上。
$ gcc -g -o hello hello.c

啟動 GDB
$ gdb ./hello

必要時加入"-d (dirctory)"的參數,指定 source code 的位置
$ gdb -d /home/brian/test ./hello 

若程式已經在執行了,可以先查詢 pid,然後用 attach 的方式。記得 binary 的要跟正在 run 的 program 一致
$ gdb ./hello 12238

進入GDB後執行程式
(GDB) run
若要帶參數的話
run (init parameter)
Ex:
(GDB) run -h localhost -p 8080

Breakpoint
設定中斷點
b (filename):(line num)
Ex:
(GDB) b hello.c:5

列出目前的中斷點
(GDB) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040049c in main at hello.c:5

移除中斷點
d (breakpoint id)
Ex:
(GDB) d 1

列出當下的狀況
列出 function stack (Back trace)
(GDB) bt
#0  hello () at hello.c:9
#1  0x00000000004004cf in main () at hello.c:14

列出更詳細的資訊,包含 variable 的值
(GDB) bt full
#0  hello () at hello.c:9
        i = 0
#1  0x00000000004004cf in main () at hello.c:14
No locals.

列印變數
p (variable)
Ex:
(GDB) p iValue
(GDB) p *stEmployee

切換 frame。要列印區域變數時,必須要切換到正確的 frame
f (frame num)
EX:
(GDB) f 3

流程控制
Step over (不會進 function)
(GDB) n
Step into (會跳入 function)
(GDB) s
Continue
(GDB) c

Signal Handle
handle (signal) (operation)
Operation 預設為 stop print noignore,也就是遇到 signal 時,GDB 會先攔截,並中斷程式,必要時可以改為 nostop noprint,讓程式本身去處理 signal。若下達 ignore 則是讓程式忽略此 signal。
(GDB) handle SIGUSR nostop noprint

列出目前 signal 設定的狀態
(GDB) i handle
Signal        Stop      Print   Pass to program Description

SIGHUP        Yes       Yes     Yes             Hangup
SIGINT        Yes       Yes     No              Interrupt
SIGQUIT       Yes       Yes     Yes             Quit
SIGILL        Yes       Yes     Yes             Illegal instruction
SIGTRAP       Yes       Yes     No              Trace/breakpoint trap
有關 signal 的部分可以參考 http://sourceware.org/gdb

Thread
查看目前在哪個 thread
(GDB) thread

切換 thread
(GDB) thread 3

列出所有 thread 的 function stack
(GDB) thread apply all bt
(GDB) thread apply all bt full

Ref:
Examining the Symbol Table

在 Mac OS 上使用 Wireshark

Network interface 預設的權限是 root,由於 wireshark 是以 user 的權限來開啓,故無法存取 interface,解決的辦法就是修改權限為大家都可讀。
sudo chmod 644 /dev/bpf*
解決!

2012/08/01

Ignore SIGPIPE in socket programming

通常在寫 socket programming 時,系統對一個 invalid fd (file descriptor) 做寫入時會讓系統丟出 SIGPIPE 的 signal,為了避免程式被中斷,通常都會 ignore 它。

#include <signal.h>
struct sigaction sa;

sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;

sigemptyset(&sa.sa_mask);
sigaction(SIGPIPE, &sa, 0);