모든 테스트는 BORANET(by LGU+) 망의 PC에서 수행.



CloudPing을 이용한 Latency 테스트


US-East (Virginia)

234 ms

US-West (California)

141 ms

US-West (Oregon)

158 ms

Europe (Ireland)

298 ms

Asia Pacific (Singapore)

202 ms

Asia Pacific (Sydney)

152 ms

Asia Pacific (Japan)

67 ms

South America (Brazil)

341 ms

참고: http://www.cloudping.info/




EC2 업/다운로드 Throughput 테스트


US-West(Oregon), Asia-Pacific(Singapore), Asia-Pacific(Japan)의 EC2 인스턴스가 대상.

업로드는 rsync, 다운로드는 wget을 이용.


결과:

US-West(Oregon), Asia-Pacific(Singapore):

업/다운로드 모두 600~1200 KB/s의 속도를 보임.

동시 업/다운로드에서 속도 저하 없음.

긴 Latency로 인한 다운로드 속도의 변화폭은 그리 크지 않음.


Asia-Pacific(Japan):

1.6~1.8 MB/s 의 양호한 속도.



비고:

1. Olleh uCloud의 VM에서 테스트를 한 결과, 3 MB/s 쯤에서 다운로드가 완료되었는데 속도는 계속 상승 중이었음. 데이타 센터의 기간망이 빠르긴 하겠지만, 그래도 KT 망에서 더 빠른 속도를 낼 것이라 희망적으로 예상.



S3 업로드 Throughput 테스트


결과#1 US-West(Oregon):

200 ~ 350 KB/s 정도로 조금 변동폭 있음.

긴 Latency로 인한 다운로드 속도의 변화폭은 그리 크지 않음.


결과#2 Asia-Pacific(Singapore)

250 KB/s 정도로 균일함.


결과#3 Asia-Pacific(Japan)

최대 750 KB/s 까지 상승했지만 대체로 600 KB/s 안팎 수준에서 안정.




비고:

1. 모든 업/다운로드가 10 KB/s 수준의 속도에서 시작하는 것으로 보아, 초기 TCP Window 크기가 작은 것으로 추정됨.


Posted by 배트
,

이런건 보관해놓자.





Posted by 배트
,
Web Server의 간단한 스트레스 테스트를 하려고 하는데,
하늘의 별만큼 많은 게 테스트 툴이라... 

MS Web Application Stress Tool은 일정 버전 이상의 윈도우에서 동작을 안하고,
JMeter는 쉽고, 많이 쓰이지만 장기가 테스트를 돌리면 뻗는 문제가 있다.
WebLoad를 사용해보려 한다.

아래 링크에 가면 별처럼 많은 테스트 툴들을 볼 수 있다.
http://www.opensourcetesting.org/performance.php  
Posted by 배트
,
Apartment(STA)와 Single(Legacy Single)의 차이점을 몰라서 엄청 헤매던 끝에 해답을 준 아티클입니다.
Windows 서버에서 COM의 동접이나 성능에 관련된 문제를 겪으시는 분들을 읽어보세요.
이걸로 해!결!

Part1
http://www.codeproject.com/Articles/9190/Understanding-The-COM-Single-Threaded-Apartment-Pa 


Part2
http://www.codeproject.com/Articles/9506/Understanding-The-COM-Single-Threaded-Apartment-Pa  
Posted by 배트
,
This code is based on Apache common library.
If you are able to use the library, I recommend it. :-)

private boolean contentEquals(File file1, File file2) throws IOException {

    boolean file1Exists = file1.exists();

    if (file1Exists != file2.exists()) {

        return false;

    }


    if (!file1Exists) {

        // two not existing files are equal

        return true;

    }


    if (file1.isDirectory() || file2.isDirectory()) {

        // don't want to compare directory contents

        throw new IOException("Can't compare directories, only files");

    }


    if (file1.length() != file2.length()) {

        // lengths differ, cannot be equal

        return false;

    }


    if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) {

        // same file

        return true;

    }


    FileInputStream fileStream1 = new FileInputStream(file1);

    FileInputStream fileStream2 = new FileInputStream(file2);


    BufferedInputStream bufferedStream1 = new BufferedInputStream(fileStream1);

    BufferedInputStream bufferedStream2 = new BufferedInputStream(fileStream2);


    int ch = bufferedStream1.read();

    while (-1 != ch) {

        int ch2 = bufferedStream2.read();

        if (ch != ch2) {

            return false;

        }

        ch = bufferedStream1.read();

    }


    int ch2 = bufferedStream2.read();


    bufferedStream1.close();

    bufferedStream2.close();


    return (ch2 == -1);

}



Posted by 배트
,
조금 재미있긴 했는데 업무 시간에 너무 딴짓 했네.

<html>

<head> 


<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=euc-kr"> 


<title>Layer Test</title>


<script language="JavaScript"> 


var newArticleDivId = "write_article_layer";

var newArticleUrl = "http://www.naver.com/";

var minimumMargine = 50;

var maximumWidth = 800;


/*

 * openLayeredDialog

 * 레이어에 떠 있는 iFrame을 웹 페이지에 표시한다.

 */

function openLayeredDialog() {

    // 배경이 되는 반투명 레이어를 생성한다.

    var div1 = document.createElement("DIV");

    div1.id = newArticleUrl;

    div1.onclick = function () {closeLayeredDialog(false);};

    div1.style.position = "absolute";

    div1.style.height = "100%";

    div1.style.width = "100%";

    div1.style.top = "0";

    div1.style.left = "0";

    div1.style.background = "#000000";

    div1.style.opacity = "0.6";

    div1.style.filter = "alpha(opacity=60)";

    

    // iFrame을 담는 레이어를 생성한다.

    var div2 = document.createElement("DIV");

    div2.id = newArticleDivId + "_inner";

    div2.style.position = "absolute";

    div2.style.background = "#ffffff";

    

    // iFrame을 생성한다.

    var iframe1 = document.createElement("IFRAME");

    iframe1.src = newArticleUrl;

    iframe1.frameborder = "0";

    iframe1.style.height = "100%";

    iframe1.style.width = "100%";

    

    // 앞서 생성한 Element들을 웹 페이지에 추가한다.

    div2.appendChild(iframe1);

    document.body.appendChild(div1);

    document.body.appendChild(div2);

    

    // 레이어의 크기를 조정한다.

    adjustmentLayeredDialog();

    

    // 웹브라우저의 크기를 조절할 때 발생하는 이벤트의 핸들러를 등록한다.

    window.onresize = function(event) {adjustmentLayeredDialog();};

}


/*

 * closeLayeredDialog

 * 레이어를 제거한다.

 * 인자 normalClose가 true라면 Confirm 대화 창을 표시한다.

 * 인자 normalClose가 false라면 Confirm 대화 창을 표시하지 않는다.

 */

function closeLayeredDialog(normalClose) {

    // Confirm 대화 창을 표시한다.

    if (!normalClose) {

        willClose = confirm("이 페이지에서 나가면 작성하던 내용들은 저장되지 않습니다.\n정말 나가겠습니까?");

    } else {

        willClose = true;

    }

    

    // 레이어를 제거한다.

    if (willClose) {

        var child_background = document.getElementById(newArticleDivId);

        var child_inner = document.getElementById(newArticleDivId + "_inner");

        

        if (child_background) {

            document.body.removeChild(child_background);

        }

        if (child_inner) {

            document.body.removeChild(child_inner);

        }

        

        // 레이어를 제거하며 웹브라우저의 크기를 조절할 때 발생하는 이벤트의 핸들러도 제거한다.

        window.onresize = null;

    }

}


/*

 * adjustmentLayeredDialog

 * 레이어를 크기와 위치를 조정한다.

 */

function adjustmentLayeredDialog() {

    var child_inner = document.getElementById(newArticleDivId + "_inner");

    if (child_inner) {

        var clientHeight = document.body.clientHeight;

        var clientWidth = document.body.clientWidth;

        var top = minimumMargine;
        var left = 0;

       

        var height = clientHeight - minimumMargine * 2;

        var width = clientWidth - minimumMargine * 2;

        

        if (width > maximumWidth) {

            width = maximumWidth;

        }

            

        left = (clientWidth - width) / 2;

    

        child_inner.style.height = height;

        child_inner.style.width = width;

        child_inner.style.top = top;

        child_inner.style.left = left;

    }

}


</script> 


</head> 


<body>


<a href="javascript:openLayeredDialog();">레이어 보이기</a>


</body>

</html>

 
Posted by 배트
,
성능은 보장 못해도 완전 심플하다 ㅋㅋㅋ

출처: Simple Implementation of Wildcard (*) Text Matching using Java
http://www.adarshr.com/papers/wildcard

/**
 * Performs a wildcard matching for the text and pattern 
 * provided.
 * 
 * @param text the text to be tested for matches.
 * 
 * @param pattern the pattern to be matched for.
 * This can contain the wildcard character '*' (asterisk).
 * 
 * @return <tt>true</tt> if a match is found, <tt>false</tt> 
 * otherwise.
 */

public static boolean wildCardMatch(String text, String pattern)
{
    // Create the cards by splitting using a RegEx. If more speed 
    // is desired, a simpler character based splitting can be done.
    String [] cards = pattern.split("\\*");

    // Iterate over the cards.
    for (String card : cards)
    {
        int idx = text.indexOf(card);
        
        // Card not detected in the text.
        if(idx == -1)
        {
            return false;
        }
        
        // Move ahead, towards the right of the text.
        text = text.substring(idx + card.length());
    }
    
    return true;
}

Posted by 배트
,
// this code is just sample. not function form.
// just a reference!

const unsigned char pKey[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

const unsigned char pIn[] = {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf};
unsigned char pCipher[16] = {0,};
unsigned char pPlain[16] = {0,};

{
    /**
    * AES ECB Encryption
    *
    * @param pKey 128bit key
    * @param pIn 128bit plain input
    * @param pCipher (output) 128bit cipher output
    * @return true/false
    */
    AES_KEY stKey;
    memset(&stKey, 0, sizeof(AES_KEY));
    if(AES_set_encrypt_key(pKey, 128, &stKey)<0)
        return false;
    AES_ecb_encrypt(pIn, pCipher, &stKey, AES_ENCRYPT);
    //return true;
}

{
    /**
    * AES ECB Decryption
    *
    * @param pKey 128bit key
    * @param pCipher 128bit cipher input
    * @param pPlain (output) 128bit plain output
    * @return true/false
    */
    AES_KEY stKey;
    memset(&stKey, 0, sizeof(AES_KEY));
    if(AES_set_decrypt_key(pKey, 128, &stKey)<0)
        return false;
    AES_ecb_encrypt(pCipher, pPlain, &stKey, AES_DECRYPT);
    //return true;
}
Posted by 배트
,
public static void printCurrentStackTrace() {
    try {
        StackTraceElement[] cause = Thread.currentThread().getStackTrace();
        if(cause==null || cause.length==0)
            return;

        // 1st stack is skipped
        for( int i=0 ; i<cause.length ; i++ ) {
            if(i==1)
                continue;
            System.err.println(cause[i].toString());
        }
    } catch(SecurityException e) {
        e.printStackTrace();
        return;
    }
}

public static void printErrorAndStackTrace(String err) {
    System.err.println(err);
    
    try {
        StackTraceElement[] cause = Thread.currentThread().getStackTrace();
        if(cause==null || cause.length==0)
            return;

        // 1st stack is skipped
        for( int i=0 ; i<cause.length ; i++ ) {
            if(i==1)
                continue;
            System.err.println(cause[i].toString());
        }
    } catch(SecurityException e) {
        e.printStackTrace();
        return;
    }
}
Posted by 배트
,

Rules of JAVA Exception

by Junseok Oh

 

1.     간단한 기능을 하는 메소드는 굳이 예외를 발생시키지 않고, C와 유사하게 boolean 형 또는 에러코드를 의미하는 int 형을 반환한다. (하지만 에러코드를 정의하는 게 비효율적일 수 있다.)

2.     boolean/int 반환 메소드에서 Exception이 발생 시, error stack을 출력하고 해당 Exception에 해당하는 적절한 값을 리턴한다. (C 스타일)

3.     Exception은 메소드의 기능과 문맥에 맞는 다른 Exception으로 변환/추상화한다.
발생한 Exception에 해당하는 기능이 메소드에 암시되어 있다면, 그대로 bypass한다.

4.     제작하는 메소드가 다른 메소드의 기능을 얇게 추상화한다면, 모든 Exception bypass하게 throws Exception으로 정의할 수 있다.
boolean
을 반환할지, bypass 할 지는 메소드의 기능이 critical한지 trivial한지에 따라 달라진다. 발생할 수 있는 Exception의 종류를 기준으로 삼지 않는다.

5.     파일 입출력을 암시하는 메소드 안에서 발생하는 IOException bypass한다.
하지만 메소드의 문맥에 따라 IOException을 다른 Exception으로 변환한다.

6.     Exception을 던지는 경우, 되도록 Java에 정의되어 있는 표준 Exception을 사용한다.

7.     비록 귀찮더라도 너무 많은 코드를 try문으로 감싸는 것은 지양한다.
비록 귀찮더라도 구체적인 하위 Exception catch한다.

8.     되도록 Exception에 구체적인 에러 메시지를 포함시킨다.

9.     catch 블록에서 할 수 있는 작업은 복구/트레이스/ Exception 발생/종료뿐이다. 그냥 지나치는 것은 지양한다.
finally
블록에서 할 수 있는 작업은 try/catch 블록에서의 작업에 대한 공통 마무리이다. finally 블록에서 메소드를 종료하는 것은 지양한다.
(try/catch
블록에 return이 있다면, finally 블록 코드를 실행 후에 메소드를 종료하기 때문.)

10.   (임시) 부모/자식 예외를 모두 catch하는 블록이 연속되는 경우, 반드시 자식 예외에 해당하는 catch 블록이 앞에 위치해야 한다.


will be continuously updated...
Posted by 배트
,