분류

2019년 1월 26일 토요일

무지개는 어른이 되어서 보아도 신기합니다. ㅎㅎ;;

2018년 10월 1일 사무실 창밖에 무지개가 너무 예쁘게 자리 잡고 있었다. 



2018년 12월 30일 구름 낀 하늘에 보였던 무지개 


최근 들어 무지개가 자주 보이는 걸 보면 개인적으로 좋은 일이 있을까? 싶기도 하고 2019년에는 소망이 좀 이루어지나 싶기도 합니다 ㅎㅎ

2019년 1월 25일 금요일

log4j 로그 레벨에 의한 데이터 입출력 시간 실험

이 문서는 tomcat 서버 혹은 JEUS 서버에서 나타나는 대용량 파일에 대한 (3.78GB, 약2500만 로우의 데이터가 수록된) 데이터베이스 적재 작업에서 발생한 성능 저하 현상이 발생해 해당 작업에 로거가 미치는 영향을 정확한 결과로 기록하기 위해 수행하였습니다.

1. log4j 간략정보

아파치의 오픈소스 도구라고 합니다. JAVA기반이기에 웹/와스 기반의 시스템에서 많이 사용합니다. C와 PYTHON등 다양한 언어를 지원한다고 합니다.  프레임워크에 라이브러리로 참조 되는 경우가 많고 환경설정은 대체로 log4j.xml 혹은 log4j2.xml 파일을 통해 로거레벨을 설정하고 있습니다. 로깅 수준에 따라 등록된 다양한 로그들을 유형별로 보여주거나, 숨길 수 있습니다.

로거 레벨에 대한 정보는 아래와 같습니다.
인용 : https://www.tutorialspoint.com/log4j/ 

LevelDescription
ALL사용자 정의를 포함한 모든 레벨 
DEBUG응용 프로그램 수정에 필요한 세부 정보를 지정 
INFO응용 프로그램 진행에 해당하는 정보를 굵은 글씨로 강조하여 지정
WARN잠재적 유해 사항을 지정
ERROR응용 프로그램 진행에는 영향이 없으나, 악영향을 줄 수 있는 오류를 지정
FATAL프로그램 중단이 예상되는 치명적인 오류를 지정 
OFF로그를 해제 
TRACE디버그 보다 상세한 이벤트 정보를 지정

2. 로거 성능 테스트 환경

사용 pc환경 :
프로세서 : Intel(R) Core(TM) i5-3230M@2.60Ghz
설치된 메모리: 8.0GB ddr3
os : windows 7 64bit

대상파일 :
출처 : http://data.imf.org   > Download Imf Data > InterNational Financial Statistics (IFS)
용량 : 3.78GB
행수 : 25,691,217

데이터 추출용 프로그램은 자작으로  4개의 멀티 스레드를 사용하며 jdbc의 array parsing 을 이용한 인서트 작업을 수행합니다. 전체 데이터를 넣는데 1시간이 걸리므로 약 400건씩 데이터를 쪼개 넣는 작업을 1000회 수행 후 종료하도록 한 후 소요시간을 체크해보았습니다.

3. LEVEL에 따른 성능 측정 


Level총 수행정보
ALL224초  입력 - 총 : 312843, 분당 : 83797, 초당: 1396
DEBUG222초  입력 - 총 : 312843, 분당 : 84552, 초당: 1409 
INFO101초  입력 - 총 : 312843, 분당 :185847, 초당: 3097
WARN101초  입력 - 총 : 312843, 분당 : 185847, 초당: 3097 
ERROR97초  입력 - 총 : 312843, 분당 : 191536, 초당 : 3192
FATAL100초  입력 - 총 : 312843, 분당 : 187705, 초당 : 3128
OFF104초  입력 - 총 : 312843, 분당 : 180486, 초당 3008 
TRACE226초  입력 - 총 : 312843, 분당 : 83055, 초당 1384
각각 1회씩 수행한 결과입니다. off만 예측과 너무 다른 결과가 나와서 3회 수행하였습니다. 하지만 3회 모두 유사한 결과가 도출되었습니다.

처리속도에 연관되는 debugger level 별 성능 순위는 아래와 같습니다.
성능은 초당 입력 건수를 기준으로 상승률을 %로 뽑아봤습니다.

1위 ERROR                    :  5위 대비 130% 성능 상승
2위 FATAL                     :  5위 대비 126% 성능 상승
3위 OFF                        :  5위 대비 123% 성능 상승
4위 INFO, WARN             :  5위 대비    7% 성능 상승
5위 ALL, DEBUG, TRACE   

운영 시스템의 성능 최적화를 위한 로거 레벨은 ERROR, FATAL을 사용하는 것이 나은 것 같습니다. OFF의 성능이 생각보다 낮은 이유는... 언젠가 알고 싶네요 ㅎㅎ;

4. 기타 

최근 사무실에서 사람들이 SQL오류를 확인하기 위해서 core.log.jdbc.driver.OracleDriver 라는 드라이버 클래스를 사용하기 시작했습니다. 줄 바꿈과 파라미터 인풋을 지원하는 드라이버 클래스인데 개발자 중 일부가 이것을 운영 서버에 적용하면서 어마어마한 일이 일어났었습니다. 파일 적재 시스템 마비가 왔었죠.... 약 3천만 건 처리 예상 시간이 21일 16시간이었습니다. ;

일상적으로 사용하는 oracle 용 jdbc드라이버 클래스는 oracle.jdbc.driver.OracleDriver인데 상위 드라이버를 사용할 시 로거 레벨과 관계없이 속도가 저하됩니다. CPU와 메모리의 사용율도 100%가 유지되며, 시스템의 각 기능이 정상동작하지 않게 됩니다.

core.log.jdbc.driver.OracleDriver의 성능

경과시간 1950초 총 입력 건수 23108건, 분당입력 710, 초당입력 11건

1000번은커녕 77회 수행 후 종료해야 했습니다. 저도 일은 해야 하니까요 ㅎㅎ;;;

1위 대비 29018% 성능 저하

이 정도면 사람 하나 죽어나갈 속도입니다. 부디 운영 중인 시스템에 이런 로그 클래스를 사용하는 일이 없으시길 바랍니다.

이상 log4j에 대한 간결한 시험기였습니다. 읽어주셔서 감사합니다. 행복하세요 ㅎㅎ


2019년 1월 18일 금요일

Iframe 을 이용한 cross - domain 메시지 교환

하나의 세션에 대한 인증 결과와 경과 시간에 대한 주기적인 체크를 할 수 있는 방법이 필요했습니다.

여러 다른 url을 가진 사이트간의 통신은 cross-domain 보안 정책에 의해 기본적으로 차단되어 있는 상황에서 보안정책을 변경하는 것 보단 간단한 메시지를 전달하는 정도의 방식으로 프로그래밍을 하는 것이 수월하기에 iframe을 이용해 서로 다른 도메인간의 통신을 유도하는 방법을 찾아보았습니다.

일단 메시지를 보내는 주 사이트와, 메시지를 받는 사이트 측으로 분리해서 아래와 같은 스크립트를 만들어보았습니다.

크로스 도메인을 위한 스크립트 구성 

부모페이지에 추가된 script (메시지를 받는 쪽)
//iframe를 첨부할 jsp 내에 아래와 같은 스크립트와 iframe을 추가합니다. 

<script type="text/javascript">
//iframe에서 전송하는 메시지를 받을 리스너를 생성 
//(iframe과 동일한 페이지 현재 스크립트가 있어야함)
function receiveMessage(event){
//리스너 이벤트 전송자와, 명령어가 동일할 경우 수행 
if(event.data === "testMessage" && event.origin === "http://testsite"){ 
//event.data는 리스너를 통해 전달받는 데이터입니다. 
// ===은 데이터 타입과 데이터 내용이 모두 일치하는지 비교하는 연산자 
//event.origin은 지정된 주소를 입력하여 지정된 도메인에서 발신한 것인지 확인합니다.
alert("메시지 전달 받았습니다.");//메시지 수신 후 실행할 스크립트를 입력합니다.
}
}
//현재창에 메시지 이벤트 리스너를 추가 
window.addEventListener("message", receiveMessage); 
</script>
//현재창에 메시지 이벤트 리스너를 추가 
<iframe id="test" name="test" src="http://testsite/innerFrame.jsp"></iframe>

메시지를 주는 쪽인 http://testsite/의 innerFrame.jsp
<script type="text/javascript">
var parent = window.parent; 
if(parent && parent.postMessage){
        //postMessage("전송메시지","전송 도메인") 
parent.postMessage("testMessage",  "*");
}else{
console.log("post Message is not allow"); 
}
</script>

위와 같은 비교적 단순한 구성을 통해 서로 다른 도메인 간의 메시지를 주고받을 수 있습니다.

postMessage 함수는 메시지와 함께 전송할 대상 도메인을 특정할 수 있습니다. 이유는 불필요한 도메인에서 해당 소스를 붙여 메시지를 가로채거나 하는 문제를 방지하기 위해서 입니다.

이 스크립트는 iframe내부 문서와 부모창의 구성을 바꿔서 사용할 수도 있습니다.

postMessage구성 

postMessage(메시지, 대상도메인)

메시지 : 다른 창으로 보낼 데이터를 담는 부분입니다. (구조화된 복제 알고리즘을 통해 정해진 양식으로 변형되어 전송된다고 합니다. )

대상도메인 : "*"을 입력한경우 대상을 특정하지 않고 아무에게나 보내는 것입니다. 공개된 메시지가 되는 것이므로, 중요한 데이터를 보내면 위험할 수 있습니다. 아무나 iframe을 사용하여 메시지를 확인할 수 있으니까요.
사용 예) document.postMessage("메시지", "http://test.kr") 의 형태로 메시지를 보낼경우 http://test.kr이 아닌 도메인에선 해당 메시지를 확인할 수 없습니다. 

SANDBOX 


HTML5에서는 SANDBOX라는 속성이 생겼습니다. 이것을 이용해 크로스도메인 정책을 우회할 수 있다는 인터넷의 일부 문서를 확인했습니다만. 적용결과 실패하였습니다. 안됩니다.

샌드박스 속성과 값 

1. (값없음)                   모든 제한 사항 적용
2. allow-forms               폼 전송을 사용할 수 있습니다.(form.submit())
3. allow-pointer-lock       api를 사용할 수 있습니다.
4. allow-popups             팝업을 사용할 수 있습니다.
5. allow-same-origin        iframe내부의 콘텐츠가 같은 도메인으로 취급됩니다.
6. allow-scripts               스크립트를 사용할 수 있습니다.
7. allow-top-navigation     iframe 내부 콘텐츠가 top.document의 location을 제어할 수 있습니다.

위와 같은 태그 속성이 있고 iframe을 선언할 때 사용하는 코드입니다. 사용방법은 아래와 같습니다.
1. (값없음)  <iframe sandbox src=""> </iframe>
2. allow-forms   <iframe sandbox="allow-forms" src=""> </iframe>
3. 복합 <iframe sandbox="allow-forms allow-top-navigation" src="">  </iframe>

단일 속성을 사용할 수도 있고, 복합 속성을 사용할 수도 있습니다. allow-same-origin  의 경우 서로 다른 도메인일 경우에도 같은 출처로 취급할 수 있다고 설명되어있지만, 실제 사용결과는 다음 오류가 발생합니다.

예) iframe 내에서 top.window.document.reload()를 수행한경우 오류
Uncaught DOMException: Blocked a frame with origin "" from accessing a cross-origin frame.

도메인이 다르기 때문에 발생하는 오류입니다. 이것이 postMessage를 사용하게 된 이유이기도 합니다. 같은 도매인 내에서의 iframe호출은 성공적이었지만, 서로 다른 도메인에 적용한 결과 위와 같은 오류가 발생하여 사용할 수 없습니다.

w3schools에서는 모든 브라우저에서 적용된다고 되어있지만, 실제로 되지 않고 있습니다. 이유를 아시는 분이 계신다면 댓글을 달아주시면 감사하겠습니다.


인터넷 익스플로러 오류 해결 SCRIPT5009: 'JSON'이(가) 정의되지 않았습니다.

최근 여러 사이트에 대한 연동 시스템을 구축하면서 다양한 개발 환경 문제에 직면하게 되었습니다. 그중 ifame을 통한 부모와 자식 창간의 데이터 통신을 하는 과정에서 특정 사이트만 되지 않는 오류를 확인하였는데 이유는 javascript를 해석하는 엔진 버전의 문제인 것 같습니다.


인터넷 익스플로러 오류 SCRIPT5009: 'JSON'이(가) 정의되지 않았습니다.
웹 호환성을 위해 모든 브라우저에서 테스트 하지만 특정사이트만 Internet Explorer에서 지원되지 않는 현상이 있었습니다. 확인하려고 로그를 열어보니 저 빨간색 동그라미 2개가 신경이 쓰입니다. 문서모드7 ? 그리고 우측에 7?

정체는 바로 Internet Explorer 7 버전의 문서모드를 사용하겠다는 선언이  jsp문서에 있었습니다.

<meta http-equiv="X-UA-Compatible" content="IE=7" />

메타 테그로 설정되어있는 이 모드는 일부 html5 기능과 javascript의 동작을 방해하게 됩니다. 최근 트랜드인 웹표준에도 당연히 저해되는 코드입니다. 비슷한 유형의 오류가 발생하고 있다면 해당 태그를 삭제하시면 해결 됩니다.

JSON 데이터 타입은 HTML5에서부터 표준으로 제공되고 있습니다. 웹표준으로 지정되기 이전에는 JSON.ORG를 통해 JSON.JS 라이브러리를 다운받거나, 웹 문서에 링크해 사용했었습니다. https://www.json.org/json-ko.html

html5 라는 웹 표준이 생기면서 여러 라이브러리들이 통합적으로 브라우저에서 지원되는 환경으로 바뀌면서 생기는 오류로, ie도 8버전에서부턴 기본 스크립트로 지원하지만, 하필 7 이하에선 지원하지 않아 생기는 오류입니다.