암호화에 대한 기본 상식

암호화(Encryption)의 방식에는 단방향 암호화, 대칭 암호화, 비대칭 암호화가 있다.

단방향 암호화(One-way Encryption)는 복호화할 수 없도록 하는 방식이다. 이 방식에서는 해시 알고리즘(Hash Algorithm)을 사용하는데, 이 과정을 통해 고유한 지문(Fingerprint)을 생성한다.

일반적으로, 단방향 암호화를 통해 얻은 값으로는 복호화가 불가능하다고 하는데 원문이 짧거나 일반적으로 널리 사용되는 문자열일 경우에는 무작위 값 입력을 통한 공격(Brute Force Attack)을 통해 무력화되기 쉽다.

MD5, SHA1 등이 대표적인 해시 알고리즘이다.

대칭 암호화(Symmetric Encryption)는 키(Key)를 통해 동일한 알고리즘으로 암호화/복호화를 하는 방법이다. 이 방식은 2차 세계대전 중에 암호화 기계(Enigma Machine)에 사용된 방식이다.

암호화/복호화에 필요한 키가 유출되지만 않는다면 매우 안전한 방식이다. DES, TWOFISH, GOST 등이 대표적인 알고리즘이다.

비대칭 암호화(Asymmetric Encryption)는 SSL 같은 방식이라고 하는데, 자세한 내용은 모르므로 넘어가겠다.

이 글에서는 PHP에서 대칭 암호화 방식을 통한 암호화/복호화에 대해 설명하겠다.

Mcrypt 라이브러리의 설치와 설정

PHP에서는 Mcrypt 라이브러리를 통해 대칭 암호화를 지원한다. 따라서 Mcrypt를 이용하려면 라이브러리를 추가로 설치해 주어야 한다.

http://mcrypt.sourceforge.net/에서 Mcrypt 라이브러리를 다운로드 받을 수 있으며, 윈도우 서버라면 http://files.edin.dk/php/win32/mcrypt/에서 컴파일된 라이브러리 파일을 다운로드 받아 사용할 수 있다. 작동하도록 설정하려면 php.ini의 설정을 변경해 주어야 하는데, 자세한 설정 방법은 http://www.php.net/manual/kr/book.mcrypt.php 에서 확인할 수 있다.

데비안 계열 리눅스 서버라면 터미널에서 다음의 명령어를 입력하는 것으로 Mcrypt를 설치와 설정을 완료할 수 있다.

1.$ sudo apt-get install php5-mcrypt
2.$ sudo apt-get install libmcrypt4
3.$ sudo /etc/init.d/apache2 restart

Mcrypt를 이용한 암호화/복호화 예제

다음의 코드를 보면 쉽게 이해할 수 있다.

01.$key = "열쇠";
02.$plainData = "개인정보";
03.$encryptedDataOnBinary = mcrypt_ecb(MCRYPT_GOST, $key, $plainData, MCRYPT_ENCRYPT);
04.$encryptedData = base64_encode($encryptedDataOnBinary);
05.echo "암호화 할 평문 : ".$plainData;
06.echo "<BR>
07.";
08.echo "암호화 결과로 나온 바이너리 값: ".$encryptedDataOnBinary;
09.echo "<BR>
10.";
11.echo "암호화 결과를 아스키 코드로 변환한 값 : ".$encryptedData;

앞서 설명했듯, 대칭 암호화를 하기 위해서는 키가 필요하다. 이 예제에서는 $key로 "열쇠"라는 임의의 문자열을 넣었는데 실제로는 더 복잡하고 고유한 것을 사용하는 것이 좋겠다. $plainData는 암호화 할 대상을 말한다. 이 예제에서는 예로 "개인정보"라는 문자열을 넣어보았다.

mcrypt는 여러 기본 함수를 제공하는데, 그 중 이번에는 mcrypt_ecb() 함수를 이용했다. 참고로 ECB란 전자 부호표 모드(Electric CodeBook mode)의 약자다. mcrypt_ecb() 함수에는 네 가지 값을 넣어주어야 하는데, Mcrypt에서 제공하는 알고리즘 상수, 키, 암호화 할 값, 암호화/복호화를 위한 상수가 그것이다.

Mcrypt에서는 DES, TWOFISH, GOST 등 많은 알고리즘을 지원하는데 이 목록은 http://www.php.net/manual/en/mcrypt.ciphers.php에서 확인할 수 있다. 이 예제에서는 GOST 방식을 사용하기 위해 MCRYPT_GOST라는 상수를 사용했다. 또한 이 예제에서는 암호화을 할 것이므로 MCRYPT_ENCRYPT라는 상수도 넣었다.

이렇게 Mcrypt를 통해 암호화를 하면 그 결과로 바이너리(Binary) 값을 반환한다. 즉, 컴퓨터만 이해할 수 있는 2진수 데이터를 반환한다는 의미다. 따라서 브라우저는 "'ӫ�{3�ѠO#�c�ʾfBg�"와 같이 인간도, 브라우저도 이해할 수 없는 결과를 출력할 것이다.

이 문제는 base64_encode() 함수를 이용함으로써 해결할 수 있다. 결과적으로 "8UHT/jWsIopHDCUpbfJLIA=="와 같이 아스키 코드로 변환한 값을 얻을 수 있다. 이로써 암호화가 성공적으로 이루어졌다.

이제 복호화 코드를 보자.

1.$decryptedDataOnBinary = base64_decode($encryptedData);
2.$decryptedData = mcrypt_ecb(MCRYPT_GOST, $key, $decryptedDataOnBinary, MCRYPT_DECRYPT);
3.echo "바이너리 값으로 다시 변환한 암호화 결과 값 : ".$decryptedDataOnBinary;
4.echo "<BR>
5.";
6.echo "바이너리 값을 복호화 한 결과 값 : ".$decryptedData;

앞서 (아스키 코드로 까지) 암호화한 결과 값을 base64_decode() 함수를 이용해 다시 바이너리 값으로 변환한다. 이 값을 다시 mcrypt_ecb() 함수를 이용해 복호화 하기 위해, 앞서 암호화하기 위해 사용했던 알고리즘의 상수인 MCRYPT_GOST, 앞서 암호화 하기 위해 사용했던 키, 바이너리로 다시 변환한 암호화 결과 값, 복호화를 위한 상수 MCRYPT_DECRYPT를 넣는다. 그 결과로 복호화 된 결과 값인 $decryptedData를 출력하면 "개인정보"라는 문자열을 얻게 된다. 이로써 복호화도 성공적으로 이루어졌다.

위의 결과를 아래와 같이 함수로 정리하면 편리하게 사용할 수 있다.

01.// mcrypt.php
02.$key = "1dasd12WESA12dsaasd456TGDFsd";
03.
04./**
05.* 데이터 암호화 함수
06.*/
07.function function_for_encryption($plain_data){
08. global $key;
09. $encrypted_data_on_binary = mcrypt_ecb (MCRYPT_SERPENT, $key, $plain_data, MCRYPT_ENCRYPT);
10. $encrypted_data = base64_encode($encrypted_data_on_binary);
11. return $encrypted_data;
12.}
13.
14./**
15.* 데이터 복호화 함수
16.*/
17.function function_for_decryption($encrypted_data){
18. global $key;
19. $decrypted_data_on_binary = base64_decode($encrypted_data);
20. $plain_data = mcrypt_ecb (MCRYPT_SERPENT, $key, $decrypted_data_on_binary, MCRYPT_DECRYPT);
21. return $plain_data;
22.}

Mcrypt를 이용한 암호화/복호화를 DB 입력/조회에 적용하기

이제 암호화/복호화를 DB 입력/조회에 적용해 보겠다.

DB에는 mailing_list라는 테이블이 있고 그 안에 no, name, email, date라는 필드가 있고 no 필드는 int이며 Auto Increment, 나머지 필드는 모두 varchar라고 가정한다.

POST 값으로 다음과 같은 메일링리스트 가입 정보를 받았다고 가정하자.

1.Array (
2. [name] => testman
3. [email] => test@example .com
4. [date] => 20110521
5.)

이제 POST로 넘겨받은 모든 값을 암호화 해서 DB에 입력할 것이다.

01.// insertDB.php
02.include ./dbConnect.php; // DB 연결 (구체적인 코드는 생략한다)
03.include ./mcrypt.php;
04.
05.foreach($_POST as $key => $value) {
06. $_POST[$key] = function_for_encryption($value);
07.}
08.$query = "INSERT INTO `mailing_list` (`name`, `email`, `date`)
09. VALUES ('{$_POST['name']}', '{$_POST['email']}', '{$_POST['date']}')";
10.$result = mysql_query($query);

이제 mailing_list 테이블의 모든 데이터를 조회해서 복호화 한 다음, 화면에 출력할 것이다.

01.//selectDB.php
02.include ./dbConnect.php; //DB 연결 (구체적인 코드는 생략한다)
03.include ./mcrypt.php;
04.
05.$query = "SELECT * `mailing_list`";
06.$result = mysql_query($query);
07.$number_of_rows = mysql_num_rows($result);
08.for ($i=0; $i<$number_of_rows; $i++){
09. $row = mysql_fetch_array($result);
10. foreach($row as $key => $value) {
11. if ($key=='no') {
12. continue; // $row['no']는 복호화 할 필요가 없다.
13. }
14. $row[$key] = function_for_decryption($value);
15. }
16. echo "번호 : ".$row['no']." 이름 : ".$row['name']." 이메일 : ".$row['email']." 날짜".$row['date'];
17.}
 
웹개발자나 FT개발자는 기본적으로 Firefox나 Chrome을 기본 브라우져로 사용하는 경우가 많다.
일단 빠르고 (파폭은 쫌 느림;) 다양한 Extensions이 존재하기 때문인데, 그 중에서도 개발을 위해선 Extionsions 중 firebug를 빼먹을순 없다.

오늘은 강력한 firebug의 기능 중 console에 대해서 자세히 살펴보려 한다.

1. console.log(object[, object, ...])
script내 단순 메세지 출력을 위해 사용.

1
2
3
4
5
6
7
8
9
10
<SCRIPT type=text/javascript>
var str = "콘솔 테스트";
var num = 1;
var num1 = 2;
var num2 = 1;
console.log(str);
console.log(num);
console.log("지금 하는건 %s. 번호는 %d", str, num);
</SCRIPT>

결과 :


2. console.debug(object[, object, ...])
console.log()와 동일하나 추가적으로 실행라인이 표시됨.

1
2
3
4
5
6
7
8
9
10
<SCRIPT type=text/javascript>
var str = "콘솔 테스트";
var num = 1;
var num1 = 2;
var num2 = 1;
console.debug(str);
console.debug(num);
console.debug("지금 하는건 %s. 번호는 %d", str, num);
</SCRIPT>

결과 :


3. console.info(object[, object, ...])
console.debug()와 동일하고 앞에 Info를 가르키는 아이콘이 출력된다. (배경색 : 시원한 파란색)

1
2
3
4
5
6
7
8
9
10
<SCRIPT type=text/javascript>
var str = "콘솔 테스트";
var num = 1;
var num1 = 2;
var num2 = 1;
console.info(str);
console.info(num);
console.info("지금 하는건 %s. 번호는 %d", str, num);
</SCRIPT>

결과 :


4. console.warn(object[, object, ...])
console.debug()와 동일하고 앞에 warning을 가르키는 아이콘이 출력된다. (배경색 : 불안한 노란색)

1
2
3
4
5
6
7
8
9
10
<SCRIPT type=text/javascript>
var str = "콘솔 테스트";
var num = 1;
var num1 = 2;
var num2 = 1;
console.warn(str);
console.warn(num);
console.warn("지금 하는건 %s. 번호는 %d", str, num);
</SCRIPT>

결과 :


5. console.error(object[, object, ...])
console.debug()와 동일하고 앞에 error를 가르키는 아이콘이 출력되고 에러난 부분의 메세지가 출력된다. (배경색 : 에러의 빨간색)

1
2
3
4
5
6
7
8
9
10
<SCRIPT type=text/javascript>
var str = "콘솔 테스트";
var num = 1;
var num1 = 2;
var num2 = 1;
console.error(str);
console.error("이건 num 변수다.", num);
console.error("지금 하는건 %s. 번호는 %d", str, num);
</SCRIPT>

결과 :


6. console.assert(expression[, object, ...])
조건을 입력하고 출력할 텍스트를 입력하면 해당 조건이 통과하였을경우 Console창에 출력되지 않고 통과하지 못하였을땐 Console에 출력된다.

1
2
3
4
5
6
7
8
<SCRIPT type=text/javascript>
var num = 1;
var num1 = 2;
console.assert(num == 2, "num은 2?");
console.assert(num > num1, "num > num1 이건 통과?");
console.assert(num < num1, "num < num1 이건 통과?");
</SCRIPT>

결과 :


7. console.dir(object)
인자로 넘어간 개체에 대해 모든 프로퍼티와 값들을 출력한다. (HTML 마크업을 넘기면 Dom Tree 출력)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<DIV id=division class=division>
test division
</DIV>
<SCRIPT type=text/javascript>
console.dir(document.getElementById("division"));
var objGirl = {
Name: "Test",
Eyes: "Brown",
BestQualities:
[
"Smile",
"Laugh"
]
};
console.dir(objGirl);
</SCRIPT>

결과 :


8. console.dirxml(node)
인자로 넘어온 노드에 대한 소스(innerHTML)를 출력한다.

1
2
3
4
5
6
7
<DIV id=division class=division>
test division
</DIV>
<SCRIPT type=text/javascript>
console.dirxml(document.getElementById("division"));
</SCRIPT>

결과 :



9. console.trace()
자바스크립트가 최초 실행된 순간부터 console.trace를 만날때까지의 실행 정보를 출력한다.

1
2
3
4
5
6
7
8
9
10
<A onmouseover=mouseover(); onmouseout=console.trace(); onclick=click(); href="#">Trace Test</A>
<SCRIPT type=text/javascript>
function click() {
console.trace();
}
function mouseover() {
console.trace();
}
</SCRIPT>

결과 :


10. console.group(object[, object, ...]), console.groupEnd()
그룹을 생성하여 그룹별로 log를 출력할수 있게 해준다. groupEnd는 group()을 열어줬으면 반드시 닫아주는 코드도 삽입해야한다.
그리고 console.groupCollapsed()는 group()과 기능은 동일하나 Default가 접혀있는 상태이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<SCRIPT type=text/javascript>
var str = "콘솔 테스트";
console.group("기본적으로 펼쳐짐!!");
console.log(str);
console.log("console");
console.warn("warning");
console.groupEnd();
console.groupCollapsed("기본적으로 접혀짐!!");
console.log(str);
console.log("console");
console.warn("warning");
console.groupEnd();
</SCRIPT>

결과 :


11. console.time(name), console.timeEnd(name)
실행 시간을 체크하길 원하는 function이나 구문을 감싸면 실행 시간을 출력해준다.
console.time()을 열었으면 반드시 console.timeEnd()로 닫아줘야 한다.

1
2
3
4
5
6
7
8
9
10
<SCRIPT type=text/javascript>
console.time("while test");
var i = 100000;
while (i--){
if( 100 > i ) {
}
}
console.timeEnd("while test");
</SCRIPT>

결과 :


12. console.profile([title]), console.profileEnd()
자바스크립트 프로파일러를 실행한다. profile()로 연 순간부터 profileEnd()를 만날때까지 실행한 모든 스크립팅에 대한 시간(고유시간, 시간, 평균, 최소, 최대)와 호출횟수, 전체 실행 평균 퍼센트를 출력한다. console.profile()을 열었으면 반드시 console.profileEnd()로 닫아줘야한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<SCRIPT type=text/javascript>
console.profile("profile test");
function abc() {
var i = 1000;
while (i--) {
//block
}
return i;
}
function def() {
for (var i = 0; i < 1000; i++) {
//block
}
return i;
}
abc();
def();
console.profileEnd();
</SCRIPT>

결과 :


13. console.count([title])
실행한 횟수 만큼 count를 집계하여 출력해준다. 이때 title이 동일하다면 title별로 count를 더하여 보여준다.

1
2
3
4
5
6
7
8
<SCRIPT type=text/javascript>
console.count("난 실행될때마다 Count증가. 그래서 Count는?");
var i = 1000;
while (i--) {
console.count("여기 Count는?");
}
console.count("난 실행될때마다 Count증가. 그래서 Count는?");
</SCRIPT>

결과 :


14. console.exception(error-object[, object, ...])
try ~ catch에서 catch의 error 객체를 인자로 넘기면 에러 메세지를 자세히 출력해준다.

1
2
3
4
5
6
7
8
9
10
11
12
<SCRIPT type=text/javascript>
function zzz() {
try {
var a = 0;
var c = b * 10;
}
catch (e) {
console.exception(e);
}
}
zzz();
</SCRIPT>

결과 :


15. console.table(data[, columns])
Array나 Object등 형태의 가공된 데이터를 table 형태로 출력해준다.

1
2
3
4
5
6
7
8
9
10
11
<SCRIPT type=text/javascript>
var arr = [1, 2,3 ];
console.table(arr);
var obj = [
{city:"서울", eng:"Seoul"},
{city:"제주", eng:"Jeju"},
{city:"부산", eng:"Busan"}
];
console.table(obj);
</SCRIPT>

결과 :

'Dev > Javascript' 카테고리의 다른 글

20 Best jQuery Slideshow / Photo Gallery Plugins  (0) 2012.02.29
Prototype에서 jQuery로 옮겨타기  (0) 2011.07.31
fireBug 사용법  (0) 2011.07.19
[jQuery] firebug로 디버그  (0) 2011.07.19
Javascript 배열 메서드  (0) 2011.04.29
자바스크립트를 사용하다 보니 디버깅시 alert으로만 하기에는 너무 고된 길이 예상되어서
fireBug사용법을 검색하여 보았습니다.

역시 구글에 없는 내용은 없더군요^^
아래 사이트에 기본적인 내용이 잘 정리된 것 같습니다.

console.log보기
로그 레벨에 따라 info, debug, error, log중에서 골라서 사용하면 된다.


파이어 폭스에서 이렇게 보임.


코드 실행에 걸리는 시간체크하기
console.time으로 시작을 알리고 테스트 코드를 넣은 후 console.timeEnd()로 닫아준다.
함수단위도 체크가 가능한지 함수 이름을 넣어봤지만 안되더군요.


결과화면


프로파일 명령 사용 코드
while문과 for문을 실행하는 프로파일을 만들어 봤습니다.
console.profile()로 시작하고 마지막에 console.profileEnd()를 사용하면 됩니다.



프로파일 결과
호출 횟수, 시간, 평균시간 등등 코드에 대한 프로파일 분석결과가 화면에 표시됩니다.

크롬에서도 log, profile등은 지원이 되는 것 같더군요.
이 외에도 commandAPI를 이용해 console창에서 돔요소를 탐색하는 기능이 있는데
이 부분은 다음에 기회되면^^

출처 : http://chaospace.tistory.com/

책 ( jQuery Cookbook ) 을 읽다가 알게된 파이어폭스에서

제대로된 객체가 선택되었는지 확인하는 방법입니다. ㅋㅋ


왠만한 분들 다 아시겠지만;; 전 처음 안거라 신기해서 ㅋㅋ

파이어폭스 사용하여 개발하신 분이라면 다들 아시겠지만,

firebug 라고 디버그 해주는 기능을 다 아시리라 믿습니다~

모르시면
도구 > 부가기능 > 검색 해보시면 나와요~ 설치하시면 디버그 하실 수 있습니다~


이제 중요부분을 말하자면,

상당히 짧아서 서론을 일부러 길게 쓴....

아래는 사용 방법 입니다!~

var $test = $('.test'); // test 라는 클래스 명으로 된 모든 걸 가져옴.
console.log($test); // 파이어폭스 firebug 에 콘솔 이라는 곳에 가져온 test 를 찍습니다.
// 제대로 못 찍으면 잘 못 됐다는 거겠지요?


## 제대로 가져왔을 경우

## 가져오지 못 했을 경우



본인은 제대로 했는데 원활히 수행되지 않거나 에러도 나지 않을 경우에

유용하게 사용할 수 있을 거 같습니다.!!


모르셨던 분들에게 도움이 되셨길!~ ㅋㅋ

다른 것도 아는 것 있으면 공유합시다~~~

방문자가 별로 없어서 널리 퍼지진 않겠지만;;; 쿨럭쿨럭;;



도움이 되셨으면 하단 추천 버튼 혹은 광고 를 눌러주시는 것도 좋습니다.!!
많은 사람들이 볼 수 있도록 해주세요!~~


출처 : http://dokeby.tistory.com/

1. UI 프레임워크

http://jqtouch.com/

http://code.google.com/p/iui/

http://webapp-net.com/

jqtouch + ext js + raphael
http://www.sencha.com/

iAd JS : Apple`s Javascript Web UI Library

monocle : 모바일 E-Book
http://monocle.inventivelabs.com.au/


2. Native App Framework

Phone Gap

http://www.phonegap.com/

 

Titanium

http://www.appcelerator.com/

 

QuickConnect

http://quickconnectfamily.org/


Nimble Kit

http://www.nimblekit.com/index.php

PHP코드를 C++코드로 변환, g++로 빌드할 수 있게 하는 물건. 
결과물로 libevent 를 사용한 독립 웹서버 실행파일이 떨어진다. 
페이스북에서 쓰이고 있으며 성능 개선이 상당하다고 한다. 
모든 PHP 코드가 다 동작하는 것은 아니겠지만 관심이 무럭무럭!!

일단 홈페이지. 
https://github.com/facebook/hiphop-php/wiki/

한글로 된 소개글
http://enzine.tistory.com/entry/HipHop-for-PHP-%EB%8D%94-%EB%B9%A0%EB%A5%B8-PHP%EB%A5%BC-%EC%9C%84%ED%95%B4

KLDP의 새소식
http://kldp.org/node/112325

먼저 써보신 분의 의견. 
http://code.p-ark.co.kr/167 





레드마인을 위해 설치해 둔 우분투 10.04에 깔아보자. 9.10에 설치하는 참고링크는 여기.
https://github.com/facebook/hiphop-php/wiki/Building-and-Installing-on-Ubuntu-9.10
10.10용은 여기. (명색이 LTS인 10.04만 빠져있네...) 
https://github.com/facebook/hiphop-php/wiki/Building-and-Installing-on-Ubuntu-10.10


먼저 관련프로그램 설치. 

sudo apt-get install git-core cmake g++ libboost-dev libmysqlclient-dev libxml2-dev libmcrypt-dev libicu-dev openssl binutils-dev libcap-dev libgd2-xpm-dev zlib1g-dev libtbb-dev libonig-dev libpcre3-dev autoconf libtool libcurl4-openssl-dev libboost-system-dev libboost-program-options-dev libboost-filesystem-dev wget memcached libreadline-dev libncurses-dev libbz2-dev libc-client2007e-dev



9.10과 마찬가지로 10.04의 libmemcached 는 버전이 0.31이므로 쓸 수 없다. 0.39 이상이 필요하므로 따로 빌드. 

HipHop 소스 얻기. 

mkdir hiphop
cd hiphop
git clone git://github.com/facebook/hiphop-php.git
cd hiphop-php
export CMAKE_PREFIX_PATH=`/bin/pwd`/../
export HPHP_HOME=`/bin/pwd`
export HPHP_LIB=`/bin/pwd`/bin
git submodule init
git submodule update
cd ..



LIBEVENT 빌드.

wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
tar -xzvf libevent-1.4.13-stable.tar.gz
cd libevent-1.4.13-stable
cp ../hiphop-php/src/third_party/libevent-1.4.13.fb-changes.diff .
patch -p1 < libevent-1.4.13.fb-changes.diff
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..



ICU4 빌드

wget http://download.icu-project.org/files/icu4c/4.2.1/icu4c-4_2_1-src.tgz
tar -xvzf icu4c-4_2_1-src.tgz
cd icu/source
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ../../




LIBCURL 빌드. 시스템 시간 잘 맞추지 않으면 ./configure 가 실패한다네. 
중간에 패치가 필요하므로 지정된 버전을 쓸 것. 

wget http://curl.haxx.se/download/curl-7.20.0.tar.gz
tar -xvzf curl-7.20.0.tar.gz
cd curl-7.20.0
cp ../hiphop-php/src/third_party/libcurl.fb-changes.diff .
patch -p1 < libcurl.fb-changes.diff
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..



LIBMEMCACHED 빌드. 현재 최신버전인 0.49로

wget http://launchpad.net/libmemcached/1.0/0.49/+download/libmemcached-0.49.tar.gz
tar -zxvf libmemcached-0.49.tar.gz
cd libmemcached-0.49
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..



HipHop 빌드. 걸어놓고 밥먹고 오자. 

cd hiphop-php
cmake . <- 점 주의!
make



hphp 바이너리가 src/hphp 에 생성된다. 

  



테스트. 사용법은 일단 여기.
https://github.com/facebook/hiphop-php/wiki/Running-HipHop


먼저 hphp를 체크아웃 한 디렉토리로 이동. 

export HPHP_HOME=`pwd`
export HPHP_LIB=`pwd`/bin



우분투에서는 추가로 이렇게 해주라는군.

export CMAKE_PREFIX_PATH=`/bin/pwd`/../



예전 GD 가지고 놀 때 코드를 한번 컴파일 해보자. 
적당한 디렉토리에 예제 php 파일 생성. 


ip-test.php
 

<?php
$img_number = imagecreate(140,25);
$backcolor = imagecolorallocate($img_number,255,255,255);
$textcolor = imagecolorallocate($img_number,50,104,28);

imagefill($img_number,0,0,$backcolor);
$number = "IP - $_SERVER[REMOTE_ADDR]";

Imagestring($img_number,3,0,5,$number,$textcolor);

header("Content-type: image/jpeg");
imagejpeg($img_number);
?>



컴파일

$HPHP_HOME/src/hphp/hphp ip-test.php -k 1 --log=3 --force=1 




임시 디렉토리 (내 경우에는 /tmp/hphp_TFludl) 에 실행파일이 생성된다. 
관리자 권한으로 실행. 

sudo /tmp/hphp_TFludl/program -m server -p 8080


 
해당 서버에 접속해보자. http://my-ubuntu:8080/ip-test.php
결과는 짜잔~~





GD 테스트를 조금 더 해본다. 
프리타입이 동작하는지도 확인해보자. 윈도의 gulim.ttc 를 /tmp 에 복사해넣자. 

gd-test.php

<?php
// 이미지 생성
$image_test = ImageCreate(200,150);

// 색의 설정
$grey = ImageColorAllocate($image_test,200,200,200);
$blue = ImageColorAllocate($image_test,0,0,255);

imagefill($image_test,10,0,$grey);

// 내장폰트 사용 예
Imagestring($image_test,3, 25,50,"hahaha",$blue);

// 프리타입으로 TTF 폰트 사용 예
Imagefttext($image_test,10, 0, 25, 100, $blue, "/tmp/gulim.ttc", "우하히");

header("Content-type: image/png");
imagepng($image_test);
ImageDestroy($image_test);
?>



HipHop은 컴파일 이전에 이 PHP가 제대로 동작할지를 미리 확인해볼 수 있는 hphpi 를 제공한다. 

$HPHP_HOME/src/hphpi/hphpi  -m server -p 8080



현재 디렉토리를 기준으로 서버가 동작한다. 매번 빌드하는 것도 시간이 걸리는 일이므로, 이걸 쓰면 지금 작성중인 코드가 HipHop에서 잘 동작하는지 확인해 볼 수 있다. 

접속해보면 잘 처리되는데... 



이 PHP 파일에 include, 또는 include_once 를 써서 다른 PHP 유니트를 포함시키면 이미지 출력이 제대로 되지 않는다. 
이미지 출력을 위해 사용되는 header(), imagepng() 등의 함수가 아예 동작하지 않는 듯 하다. 
현 시점에서 GD 관련해서는 단일 유니트만 사용 가능할 듯. 진심으로 아쉬운 부분... 










예전 게임서버는 DB 입출력을 담당하는 에이전트 서버를 통해 각종 정보를 저장해 왔었다. 
이 경우 운영도 귀찮고 뭐 하나 바꾸려 할때 만져야 할 부분이 참 많다. 

때문에 로그 저장 서버는 상대적으로 편한 PHP + xmlrpc 를 써서 만들었었고
나중에 게임서버를 새로 만든다면 DB 입출력은 이 방식으로 하리라 마음먹었었는데...

HipHop을 이용하면 그 부분도 네이티브 바이너리로 굴릴 수 있다는 이야기. 
퍼블리셔에 텍스트로 된 PHP 파일을 그대로 전달해야 하는 찝찝함도 더불어 해결. 

다만 생성된 실행파일의 크기가 약 20메가 정도로 큰 편인데, UPX로 압축하면 7메가 정도로 줄어든다. 

# sudo apt-get install upx-ucl
# upx program


서버에서 실행파일의 크기야 별 의미가 없겠지만... 

언제 시간날 때 VCL4PHP 를 빌드해봐야겠다. 

from : http://oranke.tistory.com/173
 

프로젝트를 성공적으로 수행함에 있어 빠질 수 없는 것이 프로젝트 구성원들간의 원활한 커뮤니케이션 및 협업을 들 수 있다. 하지만 실제 프로젝트를 경험해 보면 이해관계자들의 다양한 관점으로 인한 커뮤니케이션의 어려움, 세분화되지 않은 작업 단위로 인한 진척관리 및 변경관리의 어려움, 보고를 위한 불필요한 작업의 반복, 비 정량적인 품질지표로 인한 품질신뢰도 하락 등 다양한 이유로 인해 업무 진행에 어려움을 경험하게 된다. 이러한 어려움을 극복하기 위해 프로젝트에 맞는 방법론과 이를 원활하게 수행할 수 있는 다양한 헙업도구들이 존재한다. 이 글에서는 작업관리 도구, 형상관리 도구, 품질측정 도구, 빌드 자동화 도구 이렇게 네 가지 타입의 오픈소스 협업도구들에 대해 살펴보도록 한다.

이윤걸 gerion@gmail.com|아이티와이즈컨설팅 SE팀에서 엔지니어로 근무하고 있으며, 엔터프라이즈 환경에서의 소프트웨어 아키텍처, 프레임워크와 관련된 일을 주로 수행하고 있다. 최근에는 모바일 비즈니스 환경에 대해 관심이 많으며 소프트웨어 아키텍트로 성장하기를 꿈꾸고 있다.

프로젝트를 수행할 때 팀원간의 작업 배분, 이슈에 대한 토론, 변경된 요구사항의 반영 등을 해결하기 위해 회의, 이메일, 전화 등을 통해 협의하고 협의한 내용을 문서화해 이슈에 대한 관리를 해본 경험이 있을 것이다. 이런 이슈에 대한 관리 및 커뮤니케이션을 원활하게 수행할 수 있도록 도움을 주는 도구를 작업관리 도구 혹은 프로젝트관리 도구라고 한다.

작업관리도구
대표적인 오픈소스 작업관리 도구로 레드마인(http://www. redmine.org)과 트랙(http://trac.edgewall.org/)을 들 수 있다. 둘 다 인기있는 프로젝트 관리도구로 기본적인 기능은 유사하나 레드마인의 경우 여러 개의 프로젝트를 관리할 수 있고 역할 기반으로 접근통제를 할 수 있으며, 간트 차트 생성을 기본으로 지원한다. 또한, 위키 이외에 게시판, 커뮤니티 기능을 제공해 개발자뿐만 아니라 다양한 사용자들이 쉽게 접근할 수 있다. 트랙은 다양한 플러그인을 통해 기능확장을 쉽게 할 수 있고, 형상관리 도구와 연동해 변경사항에 대한 내용을 확인할 수 있는 특징이 있다. 여기서는 레드마인에 대해 살펴보도록 하자.

레드마인은 RoR(Ruby on Rails) 기반으로 만들어졌으며, 다양한 플랫폼과 데이터베이스를 지원한다. 또한, 트랙과는 다르게 다수의 프로젝트를 동시에 관리할 수 있으며 커스터마이징을 통해 프로젝트에 맞게 다양한 환경을 구성할 수 있다.

환경구성을 위해 RoR, 웹서버, DB, 형상관리 등 여러 가지 도구를 필요로 하지만, BitNami(http://bitnami.org/stack/ redmine)에서 제공하는 인스톨러를 사용하면 손쉽게 설치할 수 있다. 설치 및 특징에 대한 자세한 내용은 BitNami 사이트를 살펴보길 바란다.

위에서도 잠깐 언급했지만, 레드마인의 첫 번째 특징으로 여러 개의 프로젝트를 동시에 특성에 맞게 관리할 수 있다는 것이다. 프로젝트 생성 화면을 간단히 살펴보면 Issue tracking, Time tracking, News, Documents, Files, Wiki, Repository, Boards, Calendar, Gantt와 같은 다양한 모듈을 제공하고 프로젝트 생성시 사용하고자 하는 모듈을 입맛에 맞게 선택하고 생성할 수 있도록 옵션 처리가 되어 있다. 프로젝트가 생성되면 프로젝트에 참여할 인원을 등록하고 각 인원들이 수행할 역할을 할당할 수 있다.

<화면 1> 레드마인 프로젝트 생성

두 번째 특징으로 이슈 트래킹을 들 수 있다. 이 기능은 등록된 활동에 대해 세부내용까지 관리하고 변경사항에 대해 추적할 수 있다. 특정 이슈가 발생한 경우 해당 내용을 기입하고 참여자를 할당함으로써 활동을 등록할 수 있다. 이후, 이슈에 대한 진행 상황을 지속적으로 반영함으로써 현재 프로젝트에 대한 이슈는 어떠한 것들이 존재하는지 알려주고, 관련 이슈나 하위 태스크를 연결해 해당 이슈뿐만 아니라 관련된 이슈에 대해서도 진행되고 있는 상태를 쉽게 관리할 수 있게 해준다.

<화면 2> 이슈 트래킹 관리화면

세 번째 특징으로 간트 차트(Gantt chart)를 들 수 있다. 위키피디아에서 간트 차트에 대해 찾아보면 다음과 같이 정의하고 있다. 간트 차트는 프로젝트 일정관리를 위한 바(bar) 형태의 도구로서, 각 업무별로 일정의 시작과 끝을 그래프로 표시해 전체 일정을 한눈에 볼 수 있다. 또한 각 업무(activities) 사이의 관계를 보여줄 수도 있다. 

레드마인은 등록된 이슈 정보를 통해 각 작업들에 대한 현재 상태를 보여주고 전체 프로젝트 상태를 한눈에 파악할 수 있게 간트 차트를 생성한다. 또한, 내보내기 기능을 통해 PDF나 PNG로 해당 내용을 추출해 낼 수 있어 일정관리에 있어 편리함을 제공해 준다.

<화면 3> 칸트 차트

네 번째 특징으로 위키를 들 수 있다. 위키는 사용자들의 협업을 통해 콘텐츠를 구성할 수 있도록 해주는 프로그램이다. 유명한 위키사이트로 위키피디아(http://www.wikipedia.org/)를 들 수 있다. 사용자들은 누구라도 웹 브라우저를 통해 콘텐츠를 편집할 수 있어 공통작업을 진행할 경우 팀원들간의 의견을 결과물에 빠르게 반영할 수 있다. 하지만 단점도 존재한다. 처음 접하는 사용자의 경우 위키 문법을 익혀야 하기 때문에 익숙해지기까지 상당한 기간이 소요될 수 있다. 개발자들로만 구성된 프로젝트가 아니라면 프로젝트를 구성하고 있는 다양한 이해관계자들 중에는 위키 문법 때문에 어려움을 겪는 사람이 존재할 가능성이 매우 높다. 레드마인에서는 위키 이외에 게시판 기능을 제공해 주기 때문에 다양한 사용자들이 쉽게 사용할 수 있다.

형상관리 도구
다수의 사람들이 함께 작업을 진행할 경우 작업 결과를 모아둘 수 있는 저장소가 필요하다. 이때 쉽게 떠올릴 수 있는 저장소는 공유 디렉터리를 만들거나 FTP 환경을 구축하는 것이다. 이 저장소에는 프로젝트 수행 중에 발생한 각종 문서, 소스 코드 등 여러 종류가 존재할 것이다. 작업자는 개별로 작업한 결과물을 저장소에 반영하게 되는데 이때, 결과물이 덮어써지면서 이전 결과물이 사라지는 경우들이 종종 발생하게 된다. 다수의 사람들이 동시에 작업하는 프로젝트의 경우 이러한 변경에 영향을 받게 되고 이런 문제를 해결하기 위해 등장한 도구가 형상관리 도구이다. 형상관리 도구는 작업방식에 따라 여러 사람이 동시에 작업하다가 충돌이 발생할 경우 처리하는 낙관적 잠금(Optimistic locking), 충돌을 미연에 방지하기 위해 한번에 한 사람만 작업할 수 있도록 하는 비관적 잠금(Pessimistic locking) 두 가지 방식이 존재한다. 여기서는 낙관적 잠금을 사용하는 오픈소스인 SVN(Subversion)과 CVS(Concurrent Version System)를 중심으로 살펴보도록 하자.

CVS는 1980년대 중반에 탄생해 지금까지 사용되는 가장 오래되고 대중적인 도구이다. 이 도구는 오랜 기간 동안 다양한 연구를 통해 많은 발전을 해 왔으며 그 결과로 윈도우 버전, GUI 버전, 웹 버전 등 다양한 형태로 수많은 프로젝트나 기업에서 사용되고 있다. 단점으로는 첫째, CVS 저장소의 파일들은 이름을 바꿀 수 없어서, 파일을 제거한 후 다시 추가해야 한다. 둘째, 디렉터리의 이동이나 이름의 변경을 허용하지 않는다. 이에 따라 서브 디렉터리의 파일을 모두 지우고 다시 추가해야 한다. 셋째, 개별 파일 단위로 버전이 관리된다. 넷째, 아스키코드로 된 파일명만 지원하고 유니코드에 대해서는 제한적으로 지원한다.

SVN은 2004년부터 CVS를 만들었던 핵심 개발자들이 CVS를 대체하기 위해 CVS의 한계를 일부 수정하면서 등장했고, 그 이후에 많은 인기를 얻으면서 빠르게 자리를 잡아가고 있다. CVS 와 비교한 SVN의 장점은 다음과 같다. 첫째, 개별 파일 단위가 아닌 변경작업 단위로 커밋을 한다. 둘째, revision의 diff만 저장하는 방식을 통해 CVS에 비해 빠르다. 셋째, 소스 코드뿐만 아니라 바이너리 파일도 지원한다. 넷째, CVS와 유사한 개념과 사용법으로 인해 CVS 사용자들도 쉽게 사용할 수 있다. SVN의 개념이 CVS의 단점을 보완해 나온 도구이기 때문에 SVN을 기준으로 좀 더 자세히 살펴보도록 하자.

SVN은 클라이언트-서버 모델을 채택하고 있기 때문에 우선 서버를 설치하고 저장소를 만들어야 한다. 서버의 설치는 VisualSVN(http://www.visualsvn.com/server/) 사이트에서 설치 파일을 내려 받아 사용하면 간단하게 설치할 수 있다. 저장소의 경우 여러 가지 프로토콜을 지원하며 기본적으로 svn 프로토콜을 사용한다. 만약, 웹으로 접근하고자 한다면 http 프로토콜을 사용해 접근할 수도 있다. 저장소는 trunk, branches, tags 세 가지로 분리해서 관리되는데 trunk는 원본 소스를 관리하는 곳이고 branches는 trunk에서 관리되는 버전과 별도로 분기해 처리해야 할 경우 사용하고 마지막으로 tags는 특정 시점의 결과물에 대한 베이스라인을 지정할 수 있다. 

<화면 4> 윈도우 탐색기에서의 TortoiseSYN

저장소를 생성하고 나면 해당 저장소를 이용하기 위해 별도의 클라이언트가 필요하다. 필자가 추천하는 클라이언트는 TortoiseSVN(http://tortoisesvn.tigris.org)와 Subversive(http://www.polarion.com/products/svn/subversive.php) 두 가지를 들 수 있다. TortoiseSVN은 윈도우 탐색기와 결합된 형태로 동작하기 때문에 각종 문서들과 같은 산출물을 관리하기에 매우 편리하다.

Subversive는 Eclipse(http://www.eclipse.org) IDE 플러그인 형태로 제공한다. 다수의 개발자가 이클립스 IDE 환경을 통해 개발을 진행할 경우 매우 편리하게 사용할 수 있다. 일반적으로 많이 사용하는 기능들을 간략하게 살펴보도록 하자.

첫째, 체크아웃(CheckOut)을 들 수 있다. SVN 저장소에서 관리하고 있는 프로젝트의 대상 파일들을 로컬환경으로 받아오는 것을 의미한다. 기본적으로 파일을 내려받기 위해서는 계정정보가 있어야 하고, 저장소의 설정에 따라 익명으로 파일을 받아올 수도 있다. 둘째, 로컬환경에서 작업한 내용을 저장소에 반영하는 커밋(Commit)을 들 수 있다. 로컬에 있는 파일을 저장소와 동기화하는 행위이다. 셋째, 업데이트(Update)가 있다. 다수의 작업자들이 저장소에 작업내용을 반영하게 되면 본인의 로컬환경의 파일들이 최신 상태가 아닐 수 있다. 이와 같은 경우 저장소의 파일을 기준으로 로컬파일과 동기화하는 것을 업데이트라고 한다. 주기적으로 업데이트함으로써 작업간의 충돌을 최소화할 수 있다. 넷째, 가장 최근에 저장소에 반영된 버전으로 동기화시키는 리버트(Revert)를 들 수 있다. 작업을 진행하다가 잘못 처리된 경우 저장소로부터 반영된 버전을 동기화시킬 수 있다. 이 기능은 필자도 종종 유용하게 사용하는 기능 중의 하나이다. 다섯째, 충돌을 최소화시키기 위해 저장소에 반영된 내용과 로컬파일간의 차이를 확인하고 반영할 수 있는 Synchronized 기능이다. 로컬파일을 저장소에 반영하고자 한다면 Override and Commit을 사용하면 되고 반대의 경우는 Override and Update를 사용하면 된다. 마지막으로 리비전(Revision)을 들 수 있다. 커밋을 하게 되면 해당 커밋마다 버전정보가 생성되는데, 이 버전정보를 통해 변경에 대한 관리를 할 수 있다. 리비전 정보를 잘 활용하면 특정시점의 정보를 확인할 수 있다.

<화면 5> Eclipse에서 사용하는 Subversive

지금까지 형상관리 도구와 대표적인 형상관리 도구인 SVN에 대해 살펴봤다. 필자가 설명한 내용 이외에도 수많은 기능들이 존재한다. 상세한 내용은 참고사이트나 관련 서적을 통해 얻을 수 있다. 형상관리 도구는 협업이 필요한 환경에서 없어서는 안 될 필수적이고 반드시 이해해야 하는 도구라고 생각한다.

빌드 자동화 도구
빌드는 소프트웨어를 개발함에 있어서 지속적이고 반복적으로 수행해야 하는 작업이다. 물론, 빌드가 필요없는 스크립트 언어들도 존재하지만 컴파일이 필요한 환경에서는 항상 거쳐야 하는 과정 중의 하나이다. 빌드 도중에 오류가 발생하지 않는다면 별 문제 없겠지만, 혹시라도 오류가 발생할 경우 오류내용을 추적하고 수정하는 작업을 수행해야 한다. 이런 단순작업을 수행하는 시간에 리팩토링 등을 통해 좀 더 소스 코드의 품질을 향상시키는 생산적인 작업을 할 수 있다면 얼마나 좋을까? 이를 도와줄 수 있는 협업도구로 빌드자동화 도구를 들 수 있다. 이 도구는 소스 코드의 변화 여부를 체크하고 있다가 변화가 발생되는 시점에 빌드를 수행하고 해당 결과에 대한 관리를 수행함으로써 지속반복적으로 소프트웨어의 안정성과 품질을 체크할 수 있다. CI (Continuous integration)라고도 부르기도 하는 대표적인 오픈소스 소프트웨어로 Hudson(http://hudson-ci.org/)과 Cruise Control(http://cruisecontrol.sourceforge.net/)을 들 수 있다. Hudson은 설치가 매우 쉽다. 프로젝트 홈페이지에 가서 최신 버전을 받아보면 war 형태의 파일 하나를 받아서 실행하는 것이 전부이다. 또한, 다양한 플러그인을 통해 쉽게 기능 확장을 할 수 있다. 작업 결과물에 대한 퍼머넌트링크(permanent link)도 제공한다. CruiseControl도 설치는 간단하다. zip 파일을 내려받고 작업 디렉터리에 압축을 풀고 실행하는 것이 전부이다. 설정은 Hudson에 비해 어려운 편이다. 대부분의 설정을 config.xml에 정의해야 한다. 또한, UI적인 측면에서 Hudson에 비해 부족한 부분이 존재한다. Hudson이 사용성 측면에서 더 접근하기 쉬우므로 Hudson에 대해 자세히 살펴보도록 하자.

설치에 관해서는 위에서도 언급했지만, war 파일을 tomcat 같은 서블릿 컨테이너에 배포하면 된다. 설치 후 브라우저를 통해 접속하면 <화면 6>을 볼 수 있다.

<화면 6> Hudson 설치 후 초기구동 화면

초기 화면의 왼쪽 상단을 보면 기본 메뉴들을 볼 수 있다. Hudson 관리 쭻 Configure System 메뉴를 선택하면 구동을 위한 설정 화면을 볼 수 있다. JDK, Ant, Maven 설치정보를 입력할 수 있다. 여기서는 ant를 설정하도록 한다. 즉, Hudson이 ant를 이용해 빌드를 실행하고 그 결과를 보여준다고 할 수 있다. 빌드를 위해 형상관리 서버의 정보를 필요로 한다. 기본적으로 제공하는 형상관리는 SVN과 CVS이다. 입력한 형상관리 서버를 통해 소스 코드를 다운로드하고 빌드를 수행하게 되는 것이다. 다른 옵션들을 더 살펴보면 E-mail Notification 항목이 있는 것을 볼 수 있다. 이 옵션을 설정하게 되면 빌드가 실패했을 경우 이메일을 이용해 관리자에게 실패에 대한 내용을 통보해 준다. 또한, RSS 기능을 제공해 Hudson이 발생한 이벤트에 대해 구독할 수도 있다. 

<화면 7> Hudson 설정화면

기본 설정이 끝나면 이제는 Hudson이 실제 수행할 작업을 등록해야 한다. 좌측 상단의 ‘새 작업’ 메뉴를 선택하고 새롭게 등록할 작업명을 넣어주고, 프로젝트 특성에 맞는 옵션을 선택해 준다. 우리는 ant를 사용해 빌드를 수행하기 때문에 ‘Build a free-style software project’ 옵션을 선택하도록 한다. 만약 메이븐을 사용한다면 그에 맞는 옵션을 선택하면 된다.

<화면 8> Hudson 작업등록 화면

이후에는 프로젝트에 대한 상세 설정 화면으로 이동하게 된다. 여기에서 살펴볼 부분은 Build Trigger 설정이다. 이 설정은 언제 빌드가 수행되어야 하는지 설정하는 부분으로 세 가지 옵션을 제공하고 있다. 첫째, ‘Build after other projects are built’이다. 이 옵션은 다른 Job의 이름을 인자로 넣으면 된다. 지정된 프로젝트의 빌드가 완료되면 트리거가 발생해 자동으로 이 프로젝트의 빌드가 수행된다. 프로젝트간의 선, 후행 관계가 맺어져 있을 경우 사용할 수 있다. 예를 들면, 테스트 프로젝트와 실제 프로젝트를 분리해 관리할 경우 테스트 프로젝트를 선행 프로젝트로 설정해 놓고 테스트가 통과해야만 실제 프로젝트를 빌드하도록 처리하게 한다. 둘째, ‘Build periodically’은 특정주기별로 소스의 변동과 상관없이 빌드를 수행하고 crontab 형식으로 스케줄을 관리한다. 셋째, ‘Poll SCM’은 주기적으로 형상관리 시스템을 체크해 변동사항이 발견되었을 경우 빌드를 수행하게 된다. ‘Build periodically’와 마찬가지로 crontab 형태로 관리한다.

다음으로 플러그인에 대해 살펴보자. Hudson은 다양한 플러그인을 통해 많은 확장을 할 수 있다. Hudson 관리 쭻 Manage Plugins 메뉴에 들어가 보면 네 가지 메뉴를 볼 수 있다. ‘업데이트’는 설치한 플러그인 중 업데이트 가능한 버전이 나왔을 경우 표시된다. ‘설치 가능’은 현재 설정할 수 있는 플러그인 목록을 보여주는데 매우 다양한 플러그인이 지원됨을 확인할 수 있다. 필요한 플러그인을 선택하고 설치 버튼을 클릭하면 설치가 진행되는 화면을 볼 수 있다. 플러그인 설치가 완료되면 Hudson을 재기동시켜야 동작한다. ‘설치됨’은 내가 설치한 플러그인 목록을 보여준다. 마지막으로 ‘고급’은 플러그인 저장소 관련 옵션을 제공해 준다. 필자는 FindBugs, Google Calendar, PDM, Sonar 같은 플러그인을 설치해 유용하게 사용하고 있다. 

<화면 9>  Hudson 플러그인 관리화면

지금까지 간단하게 Hudson을 살펴봤다. 빌드 자동화 도구를 통해 단순반복적인 작업을 줄이고 문제 발생시에 신속하게 대처하고, 다양한 보고서를 통해 안정적인 소프트웨어를 만들 수 있다.

품질측정 도구
다수의 개발자가 함께 개발을 진행할 경우 보통 개발표준 절차가 존재한다. 그러나 이런 표준을 준수하지 않거나, 개발자 테스트가 충분하지 않은 탓에 잠재적으로 오류가 발생 가능한 형태의 코드를 가지고 있어서 통합테스트 단계에서 문제가 발견되면 그 후에 개발자가 다시 코드를 수정해야 하는 일이 빈번하게 발생할 수 있다. 이런 잠재적인 문제점을 낮추고 코드의 품질을 높이기 위해서는 소스 코드를 지속적으로 품질측정하고 개선하는 작업을 수행해야 한다. 보통 코드 품질 체크를 위한 항목으로 개발표준, 코드 중복 체크, 코드 커버리지 측정, 의존성 분석 등을 들 수 있다. 각 항목에 대해 살펴보면 첫째, 지속적인 품질개선 활동의 일환으로 코드 인스펙션을 수행할 경우에 개발표준을 준수하게 되면 인스펙션 참가자들이 코드에 대한 이해를 높인 상태에서 진행할 수 있다. 둘째, 중복 코드를 도출하게 되면 관리하는 소스 코드의 양을 줄일 수 있고, 한 곳의 소스만 수정할 경우 오류 없이 일관성을 유지할 수 있다. 셋째, 단위테스트를 통해 검증된 소스 코드에 대한 커버리지를 측정함으로써 테스트 케이스를 지속적으로 늘려 잠재적 오류에 대한 위험도를 낮출 수 있다. 넷째, 의존성 분석을 통해 패키지간의 의존성을 체크해 무한 반복되는 의존관계를 도출하고 개선할 수 있다. 프로젝트를 진행하면서 이러한 품질속성에 대한 측정 및 개선 활동을 하기 위한 방법은 다수 존재한다. 개발자의 IDE 환경을 통해 수행할 수도 있고, 통합 빌드 시 코드에 대한 분석을 통해 측정할 수도 있다. 여기서는 앞서 설명한 Hudson을 통해 통합 빌드가 수행될 때 소스 코드에 대한 품질측정을 수행하고 그 결과에 대해 쉽게 공유할 수 있는 품질측정 도구인 Sonar에 대해 살펴보도록 하자. Sonar(http:// www.sonarsource.org) 사이트에서 Sonar에 대해 ‘Sonar is an open platform to manage code quality. As such, it covers the 7 axes of code quality’라고 정의하고 있다. 일곱 가지 측면에서의 코드 품질을 측정하고 있다고 표현하는데, 일곱 가지 요소는 Architecture & Design, Comments, Coding rules, Potential bugs, Duplications, Unit tests, Complexity이다. PMD, Findbugs, Conbertura 등 품질관련 도구들을 포함하고 있는 메이븐 플러그인을 활용해 소스 코드를 분석하고 저장하고 그 결과를 브라우저를 통해 확인한다.

<화면 10> Sonar 아키텍처

Hudson에서는 Sonar와의 연동을 위해 플러그인을 제공하고 있어서 연동이 매우 간편하다. 우선 Sonar 서버를 설치해 보자. 다운로드한 파일의 압축을 풀고, 하위의 bin 폴더에 있는 서버기동 스크립트를 실행하면 된다. 플러그인 설치는 Hudson의 Hudson 관리 쭻 Manage Plugins 메뉴에 들어가서 설치 가능 탭의 Sonar를 선택하고 설치 버튼을 누르면 된다. 적용을 위해 Hudson을 재기동하도록 하자.

<화면 11> 설치된 Sonar 플러그 인

Sonar는 Maven 기반의 프로젝트 빌드 설정이 필요하므로, Hudson의 Hudson 관리 - Configure System에서 Maven 정보를 입력하도록 한다. 그리고 Sonar 설정에서 Sonar 접속서버와 데이터베이스 정보를 설정하면 된다. 빌드를 수행하고, 정보를 관리하는 것은 Hudson에서 이뤄지지만, 결과에 대한 모니터링 및 품질 전반에 대한 관리는 Sonar에서 이뤄진다.

대시보드를 잠깐 살펴보면 다양한 정적 코드분석 정보를 보여주고 있다. 소스 코드 분석, 코드 커버리지 측정, 유사 코드 분석, 의존성 분석 등 다양한 정보를 제공하는 것을 확인할 수 있다. Sonar에서 사용하는 룰셋은 변경이 가능하므로 프로젝트 상황에 맞는 룰을 정의하고 활용하면 매우 유용하게 사용할 수 있다.

<화면 12> Sonar에서 제공하는 대시보드

사용 유도가 중요
지금까지 오픈소스를 이용해 협업환경을 구성하는 것을 간단히 살펴봤다. 이 글에서 소개한 도구 이외에도 수많은 협업도구들이 존재하므로, 협업도구 도입을 위해서는 먼저 충분한 검토와 테스트가 필요하다. 하지만 도구는 어떤 작업을 수행함에 있어 작업을 효율적으로 진행하기 위한 보조적인 수단이다. 프로젝트 상황에 맞는 최적화된 협업환경을 구성하기 위해서는 많은 고민들이 필요하지만, 협업환경을 구성하는 것이 협업의 전부는 아니라는 것이다. 협업도구를 도입함에 있어서 큰 어려움 중의 하나는 그것을 사람들이 사용하도록 유도하기 힘들다는 것이다. 하지만 누군가와 함께 일을 할 경우 협업은 매우 중요한 요소이고 프로젝트의 성공 여부와도 밀접한 관계를 가질 수 있다. 프로젝트를 수행하면서 나오는 산출물은 개인이 아니라 프로젝트 팀 전원의 책임이다. 이러한 책임의식을 지속적으로 인지시키고 수행 작업에 대해 적극적으로 참여를 유도하고 이를 효율적으로 처리하기 위한 보조수단으로 협업도구를 활용하도록 하자.

참고자료
1. redmine - http://redmine.org
2. trac - http://trac.edgewall.org
3. Comparison of issue-tracking systems - http://en.wikipedia.org/wiki/Comparison_of_issue_tracking_systems
4. Gantt chart - http://ko.wikipedia.org/wiki/간트_차트
5. VisualSVN - http://www.visualsvn.com
6. Polarion - http://www.polarion.com/products/svn/index.php
7. TortoiseSVN - http://tortoisesvn.tigris.org
8. Hudson - http://hudson-ci.org
9. CruiseControl - http://cruisecontrol.sourceforge.net
10. Sonar - http://www.sonarsource.org
11. Maven - http://maven.apache.org


http://www.imaso.co.kr/?doc=bbs/gnuboard.php&v2=1&bo_table=article&cmode=1&keywords=%C0%D0%C0%BB%B0%C5%B8%AE%3B%C6%AF%C1%FD

출처 : http://briele.tistory.com/


from Canvas2Image: Save out your canvas data to images on Ajaxian

테스트 이미지

EnZine을 쓰고 이미지로 변환한 결과물


Jacob Seidelin씨의 또 다른 작업입니다. 그는 <canvas> 데이터를 이미지로 내보낼 수 있는 라이브러리인 Canvas2Image를 만들었습니다. 즉, 이런 식으로 canvas 이미지를 만들 수 있다는 얘기입니다:
var strDataURI = oCanvas.toDataURL();
// returns "https://t1.daumcdn.net/cfile/tistory/217E413B56EA4D9929"

전체 API를 사용한 예제입니다:
/*
 * Canvas2Image.saveAsXXXX = function(oCanvasElement, bReturnImgElement, iWidth, iHeight) { ... }
 */

var oCanvas = document.getElementById("thecanvas");

Canvas2Image.saveAsPNG(oCanvas);  // PNG 이미지 저장 대화창이 나타납니다.

Canvas2Image.saveAsJPEG(oCanvas); // JPEG 이미지 저장 대화창이 나타납니다.
                                  // Firefox만 가능.

Canvas2Image.saveAsBMP(oCanvas);  // BMP 이미지 저장 대화창이 나타납니다.


// PNG로 변환된 <img> 엘리먼트 반환
var oImgPNG = Canvas2Image.saveAsPNG(oCanvas, true);  

// JPEG로 변환된 <img> 엘리먼트 반환(Firefox만 가능)
var oImgJPEG = Canvas2Image.saveAsJPEG(oCanvas, true);
                                                      
// BMP로 변환된 <img> 엘리먼트 반환
var oImgBMP = Canvas2Image.saveAsBMP(oCanvas, true);


// 모든 함수는 너비와 높이를 인자로 줄 수 있습니다
// 모든 이미지는 크기에 맞게 축소/확대 됩니다:

// 100x100 크기의 PNG 이미지 저장
Canvas2Image.saveAsPNG(oCanvas, false, 100, 100);

출처 : http://enzine.tistory.com/

'Dev > RIA' 카테고리의 다른 글

[HTML5] Canvas  (0) 2011.06.10
HTML5 Guide  (0) 2011.06.06

+ Recent posts