OSX 사용하면서 제가 느끼기에 가장 불편한 점은 PgUp/PgDown의 동작이 Windows나 다른 OS와 다르다는 겁니다. PgDown을 누르면 당연히 커서가 따라갈거라 생각하는데, 안그렇습니다. 특히 프로그램 짤때 에디터(Xcode)에서 PgUp/Down으로 이동하다가 이부분 편집해야지 하고 입력을 하거나 화살표를 누르면 커서 원래 있던 곳으로 돌아갑니다. 무슨 생각으로 이렇게 만들었는지 아무리 생각해도 이해가 안되더군요. 그리고 맥북에서 PgUp/PgDown은 Function-위/아래 화살표입니다! 키보드에 표시도 안되어 있죠.

해결 방법은 ~/Library/KeyBindings 폴더를 만들어주고, DefaultKeyBinding.dict 파일을 아래 내용대로 저장하고, 재로그인 하면 해결됩니다.

{

/* http://www.hcs.harvard.edu/~jrus/site/cocoa-text.html */

/* page up/down with moving insertion point, caret */
"\UF72C" = "pageUp:";
"\UF72D" = "pageDown:";

"^\UF700" = "pageUp:"; /* Control up */
"^\UF701" = "pageDown:"; /* Control down */

/* Option/Alt + PgUp/PgDn */
"~\UF72C" = "scrollPageUp:";
"~\UF72D" = "scrollPageDown:";
}


다만, Finder에서도 PgUp/Down이 이런식으로 동작하는데, 해결 방법을 아직 찾지 못했습니다. 그리고 OSX 사용하다 보면 가끔 마우스를 쓰지 않으면 안될때가 있더군요. 마우스 없어도 대부분의 작업을 키보드로 할수 있는 면에서는 윈도우즈가 약간 더 좋은거 같네요 --;

또한 창 버튼 중 + (최대화) 버튼의 동작이 어플마다 미묘하게 다릅니다. 대표적으로 iTunes는 누르면 미니창으로 바뀝니다. iTunes 창크기가 화면 크기를 넘어가서 창 줄일려니 마땅한 방법이 없더군요 --. 한참 고민하다가 방법은 찾았습니다. option + 클릭하면 최대화가 되더군요. 크롬은 + 누르면 어정쩡하게 최대화됩니다. 아직 로직을 파악 못하겠네요. 위아래로만 되는거도 아니고, 전체화면 되는거도 아니고... 뭐 어플 잘못일수도 있지만... 시스템 버튼 영역이 일관성이 없는건 애플답지 않네요.

그리고 취향의 차이이겠지만, 전 Command-Tab, Command-` 의 조합으로 프로그램 이동하는거보다, 윈도우즈의 Alt-Tab이 더 편하네요.

또한가지, 외부모니터로 보다가 모니터 연결 빼고 나면, 어떻게도 창을 못찾는 상태가 되는 경우가 있습니다. 키보드 단축키가 없으니 화면 밖으로 사라진 창을 가져올 방법이 없더군요. 이련 경우가 저만 당한게 아니라 그런지 찾아보니 창 모아주기 애플스크립트가 있습니다. 외부 모니터 연결한다면 꼭 필요한 스크립트입니다.

-- Example list of processes to ignore: {"xGestures"} or {"xGestures", "OtherApp", ...}
property processesToIgnore : {}

-- Get the size of the Display(s), only useful if there is one display
-- otherwise it will grab the total size of both displays
tell application "Finder"
    set _b to bounds of window of desktop
    set screen_width to item 3 of _b
    set screen_height to item 4 of _b
end tell

tell application "System Events"
    set allProcesses to application processes
    set _results to ""
    repeat with i from 1 to count allProcesses
        set doIt to 1
        repeat with z from 1 to count processesToIgnore
            if process i = process (item z of processesToIgnore) then
                set doIt to 0
            end if
        end repeat
       
        if doIt = 1 then
            tell process i
                repeat with x from 1 to (count windows)
                    set winPos to position of window x
                    set _x to item 1 of winPos
                    set _y to item 2 of winPos
                   
                    if (_x < 0 or _y < 0 or _x > screen_width or _y > screen_height) then
                        set position of window x to {0, 22}
                    end if
                end repeat
            end tell
        end if
    end repeat
end tell

applescript 편집기에 내용 붙여넣고 저장하시고 사용하시면 됩니다.

저는 iphone simulator가 자주 그런 경우를 당했는데, 프로그램 재시작해도 안나옵니다. 창 옮기는거 단축키 혹시 있으면 알려주세요 TT

제가 터미널에서 많이 작업하는데, 터미널 창의 가장자리가 없어서 많이 불편합니다. 여러창을 동시 띄우면 구별이 잘 안되고, 특히 투명도 주면(디폴트) 머리가 산만해지더군요. 지금은 투명도 안주고 어느정도 적응해서 참으며 쓰고 있습니다.

물론 좋은점도 많습니다. UI 예쁘고, UNIX 기반, Spotlight, 속도, 바이러스로부터 비교적 안전. 프로그램 설치/제거 쉬움. 유닉스에 없는 상용 프로그램들.
2010/07/14 09:23 2010/07/14 09:23

20100511

1009의 음악 2010/07/12 13:11
맥북에서 GarageBand를 이용해서 만든 음악입니다. 회사에서 업무시간 피해서(?!) 만들었습니다. GarageBand 프로그램은 정말 깔끔한데, 기능면에서는 아쉬운 점이 많네요.

제목은 아직 못 정했어요. 20100511



2010/07/12 13:11 2010/07/12 13:11

오랜만에...

프로그래밍 2010/07/11 02:25
작년말부터 계속 글을 못올렸네요.

작년 12월초에 아이폰을 구매하면서부터 컨텐츠 소비(주로 구글리더)를 출퇴근시간에 하다보니 따로 시간 내어서 블로그에 글쓰는게 더 어려워졌던거 같네요.

아이폰 쓰기 시작하면서부터 플랫폼으로써 가능성이 보여서 혼자 공부도 하고, 노트북(Lenovo X61)에 OSX도 깔아보고, 회사에 어필한 결과 올해 2월부터 맥북으로 아이폰앱을 개발하게 됐었습니다. OS도 새롭고, 개발환경도 새롭고, 언어는 더 생소해서 여러가지로 많이 배울수 있었던 시간이었네요. 다만 4월말에 개발이 완료 됐는데, 애플의 정책정리로 얼마전에서야 앱스토어에 올라오게 됐습니다.

생각보다 반응이 괜찮아서 올린지 하루만에 카테고리 1위하고, 열흘정도 됐는데 아직 카테고리 1위를 유지하고 있습니다. 전체 순위도 6위까지 올라갔다가, 현재는 상당히 밀렸네요. iOS4에 맞춰서 새로운 기능이 들어가서 나름 선전한거 같습니다.

개인적으로 만들어보고 싶은 여러가지 어플들이 있는데, 집에 오면 다 귀찮아져서... 아직 개인 앱은 올리지 못하고 있습니다.

아이폰 개발하면서 그전에 사용하던 언어와 개발환경에 대해서 다시 생각해보는 계기가 되었네요.

제가 사용하거나 했던 언어와 개발 환경 정리입니다.
  • BASIC (C-64)
  • UNIX - C, pro-c, X11, Motif, Tcl/Tk, Qt
  • Java
  • FreeBSD/Linux - C, lex/yacc
  • Python
  • Windows - Visual C++, MFC
  • Flash - Actionscript3
  • iOS - Objective-C

언어와 제가 느낀 점.
  • BASIC  - 제가 접한 첫 언어. 초딩때 게임도 만들었어요.
  • C - 가장 기본이 되는 언어.
  • Tcl/Tk - 스크립트 언어로서 UI와 UI builder(XF)까지 놀라웠죠. (95년?)
  • Python - 간결함과 표준 라이브러리가 인상적. 자료구조 쉽게 쓸수 있어서 프로그래밍 방식 변화
  • C++ - STL 좋음. 언어는 너무 복잡. 자유도 많아서 안좋음.
  • Java - 언어는 모르겠고, JVM에는 관심갑니다.
  • Actionscript3 - FlashDevelop와 사용하면 너무 편한 언어. 도움말 및 예제 굿! Javascript에 비하면 좀더 일반적인 객체지향 언어.
  • Objective-C - 강력한 개발환경과 애플의 개선을 위한 필사적인 노력.

이외 관심있는 언어:
  • OCaml
  • LISP
  • Erlang
  • JVM 위에서 돌아가는 함수형 언어들

2010/07/11 02:25 2010/07/11 02:25

아이리버 스토리로 읽을 책도 많지만... man 페이지는 잘 안보게 되지만, 유용한 정보가 많은 자료죠.

여기서 설명하는 PDF 생성은 한글이 되는지는 확인 안해봤습니다.

1. UNIX man페이지 변환 방법

man2pdf.sh 이용. (groff와 ghostscript가 있어야 합니다.)

man2pdf.sh 파일 저장후

% chmod 755 man2pdf.sh
% ./man2pdf.sh man


이렇게 하면 man.1.pdf 파일이 생성됩니다. 1은 메뉴얼이 속한 섹션입니다.

가끔 안되는 게 있더군요:

$ ./man2pdf.sh varnishd
cat: /usr/local/man/cat1/varnishd.1.gz (source: /usr/local/man/man1/varnishd.1.gz): No such file or directory


이럴 경우.. 아래처럼 실행하면 되더군요.

$ zcat /usr/local/man/man1/varnishd.1.gz | groff -t -E -Tps -mandoc -ma4 | gs -q -sDEVICE=pdfwrite -sOutputFile="v.pdf" -dNOPAUSE -dBATCH -sPAPERSIZE='a4' -


2. Wikipedia 웹페이지를 PDF로 변환 방법

리눅스용 firefox에서 페이지를 PDF로 출력하는 기능이 있긴 하지만, 불편하고 메뉴 부분등을 제거하려면 추가의 노력이 들어갑니다. 그리고 파일도 따로 생성되죠.

위키피디아(영문) 문서를 변환하는 건 이 링크를 이용해서 들어가시면 쉽게 만들수 있습니다. "start book creater"를 누르시면 위키피디아로 연결됩니다. 상단에 두개의 영역이 노출되는데 위쪽은 광고이고, 중간에 Book creater에서 add(+)를 누르면 현재 페이지가 추가됩니다. 여러 페이지 왔다갔다하면서 문서를 추가하고 "show book" 하면 오른쪽에 PDF로 만들수 있는 버튼이 있습니다. 하나의 PDF 파일로 만들어서 다운로드 할수 있습니다 :)

2009/12/07 16:19 2009/12/07 16:19

여러대의 서버를 관리하면서, 모니터링할수 있는 페이지를 만들고, 해당 서버를 클릭하면 SSH로 바로 연결할수 있도록 MIME 링크를 만들어서 사용하고 있습니다. MIME 링크 처리는 윈도우즈에서 프로그램을 제작해서 ssh:// 형태의 MIME type에 대해서 처리하게 했습니다. 프로그램은 단순히 putty를 찾아서 실행해주는 간단한 구조입니다.

이걸 리눅스에서 할려고 했더니 어떻게 해야하는지 좀 헤맸습니다. mime type이라는 건 서버에서 파일이 내려갈때 HTTP header에 붙어서 가고, 이를 브라우저에서 처리하는 거라... ssh:// 형태의 링크는 mime 링크로는 처리가 안되고, 이를 처리하는 걸 protocol handler라고 하더군요. 검색어 자체가 잘못되서 해결책을 찾는데 꽤 시간이 걸렸습니다.

먼저 gnome에서 ssh 프로토콜을 프로그램 연결하는 부분입니다.

$ gconftool-2 -s /desktop/gnome/url-handlers/ssh/command '/usr/bin/gnome-terminal -e "~/bin/handle_protocol.sh %s"' --type string
$ gconftool-2 -s /desktop/gnome/url-handlers/ssh/enabled -t boolean true

참고 URL: http://kb.mozillazine.org/Register_protocol

~/bin/handle_protocol.sh 파일 내용입니다.
#!/bin/sh

link=$1
proto=`echo "$link"|cut -d: -f1`
host=`echo "$link"|cut -d/ -f3`
echo "$proto $host"
exec $proto $host


파일 만들고 실행되도록 chmod 해야 합니다.

$ chmod a+x ~/bin/handle_protocol.sh

이렇게 하면 firefox에서 ssh:// 로 시작하는 링크 누르면 gnome-terminal이 뜨면서 ssh로 연결됩니다. telnet도 똑같은 방법으로 등록하면 사용이 가능합니다.

이렇게 설정했는데 우분투(9.10)에서 원격 접속했을때 윈도우즈에서 putty 이용했을때보다 속도가 많이 느리더군요. /etc/ssh/ssh_config에서 맨 아래 두줄을 주석 처리하면 빨라집니다.

#GSSAPIAuthentication yes
#GSSAPIDelegateCredentials no

출처: http://onlyubuntu.blogspot.com/2007/04/fix-for-ssh-slow-to-ask-for-password-in.html

2009/11/28 01:20 2009/11/28 01:20

PF로 DDoS 공격을 어느정도 막으면서, iptables에서도 가능한지 궁금해졌습니다. PF 처럼 쉽게 공격 IP를 완전하게 차단하는 방법은 찾지 못했지만, IP당 시간당 연결수를 제한하는 방법은 있네요.

iptables -N SSHSCAN
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSHSCAN
iptables -A SSHSCAN -m recent --set --name SSH
iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

5분동안 22포트에 똑같은 IP가 3번 이상의 TCP 연결이 들어오면 그 이후로는 막습니다. 즉 5분간 3개의 연결만을 허용합니다. SSH 돌리기 신공은 막을수 있겠지만, DDoS 공격을 차단하기는 부족한 기술인듯하네요.

using-iptables-to-block-brute-force-attacks 문서를 보시면, 자세한 설명이 있고, 공격 아이피에 대해서 로깅을 하는 방법도 있습니다. 로그 분석해서 iptables rule을 등록해주면 공격 아이피에 대해서 차단할수 있을듯하네요. 하지만 이 방법 말고 더 쉬운 방법이 없을까 고민중입니다.

여러가지 로그 파일에서 로그인 실패를 모니터링해서 공격을 막아주는 fail2ban 이라는 툴도 있네요. 설명은 여기를 참고하세요. 역시 DDoS 방어용은 아니지만, 로그 분석을 통해서 방화벽에 IP 등록하는걸 응용할수 있을듯합니다.

최근
Linux Firewalls: Attack Detection and Response with iptables, psad, and fwsnort 책을 보기 시작했는데 좀더 좋은 방어 방법 찾으면 다시 글 올리겠습니다.
2009/11/26 00:40 2009/11/26 00:40

PF(Packet Filter)는 BSD용 방화벽입니다. 원래 IPF라고 개인이 만든 공개 방화벽이 있어서, 여러 BSD 계열 UNIX에서 주로 사용하였었습니다. 다른 개발자들이 라이센스에 대해 명확하지 않은 부분에 대해서 설명 요구에 대한 응답에 만족하지 못한 오픈소스 개발자들이 새롭게 만든 방화벽이 PF입니다. 정말 너무나도 빠르게, IPF와 기능은 유사하게 만들어졌습니다. IPF는 소스는 공개였지만, 소스 분기는 허용하지 않고 원 개발자가 필요한 패치만 해서 하나의 버전을 유지하겠다고 했었습니다...


하여간 PF가 OpenBSD 개발자들에 의해서 순식간에 만들어지고, 여러개발자들이 참여가 가능했기 때문에 금방 여러가지 추가 기능들이 구현됐습니다. 오픈 소스 최고의 방화벽으로 자리 잡았고, 상용 방화벽이 갖추지 못한 좋은 기능들도 많이 가지고 있습니다.

FreeBSD에서 PF 방화벽을 사용하려면 /etc/rc.conf 에

pf_enable="YES"
pflog_enable="YES"

를 추가해야합니다.

정책 설정은 /etc/pf.conf 에서 합니다.

설정 파일에서 가장 중요한 부분은 pass/block이죠...

pass/block in/out (log) on 인터페이스
proto 프로토콜
from 주소/마스크비트 port 포트

to 주소/마스크비트 port 포트


1.2.3.x 에서 오는 모든 udp 패킷을 막고 싶다면...

block in proto udp from 1.2.3.0/24 to any


80포트로 오는 걸 열어주고 로그로 남기고 싶으면,

pass in log proto tcp from any to port 80 keep state


keep state하면 생성된 TCP 세션에 대해서 들어오고 나가는 패킷이 방화벽을 통과합니다.


패킷이 왔을때 위에서 부터 비교가 되며... 맨 마지막 매치가 선택됩니다.
단, quick이 설정되어 있으면 그 매치가 선택됩니다.

아래는 현재 사용중인 설정입니다. 추가적인 보안 관련 설정이 여러가지 있습니다..

ext_if="em0"

set limit { states 80000, frags 5000 }

set block-policy drop

set skip on lo0

scrub in all
antispoof for $ext_if

block in all
block out all

table <bruteforce> persist
table <sshbruteforce> persist

block in quick log proto tcp from <bruteforce> to port 80
block in quick log proto tcp from <sshbruteforce> to port 22

pass in on $ext_if proto tcp from any to $ext_if port 22 \
            flags S/SA keep state \
            (max-src-conn-rate 10/30, overload <sshbruteforce> flush global)
pass in on $ext_if proto tcp from any to $ext_if port 80 \
        flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $ext_if port 80 \
        flags S/SA keep state \
        (max-src-conn 100, max-src-conn-rate 300/10, \
        overload <bruteforce> flush global)


위에 설정에서 ssh나 http로 하나의 IP에서 여러개의 요청이 한번에 오면 막는 기능이 동작합니다. HTTP의 경우 최대 100개의 동시 연결, 10초간 300개 이상의 연결이 발생하게 되면 공격자로 인식하고 기존 연결을 모두 끊어버리고 연결을 막습니다.

한번 등록되면 방화벽 재시작 전에는 해당 IP에서 연결이 안됩니다. 일정 기간이 지나면 풀리게 하는 방법은 expiretable를 사용하면 가능합니다.

FreeBSD에서는
# cd /usr/ports/security/expiretable
# make install

# /usr/local/sbin/expiretable -t 2h bruteforce

2시간 이상 지난 IP를 풀어주는 명령으로 crontab에 등록해서 사용하면 됩니다.

최신 버전 PF를 사용하면 pfctl로 같은 기능을 할수 있다고 합니다.

# pfctl -t bruteforce -T expire 7200


방화벽 시작, 재시작, 설정 파일 다시 읽기, 종료 방법:
# /etc/rc.d/pf start
# /etc/rc.d/pf restart
# /etc/rc.d/pf reload
# /etc/rc.d/pf stop
# /etc/rc.d/pflog start
# /etc/rc.d/pflog stop


방화벽 로그를 실시간으로 보는 방법
# tcpdump -i pflog0


쌓인 로그를 보는 방법
# tcpdump -r /var/log/pflog


방화벽 상태 보기
# pfctl -s all
# pfctl -vvs all (보다 자세한 정보 보기)

방화벽 공격 IP 보기
# pfctl -t bruteforce -T show



마지막으로... 원격에서 방화벽 잘못 설정하면 IDC로 튀어가야합니다.
신중을 기해야합니다.

한가지 터득한 방법은...

# /etc/rc.d/pf reload; sleep 15; /etc/rc.d/pf stop


restart보다는 reload가 그나마 안전합니다. reload할 때는 세션 테이블이 초기화 되지 않습니다.

DDoS의 공격의 종류가 많고 어디가 bottleneck이 되느냐에 따라 해결방법이 틀려집니다. 서버 자체의 부하를 일으켜 서비스 거부 공격을 받는 경우 PF로 많은 공격을 막을수 있습니다.

pfstat을 설치하면, PF의 여러가지 상황을 모니터링 할수 있습니다.

# cd /usr/ports/sysutils/pfstat
# make install

pfstat 홈페이지의 설정파일을 복사하고, 인터페이스명과 파일 저장 위치들만 바꿔주고
crontab에 아래처럼 등록했습니다.

# crontab -l
* * * * * /usr/local/bin/pfstat -q
*/5 * * * * /usr/local/bin/pfstat -p


2009/11/21 21:09 2009/11/21 21:09

꽤 오래전부터 ebook reader에 관심을 두고 있었는데 아이리버에서 나온 스토리를 구매했습니다.

정가가 35만원정도인데 아래 링크 통해서 10% 할인해서 구입했습니다 :)

http://www.dnshop.com/front/product/ProductDetail?PID=C960_story_1&CID=R2100028&Sid=0101_10070000_01_01&szSearchKeyword=%BE%C6%C0%CC%B8%AE%B9%F6%BD%BA%C5%E4%B8%AE

어제 받자마자 1.04 펌웨어로 업그레이드하고 테스트해보았습니다.

일단 스크린 자체에서 빛이 안나니 처음에는 좀 허전하더군요 --; 오래보니까 눈에 주는 피로는 훨씬 덜한거 같네요. 주로 원서 컴퓨터 관련 기술 서적을 PDF로 보려고 하는데 세로보기로는 글씨가 너무 작아서 보기 힘듭니다. 펌웨어 1.04에서 제공하는 PDF reflow 기능을 사용하거나, 가로보기를 보면 볼만합니다. 특히 영문 폰트는 가독성이 상당히 좋네요. 종이 같아요 :)

하지만 몇가지 단점을 찾았는데 펌웨어 업그레이드로 점차 나아지리라 생각되네요.

1. PDF reflow off 상태에서 zoom 했을때 페이지내 보는곳 이동이 원활하지 않습니다.
   다음페이지 넘어갈때 페이지 안보였던 부분으로 이동은 하는데 어떤 원리로 이동하는지 모르겠네요. 그리고 절대로 못보는 위치도 있는듯하네요.

2. PDF reflow off 상태에서 가로보기일때는 zoom이 안됩니다.

3. 다른 문서 고를때 페이지 위치 등은 기억되지만, reflow 상태나 zoom은 기억이 안됩니다. 이게 좀 불편한데... 책 본격적으로 보면 여러책 왔다갔다하면서 보는 경우가 적기 때문에 아주 불편하진 않을듯합니다.

4. 세벌식 지원이 안됩니다. 메모와 다이어리 기능을 저는 거의 사용못하겠네요.

5. 한글 PDF는 reflow 기능이 안되는 파일이 있습니다. (글자가 겹쳐서 못봄)

6. 사전이 내장 안되어있는게 아쉽네요.

7. PDF 내 링크 이동과 검색이 지원되면 좋겠네요.

그리고 많은 분들이 옆면의 페이지 이동 버튼이 너무 아래쪽으로 치우져있다고 하시는데, 저는 페이지 넘길때 두손 써도 상관 없어서 별로 불편함은 못 느끼겠네요.

하여간... 이제부터 책 많이 보려고 합니다.

2009/10/29 13:03 2009/10/29 13:03

Varnish Cache의 grace 기능을 PHP/memcached로 구현했습니다.

grace 기능은 백엔드 서버가 죽더라도, 캐싱되어 있는 정보로 지속적인 서비스가 가능하도록 하는 기능입니다. 캐싱할때 여분의 시간(grace 시간)동안 더 캐시를 유지하며, 캐싱 시간이 지났을때 백엔드에 요청이 한번만 전달되게 하고, 나머지 요청에 대해서는 우선적으로 그 전에 있던 캐시로 서비스를 하도록 하여 백엔드 서버의 부하를 줄일수 있습니다.

현재는 memcached에서 expire 되면서 동시에 요청이 발생하는데, grace 기능을 구현하면 오래걸리는 페이지 생성할때 큰 효과를 발휘할수 있을거라 기대됩니다.

PHP 구현은 간단합니다. 원래 key,value 항목의 expire 시간을 grace 시간 만큼 늘리고, 다른 키(key+"_s")에 expire 시간동안 상태값을 입력해두면, 어렵지 않게 grace 기능을 구현할수 있습니다.

초기에 캐시에 없을때는 백엔드에 동시에 여러 요청이 들어갈수 있습니다. 이미 요청이 처리되고 있을때(state="G"), 일정시간동안 주기적으로 memcached를 조회해서 key가 있을때까지 대기하는 방법으로 어느정도 해결 가능할 거라 생각하지만 구현은 하지 않았습니다.


 array('127.0.0.1:11211'), 'debug' => false, 'persistant' => false));

    function generate_value($key) {
        sleep(5);
        return "VALUE". $key;
    }

    function get_value($key) {
        global $mc;
        $expire = 60;
        $grace_timeout = 600;
        $generation_timeout = 10;

        $state = $mc->get($key."_s");
        //echo("state=$state<br>\n");
        if ($state == "C" || $state == "G") {
            $value = $mc->get($key);
            if ($value) {
                //echo("retreive key=$key<br>\n");
                return $value;
            }
        }

        $mc->set($key."_s", "G", $generation_timeout); // state: Generating
        $value = generate_value($key);
        $mc->set($key, $value, $expire + $grace_timeout);
        $mc->set($key."_s", "C", $expire); // state: Cached
        //echo("insert key=$key<br>\n");

        return $value;
    }

    get_value("hahaha");
?>

 
2009/10/25 03:47 2009/10/25 03:47

Varnish Cache에 대해서 글을 올린지 얼마 안된 듯한데 찾아보니 3년정도가 지났네요. 아직까지 실제 서비스 환경에서는 Varnish를 도입하지 못했었는데... 다시 필요에 의해서 로드밸랜서(+서버단 캐시)를 고려하게 되었습니다.

원래 수동으로 서브도메인별로 나누어서 로드밸런싱을 하고 있었는데, 서브도메인간 자바스크립트 연동의 문제들이 여러곳에서 발생하기 시작해서, 로드밸런서를 도입하려고 합니다. 그외에도 여러가지 장점이 있을듯 하네요.

Varnish가 이제 버전 2.0이 나왔고(나온지 1년 됐네요 --), 여러가지 변화가 있었네요.
현재 버전은 2.0.4 입니다.

1. VCL 언어가 좀더 프로그래밍 언어 다워졌습니다.

VCL 언어가 약간 언어답지 않은 면이 있었는데.. return 등의 도입으로 좀더 설정파일(소스) 보기가 편해졌습니다. 그리고 C언어를 embedding 할수 있는 방법이 있네요.

2. grace 지원

개체(요청결과)를 캐싱할때 expire 시간과 함께 grace 시간을 설정할수 있습니다. expire 시간이 지나고 웹서버(backend)들이 요청 처리를 하지 못할때 grace 시간 동안 캐시에 있는 내용으로 서비스가 됩니다. 또한 expire 시간이 지나는 순간 하나의 웹서버에 하나의 요청만으로 캐시를 업데이트하며 그 동안은 캐시에서 서비스가 되도록 설정할수 있습니다. 예를 들면 메인 페이지가 1초에 100번 요청되고 메인 페이지 처리하는데 2초가 걸린다고 하면, 서버에 원래 200번 요청 들어갈것이 1번만 가면 되는거죠. 웹서버와 디비 입장에서 아주 고마운 일이죠.

3. ESI (Edge Side Script) 일부 지원

 페이지에서 특정 부분은 사용자 정보가 포함되기 때문에 전체 페이지 캐싱이 어려운 경우가 많습니다. 사용자 별로 캐시를 두면 캐시의 의미가 많이 떨어집니다. 이럴 경우 해당 부분만 별도의 페이지로 저장해두고

<esi:include src="userinfo.php" />

형태로 원본 페이지에 넣어주면 캐시에 그대로 저장되고, 요청을 처리할때 userinfo.php 부분만 웹서버에 요청하여 varnish에서 조합해서 보내줍니다.

ESI가 아주 유용한 기능이기는 하지만 아쉬운 점은 Varnish가 아직 압축을 지원하지 못한다는 점이네요. 웹서버 측에서 페이지를 압축하면 ESI를 쓸수 없고, Varnish 쪽에서 압축할수 있는 방법을 지원하지 않습니다. ESI와 압축을 조합해서 쓸수 있었으면 정말 좋았을텐데 정말 아쉬운 부분이네요.


현재 회사에서 varnish 도입을 위한  테스트중입니다. ESI는 압축 미지원으로 도입에서 제외되었으며, 로드밴런싱, 캐싱 기능, 서버 죽을때 처리 등만 활용하려고 합니다.

grace의 개념을 이해하면서, memcached를 웹에서 사용하는 방법을 비슷한 방법으로 변경을 고려하고 있습니다.

PHP 모든 페이지를 캐싱하기는 로직상으로 문제가 발생할 확률이 커서 정해진 HTTP 헤더가 포함된 PHP 페이지만 캐싱 되도록 설정했습니다. 캐싱해도 안전하다고 생각하는 페이지에 특정 헤더를 포함하면 캐싱이 됩니다.

url.purge 명령으로 정규식에 해당하는 캐싱된 페이지를 날릴수 있는 기능도 활용할 생각입니다. 캐싱이 유용한 페이지이지만 사용자가 글을 등록하고 바로 글이 안보인다던지 하는 문제는 url.purge를 써서 해결하려고 합니다.
2009/10/22 22:01 2009/10/22 22:01

◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [14] : NEXT ▶