Clean Code that Works.

이 내용은 대부분 Java Message Service 책에서 가져온 것이고, 위키디피아 및 구글 검색을 통해 얻어진 것입니다.
허접하니 그냥 참조만...

이번에 설명 할 내용
1. What is Message ? - Message란 무엇이고 왜 사용 하는가
2. JMS Architecture - JMS의 전반적인 아키텍쳐와 사용 모델
3. JMS Element - JMS에서 사용하는 엘리먼트들에 대한 설명

그럼 대충 시작.

1. What is Message?
메시지은 느슨하게 결합된 분산 통신의 한 형태이다. 여기서 통신이란 용어는 소프트웨어 컴포넌트들 간의 구성요소들 사이에 메시지의 교환으로 이해할 수 있다. 메시지 지향 테크놀로지들은 강하게 결합된 통신(TCP network socekst, CORBA or RMI 같은)을 중간요소의 도입을 통해 완하하려고 시도한다.  후자의 접근 방식을 통해 소프트웨어 컴포넌트가 서로 '간접적으로' 통신 할 수 있다. 이러한 메시지의 장점은 보내는 쪽에서 받는 쪽에 대한 정확한 정보가 없어도 가능 하다는 점이다.

메시징의 장점은 이기종 플랫폼 간의 통합과 시스템의 병목현상을 감소 시키고, 확장성을 증가 시키며 변화에 신속하게 대응 할 수 있다.


안좋은 예


간단한 메시징 시스템의 예로 콜센터를 들 수 있다.

고객과 콜센터 직원이 라인을 통해 다이렉트로 통화를 할 경우, 고객이 늘어날 경우에 콜센터 직원이 통화가 가능 할 때까지 계속 다시 전화를 걸어서 통화가 가능한 라인을 찾아야 한다.


좋은 예


위 그림처럼 중간에 경유할 수 있는 Voice Mail Box 같은 장치를 두면, 고객의 요청은 box에 쌓이게 되고 직원은 이것을 확인하고 처리 하면 되기 때문에 고객은 계속 전화를 걸어 통화가 가능한 라인이 있는지 확인할 필요 없이 처리 할 수 있다.


2. JMS Architecture

비즈니스 시스템에 사용되는 응용프로그램들간의 메시징 시스템은 엔터프라이즈 메시징 시스템이나 메시지 지향 미들웨어(Message-Oriented Middleware, MOM)이라고 한다.

대부분의 기업들이 메시징 시스템의 데이터 교환을 destinations라 부르는 가상 채널을 사용한다. 메시지가 전송되고 나면 특정 응용프로그램이 아니라 destination으로(queue 나 topic)에 저장 된다. 아무 응용프로그램이 관심이 있는 destinatin에 등록하여 메시지를 받아 볼 수 있다. 이러한 바법을 통해 메시지를 주고 받는 응용프로그램간의 관계가 느슨하게 유지된다. 메시지를 보내는 쪽이나 받는 쪽이나 어떤식으로든 서로 얽매이게 되지 않고 메시지를 주고 받을 수 있다.


destination


JMS는 응용프로그램 개발자가 같은 API로 다른 시스템들에 사용할 수 있는 JDBC와 유사 하다. 만약 JMS를 준수하여 서비스를 할 경우, JMS API를 통해 공급자가 해당 업체에 메시지를 주고 받을 수 있다. 예를 들어 SonicMQ를 사용하여 메시지를 보내고 IBM WebSphere MQ를 통해 메시지를 처리 할 수 있다.


메시징의 장점
1. 이기종 시스템간의 통합
- 이기종 플랫폼간의 커뮤니케이션과 통합은 메시징의 오래된 사용 방법이다. 메시징을 사용하여 애플리케이션의 서비스를 호출할 수 있고 완전히 다른 플랫폼에서 구현하는 시스템으로 사용할 수 있다. 많은 오픈 소스 및 상용 메시지 시스템은 자바 사이의 매끄러운 연결을 제공하고 다른 언어 및 다른 플랫폼에도 제공한다.
역사적으로 이기종 시스템간의 통합 작업은 많은 방법이 존재 하였다. 정보를 공유하는 데이터베이스를 사용하여 두 이기종 시스템 또는 응용프로그램간에 접근하는 방식이 아직까지 널리 사용되고 있는 방법이다. Remote Procedure CALL은 이종 분산 시스템간의 데이터 및 기능 공유의 또다른 방법이다. 이러한 해결책은 각각 장점과 단점을 가지고 있다. 메시징을 사용함으로써 데이터 및 기능을 애플리케이션이나 서브 시스템을 통해 공유함으로서 결합도를 낮추어 사용한다. 최근 웹 서비스가 또 다른 이기종 시스템 통합을 위한 솔루션으로 등장하였지만 아직 신뢰성이 부족하므로 메시징이 더 좋은 선택이다.(최근에는 웹 서비스도 많이 늘어 나는 추세)

2. 시스템 병목 현상을 감소
- 일반적으로 작업을 처리 하기 위해 많은 수의 프로세스를 만들고 해당 프로세스의 요청 속도를 유지 하기 위해 시스템과 애플리케이션의 병목현상이 발생한다. 가장 많이 볼 수 있는 예로는 튜닝 수준이 낮은 데이터베이스에 연결될 때 까지 기다리는 애플리케이션과 프로세스를 들 수 있다. 이러한 시점에서 응답시간은 악화되고 타이밍이 어긋나게 된다.
한정된 시간내에 처리할 수 있는 용량은 제한되어 있으므로, 이를 처리하기 위해서는 많은 시간이 추가된다.

3. 확장성을 향상
- 병목현상을 감소하는것과 같은 방법으로, 시스템의 전반적인 확장성 및 처리량을 증가 시킬 수 있다.

4. 최종 사용자의 생산성을 높임
- 비동기 메시징을 사용함으로서 생산성을 향상 시킬 수 있다. 동기적으로 처리할 경우 요청을 보내고 처리를 기다리는 동안 많은 시간이 소비 되는데, 비동기 메시징을 사용함으로써 이 시간을 감소 시키고 유용하게 사용 할 수 있다.

5. 아키텍쳐의 유연성 및 민첩성
- 아키텍쳐의 민첩성은 끊임없이 변화하는 환경에 신속하게 대응하는 능력이다. 추상화되고 연결성이 낮은 컴포넌트들에 메시징을 사용하게 되면 소프트웨어, 하드웨어, 비즈니스로직의 변경에 까지 빠른시간에 대응할 수 있다. 메시징을 통해 메시지 공급자나 클라이언트 컴포넌트는 프로그래밍 언어나 플랫폼에 종속족이지 않기 때문에 유연하고 민첩한 대응을 할 수 있다.

2.1 메시징 모델
JMS는 두가지 타입의 메시징 모델을 지원한다.
Point-to-point, publish-and-subscribe
이 메시징 모델은 메시징 도메인이라고 불리기도 한다. 줄여서 p2p와 pub/sub 각각 불리운다.
가장 간단한 의미로 pub/sub는 one-to-many 브로드 캐스트 메시징을 위한거고 p2p는 one-to-one 딜리버리 메시징이다.


JMS 관전에서 메시징 클라이언트들은 JMS 클라이언트라고 부르고 메시징 시스템은 JMS 프로바이더로 불리운다. JMS 애플리케이션은 많은 수의 JMS 클라이언트와 일반적으로 하나의 JMS 프로바이더로 구성된다.
추라고, 메시지를 제공하는 JMS 클라이언트는 message producer라고 하고, 메시지를 받는 쪽을 message consumer 라고 부른다. JMS 클라이언트가 각각 consumer나 producer가 될 수 있다. consumer 와 producer라는 용어를 사용할 때 JMS 클라이언트가 각각 메시지를 consume 하거나 produce하는걸 의미 한다.

2.1.1 Point-to-Point
- p2p 메시징 모델은 JMS 클라이언트가 메시지를 동기 및 비동기 방식으로 queue라고 불리우는 가상 채널을 경유하여 전송하거나 받을 수 있다. p2p모델에서 message producer는 sender, message consumer 는 receiver로 불리운다. p2p 메시징 모델은 Pull 기반이거나 클라이언트에게 자동으로 push되는 Polling 기반 모델이다. p2p 메시징 모델의 구분되는 특징중에 하나는 메시지는 queue에 전송되고 다른 수 많은 receiver가 같은 메시지를 받기위해 대기하고 있어도, 하나의 receiver에 하나씩 전송 된다는 점이다.
Point-to-point 메시징은 "발생하고 잊어 버리는" 비동기 메시징을 지원하는것 뿐만 아니라 동기정 요청/응답 메시징을 지원한다. Point-to-point 메시징은 publish-and-subscribe 모델보다 좀 더 결합할려는 경향이 있다. 보내는 쪽에서 메시지가 어떻게 사용되기 위해서 전송되는지 알고 누가 메시지를 받는지 알기 때문이다. 예를 들어, 전송하는 쪽에서 주식 거래를 하기 위해 큐에 내용을 전송하고 거래 확인 번호를 포함한 내용을 기다릴 때 이다. 이 예제에서 메시지를 보내는쪽은 메시지를 받는쪽이 거래요청을 처리할 것이라는 것을 알고있다. 다른 예는 시간이 오래걸리는 레포트 생성을 비동기적으로 요청할 때다. 보내는 쪽에서 레포트를 위한 요청을 만들고 레포트가 준비 되면 알림 메시지가 보내는쪽에게 전송된다. 이 예에서 센더는 보내는 쪽은 받는쪽에서 메시지를 보고 레포트를 생성하러 갈 것이라는 것을 알고있다.
Point-to-Point 모델을 로드밸런싱을 지원한다. 다중 리시버가 같은 큐에서 수신 대기 하고 있고 따라서 부하가 분산된다. 그림 1-4처럼 JMS provider는 메시징을 큐에서 관리한다. 각각 메시지가 한번에 한개씩 리시버 그룹에서 처리가 가능한 리시버가 처리하는것을 보장한다. JMS 스펙은 분산 메시징 처리를 강요하지 않는다. 비록 몇몇 JMS 벤더들이 이 로드밸런시을 구현하고 있지만. Point-to-point은 메시지가 읽혀지기 전에 대기열의 내용을 볼 수 있는 대기열 브라우저 같은 다른 기능을 제공 한다. 이 브라우저 컨셉은 pubish-and-subscribe 모델에서는 지원되지 않는다.

2.2.2 Publish-and-Subscribe
pub/sub 모델에서 메시지는 topic이라고 불리는 가상 채널을 통해 공급된다. Message producers 는 publishers, message consumers는 subscribers라고 불리운다. p2p모델과는 달리 topic을 통해 공급되는 메시지는 여러 subscribe에게 전달 될 수 있다. 이 방법은 가끔지 메시지를 브로드캐스팅하기위해 추천하는 방법이다. 모든 subscriber는 복제된 같은 메시지를 받는다. pub/sub 메시징 모델은 대형 푸쉬 기반 모델이다. 메시지는 consumer들에게 새로운 메시지 확인을 위해 요청및 poll을 할 필요 없이 자동적으로 broadcast 되는 모델이다.
pub/sub 모델은 p2p모델 보다는 결합도가 낮다. publisher는 많은 subscribers들이 있고, 이들이 메시지를 가지고 무엇을 할지 알지 못한다. 


3. JMS Element
기본적인 아키텍쳐 설명은 이정도 까지만 하고, 자주 사용되는 용어에 대해서 정리해보자.
이 내용은 http://en.wikipedia.org/wiki/Java_Message_Service에 잘 정리 되어 있다.

  • JMS provider : Message Oriented Middledware(MOM)을 위한 JMS 구현체. Java JMS의 구현체 이거나 이기종 MOM의 아답터 역할도 한다.
  • JMS client : 메시지를 전송하거나 받는 애플리케이션
  • JMS producer/publisher : 메시지를 만들고 전송하는 클라이언트
  • JMS consumer/subscriber : 메시지를 받는 클라이언트
  • JMS message : JMS 클라이언트 사이에 전송되는 오브젝트
  • JMS queue : 메시지를 전거나 메시지를 읽기 위해서 메시지가 대기중인 영역. 메시지의 전송 순서는 보장 하지 않고, 오직 한번 읽는 다는 것만 보장한다.
  • JMS topic : 다양한 subscriber들에게 메시지를 전송하기 위한 방법.


비밀번호 조합에서, 꼭 영문/숫자를 혼용하도록 해야 하는 요구사항이 있었다.
정규식으로 어찌저찌 해보고 @Pattern 을 사용해서 해볼려고 했지만.. 정규식으로는 안되는것 같았다.

하여, 그냥 만들어 보기로 결정.
JSR 303 구현체중 하나인 Hibernate Validator 를 사용 하는 중인데.
http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-customconstraints
여길 보면 자세히 설명이 되어 있다.

위 것을 참조 하여 일단 custom anontation을 만들어 보면, 아래와 같은 코드가 탄생..

@ConstraintComposition(CompositionType.AND)
@Target({ METHOD, FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = AlphabetAndNumberValidator.class)
public @interface AlphabetAndNumber {
     public abstract String message() default "{AlphabetAndNumber.message}";
     public abstract Class<?>[] groups() default { };
     public abstract Class<? extends Payload>[] payload() default { };
}

여기서 @Constraint 쪽에 제약 조건을 체크하는 클래스를 지정해 주어야 한다.

하여 AlphabetAndNumberValidator를 살펴 보면, 아래와 같은데.
isValid에서 제약 조건을 체크 하는 것을 볼 수 있다.
이 경우엔 영문을 가지고있는지, 숫자를 가지고 있는지 확인하고 이를 둘 다 가지고 있어야 통과 하도록.

public class AlphabetAndNumberValidator implements ConstraintValidator<AlphabetAndNumber, String> {

    @Override
    public void initialize(AlphabetAndNumber constraintAnnotation) {
    }
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if ( value == null) {
            return false;
        }
        Matcher matcher = Pattern.compile("[a-zA-Z]+").matcher(value);
        boolean isExistAlphabet = matcher.find();
        matcher = Pattern.compile("[0-9]+").matcher(value);
        boolean isExistNumber = matcher.find();
       
        if ( isExistAlphabet && isExistNumber) {
            return true;
        } else {
            return false;
        }
    }
}

이렇게 구현 한 후에 도메인 클래스나 기타 method 및 field에 @AlphabetAndNumber 를 붙여주고 valid 체크를 하게 되면 적용 된다.


아래 블로그에도 잘 정리 되어 있는데, 여기서 만든 custome validator는 Spring bean으로도 등록이 된다고 하니 다른 빈들을 참조 해서 좀 더 복잡한 제약 조건을 걸도록 만들수도 있다.
http://chanwook.tistory.com/855

하이버네이트 페이지에 설명이 상당히 잘 되어 있기 때문에, 아래 url 참고 해서 test 케이스 작성도 잊지 말도록 하자. :)
http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#Using%20the%20constraint



리소스 지향 아키텍쳐(Resource Oriented Architecture, ROA) 란?
REST한 아키텍쳐를 구현하기 위한 한가지 방법.
http://en.wikipedia.org/wiki/Resource-oriented_architecture 

헐.. 위키 주소가 정말 RESTFul 한 URI 구나. !!

아무튼..

1. 웹 서비스에서 제공할 데이터를 특정한다. 
2. 데이터를 리소스로 나눈다.
3. 리소스에 URI로 이름을 부여한다.
4. 클라이언트에 제공할 리소스의 표현을 설계한다.
5. 링크와 폼을 이용해 리소스와 리소스를 연결한다.
6. 이벤트의 표준적인 코스를 검토한다.
7. 에러에 대해 검토한다.



 from. 웹을 지탱하는 기술.

 

JMS with spring - 1

Java2011. 6. 17. 17:47

1. JMS
수년간 시스템들은 복잡도가 올라가고 더 세련되어져 갔습니다. 시스템들은 과거의 시스템들에 비해 믿을 수 있고, 확장성이 증가하고, 더 많은 유연성이 필요하게 되었습니다. 이러한 요구들의 증가에 대응하여 이 빠른 시스템, 아키텍쳐, 디자이너 및 개발자들은 이들 복잡성을 해결하는 한가지 방법으로 메시징을 활용했습니다.

메시징이 사용되고 나서  Java Message Service(JMS) API 는 1999년 도입 이후 크게 변경되지 않았습니다. 메시징은 유연성과 확장성 문제의 해결을 위해 폭넓게 사용되었지만 많은 비지니스적 문제와 다른 애플리케이션의 문제에서도 사용 되었습니다.

 이기종간의 통합은 메시징이 중요한 역할을 하는 기본 영역중 하나 입니다. 

또한 메시징은 비동기 요청을 처리할 수 있는 기능 및 아키텍쳐 와 개발자들이 시스템 병목 현상을 감소 또는 제거를 위한 솔루션을 제공하고, 최종 사용자의 생산성 및 전반적인 시스템 확장성을 제공 합니다. 이기종 시스템 간에 높은 수준의 약한 결합 및 메시징을 활용하는 시스템에 높은 수준의 구조적인 유연성과 민첩성을 제공 합니다.
 
비즈니스 시스템에 사용되는 애플리케이션간의 메시징 시스템은 엔터프라이즈 메시징 시스템이나 메시지 지향 미들웨어(Message-Oriented Middleware, MOM)이라고 합니다.  

엔터프라이즈 메시징 업체들은 서로 다른 메시지 포맷과 네트워크 프로토콜을 사용하여 메시지를 교환하지만, 기본적인 의미는 동일합니다. API는 새 메시지 생성, 애플리케이션데이터로딩, 라우팅 정보 지정과 메시지를 보냅니다. 이 동일한 API를 사용하여 다른 애플리케이션에서 만든 메시지를 수신합니다. 

대부분 기업들이 메시징 시스템, 응용 프로그램 교환을 destinations라 부르는 가상 채널을 사용합니다. 메시지가 전송되면, 그것은 특정 애플리케이션이 아닌 대상 destination으로(queue or topic) 기록 됩니다. 아무 애플리케이션이나 관심있는 destination에 등록을 하여 메시지를 받아 볼 수 있습니다. 이러한 방법으로 메시지를 주고 받는 애플리케이션의 약한 관계가 성립됩니다. 메시지를 보내는 쪽이나 받는 쪽이나 어떤식으로든 서로 얽매이지 되지 않고 메세지를 주고 받을 수 있습니다.

JMS는 애플리케이션 개발자가 같은 API로 다른 시스템들에 사용할 수 있는 JDBC와 유사하다. 만약 JMS를 준수하여 서비스를 할 경우, JMS API를 통해 공급자가 해당 업체에 메시지를 주고 받을 수 있다. 예를 들어 SonicMQ를 사용하여 메시지를 보내고 IBM WebSphere MQ를 통해 메시지를 처리 할 수 있다. 

2. The advantages of Messaging
이기종 시스템간의 통합
이기종 플랫폼의 커뮤니케이션과 통합은 아마도 메시징을 위한 오래된 유스케이스입니다. 메시징을 사용하여 애플리케이션의 서비스를 호출할 수 있고 완전히 다른 플랫폼에서 구현하는 시스템으로 사용할 수 있습니다. 많은 오픈 소스 및 상용 메시징 시스템은 자바 사이의 매끄러운 연결을 제공하고 다른 언어 및 다른 플랫폼에도 제공 합니다. 예를 들어 ActiveMQ(open source) 와 IBM WebSphere MQ(commercial)이 있습니다. 이 두 메시징 시스템은 JMS를 지원 하고 또한 자바 메시징 클라이언트가 사용하는 기본 API를 지원 합니다(C, C++). 벤더에 의존하지 않고 non-java 시스템과 non-jms 메시징 클라이언트를 사용할 수 있습니다.
역사적으로, 이기종 시스템간의 통합 작업은 많은 방법이 존재 하였습니다. 정보를 공유하는 데이터베이스를 사용하여 두 이기종 시스템 또는 응용 프로그램간에 접근하는 방식이 아직 까지 널리 사용되고 있는 방법입니다. Remote Procedure Call, or RPC 는 이종 분산 시스템간의 데이터 및 기능 공유의 또 다른 방법입니다. 이러한 해결책은 각각 장점과 단점을 가지고 있고 메시징은 데이터 및 기능을 애플리케이션이나 서브 시스템을 통해 굥유할수 있는 진정한 결합도가 낮은 방법입니다. 최근 웹 서비스가 또 다른 이기종 시스템 통합을 위한 솔루션으로 등장했습니다. 그러나 웹서비스는 아직 신뢰성이 부족하므로 메시징이 더 좋은 선택 입니다.

시스템 병목 현상을 감소
많은 수의 프로세스를 만들고 해당 프로세스의 요청 속도를 유지 하기 위해 시스템과 애플리케이션의 병목현상이 발생 합니다. 고전적인 시스템 병목현상의 예는 저조한 튜딩이된 데이터 베이스에 연결될 때 까지 기다리는 애플리케이션과 프로세스를 들 수 있습니다. 시스템이 백업되는 시점에서 응답시간은 악화되고 결국 타이밍이 어긋 납니다.
시스템 병목 현상의 좋은 비유는 깔때기에 물을 붓는 것입니다. 한정된 시간내에 처리 할 수 있는 용량은 제한되어 있으므로 이를 처리 하기 위해서는 많은 시간이 추가 됩니다. 하지만 깔때기에 입구를 추가 하게 되면 이것을 해결 할 수 있습니다. 이 예는 Point -to-Point 모델로 해결이 가능하고, 병목현상이 감소 또는 어떤 경우에는 완전히 제거 됩니다.

확장성을 향상
많은 메시징 시스템 병목 현상을 감소하는 것과 같은 방법으로, 시스템의 전반적인 확장성 및 처리량을 증가 시킬수 있을 뿐만 아니라 효과적으로 응답시간을 감소 시킬수 있습니다. 

최종 사용자의 생산성을 높임
비동기 메시징의 사용은 최종 사용자의 생산성 역시 향상시킬 수 있습니다. 

아키텍쳐의 유연성 및 민첩성
아키텍쳐의 민첩성은 끊임없이 변화하는 환경에 신속하게 대응하는 능력입니다. 추상화되고 연결성이 낮은 컴포넌트들에 메시징을 사용하게 되면 소프트웨어, 하드웨어, 비즈니스로직의 변경에 까지 빠른시간에 대응할 수 있습니다. 메시징을 통해 메시지 공급자나 클라이언트 콤포넌트는 프로그래밍 언어나 플랫폼에 종속적이지 않기 때문에 유연하고 민첩한 대응응 할 수 있습니다.

엔터프라이즈 메시징
엔터프라이즈 메시징은 새로은 컨셉이 아닙니다. 메시징은 IBM Web-Sphere MQ, SonicMQ, Microsoft Message Queuing(MSMQ), and TIBCO Rendezvous 등이 수년간 존재해 왔습니다. 최근에 오픈 소스인 ActiveMQ가 참여하였습니다. 
엔터프라이즈 메시징의 핵심 컨셉은 메시지가 비동기적으로 한시스템에서 네트워크를 통해 다른 시스템으로 전달 되는 구조이다. 메시지가 비동기적으로 전달 된다는 말은 수신하는 쪽에서 메시지를 받기위해 대기하거나 처리를 하기 위해서 대기할 필요가 없다는 뜻이다. 



client 라든 용어에 대해서 정의해 보면, 메시징 시스템은 메시징 클라이언트와 몇몇 종류의 메시징 미들웨어 서버로 구성되어 있다. 클라이언트들은 메시징을 메시징 서버로 보낸 다음 메시지들은 다른 클라이언트들에 배포 된다. 클라이언트 비즈니스 애플리케이션이나 컴포넌트들이 이를 위해 메시징 API를 사용한다(우리의 경우엔 JMS)

중앙 아키텍쳐
엔터프라이즈 메시징 시스템들은 중앙 아키텍처를 사용하는 메시지 서버에 의존하는 하고 사용한다. 메시지 서버는 메시지 라우터나 브로커로 블리우고 메시지들을 메시징 클라이언트로 부터 다른 메시징 클라이언트로 전달하는 책임을 가지고 있다. 메시징 서버는 메시지를 보내는 클라이언트와 받는 클라이언트들로부터 분리되어 있다. 클라이언트들은 오직 메시징 서버만 바라보고 다른 클라이언트들은 신경쓰지 않는다. 전체 시스템에 영향을 미치지 않고 클라이언트들을 추가 및 수정할 수 있습니다. 
요약하면, 중앙 아키텍쳐는 hub-and-spoke topology에 사용된다. 간단한 예를 들면, 중앙 메시지 서버가 있고 모든 클랑이언트들은 이곳에 연결한다. 아래의 그림처럼,
 hub-and-spoke 아키텍쳐는 네트워크의 최소한 연결을 허용하고 다른 파트의 시스템간 최소한의 커뮤니케이션을 허용합니다. 

실제로, 중앙 메시지서버는 분산서버의 클러스터 수의 논리 단위로 운영된다.

분산 아키텍쳐
모든 분산 아키텍쳐는 현재의 네트워크 레벨에서 IP 멀티 캐스트를 사용합니다. 메시징 시스템은 멀티캐스팅을 바탕으로 중앙서버가 없습니다. 몇몇 서버들은 기능적으로 클라이언트 내의 일부로 내장 되어 있는 동안 메시지 라우팅은 IP 멀티 캐스트 프로토콜을 사용하여 네트워크 계층에 위임합니다.
IP 멀티캐스트는 애플리케이션이 한개 이상의 IP 멀티캐스트 그룹에 참여 하도록 허락합니다. 각 그룹은 IP 네트워크 주소를 사용하고 모든 회원들은 어떤 메시지든 간에 그 그룹안에서 재배포를 받습니다. 이러한 방법으로, 애플리케이션은 IP 멀티케스트 주소로 메시지를 전송할 수 있고 네트워크 레이어에서 메시지가 적절하게 재배포되는것을 기대할 수 있습니다(Figure 1-3 참조)
중앙 아키텍처와는 달리, 분산 아키텍쳐는 메시지 라우팅을 목적으로한 서버를 필요로 하지 않는다.(네트워크가 자동적으로 라우팅을 해줌). 그러나 기능적으로 각 클라이언트에 포함되어 , 이러한 메시지의 영속성 및 메시지 배달의 의미는 once-and-only-once 배달과 같습니다.




메시징 모델
JMS는 두가지 타입의 메시징 모델을 지원한다: point-to-point 와 publish-and-subscribe.
이 메시지 모델은 때로는 메시징 도메인이라고 한다. Point-to-point 메시징과 publish-and-subscribe 메시징은 줄여서 p2p 와 pub/sub로 각각 불리웁니다. 
가장 간단한 의미로 publish-and-subscribe는 one-to-many 브로드 캐스트 메시징을 위한거고 point-to-point 는 one-to-one 딜리버리 메시징입니다.


JMS 관점에서 메시징 클라이언들은 JMS 클라이언트라고 부르고 메시징 시스템은 JMS 프로바이더로 불리웁니다. JMS 애플리케이션은 많은 수의 JMS 클라이언트와 일반적으로는 하나의 JMS 프로바이더로 구성됩니다.
추가로, 메시지를 제공하는 JMS 클라이언는 message consumer로 불리웁니다. JMS 클라이언트는 message producer 와 message consumer가 될 수 있습니다. consumer 와 producer라는 용어를 사용할 때 JMS 클라이언트가 각각 consumes messages 나 produces message 하는걸 의미 합니다.

Point-to-Point
Point-to-Point 메시징 모델은 JMS 클라이언트가 메시지를 동기 및 비동기 방식으로 queue라고 부르는 가상 채널을 경유하여 전송하거나 받을 수 있습니다. point-to-point 모델에서, message producers 는 sender(보내는사람), message consumers 는 receivers(받는사람)으로 불립니다.
 

보통 프로퍼티 값을 Service나 Repository에서 가져다 쓸 때

<!-- Properties Files -->
<context:property-placeholder location="classpath:properties/*.properties"/>

처럼 프로퍼티 파일을 정의 해 두고,
@Value("${jdbc.username}") String userName;
이렇게 사용한다.

하지만, Controller에서 @Value("${jdbc.username}")로 주입을 받을려고 해 보면 안되고
값을 출력 해 보면 "${jdbc.username}" 값이 출력 된다.

왜 그럴까 해서 구글링을 좀 해 봤더니

http://www.dotkam.com/2008/07/09/spring-web-application-context-visibility/

아래에서 답을 알 수 있었다.

Here is the semi-official version “why” from Juergen (Spring Lead Developer):

“PropertyPlaceholderConfigurer is an implementation of the BeanFactoryPostProcessor interface: This interface and its sibling BeanPostProcessor just apply to the BeanFactory that defines them, that is, to the application context that defines them.

If you combine multiple config files into a single contextConfigLocation, a PropertyPlaceholderConfigurer defined in any of the files will apply to all of the files, because they are loaded into a single application context.

However, a DispatcherServlet has its own application context, just using the root web application context as parent. Therefore, it needs to define its own BeanFactoryPostProcessors and/or BeanPostProcessors, in this case its own PropertyPlaceholderConfigurer.”

Happy Springing!


알다 시피 웹 환경에서
부모(보통 applictionContext) - 자식(dispathcerServlet)으로 구성을 한다.
컨텍스트 영역이 다르 다는 말이다.

PropertyPlaceholderConfigurer는 BeanFactoryPostProcessors and/or BeanPostProcessors 이것인데
부모와 자식의 생성 주기가 틀리므로 부모의 PropertyPlaceholderConfigurer를 적용할 수 없다.
그래서 각자 자신의 PropertyPlaceholderConfigurer를 만들어서 써야 한다는 말



http://www.springsource.org/node/2966..

More content from SpringOne 2GX 2010 has just been posted on the InfoQ media library.

In this session Juergen Hoeller gives a presentation covering Spring and Java EE 6: Synergy or Competition?. This has been a topic of great interest recently and the presentation provides a good complement to Juergen's earlier blog post on a similar topic.

이번세션에서 유겐 휄러는 "스프링과 Java EE 6 : 시너지 인가 경쟁인가?"에 대한 발표를 했다.
이것은 최근에 큰 관심을 끄는 주제이고 이 프레젠테이션은 유겐이 예전에 포스팅한 비슷한 주제를 보완하고있다.

Juergen starts with a review of Spring's general deployment approach and then provides a brief review of some of the Java EE 6 specifications and how they relate to the Spring projects. Finally Juergen discusses some of the key considerations that developers and architects should think about when making a technology choice for their applications.

유겐은 스프링의 일반적인 배포 방법에 대해서리뷰를 하고 Java EE 6 명세와 이것이 어떻게 스프링 프로젝트들과 관계가 있는지 리뷰를 한다. 마지막으로 유겐은 개발자와 아키텍쳐가 그들의 어플리케이션을 만들 때 선택할 기술에 대해서 생각해야 할 몇몇 핵심 고려사항을 설명 한다.

Again, many thanks to InfoQ who was at SpringOne 2GX to capture so many of the great presentations and provided fantastic coverage for the show.

이런 발 번역 -_-


우옷!!!

아파치를 한번도 써보지 않았는데, 써야할 일이 생겨서 연동 방법에 대해 알아 보았다.

지금 하려는 방법은
로컬 PC에 아파치를 띄워놓고, 이클립스에서 띄워놓은 톰캣하고 연동을 시키는 것이다.

연동 방법 참고(http://theeye.pe.kr/240)

위 설명을 들어가 보면.. 리눅스 기반이긴 하지만, 뭐 거의 비슷하다.
하지만 이것은 이클립스의 톰캣이 아닌 실제 돌아갈 톰캣의 환경 설정을 변경하는 것이다.

그럼 이클립스에서의 톰캣과 아파치를 연동 할려면 어떻게 해야할까.
그냥 아파치 설정파일에서 모듈 한개 더 로드 하면 된다.

위 블로그 설명대로 하면,
[Thu Dec 02 19:33:10 2010] [error] [client 127.0.0.1] attempt to make remote request from mod_rewrite without proxy enabled: proxy:ajp://localhost:8009/
이런 오류가 나온다.

블로그 에서는 아래 두개의 so 파일을 로드 하도록 하게 했는데, 강조한 so 파일 한개를 추가로 해 주어야 한다.
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so

그런 다음에 가상 호스트 설정 파일을 불러 오게 지정 한 후.
Include conf/extra/httpd-vhosts.conf

아이님 블로그 설정 처럼 설정을 해준다.
<VirtualHost *:80>
    ServerAdmin
your@emailhere
    DocumentRoot "/var/www/html"
    ServerName localhost
    ErrorLog "logs/theeye.pe.kr-error.log"
    CustomLog "logs/theeye.pe.kr-access.log" common

    RewriteEngine On
   
RewriteCond %{REQUEST_FILENAME} .(htm|html|xhtml|css|jpg|gif|png|swf|js$)
    RewriteRule (.*) - [L]
    RewriteRule (.*) ajp://localhost:8009$1 [P]
</VirtualHost>


그 다음으로 ...는 없다.
이클립스의 톰캣 설정(server.xml)에서는 ajp 설정을 디폴트로 해주기 때문에,
포트를 특정 포트로 변경하지 않을 것이라면, 따로 지정해 주지 않아도 잘 연동 된다.

완료 후에 이클립스에서 톰캣 실행 후 아파치 실행하면 연결 할 수 있다.

KSUG 세미나.

Java2010. 11. 17. 18:15
이번 세미나는

알려진 대로 아래 네가지 순서로 진행되었다.
1. 스프링 트러블 슈팅(http://whiteship.me/?p=12783)
2. 리치 도메인 모델
3. 스프링 원 2010(맞나..;)(http://www.ksug.org/116)
4. 스프링 레스트풀 서비스.

가장 괜찮았던 강의는 3번째 강의 였다.
정상혁님이 2010년 10월에 열렸던 SpringOne2GX 2010에 참가 하였던 후기에 대해서 발표를 하셨는데.
전체적으로 스프링이 앞으로 어떻게 나아갈 것인지에 대해서 들을 수 있어서 좋았다.

기선이형이 했던 스프링 트러블 슈팅은..
순순히 다이아몬드를 옥수수로 교환해 주면 유혈 사태는 발생하지 않는다..는 내용만 생각난다. -_-;;

리치 도메인 모델의 경우는
봄싹의 구조가 일단 DDD 스타일로 개발 되어 있기 때문에 발표 내용과 거의 일치한 다고 볼 수 있어서, 이해하기가 쉬었다.
게시판 설계할때도 도메인 모델을 기준으로 해서 만들고 개발 했었는데,
발표 내용 처럼, CRM 카드등을 통한 좀 더 정확한 설계가 필요할 것 같다.

레스트풀 서비스같은 경우는 좀 더 웹 서비스나 그런 쪽에 특화된 강의를 기대 했었는데 그런 부분이 부족해서 약간 아쉬었다.

이번에도 혹시나 책 증정 이벤트를 할까 해서 정신을 뽀짝 차리고 듣고 있었는데, 아쉽게도 없었다. ㅋ_ㅋ

발표 하신분들 준비 하신분들 모두 수고하셨습니다.
다음에도 좋은 강의 부탁 드려요 '-^




GIT 사용자 설정하기.

Java2010. 11. 16. 14:26
이클립스에서 eGit을 사용하는 경우에,
소스 커밋을 할 때 아래와 같이 Author, Commiter가 등록되어 있지 않은 경우.


Window > preperence > team > git > Configuration 에 등록해 준다.


git Config 파일을 열어보면 아래와 같이 변경 되어 있다.
여기서도 수정 해도 됨 @_@

git 명령어로 추가하는 방법도 있는데 기억이...

SRP..

Java/이론..2010. 11. 2. 18:49
클린코드 204쪽..

SRP(Single responsibility principle)는 객체 지향 설계에서 더욱 중요한 개념이다. 또한 이해하고 지키기 수월한 개념이기도 하다. 하지만 이상하게도 SRP는 클래스 설계자가 가장 무시하는 규칙 중 하나다. 우리는 수많은 책임을 떠안은 클래스를 꾸준하게 접한다. 왜일까?

소프트웨어를 돌아가게 만드는 활동과 소프트웨어를 깨끗하게 만다는 활동은 완전히 별개다. 우리들 대다수는 두뇌 용량에 한계가 있어 "깨끗하고 체계적인 소프트웨어"보다 "돌아가는 소프트웨어"에 초점을 맞춘다. 전적으로 올바른 태도다. 관심사를 분리하는 작업은 프로그램만이 아니라 프로그래밍 활동에서도 마찬가지로 중요하다.
문제는 우리들 대다수가 프로그램이 돌아가면 일이 끝났다고 여기는 데 있다. "깨끗하고 체계적인 소프트웨어"라는 다음 관심사로 전환하지 않는다. 프로그램으로 되돌아가 만능 클래스를 단일 책임 클래스 여럿으로 분리하는 대신 다음 문제로 넘어가 버린다.

게다가 많은 개발자는 자잘한 단일 책임 클래스가 많아지면 큰 그림을 이해하기 어려워진다고 우려한다. 큰 그림을 이해하려면 이 클래스 저 클래스 수없이 넘나들어야 한다고 걱정한다. 하지만 작은 클래스가 많은 시스템이든 큰 클래스가 몇 개뿐인 시스템이든 돌아가는 부품은 그 수가 비슷하다. 어느 시스템이든 익힐 내용은 그 양이 유사하다. 그러므로 고민할 질문은 다음과 같다. "도구 상자를 어떻게 관리하고 싶은가?" 작은 서랍을 많이 두고서 기능과 이름이 명확한 컴포넌트를 나눠 넣고 싶은가? 아니면 큰 서랍 몇 개를 두고서 모두를 던져 넣고 싶은가?"

규모가 어느 수준에 익르는 시스템은 논리가 많고도 복잡하다. 이런 복잡성을 다루려면 체계적인 정리가 필수적이다. 그래야 개발자가 무엇이 어디에 있는지 찾는다. 그래야 (변경을 가할 때) 직접 영향이 미치는 컴포넌트만 이애하면 충분하다. 큼직한 다목적 클래스 몇 개로 이뤄진 시스템은 (변경을 가할 때) 당장 알 필요가 없는 사실까지 들이밀어 독자를 방해한다.

강조하는 차원에서 한 번 더 말하겠다. 큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직하다. 작은 클래스는 각각 책임이 하나이며, 변경할 이유가 하나이며, 다른 작은 클래스와 협력해 시스템에 필요한 동작을 수행한다.