Jasper를 사용하기 위해 라이브러리를 등록하고 서버를 구동했더니 다음과 같은 에러가 뜬다.
 

com.jaspersoft.jasperserver.api.JSExceptionWrapper: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'splitType' is not allowed to appear in element 'band'

이 에러는 보통 jrxml이 작성된 iReport와 서버 라이브러리의 버젼 호환이 되지 않은 경우 나오는 에러라고 한다. 주로
서버쪽 jasperreports.jar가 3.5.x 이하의 버젼이 설치된 경우 발생한다.

내 경우 iReport는 최신버젼(3.7.3) 을 사용했는데 서버에 올라가 있던 jasperreports.jar 파일의 버젼은 3.5.3 의 것이었기에 서버의 jasperreports.jar 의 버젼을 3.7.3으로 업데이트 해주었더니 해결..


 
간만에 웹관련 프로젝트를 하게 되서 WTP+m2Eclipse+SVN 을 이용한 개발환경을 구축하고 한창 개발을 하던중..

Could not initialize class org.eclipse.wst.server.ui.internal.provisional.UIDecoratorManager" 라는 에러로그와 함께
이클립스를 통한 서버구동이 정상적으로 구동되지 않고 에러로그창으로만 튕기는 현상이 일어났다.

지난 번에도 동일한 증상이 있어 프로젝트를 다시 디플로이한 다음 이클립스를 재구동해 다시 정상적으로 사용할 수 있었는데
이번엔 해결되지 않아 또다시 구글링..

https://bugs.eclipse.org/bugs/show_bug.cgi?id=279479

m2Eclipse, SpringIDE, Subclipse, google plugin 등을 사용하는 경우에 위와 같은 버그가 있는 듯 싶다
버그레포트는 이클립스 3.1이지만 갈리레오 등 이후 버젼의 이클립스에서도 종종 보고된 듯 하다.

지금은 패치된 상태라 이클립스의 Check for update를 통해 업데이트를 받으면 해결된다고 하니
간만에 업데이트한번 해주시고...

그래도 안되는 분들이라면 이클립스 시작시 -clean 옵션을 주고 이클립스를 재시작하면 된다.
-clean 옵션은 이클립스 플러그인 설정을 초기화하는 것이라는데
이렇게 하면 정상적으로 이클립스를 통한 서버를 실행시킬수 있을 것 같다.

안빼줘도 상관은 없지만 초기구동이 엄청 느려지니...다음 구동시에는 -clean 옵션을 빼주자.
 

maven 기반의 프로젝트는 dependency한 라이브러리 관리나 테스팅하기에는 정말 좋은 것 같습니다.하지만 m2Eclipse 버그때문인지는 잘 모르겠지만 pom.xml은 직접 타이핑하는 것이 속편할 듯.

이번에 포스팅하는 org.apache.struts2.dispatcher.FilterDispatcher cannot be cast to javax.servlet.Filter 라는 메시지는 내가 m2Eclipse를 가지고 WTP 프로젝트를 설정할 때마다 만났던 오류이기도 한데. 이전에 진행했던 프로젝트 pom.xml을 가져와서 할 때도 간혹 생기는터라 개발환경에 따라 다양한 원인이 있는 것 같습니다.

그렇다고 운에맡길 수도 없는 노릇. 일단 이 오류가 발생하는 일반적인 이유는 pom.xml에 정의된  servlet-api 가 maven을 통해 배포시 포함되어 생기는 tomcat의 servlet-api 충돌문제라서 pom.xml에 정의되어 있는 servlet-api부분을 다음과 같이 수정하면 됩니다.

 <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <scope>test</scope>
 </dependency>

즉 scope 속성이 빠져 있거나 provided 로 되어 있는 경우에 주로 발생하게 되는 오류라 할 수 있습니다. 그런데 전자의 경우는 그럭저럭 이해가 가지만 후자의 경우인 provided은 컴파일시에는 참조를 하되 배포시에는 제외하도록 하는 것이라 결과적으로는 같은 것 같은데도 위와 동일한 에러를 발생시키는 것을 보면 잘 이해가 가지 않는 부분이기도 합니다. 의미상으로야 차이는 있겠지만....-_-a

물론 scope가 빠져있거나 provided로 되어 있어도 정상적으로 동작하는 경우가 있습니다.(운이 좋다면...) 머 이 경우에는 그냥 쓰시면 될 것 같고 앞으로는 속편하게 scope를 test 로 포함하면 될 일이다.
 

Redmine 백업하기 - MySQL 백업.

개발 이야기/Java | 2010. 3. 5. 19:19
Posted by 시반

Redmine 백업하기 – MySQL 백업.

 

지난시간에는 cwRsync를 이용한 Redmine 파일 시스템 백업에 대하여 살펴보았다면 이번에는 DB백업에 대한 부분을 언급할까 한다.

Redmine을 서비스하기 위해 사용되는 DB PostgreSQL,MySQL,SQLite 세가지지만. 우리 팀에서야 MySQL을 사용하고 있으니MySQL을 중심으로 설명을 진행하도록 하겠습니다.

 

 

위 그림에서도 나와 있지만 대부분의 프로젝트들이 CharacterSet 으로  UTF-8을 사용하고 있지만 Redmine의 경우 기본 설치시

기본 인코딩 타입은 Latin1입니다. 그렇다고 Redmine에서 한글 저장이 안되는 것은 아니지만 DB이전등을 하려고 하는 경우

UTF-8 문자열들이 깨지는 경우가 있다고 하니 처음 설치할 때 utf8로 설정하는 것이 좋을 듯 싶습니다.

 

앞서 말한대로 이전작업을 위한 백업 및 복구 절차를 위한 것이기 때문에 이전시에 인코딩타입도 utf8로 한번 바꿔보았습니다.

 

1. 기존 데이터의 백업

mysqldump를 이용하여 기존 데이터를  old_db.sql이라는 이름으로 백업합니다.

 

c:\redmine\mysql>mysqldump –uroot –p –default-character-set=latin1 bitnami_redmine > old_db.sql

Enter password: ********

 

old_db.sql 파일을 열어 latin1 utf8로 일괄변환한 다음 new_db.sql 로 저장합니다.

 

2. 데이터베이스 생성

이전  서버에 mysql을 설치하고 bitnami_redmine이라는 이름으로 데이타베이스를 생성합니다.

 

c:\redmine\mysql>mysql –uroot –p

Enter password: ******** ~중략~

mysql> drop database bitnami_redmine;

mysql> create database bitnami_redmine COLLATE utf8_general_ci;

 

3. 데이터 복구 

새로만든 bitnami_redmine에 앞서 백업 받은 데이타파일을 기본 charactoer-set을 utf8로 해서 복구합니다.

 

c:\redmine\mysql>mysql –ubitnami –p –default-character-set=utf8 bitnami_redmine < new_db.sql

Enter password: ********

 

 

4. Redmine DB접속정보 변경 

MySQL 설치폴더에서  my.ini 파일을 열어 다음과 같이 수정합니다.

 

[client]
default-character-set=utf8

 

[mysqld]
init_connect=SET collation_connection = utf8_general_ci
init_connect=SET NAMES utf8
default-character-set=utf8
character-set-server=utf8
collation-server=utf8_general_ci

 

[mysql]
default-character-set=utf8

 

show variables like 'c%'; 로 확인해보면  대부분의 characterSet들이 utf8로 변경되어 있슴을 확인할 수 있습니다.

 

 

5. Apache 재시작

http://서버주소/redmine redmine이 정상적으로 보여지는지 확인하면 됩니다.

이 때 redmine은 정상적으로 뜨지만 메뉴 등의 글자가 ???? 등으로 표시된다면 redmine 이하 lang 디렉토리에서 ko.yml 파일을 열어 utf8 형식으로 저장합니다.

아니면  get/redmine 등이 표시되면서 redmine 페이지 자체가 열리지 않는 경우 redmine 이하 config 디렉토리의  database.yml  파일의 production 항목에 encoding:utf8을 추가해 줍니다.

간혹 반대로 database.yml encoding:utf8 이 있는 경우에도 동일 증상이 발생할 수 있습니다.

이 경우에는 오히려 이 구문을 삭제한 후 아파치를 재시작하면 정상적으로 로드되는 것을 확인할 수 있습니다.

 

마치며...

Redmine DB이전작업은 별 내용 없이 MySQL 백업 및 복구에 대한 부분만 처리했습니다. 앞서 말한바와 같이 DB이전 부분은 cwRsyn 이용한 백업 및 복구는 해보지 못했지만 차후 한번 시도해 봐야 할 부분이고 한가지 아쉬웠던 점은 Redmiine버젼의 최신버젼이  0.9X버젼인데 비해 현재 연구소 설치버젼은 0.8X 버젼이라 이번 기회에 업그레이드를 하려했지만  DB 마이그레이션 부분이 가이드만큼 쉽게 진행되지는 않아 동일버젼으로만 이전작업을 마치게 되었다는 점이다.

시간을 내서라도 다시 한번 시도해봐야 할듯 싶다. 일단은 여기서 마무리..

 

 

 

 

 

Redmine 백업하기 – rsync를 이용한 원격백업.

 

얼마전 팀에서 운영하던 이슈추적시스템 중 하나인 Redmine을 다른 서버로 이전하게 되었다.

사실 이전작업이라고 해봤자 첨부파일을 복사하고 백업했던 DB를 복구하기만 하면 되는 것이긴 했지만...

리눅스서버라면 대상소스를 압축하고 ftp로 파일을 옮기고 복구하는 작업을 rsnc를 이용하면 아주 간단하게 처리될 수 있지만

팀내 서버로 윈도우즈 서버를 사용하는 터라 처음엔 그냥 압축한 다음 ftp로 이용하려고 생각했었는데

cwRsyn이라는 윈도우즈용 rsyn도 있다기에 이를 한번 사용해보기로 했다(맥용도 있다는데...쓸일이 없다... -_-).

 

먼저  cwRsyn을 다운로드 받아 설치해보자. 다운로드는 http://sourceforge.net/projects/sereds/files/  에서 받으면 된다.

현재 4.0.3 버젼이 최신버젼이네요...

 

1. cwRsynServer설치하기

 

백업소스가 있는 곳에 cwRsynServer를 설치해야 합니다. 여기서는 윈도우즈용 Redmine이 있던 서버에 설치하는 것으로 진행해보겠습니다.

 

설치시 언제나 나타나는 라이선스 동의.....I Agree 를 클릭..

 

다음엔 설치폴더를 지정합니다. 기본값이 cwRsyn 정도가 되지 않을까 싶었는데 ICW가 기본값이네요...

 

서비스 계정을 등록하는 부분입니다. 리눅스용과는 달리 cwRsynServer는 하나의 서비스 계정만을 제공하는 듯 합니다.

리눅스용처럼 auth_users 등을 설정하여 인증요청시 사용되는 것 같습니다.

기본값으로 계정은 SvcCWRYNC, 패스워드는 7ElpiAHCxi2780 이 지정되지만 

기본값대신 SyncService라는 계정으로 만들어 보았습니다.

 

이제 Install 버튼을 클릭하여 설치를 진행합니다. 끝나면 Close버튼을 클릭하여 설치를 종료합니다.

 

2. 백업소스 설정하기

 

설치가 끝났다면 설정파일(C:\Program Files\ICW\rsynd.conf)을 열어 백업 소스정보를 추가합니다.

 

[redmine_files]

path = /cygdrive/C/redmine/apps/redmine/files

read only = false

transfer logging = yes

  • [redmine_files] : [ ] 안의 이름으로 클라이언트에서 접근합니다. 한마디로 서비스명?
  • path :  실제 백업소스 경로를 지정합니다. 명명규칙에 따르면 c:\work의 경우 /cygdrive/c/work 로 표시합니다.
  • read only = false : 클라이언트에서 업로드를 허용한다는 의미입니다. false로 설정하는 경우 업로드를 위해 Prepare a Directory for Uploading ( 설치폴더/Bin/PreUploadDir.exe )를 설치해야 겠지만 이번엔 이전 작업을 위한 다운로드만을 할 뿐이라 패스...

3. 서비스 구동

 

rsynServer 는 설치를 하게 되면 자동으로 서비스로 등록은 되지만 시작유형이 수동으로 설정되어 있기 때문에 서비스에서 직접 시작을 해주어야 합니다. 주기적으로 백업을 수행하도록 설정한다면야 속성값에서 자동으로 변경해도 상관없을 듯...

 

4. 클라이언트 설치하기

 

이제 백업하고자 하는 곳에 클라이언트를 설치합니다.

여기서는 원격백업을 위해 다른 서버에 설치를 진행하지만 하나의 서버에 설치할 수도 있습니다. (로컬 백업...)

 

마찬가지로 라이선스에 동의....

 

설치할 컴포넌트를 선택합니다. 선택사양이라 해봤자 Secure Channel Wrapper 뿐이네요.

 SSH를 지원하기 위한 컴포넌트인 듯 보입니다.

 

클라이언트 설치폴더가 cwRsync 였네요. Install 버튼을 클릭한 다음  설치를 종료합니다.

 

5. 클라이언트에서 백업 설정하기

 

설치디렉토리의 cwrsync.cmd 라는 파일을 메모장등으로 열어 다음과 같은 형식으로 백업 정보를 저장합니다.

rsync [옵션] [백업소스주소::백업서비스명] [클라이언트 백업 경로]

예) rsync.exe -avzr 127.0.0.1::redmine_files /cygdrive/c/redmine/apps/redmine/files

     --> 백업소스의 모든 파일(하위 디렉토리 포함)을 압축전송을 하여 c:\redmine\apps\redmine\files 디렉토리에 백업하라

저장 후 cwrsync.cmd를 실행하면 다음과 같이 백업소스를 백업하는 것을 확인할 수 있습니다.

 

참고로 옵션은 다음과 같습니다.

 

옵션

설명

-a

아카이브 모드, 심볼릭링크, 속성,퍼미션,소유권  보존

-v

상세보기

-z

전송시 압축

-r

하위 디렉토리 포함

-l

심볼릭 링크 재생성

-p

퍼미션 업데이트

-t

변경시간 보존, 없는 경우 전송시간으로 변경

-g

그룹속성 보존

-u

추가된 파일만 전송

-b

낡은 파일일 경우 ~을 붙임

-- delete

원본서버에 없는 파일은 클라이언트에서도 삭제

--existing

추가된 파일은 제외하고 갱신된 파일만 전송

--exclude ‘PATTERN’

패턴과 맞는 패일을 제외하고 전송

--stats

결과 보고

 

마치며...

 

 http://www.rsync.net 의 튜토리얼을 살펴보면 윈도우즈용 백업 에이전트를 사용하여 파일 시스템 뿐만 아니라  SVN, Git 등의 repository에서부터 MySQL, Postgress 등의 DB백업까지 스케쥴러에 따라 다양한 백업을 하는 방법들을 소개하고 있습니다.  

사실 윈도우즈 서버에서 rsync를 이전작업을 위해 사용해 본것이라 이러한 기능들을 시도해보지는 못하고 첨부파일디렉토리만을 대상으로 해보았지만 차후 백업정책에 따라  충분히 시도해 보아도 될 것 같다는 생각도 드네요.

내용은 별로 없지만 Redmine의 DB (MySQL) 백업 부분은 다음 블로그에 올려야 될거 같습니다.

 

 

 

[MINA] Logging Configuration

개발 이야기/MINA | 2009. 11. 30. 10:27
Posted by 시반

팀내에서 MINA를 사용하면서 "선배 log4j가 있는데 계속 logging 쪽에서 에러가 떠요" 라는 질문을 받은 적이 있습니다. 지난 포스팅에서도 설명한적이 있지만 MINA 샘플들은 log4j 가 아닌 slf4j를 사용하고 있습니다. 사용법은 동일하지만 log4j보다 유연한 로깅메시지 처리를 할 수 있기 때문에 slf4j 라이브러리를 사용하였다고 하네요. 따라서 slf4j 라이브러리를 추가해야 정상적으로 샘플들을 구동할 수 있습니다.


Logging Configuration


이번 장에서는 MINA가 구현하고 있는 로깅처리부분을 살펴보도록 하겠습니다.

slf4j는 관련페이지를 참조하시길..

목차


  • 목차
  • 배경
  • SLF4J
    •  올바른 JARs 파일 선택하기
    • Jakarta Commons Logging 상속
  • log4j 예제

배경

 

Logging Confuguration  로깅환경설정에 있어서 기존의 log4j 의 환경을 그대로 사용할 수 있습니다.

SLF4J


배경에서 간단하게 언급은 했는데요 MINA가 slf4j 를 사용한다고 해서 특별한 로깅관련 설정이 필요한 것은 아니라는 점입니다. (SLF4J에 대한 정보는 이곳 에서 확인할 수 있습니다).

솔직히 특별한 로깅관련 설정이 필요없다기 보다 기존의 설정을 그대로 사용한다고 할까요. 대부분 log4j 또는 java.util.logging 또는 다른 logging관련 유틸리티를 사용하고 있을 테지만 slf4j은 그것들을 위한 간단한 facade 혹은 추상계층으로써 제공되기 때문입니다.
다시 말해서, slf4j는 엔드 유저가 희망하는 로깅 프레임워크를 배포시간에 플러그인할 수 있도록 허용하는 구조를 가지게 되기 때문에 개발중에 java.util.logging 에서 log4j로 변경해도 기존 소스의 변경이 없게 됩니다.

올바른JARs 파일 선택하기

SLF4J 은 정적 바인딩을 사용하고 있습니다. 이 말은 각 로깅 프레임워크에서 지원하는 단 하나의 JAR파일만이 있어야 한다는 것으로 사용하고 있는 버젼에 맞는 라이브러리만 추가하여야 합니다. 아래는 사용하고 있는 로깅 프레임워크에 따라 필요한 slf4j 파일들입니다.

Logging Framework
Requried JARs
Log4J 1.2.x
 slf4j-api.jar, slf4j-log4j12.jar
 Log4J 1.3.x
 slf4j-api.jar, slf4j-log4j13.jar
 java.util.logging   slf4j-api.jar, slf4j-jdk14.jar
 commons Logging
  slf4j-api.jar, slf4j-jcl.jar


주의사항 :

  • 보통 slf4j-api.jar 이 다른 JARs 내에서 이미 구현되어 사용되어 질 수도 있습니다
  • 중요한 건 당신이 당신의 클래스패스안에 하나 이상의 JAR 파일을 넣지 않는 것입니다 
    (예를 들면. slf4j-log4j12.jar slf4j-jdk14.jar 를 함께 넣지 마세요 그것은 예기치 못한 문제가 발생될지도 모릅니다
  • slf4j-api.jar slf4j-<impl>.jar 의 버전은 동일해야 합니다.

제대로 구성된 환경설정은 사용되는 로깅시스템이 유지하는 한 계속 사용할 수 있습니다(e.g. 수정된 log4j.properties).

 Jakarta Commons Logging 상속하기

SLF4J 은 또한 이미 Jakarta Commons Logging 을 사용하는 어플리케이션의 소스 변경없이 SLF4J 를 사용하도록 변환 할수 있는 방법을 제공합니다. 단지 클래스패스에서commons-loggong JAR 파일을 지우고 jcl104-over-slf4j.jar 를 추가하기만 하면 됩니다.


log4j 예제


이 예제는 log4j로 로깅 시스템을 구성하고 있습니다. 우리는 log4j.properties 를 열어 아래의 내용을 붙여 넣어 보겠습니다.


 # Set root logger level to DEBUG and its only appender to A1.
 log4j.rootLogger=DEBUG, A1

 # A1 is set to be a ConsoleAppender.
 log4j.appender.A1=org.apache.log4j.ConsoleAppender

 # A1 uses PatternLayout.
 log4j.appender.A1.layout=org.apache.log4j.PatternLayout
 log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c{1} %x - %m%n


이 파일은 프로젝트의 소스폴더에 있습니다. 만약 당신이 IDE를 사용하고 있다면 기본설정은 당신의 코드를 테스트하고자 할 때의 JVM상의 클래스패스안의 설정값으로 사용됩니다.

샘플예제는 지난 포스팅 예제인 MinaTimeServer 에 있는 예제를 가지고 설명합니다.:


 public
static void main(String[] args) throws Exception {
        IoAcceptor acceptor =
new SocketAcceptor();
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();


        LoggingFilter loggingFilter =
new LoggingFilter();
       
chain.addLast(
"logging", loggingFilter);                      
 

       
acceptor.setLocalAddress(
new InetSocketAddress(PORT));
       
acceptor.setHandler(
new EchoProtocolHandler());
       
acceptor.bind();

       
System.out.println("Listening on port " + PORT);
 }


위 예제에서는 IoAcceptor를 가지고 로깅하는 방법을 설명하고 있습니다. 어딘고 하니 acceptor에  LoggingFilter를 추가하는 부분이네요. 이 부분이 MINA가 slf4j를 구현한 부분으로 log4j를 사용하던지 commons-logging을 사용하던지 코드엔 변경이 없게 됩니다.

위에서는 간단한 로깅하는방법만을 예로 들었지만 좀더 요구사항에 따라 다양한 로깅정보를 생성할 수 있습니다.

LoggingFilter 레퍼런스에 따르면 IoAccepter 에 연결된 핸들러에 이벤트별로 로깅수준을 설정할 수 있습니다.
LoggingFilter에  setLogLevel(IoEventType,LogLevel) 이라는 메소드를 제공하고 있는데요.
IoHandler 이벤트 로깅을 추적하고 로깅수준에 따라 로그를 남길수 있습니다.

이 메소드의 옵션들은 다음과 같습니다:

IOEventType
Description
 SESSION_CREATED    새로운 세션을 생성할 때 호출된다
 SESSION_OPENED    새로운 세션이 열린 경우 호출된다
 SESSION_CLOSED    세션이 닫힌 경우 호출된다
 MESSAGE_RECEIVED    데이터를 받았을 때 호출된다
 MESSAGE_SENT    메시지를 전송할 때 호출된다
 SESSION_IDLE    세션 유휴타임에 도달한 때 호출된다
 EXCEPTION_CAUGHT    예외를 발생한 경우 호출된다

다음은 로깅 수준에 대한 설명입니다:

Log Level
Description
 NONE    설정과는 상관없이 로그를 남기지 않는다
 TRACE    로깅시스템에 추적 이벤트를 생성한다
DEBUG    로깅시스템에  debug 메시지를 남긴다.
INFO    로깅시스템에  info 메시지를 남긴다.
 WARN
   로깅시스템에  warning 메시지를 남긴다.
 ERROR    로깅시스템에  error 메시지를 남긴다.

'개발 이야기 > MINA' 카테고리의 다른 글

MINA에서 버퍼 제어하기 - IoBuffer  (0) 2009.06.01
MINA 기반의 어플리케이션 구조  (0) 2009.05.28
MINA 2.0 에코서버 만들기  (0) 2009.05.21
 

Eclipse PlugIn – Properties Editor

 

자바프로그램에서는 propeties 라는 파일을 이용하여 설정이나 다국어 처리를 위해 사용하고 있습니다.

한가지 주의할 점은 다국어처리등을 위해 인코딩타입을 UTF-8 로 저장한 경우 이클립스의 기본 에디터인 Properties File Editor로 한글을 써 놓으면 깨져서 사용할 수 없습니다.

그래서 이 경우에는 한글을 유니코드로 변환시켜 저장해야 하는데 native2ascii.exe  프로그램을 쓰고는 했었습니다

 

Properties File Editor

앞서 말한바와 같이 유니코드로 저장한 경우에는 한글을 알아볼 수 없습니다. -_-a

PropetiesEditor

 

이클립스에서 Properties 파일 편집을 하기 위해  PropEdit 또는 PropertiesEditor 라 불리는 플러그인이 있습니다. 설치방법은 Help > New Install Software... 선택후 Add..을 클릭하여 다음 주소를 추가합니다.

 

http://propedit.sourceforge.jp/eclipse/updates/

 

 

PropertiesEditor 항목을 체크하고 설치를 진행합니다.

PropetiesEditor 로 편집하기

 

파일을 열 때 Open With > PropertiesEditor를 선택하면 Properties File Editor 대신 PropertiesEditor를 이용하여 Properties 파일을 편집할 수 있습니다.

아니면. 다음과 같이 PeropertiesEditor  기본값으로 설정하여 사용할 수도 있습니다.

 

 

 

이제 파일을 열어보면 두 Editor를 비교해보겠습니다


 

위에 것은 기존의 Properties File Editor 로 연것이고 아래것은 ProperitesEditor로 연 화면입니다.

같은 파일인데도 편집기에 따라 다르게 보인다는 것을 알수 있습니다

PropertiesEditor의 장점은 편집은 가독성있는 문자코드로 작성하고 저장시에만 유니코드로 자동변환되어 저장된다는 점입니다.

 

 

[VoIP 개요] G.729 음성코덱

개발 이야기/VoIP | 2009. 9. 18. 19:26
Posted by 시반

저번에 말씀 드린 바와 같이 오늘은 G.729 코덱에 대해 좀더 알아 보도록 하겠습니다.

G.729 코덱에 대해 별도로 지면을 할애 하는 것은 그만큼 코덱이 중요하다는 의미 이지.

 

G.729 코덱은 두가지 Annex 있습니다.Annex A B 있습니다.

무슨말 이냐면 G.729 코덱의 성능의 향상을 위하여 약간의 변화를 두가지 변형이 있다고 보시면 됩니다.

 

이중에 G.729a 코덱이 대부분의 VoIP 벤더들의 기본 코덱으로 사용되고 있습니다. 시스코도 마찬가지 입니다.

더불어 시스코의 IP 폰에서 지원되는 코덱도 G.711 G.729a 코덱 두가지만 지원이 됩니.

 

여러분들이 VoIP 대한 관심이 있다면  이들 두가지 G.729 Annex 대해 아셔야 합니다.

이들은 모두 ITU 표준(Standard) 코덱 입니다.

 

또한 모두 음성을 초당 8Kbps 압축 하고 인코딩 타임(Compression Delay) 동일하게 10ms 입니다.

여기까진 동일한데그런데 몇가지 성능상의 차이점이 있습니다.

 

첫째로 가장 차이라면 G.729a 코덱은 알고리즘이 보다 단순해서 DSP 대한 부하가 G.729 비해 절반 정도 적습니다.

 

, G.729 20MIPS 이고 G.729a 10MIPS 입니다.

 

차이 때문에 하나의 DSP 칩은 동시에 두개의 G.729a 통화를 처리 할수 있는 반면에 G.729 통화는 하나밖에 지원하지 못합니다DSP(Digital Signal Processor) 칩은 NM 보이스 모듈이나 카타리스트 6500 6608모듈 이나 AS5000 시리즈의 VoIP 모듈등에 존재하는 칩이고 앞서 말씀 드렸다 시피 음성을 압축하는 부분 이라고 했습니다. 장비마다 장착 할수 있는 DSP 칩의 갯수가 한정 되어 있기 때문에 DSP 대한 부하가 얼마 인지는 중요한 요소가 됩니다.

 

예를 들면 아래 그림은 AS 5300 VoIP 모듈의 그림 입니다.

 

<그림 1>

  

<그림 2>

<그림1> AS5300 하나의 T1 모듈과 두개의 VoIP 모듈이 장착되어져서 VoIP 게이트웨이로 성되어 있는  사진 입니다.(예전에는 VoIP 모듈 대신 MICA(Modem ISDN Channel Aggregation) 모듈을 통해 PC 통신 서비스나 PPP 인터넷 접속 서비스용도로 사용되었지요.)

 

<그림2> VoIP 모듈은 <그림1> 슬롯에 장착 됩니다.하나의 VoIP 모듈에는 최대 30개의 DSP 칩을 장착 할수 있습니다.

만약 두개의 모듈을 설치하면 60개의 DSP 칩을 이용할수 있습니다.

 

이때 게이트웨이에서 사용하는 코덱이 G.729 코덱 이라면 게이트웨이는 동시에 60개의 통화만 처리할수 있습니다.하지만 사용하는 코덱이 G.729a 코덱이라면 동시에 처리할수 있는 통화는 120 개가 됩니다.DSP 칩에 대한 부하(Load) 차이가 이해 되시죠?추가해서 만약 코덱이 G.711 이라면 240개의 동시 통화가 가능합니다.

 

두번째 차이점은 MOS 값은 G.729 코덱이 약간 좋습니다.

G729 코덱은 MOS 3.92 이고 G729a 코덱은 3.9 입니다. 하지만 아주 미미한 차이죠?

 

이번엔 G.729 Annex B 입니다.

 

Annex B VAD (Voice Activity Detection) CNG(Comport Noise Generation) 정의합니다.

VAD (Voice Activity Detection) Silence Suppression 이라고도 합니다.

 

사람의 전화 통화시에 거의 절반 정도는 침묵 입니다.

, 저쪽에서 말을 하면 이쪽은 듣기만 하고 반면에 이쪽에서 말을 하면 저쪽은 듣기만 한다는 것이.

기존의 TDM 환경에서는 이렇게 말을 하지 않더라도 채널이 비어있는 채로 전송이 될뿐 채널을 다른 통화 시도자에게 할당 하지는 못합니다.

 

하지만 VoIP 환경에서는 이렇게 송화자가 침묵을 경우 IP 패킷을 생성하지 않는 입니다.

그렇게 되면 일시적으로 음성이 밴드위드를 사용하지 않게 되고 이렇게 남는 밴드위드를 다른 어플리케이션 (WEB 이나 FTP) 사용할 수가 있는 것이죠.

 

이렇게 음성의 진폭값이 일정 한도(Threshold) 도달 하는지를 감지해서 패킷의 생성 여부를 결정하는 것이 VAD 입니다.

다만 VAD 사용하게 되면 말의 시작부분이나 음성의 진폭이 떨어지는 말의 끝부분은 잘려 나갈수 있습니다. 이런것을 클리핑(Clipping) 이라고 합니다.

 

그래서 음질이 나빠질수가 있습니다.시스코 게이트웨이는 디폴트로 기능이 Enable 되어 있습니다.

 

CNG VAD 관련이 있습니다.VAD 사용하게 되면 말을 하지 않는 사람이 상대방에게 아무런 음성 패킷을 보내지 않으므로 하는 사람은 당연히 수화기에서 아무런 소리도 안들리게 됩니다.이럴경우 말을 혼자서 일방적으로 오랫동안 하는 사람은 간혹 전화가 끊어졌을까 염려해서여보세?”하고 상대의 존재 여부를 확인하게 됩니다.

 

이런 상황을 방지하고 통화자들에게 통화의 안정감을 주기 위해서 VAD 시에도 일정한 잡음을 발생시키게 되는데이걸 CNG(Comport Noise Generation) 라고 합니다.

 

이러한 G.729 Annex B G.729 코덱과 G.729a 코덱 둘다에 적용됩니다.

 

오늘은 내용이 길고 새로운 용어들이 소개 되었는데요이런 용어들은 VoIP 에서 일상적으로 사용되는 용어들이니 알아 두시고요

결론은 G.729a 코덱이 VoIP 환경에서 일반적으로 가장 많이 사용되는 코덱이고 이러한 기능들을 갖고 있다는 것을 알아 두시면 되겠습니다

[출처] VoIP 개요|작성자 스펀지밥

 

dom4j를 이용하여 웹서비스에서 데이터를 파싱하는 중에 나온 에러입니다.

JUnit으로 테스트할 때는 이상이 없던터라 데이타가 나오지 않아 깜짝 놀랐네요.

로그를 찾아보니  SAXException: Invalid byte 2 of 2-byte UTF-8 sequence

말 그대로 UTF-8 로 인코딩된 정보가 아니라는 거죠.

당연히 수신측과 송신측의 인코딩 타입은 동일해야 겠죠.

 

그동안은 보내는 쪽 코딩을 주로 했던터라. 저역시 대부분 UTF-8로 변환하여 보냈습니다만

이번에는 수신할 때가 문제였네요. 아마 그쪽에서 인코딩 타입을 EUC-KR 으로 사용했었나 봅니다.

 

  SAXReader xmlReader = new SAXReader();
  xmlReader.setEncoding("EUC-KR");
  Document doc = xmlReader.read(inputstream);

 

이렇게 stream 데이터를 읽기 전에 EUC-KR로 인코딩타입을 명시하니 이상없이 동작하네요.

 

 

 

 

 

요즈음  단위테스트로 JUnit를 많이들 사용하고 있는 듯 한데

JUnit 3.X와는 달리 JUnit 4.X 의 경우 @Test 에서 유효성 검사(Assert)를 하기  위해서 org.junit.Assert.assert*** 를 항상 static  import  해주어야 한다는 점은 다소 불편함이 있습니다..

더군다나 static import의 또하나의 불편한 점은 Eclipse에서 이를 사용시 기본적으로 추천(Intellisense)기능을 제공해 주지 않는다는 점이겠죠.

 

하지만 Eclipse에서 static import를 추천해 주도록 설정하여 조금 편하게 코딩할수 있는 Tip이 있어 간단히 소개하고자 합니다.

 

 

1. Window > Preferences > Java > Editor > Content Assist > Favorites를 선택합니다

 

 

2. New Type을 클릭하여 static type으로 org.junit.Assert를 등록합니다.
Browse..버튼을 클릭한 후 Type Selection 창에서 assert을 검색할 수 있습니다.
이 때 주의할 점은 JUnit4 는 기존 버전과의 호환성을 위해 org.framework.Assert 도 포함하고 있기 때문에 반드시 org.junit.Assert로 선택해야 합니다.

 

 

3. 이제 특별히 import 하지 않아도 위와같이 Assert 이하 함수들을 Eclipse Intellisense 기능을 이용하여 사용할 수 있습니다.(입력중 Ctrl+Space)

 

단순히 JUnit의 Assert 이하 함수들에  대하여 추천목록에 등록시켜 사용한 예이지만 기타 다른 추천기능을 제공하지 않는 static import 를 해야만 하는 다른 유형들을 Eclipse에서 좀더 유용하게 사용할 수 있을 듯 합니다.

 
블로그 이미지

시반

시반(詩伴)이란 함께 시를 짓는 벗이란 뜻을 가지고 있습니다. 함께 나눌수 있는 그런 공간이길 바라며...

카테고리

분류 전체보기 (233)
개발 이야기 (73)
WEB2.0 (57)
DB2 (24)
MySQL (6)
오라클 (26)
기타 (44)
취미 (0)
잡담 (2)