트랜잭션
기존의 MTS 환경에서와 마찬가지 로 COM+ 환경에서도 컴포넌트 수준에서 분산 트랜잭션에 쉽게 참여할 수 있다. MTS에서 분산 트랜잭션 처리를 마이크로소프트 분 산 트랜잭션 조정자(DTC)를 통해 처리했듯이 COM+ 환경 역시 동일한 방법으로 분산 트랜잭션을 처리한다. 마이크로소프트는 트랜 잭션을 처리하기 위해 객체 지향 개념의 two-phase 커밋을 지원하는 OLE 트랜잭션을 설계하였으며 MS DTC로 하여금 수행 하게 만들었다. 최초의 MS DTC는 마이크로소프트 SQL 서버의 한 제품으로 공급됐으나 현재는 다양한 트랜잭션 처리를 위한 기 본 시스템으로 윈도우 2000에 통합시켜 공급하고 있다.
보통 트랜잭션은 중요한 작업(트랜잭션을 사용해 안정적으 로 처리될 필요가 있는)시 시작되며, 애플리케이션은 트랜잭션을 MS DTC와 같은 트랜잭션 관리자에게 전달함으로써 실제 트랜잭션 을 시작한다. MS DTC는 트랜잭션에 참여하고 있는 다양한 리소스 관리자에게 각각의 트랜잭션을 수행하게 하며 성공여부에 따라 전 체적인 커밋을 할지 롤백을 할지를 결정한다. 여기서 언급하는 리소스 관리자는 SQL 서버와 같이 OLE 트랜잭션 스펙을 지원하 는 서비스 전체를 의미한다. 전형적으로 트랜잭션은 데이터베이스 액세스에 주로 사용되었지만 절대 트랜잭션 처리가 데이터베이스에 제한 되어 있지는 않다. OLE 트랜잭션을 지원하는 어떠한 서비스도 MS DTC 트랜잭션에 참여할 수 있다. 단적인 예로 MSMQ 역 시 OLE 트랜잭션을 지원하므로 분산 트랜잭션에 참여 가능하다.
COM+는 기본적으로 두 개의 리소스 분배기 (Dispenser)인 OD BC 드라이버 매니저와 공유 프로퍼티 매니저를 제공한다. ODBC 드라이버 매니저는 COM+ 컴포넌트 를 위해 데이터베이스 연결에 대한 풀링을 제공한다. 데이터베이스 연결 풀링에 관한 자세한 내용은 ‘MTS 프로그래밍의 다섯 가 지 규칙, 서버의 자원관리’ 부분을 참조하기 바란다. COM+ SDK를 사용하면 기본적인 리소스 분배기 외에 추가로 필요한 분배기 를 제작할 수 있다.
클라이언트 애플리케이션 입장에서 바라보면 리소스 관리자는 전체 트랜잭션에 참여하는 하나의 구성 요소 이지만, 리소스 관리자 역시 그 자체가 트랜잭션 관리자로서의 역할을 수행해야 한다. 클라이언트 애플리케이션에서 트랜잭션에 대 한 커밋 또는 롤백을 지시해야 트랜잭션은 종료된다. 만약 롤백이 요구됐다면 MS DTC는 트랜잭션에 참여하고 있는 모든 리소스 관 리자에게 트랜잭션에 참여하면서 진행했던 모든 작업을 롤백하라고 명령할 것이다. 각각의 리소스 관리자는 정확한 롤백 작업을 수행 할 책임이 있다. 만약 클라이언트가 커밋 또는 롤백하기 전에 오류로 죽는다면 MS DTC는 자동으로 전체 트랜잭션을 롤백한다.
클 라이언트가 트랜잭션이 커밋되도록 요청한다면 MS DTC는 트랜잭션 작업 중에 발생한 모든 변화를 커밋하기 위해 two- phase 커밋 프로토콜을 실행한다. 첫 단계로 MS DTC는 트랜잭션에 참여하고 있는 모든 리소스 관리자에게 커밋 작업에 동의하 는 지를 결정하기 위해 질문을 던진다. 질문에 답하지 않거나 커밋에 동참할 수 없다라고 응답하는 리소스 관리자가 하나라도 있으 면, MS DTC는 모든 리소스 관리자에게 트랜잭션을 취소하라고 명령하며 각 리소스 매니저는 롤백 작업을 진행할 것이다.
롤기반 보안
COM+ 보 안 모델은 윈도우 2000 보안 모델을 기본으로 하지만, 보다 쉬운 사용을 위해 두 가지 형태, 선언적(declarative) 보 안과 프로그래밍 가능한 보안을 지원한다. COM+ 보안 메커니즘의 핵심은 롤(role)의 개념을 정확히 이해하는데 있다. 롤은 대 다수 CO M+ 객체에 의해 사용되어지며 매우 유연하고, 선언적인 보안 모델의 중심에 서 있으며, 논리적 사용자 그룹(윈도 우 2000의 사용자 그룹과 유사한 개념)을 구분하는 이름이다. COM+ 객체가 시스템에 설치되어 사용될 때, 관리자는 롤을 생성 한 후 특별한 사용자 또는 사용자 그룹을 해당 롤에 포함시킨다. 그 다음 관리자는 설치된 컴포넌트에 대해 어떠한 롤을 사용할 지 를 결정한다. 기본적으로 컴포넌트 수준에서 롤을 결정할 수 있으며, 또한 컴포넌트가 제공하는 인터페이스 별로 롤을 지정할 수도 있 다. 이러한 선언적 방법은 컴포넌트 소스 코드를 전혀 수정하지 않고 컴포넌트를 설치하고 운영하는 관리자 수준에서 아주 쉽게 다양 한 보안을 제공할 수 있다.
때때로 선언적 보안만으로 처리하기 힘든 경우가 발생한다. 예를 들어 나이가 20살 이상 인 회원에 대해서만 해당 메쏘드를 실행시키길 원한다면 위의 선언적 보안으로 처리하기는 불가능하다. 이때는 COM+ 객체를 개발하 는 단계(소스 코드 작성 단계)에서 프로그램 로직으로 구현해야 한다. COM+ 보안 모델은 프로그램 상에서도 쉽게 롤을 사용 할 수 있는 여러 API를 제공한다.
결론
기존의 MTS 환경에서와 마찬가지 로 COM+ 환경에서도 컴포넌트 수준에서 분산 트랜잭션에 쉽게 참여할 수 있다. MTS에서 분산 트랜잭션 처리를 마이크로소프트 분 산 트랜잭션 조정자(DTC)를 통해 처리했듯이 COM+ 환경 역시 동일한 방법으로 분산 트랜잭션을 처리한다. 마이크로소프트는 트랜 잭션을 처리하기 위해 객체 지향 개념의 two-phase 커밋을 지원하는 OLE 트랜잭션을 설계하였으며 MS DTC로 하여금 수행 하게 만들었다. 최초의 MS DTC는 마이크로소프트 SQL 서버의 한 제품으로 공급됐으나 현재는 다양한 트랜잭션 처리를 위한 기 본 시스템으로 윈도우 2000에 통합시켜 공급하고 있다.
보통 트랜잭션은 중요한 작업(트랜잭션을 사용해 안정적으 로 처리될 필요가 있는)시 시작되며, 애플리케이션은 트랜잭션을 MS DTC와 같은 트랜잭션 관리자에게 전달함으로써 실제 트랜잭션 을 시작한다. MS DTC는 트랜잭션에 참여하고 있는 다양한 리소스 관리자에게 각각의 트랜잭션을 수행하게 하며 성공여부에 따라 전 체적인 커밋을 할지 롤백을 할지를 결정한다. 여기서 언급하는 리소스 관리자는 SQL 서버와 같이 OLE 트랜잭션 스펙을 지원하 는 서비스 전체를 의미한다. 전형적으로 트랜잭션은 데이터베이스 액세스에 주로 사용되었지만 절대 트랜잭션 처리가 데이터베이스에 제한 되어 있지는 않다. OLE 트랜잭션을 지원하는 어떠한 서비스도 MS DTC 트랜잭션에 참여할 수 있다. 단적인 예로 MSMQ 역 시 OLE 트랜잭션을 지원하므로 분산 트랜잭션에 참여 가능하다.
COM+는 기본적으로 두 개의 리소스 분배기 (Dispenser)인 OD BC 드라이버 매니저와 공유 프로퍼티 매니저를 제공한다. ODBC 드라이버 매니저는 COM+ 컴포넌트 를 위해 데이터베이스 연결에 대한 풀링을 제공한다. 데이터베이스 연결 풀링에 관한 자세한 내용은 ‘MTS 프로그래밍의 다섯 가 지 규칙, 서버의 자원관리’ 부분을 참조하기 바란다. COM+ SDK를 사용하면 기본적인 리소스 분배기 외에 추가로 필요한 분배기 를 제작할 수 있다.
클라이언트 애플리케이션 입장에서 바라보면 리소스 관리자는 전체 트랜잭션에 참여하는 하나의 구성 요소 이지만, 리소스 관리자 역시 그 자체가 트랜잭션 관리자로서의 역할을 수행해야 한다. 클라이언트 애플리케이션에서 트랜잭션에 대 한 커밋 또는 롤백을 지시해야 트랜잭션은 종료된다. 만약 롤백이 요구됐다면 MS DTC는 트랜잭션에 참여하고 있는 모든 리소스 관 리자에게 트랜잭션에 참여하면서 진행했던 모든 작업을 롤백하라고 명령할 것이다. 각각의 리소스 관리자는 정확한 롤백 작업을 수행 할 책임이 있다. 만약 클라이언트가 커밋 또는 롤백하기 전에 오류로 죽는다면 MS DTC는 자동으로 전체 트랜잭션을 롤백한다.
클 라이언트가 트랜잭션이 커밋되도록 요청한다면 MS DTC는 트랜잭션 작업 중에 발생한 모든 변화를 커밋하기 위해 two- phase 커밋 프로토콜을 실행한다. 첫 단계로 MS DTC는 트랜잭션에 참여하고 있는 모든 리소스 관리자에게 커밋 작업에 동의하 는 지를 결정하기 위해 질문을 던진다. 질문에 답하지 않거나 커밋에 동참할 수 없다라고 응답하는 리소스 관리자가 하나라도 있으 면, MS DTC는 모든 리소스 관리자에게 트랜잭션을 취소하라고 명령하며 각 리소스 매니저는 롤백 작업을 진행할 것이다.
롤기반 보안
COM+ 보 안 모델은 윈도우 2000 보안 모델을 기본으로 하지만, 보다 쉬운 사용을 위해 두 가지 형태, 선언적(declarative) 보 안과 프로그래밍 가능한 보안을 지원한다. COM+ 보안 메커니즘의 핵심은 롤(role)의 개념을 정확히 이해하는데 있다. 롤은 대 다수 CO M+ 객체에 의해 사용되어지며 매우 유연하고, 선언적인 보안 모델의 중심에 서 있으며, 논리적 사용자 그룹(윈도 우 2000의 사용자 그룹과 유사한 개념)을 구분하는 이름이다. COM+ 객체가 시스템에 설치되어 사용될 때, 관리자는 롤을 생성 한 후 특별한 사용자 또는 사용자 그룹을 해당 롤에 포함시킨다. 그 다음 관리자는 설치된 컴포넌트에 대해 어떠한 롤을 사용할 지 를 결정한다. 기본적으로 컴포넌트 수준에서 롤을 결정할 수 있으며, 또한 컴포넌트가 제공하는 인터페이스 별로 롤을 지정할 수도 있 다. 이러한 선언적 방법은 컴포넌트 소스 코드를 전혀 수정하지 않고 컴포넌트를 설치하고 운영하는 관리자 수준에서 아주 쉽게 다양 한 보안을 제공할 수 있다.
때때로 선언적 보안만으로 처리하기 힘든 경우가 발생한다. 예를 들어 나이가 20살 이상 인 회원에 대해서만 해당 메쏘드를 실행시키길 원한다면 위의 선언적 보안으로 처리하기는 불가능하다. 이때는 COM+ 객체를 개발하 는 단계(소스 코드 작성 단계)에서 프로그램 로직으로 구현해야 한다. COM+ 보안 모델은 프로그램 상에서도 쉽게 롤을 사용 할 수 있는 여러 API를 제공한다.
결론
‘휴’ 라는 한숨이 절로 나온다. 나날이 변화하는 환경 에 과연 적응할 수 있을까? 오래전 골방에서 C언어를 사용해 DOS 환경에서 수행되는 애플리케이션을 만들던 시절, 아니 좀더 시간 이 지나 피땀 흘려 C++를 익힌후 볼랜드의 OWL(Object Windows Library)을 사용해 윈도우 3.1용 애플리케이 션을 만들던 시절이 그리워진다. 그 시절의 마소를 펼쳐보았다. 멀티쓰레딩, 트랜잭션, 분산 처리라는 말은 아무리 눈을 씻고 찾아봐 도 볼 수 없었다. 물론 그때의 마소 토픽은 그 당시 컴퓨팅 환경에서 최고의 이슈였겠지만 지금 뒤돌아보면 너무도 간단하고 명료 한 문제를 가지고 고민했었구나라는 생각이 든다. 과연 수년 후 현재의 분산 환경을 뒤돌아 볼 때 이러한 생각이 들까? 필자는 향후 에도 현재의 고민을 계속해야만 할 것 같은 불길(?)한 예감이 든다. 분산 환경은 단지 컴퓨터 공학에 국한된 문제가 아니라, 인간 이 살아가는 방식에 관한 시스템적 접근에 대한 문제이기 때문이다.
DCOM, MTS, MSMQ 등의 출현으로 과거 에 비해 분산 환경을 꾸미기가 좀더 편리해졌다는 것 외에 달라진 건 없다. 아마 미래에는 보다 쉽고 강력한 도구가 만들어져 현재보 다 좀 더 편하게 된다는 것 외에 쉬워진건 하나도 없을 것이다. 우리의 삶의 방식 역시 지금보다 훨씬 더 복잡해질 것이고, 이들 을 시스템으로 표현하기 위해서는 지금보다 더 많은 고민을 해야할지도 모른다.
필자 역시 다음 프로젝트는 COM+ 기반의 검색 엔진 솔루션을 개발할 계획이다. 벌써부터 데이터 검색이라는 작업을 어떻게 효율적으로 여러 컴퓨터에 분산시키며, 다른 트랜잭션과 연동시킬 수 있을까라는 생각으로 머리가 복잡하다.
필자 연락처 : khkim97@shinbiro.com
정리 : 강경수 elegy@sbmedia.co.kr
--------------------------------------------------------------------------------
MTS 프로그래밍의 다섯 가지 규칙
MTS 에서 비롯된 COM 프로그래밍 모델의 변화는 크게 5가지로 나눠 생각할 수 있다. MTS 컴포넌트를 사용하는 클라이언트에는 큰 변 화가 없는 대신 서버에 제한된 변화이며, MTS의 성능을 최대화시키기 위한 방법으로 MTS 애플리케이션 개발자는 반드시 이 규칙 을 따라야 한다.
서버는 SetComplete를 최대한 많이 호출해야 한다. 이것은 서버가 더 이상 유지해야 할 상 태를 갖지 않는 것을 의미한다. 이렇게 함으로써 많은 수의 클라이언트에 대해 효율적인 서비스를 제공할 수 있다. 클라이언트는 되도 록 COM 개체의 인터페이스를 빨리 얻고 지속적으로 유지해 줘야 한다. 비록 당장 COM 개체를 사용하지 않더라도 먼저 인터페이스 를 얻어야 한다. 일반적으로 객체에 대한 참조를 얻는 것은 많은 리소스를 요구하지만 MTS를 이용하면 상태를 갖지 않는 객체에 대 한 참조를 유지하는 데는 전혀 자원이 필요치 않다. 서버가 사용하는 데이터베이스 연결과 같은 자원은 최대한 늦게 할당받는다. 그리 고 사용 후 신속히 반납해야 한다. MTS는 이러한 자원을 얻는 과정을 좀더 효율적으로 처리하게 해준다. 서버는 롤과 선언적 보안 을 사용해야 한다. 기존의 개인 정보와 ACL을 사용한 보안 정책은 확장성이 좋지 않다. 서버는 적절한 시기면 언제나 트랜잭션 을 사용해야 한다. SetComplete를 최대한 자주 호출하라
클라이언트가 바라보는 MTS 컴포넌트는 단지 일반적 인 COM 컴포넌트와 차이가 없지만 컴포넌트 서버는 많은 차이를 보인다. <그림 1>에서 보는 것처럼 MTS 컴포넌트 는 클라이언트와 직접 연결되어 있지 않고 MTS 실행부를 통과한다. 클라이언트가 MTS 컴포넌트를 생성하기 위 해 CoCreateInstance와 같은 API를 호출하면 MTS 실행부는 이를 가로채 특별한 부가 작업을 수행한다. 이들 부 가 작업 중 가장 중요한 것은 컨텍스트 객체를 생성한다는 것이다. 이 컨텍스트 객체를 통해 MTS 컴포넌트와 MTS 실행부는 통신 을 하게 된다. 컨텍스트 객체가 제공하는 IObjectContext 인터페이스가 제공하는 메쏘드 중 에 SetComplete, SetAbort가 있으며 호출되면 MTS 실행부는 중요한 몇 가지 작업을 수행한다. 트랜잭션 수행 시 이 메쏘드가 호출되면 트랜잭션을 커밋하거나 롤백한다. 트랜잭션을 사용하지 않을 경우도 이 메쏘드를 호출할 수 있으며, 그 경 우 MTS 실행부에게 더 이상 MTS 객체는 유지할 상태가 없다는 것을 알려준다.
객체가 더 이상 유지할 상태가 없 다는 것은 더 이상 객체가 존재할 필요가 없다는 의미다. 객체가 다시 필요하게 되면 새로운 인스턴스를 생성한다. 객체가 필요 없 을 시 제거하면 그만큼 서버 메모리 사용은 줄어든다. 이렇게 객체를 삭제했다가 필요시 다시 생성하는 일련의 작업은 클라이언트가 전 혀 알아채지 못하게 MTS 실행부가 수행한다. 이러한 동작이 가능하도록 MTS 실행부는 <그림 2>와 같이 COM 객체 를 랩퍼(wrapper) 객체로 감싸고 있다, SetComplete 호출시 MTS는 <그림 3>과 같이 실제 MTS 객 체는 릴리즈하고 다만 랩퍼만 유지한다. 클라이언트 입장에서 보면 실제 MTS 객체를 참조하는 것이 아니라 랩퍼를 참조하고 있는 상 태이므로 어떠한 변화도 감지하지 못한다. 클라이언트가 다시 이 객체의 메쏘드를 호출하면 MTS는 객체를 다시 생성하기 위해 클래 스 팩토리를 사용하게 된다. 객체가 생성되면 클라이언트의 호출을 전달해 준다. 이러한 일련의 동작을 JIT(Just-In- Time) 실행이라고 하며 <그림 2>의 상태로 복원시켜 준다. 객체는 어떠한 상태도 유지하고 있을 필요가 없으므로 새 롭게 생성된 객체는 그 전의 객체와 구분할 수 없다. 따라서 가능한 자주 SetComplete 함수를 호출해 MTS에서 더 이 상 필요 없는 객체를 제공하게 해야한다.
인터페이스 포인터를 빨리 얻고 유지하라
일반적 인 COM, DCOM 프로그램에서 클라이언트가 지금 당장 필요 없는 객체를 생성하고 이에 대한 인터페이스 포인터를 유지하고 있 는 것은 그리 바람직한 상황은 아니다. 왜냐면 사용되지 않는 객체를 위해 필요 없는 메모리를 더 쓰고 있기 때문이다. 그러 나 MTS 환경에서는 상태가 없는 객체는 즉시 메모리에서 삭제되므로 굳이 클라이언트가 객체에 대한 참조를 릴리즈할 필요가 없다.
MTS 는 클라이언트에서 보이지 않기 때문에 일반적인 COM이라고 생각할 수도 있지만, 간혹 클라이언트가 MTS 객체의 메쏘드를 호출 할 때 주의해야할 사항이 있다. 예를 들어 프로퍼티에 특정 값을 지정하고 SetComplete가 포함돼있는 메쏘드를 호출한 후 프 로퍼티 값을 읽는다고 가정하자. SetComplete를 호출하므로 객체는 메모리에서 제거되어 프로퍼티에 지정한 값 역시 사라질 것 이다. 이러한 문제를 해결할 수 있는 유일한 방법은 클라이언트가 컴포넌트에 대해 자세히 아는 것이다. 어떤 메쏘드 가 SetComplete를 호출하는지 SetAbort를 호출하는지에 대한 사전 지식이 있어야 한다.
서버의 자원 관리
일 반적으로 데이터베이스에 대한 ODBC 연결 등의 서버 자원을 얻어야하는 경우 많은 시간이 소모된다. 그러므로 보통 COM 개발자 는 이와 같은 자원을 가능하면 초기에 얻고 객체가 종료될 때 반환한다. 그러나 이러한 방식은 속도는 빨라질지 몰라도 컴포넌트를 사 용하는 클라이언트 숫자가 늘어난다면, ODBC 연결은 유한한 시스템 자원이므로 얻지 못하는 클라이언트가 발생할 것이다. 그렇다 고 필요시 연결하고 사용 즉시 반납한다면 그만큼 수행 속도는 많이 느려질 것이다.
MTS 자원 분배기는 이러한 문제 를 효율적으로 해결해준다. MTS에서 현재 가장 중요한 자원 분배기는 ODBC 연결 관리기로 사용 가능한 ODBC 연결 풀 (pool)을 관리해준다. MTS 객체가 데이터베이스 연결을 요청하면 자원 분배기는 풀에 있는 연결을 제공해 주며, 객체가 연결 을 해제하면 다시 자원 분배기는 그 연결을 풀에 돌려준다.
실제 데이터베이스 연결에 관한 자원은 생성되거나 삭제되 지 않으므로 처리 속도는 훨씬 빨라지게 된다. 따라서 MTS 컴포넌트를 제작할 때는 이러한 특성을 고려해서 메쏘드 호출시 연결 을 수행하고 데이터를 처리한 뒤 바로 연결을 반납하게 만든다. 이렇게 함으로써 한정된 자원인 ODBC 연결을 여러 클라이언트가 공 유하므로 많은 클라이언트 처리가 가능해진다.
서버 롤과 선언적 보안 사용
클라이언트가 COM 객체에 서 메쏘드를 호출할 때 그 객체는 현재 자신을 호출하는 클라이언트가 이 메쏘드를 실행할 권한이 있는지 확인해야 한다. 가장 일반적 인 방법으로는 클라이언트 개인 정보를 확인하는 서버 쓰레드가 존재해서 클라이언트가 자원을 사용할 때 처리해주는 동작을 하는 것이 다. 윈도우 NT 서버의 경우 자원의 ACL이 자동으로 체크되기 때문에 프로그래머가 이에 대한 처리를 해줄 필요가 없다.
그 러나 이러한 접근 방법은 원하는 결과를 정확히 얻기가 어렵고 확장성이 좋지 않다. 그래서 MTS는 선언적 보안이라는 새로운 방법 을 제공하고 있다. 선언적 보안은 롤이라는 개념에 기반을 두고 있으며, 롤은 단지 윈도우 NT 서버의 사용자, 그룹의 모임이며 유 일한 이름을 가진다. MTS 관리자는 MTS 관리 툴을 이용해 각 사용자와 그룹이 어떤 롤에 속하는지 지정한다. 롤이 지정되면 관 리자는 각 롤이 어떠한 MTS 컴포넌트를 사용할 수 있는지 지정할 수 있으며, 컴포넌트의 각 인터페이스에 대해 세부 권한을 지정 할 수 있다.
이와 같이 일단 롤을 지정해주면 추가적인 프로그램 코드의 사용 없이 쉽게 보안 메커니즘을 구현 할 수 있다. 물론 보다 복잡한 보안을 처리하기 위해 프로그램적 보안 방법 역시 가능하다. IObjectContext가 제공하 는 IsCallerInRole 메쏘드를 사용해 호출자가 어떤 롤에 속하는지 알 수 있으므로 보다 세밀한 제어가 가능하다.
서버 트랜잭션 사용
MTS 는 트랜잭션 처리 기능보다는 분산 컴포넌트의 효율적 수행 환경에 보다 초점이 맞춰져 있다고 많은 사람들이 생각하고 있다. 그래 서 혹자는 ‘이름을 잘못 지었다’고 이야기하곤 한다. 그러나 트랜잭션 처리 역시 MTS의 중요한 기능이므로 완전한 이해를 통해 적 재적소에 사용해야 한다.
하나의 데이터베이스에 대한 트랜잭션은 데이터베이스 자체로 충분히 처리가 가능하지만 둘 이상 의 데이터베이스에 걸친 트랜잭션 처리 및 다른 애플리케이션이 포함된 트랜잭션 처리 작업은 쉽지 않다. MTS는 이러한 이질적 시스 템에 대한 분산 트랜잭션을 지원하므로 아주 쉽게 처리할 수 있다. 또한 컴포넌트 모델과 트랜잭션 모델을 통합시켰으므로 클라이언트 는 트랜잭션에 대한 어떠한 고려를 하지 않아도 된다.
컴포넌트를 제작할 때 트랜잭션에 대해 충분히 고려한다면 설 계 단계에서부터 완전히 새롭게 구상해야 한다. 가장 활용도를 높게 하기 위해서는 각 컴포넌트를 분리된 업무 단위로 캡슐화할 필요 가 있다. 이렇게 하면 각 컴포넌트 사이의 트랜잭션 연결을 쉽게 처리할 수 있다.
http://blog.naver.com/saga111/120008481356
DCOM, MTS, MSMQ 등의 출현으로 과거 에 비해 분산 환경을 꾸미기가 좀더 편리해졌다는 것 외에 달라진 건 없다. 아마 미래에는 보다 쉽고 강력한 도구가 만들어져 현재보 다 좀 더 편하게 된다는 것 외에 쉬워진건 하나도 없을 것이다. 우리의 삶의 방식 역시 지금보다 훨씬 더 복잡해질 것이고, 이들 을 시스템으로 표현하기 위해서는 지금보다 더 많은 고민을 해야할지도 모른다.
필자 역시 다음 프로젝트는 COM+ 기반의 검색 엔진 솔루션을 개발할 계획이다. 벌써부터 데이터 검색이라는 작업을 어떻게 효율적으로 여러 컴퓨터에 분산시키며, 다른 트랜잭션과 연동시킬 수 있을까라는 생각으로 머리가 복잡하다.
필자 연락처 : khkim97@shinbiro.com
정리 : 강경수 elegy@sbmedia.co.kr
--------------------------------------------------------------------------------
MTS 프로그래밍의 다섯 가지 규칙
MTS 에서 비롯된 COM 프로그래밍 모델의 변화는 크게 5가지로 나눠 생각할 수 있다. MTS 컴포넌트를 사용하는 클라이언트에는 큰 변 화가 없는 대신 서버에 제한된 변화이며, MTS의 성능을 최대화시키기 위한 방법으로 MTS 애플리케이션 개발자는 반드시 이 규칙 을 따라야 한다.
서버는 SetComplete를 최대한 많이 호출해야 한다. 이것은 서버가 더 이상 유지해야 할 상 태를 갖지 않는 것을 의미한다. 이렇게 함으로써 많은 수의 클라이언트에 대해 효율적인 서비스를 제공할 수 있다. 클라이언트는 되도 록 COM 개체의 인터페이스를 빨리 얻고 지속적으로 유지해 줘야 한다. 비록 당장 COM 개체를 사용하지 않더라도 먼저 인터페이스 를 얻어야 한다. 일반적으로 객체에 대한 참조를 얻는 것은 많은 리소스를 요구하지만 MTS를 이용하면 상태를 갖지 않는 객체에 대 한 참조를 유지하는 데는 전혀 자원이 필요치 않다. 서버가 사용하는 데이터베이스 연결과 같은 자원은 최대한 늦게 할당받는다. 그리 고 사용 후 신속히 반납해야 한다. MTS는 이러한 자원을 얻는 과정을 좀더 효율적으로 처리하게 해준다. 서버는 롤과 선언적 보안 을 사용해야 한다. 기존의 개인 정보와 ACL을 사용한 보안 정책은 확장성이 좋지 않다. 서버는 적절한 시기면 언제나 트랜잭션 을 사용해야 한다. SetComplete를 최대한 자주 호출하라
클라이언트가 바라보는 MTS 컴포넌트는 단지 일반적 인 COM 컴포넌트와 차이가 없지만 컴포넌트 서버는 많은 차이를 보인다. <그림 1>에서 보는 것처럼 MTS 컴포넌트 는 클라이언트와 직접 연결되어 있지 않고 MTS 실행부를 통과한다. 클라이언트가 MTS 컴포넌트를 생성하기 위 해 CoCreateInstance와 같은 API를 호출하면 MTS 실행부는 이를 가로채 특별한 부가 작업을 수행한다. 이들 부 가 작업 중 가장 중요한 것은 컨텍스트 객체를 생성한다는 것이다. 이 컨텍스트 객체를 통해 MTS 컴포넌트와 MTS 실행부는 통신 을 하게 된다. 컨텍스트 객체가 제공하는 IObjectContext 인터페이스가 제공하는 메쏘드 중 에 SetComplete, SetAbort가 있으며 호출되면 MTS 실행부는 중요한 몇 가지 작업을 수행한다. 트랜잭션 수행 시 이 메쏘드가 호출되면 트랜잭션을 커밋하거나 롤백한다. 트랜잭션을 사용하지 않을 경우도 이 메쏘드를 호출할 수 있으며, 그 경 우 MTS 실행부에게 더 이상 MTS 객체는 유지할 상태가 없다는 것을 알려준다.
객체가 더 이상 유지할 상태가 없 다는 것은 더 이상 객체가 존재할 필요가 없다는 의미다. 객체가 다시 필요하게 되면 새로운 인스턴스를 생성한다. 객체가 필요 없 을 시 제거하면 그만큼 서버 메모리 사용은 줄어든다. 이렇게 객체를 삭제했다가 필요시 다시 생성하는 일련의 작업은 클라이언트가 전 혀 알아채지 못하게 MTS 실행부가 수행한다. 이러한 동작이 가능하도록 MTS 실행부는 <그림 2>와 같이 COM 객체 를 랩퍼(wrapper) 객체로 감싸고 있다, SetComplete 호출시 MTS는 <그림 3>과 같이 실제 MTS 객 체는 릴리즈하고 다만 랩퍼만 유지한다. 클라이언트 입장에서 보면 실제 MTS 객체를 참조하는 것이 아니라 랩퍼를 참조하고 있는 상 태이므로 어떠한 변화도 감지하지 못한다. 클라이언트가 다시 이 객체의 메쏘드를 호출하면 MTS는 객체를 다시 생성하기 위해 클래 스 팩토리를 사용하게 된다. 객체가 생성되면 클라이언트의 호출을 전달해 준다. 이러한 일련의 동작을 JIT(Just-In- Time) 실행이라고 하며 <그림 2>의 상태로 복원시켜 준다. 객체는 어떠한 상태도 유지하고 있을 필요가 없으므로 새 롭게 생성된 객체는 그 전의 객체와 구분할 수 없다. 따라서 가능한 자주 SetComplete 함수를 호출해 MTS에서 더 이 상 필요 없는 객체를 제공하게 해야한다.
인터페이스 포인터를 빨리 얻고 유지하라
일반적 인 COM, DCOM 프로그램에서 클라이언트가 지금 당장 필요 없는 객체를 생성하고 이에 대한 인터페이스 포인터를 유지하고 있 는 것은 그리 바람직한 상황은 아니다. 왜냐면 사용되지 않는 객체를 위해 필요 없는 메모리를 더 쓰고 있기 때문이다. 그러 나 MTS 환경에서는 상태가 없는 객체는 즉시 메모리에서 삭제되므로 굳이 클라이언트가 객체에 대한 참조를 릴리즈할 필요가 없다.
MTS 는 클라이언트에서 보이지 않기 때문에 일반적인 COM이라고 생각할 수도 있지만, 간혹 클라이언트가 MTS 객체의 메쏘드를 호출 할 때 주의해야할 사항이 있다. 예를 들어 프로퍼티에 특정 값을 지정하고 SetComplete가 포함돼있는 메쏘드를 호출한 후 프 로퍼티 값을 읽는다고 가정하자. SetComplete를 호출하므로 객체는 메모리에서 제거되어 프로퍼티에 지정한 값 역시 사라질 것 이다. 이러한 문제를 해결할 수 있는 유일한 방법은 클라이언트가 컴포넌트에 대해 자세히 아는 것이다. 어떤 메쏘드 가 SetComplete를 호출하는지 SetAbort를 호출하는지에 대한 사전 지식이 있어야 한다.
서버의 자원 관리
일 반적으로 데이터베이스에 대한 ODBC 연결 등의 서버 자원을 얻어야하는 경우 많은 시간이 소모된다. 그러므로 보통 COM 개발자 는 이와 같은 자원을 가능하면 초기에 얻고 객체가 종료될 때 반환한다. 그러나 이러한 방식은 속도는 빨라질지 몰라도 컴포넌트를 사 용하는 클라이언트 숫자가 늘어난다면, ODBC 연결은 유한한 시스템 자원이므로 얻지 못하는 클라이언트가 발생할 것이다. 그렇다 고 필요시 연결하고 사용 즉시 반납한다면 그만큼 수행 속도는 많이 느려질 것이다.
MTS 자원 분배기는 이러한 문제 를 효율적으로 해결해준다. MTS에서 현재 가장 중요한 자원 분배기는 ODBC 연결 관리기로 사용 가능한 ODBC 연결 풀 (pool)을 관리해준다. MTS 객체가 데이터베이스 연결을 요청하면 자원 분배기는 풀에 있는 연결을 제공해 주며, 객체가 연결 을 해제하면 다시 자원 분배기는 그 연결을 풀에 돌려준다.
실제 데이터베이스 연결에 관한 자원은 생성되거나 삭제되 지 않으므로 처리 속도는 훨씬 빨라지게 된다. 따라서 MTS 컴포넌트를 제작할 때는 이러한 특성을 고려해서 메쏘드 호출시 연결 을 수행하고 데이터를 처리한 뒤 바로 연결을 반납하게 만든다. 이렇게 함으로써 한정된 자원인 ODBC 연결을 여러 클라이언트가 공 유하므로 많은 클라이언트 처리가 가능해진다.
서버 롤과 선언적 보안 사용
클라이언트가 COM 객체에 서 메쏘드를 호출할 때 그 객체는 현재 자신을 호출하는 클라이언트가 이 메쏘드를 실행할 권한이 있는지 확인해야 한다. 가장 일반적 인 방법으로는 클라이언트 개인 정보를 확인하는 서버 쓰레드가 존재해서 클라이언트가 자원을 사용할 때 처리해주는 동작을 하는 것이 다. 윈도우 NT 서버의 경우 자원의 ACL이 자동으로 체크되기 때문에 프로그래머가 이에 대한 처리를 해줄 필요가 없다.
그 러나 이러한 접근 방법은 원하는 결과를 정확히 얻기가 어렵고 확장성이 좋지 않다. 그래서 MTS는 선언적 보안이라는 새로운 방법 을 제공하고 있다. 선언적 보안은 롤이라는 개념에 기반을 두고 있으며, 롤은 단지 윈도우 NT 서버의 사용자, 그룹의 모임이며 유 일한 이름을 가진다. MTS 관리자는 MTS 관리 툴을 이용해 각 사용자와 그룹이 어떤 롤에 속하는지 지정한다. 롤이 지정되면 관 리자는 각 롤이 어떠한 MTS 컴포넌트를 사용할 수 있는지 지정할 수 있으며, 컴포넌트의 각 인터페이스에 대해 세부 권한을 지정 할 수 있다.
이와 같이 일단 롤을 지정해주면 추가적인 프로그램 코드의 사용 없이 쉽게 보안 메커니즘을 구현 할 수 있다. 물론 보다 복잡한 보안을 처리하기 위해 프로그램적 보안 방법 역시 가능하다. IObjectContext가 제공하 는 IsCallerInRole 메쏘드를 사용해 호출자가 어떤 롤에 속하는지 알 수 있으므로 보다 세밀한 제어가 가능하다.
서버 트랜잭션 사용
MTS 는 트랜잭션 처리 기능보다는 분산 컴포넌트의 효율적 수행 환경에 보다 초점이 맞춰져 있다고 많은 사람들이 생각하고 있다. 그래 서 혹자는 ‘이름을 잘못 지었다’고 이야기하곤 한다. 그러나 트랜잭션 처리 역시 MTS의 중요한 기능이므로 완전한 이해를 통해 적 재적소에 사용해야 한다.
하나의 데이터베이스에 대한 트랜잭션은 데이터베이스 자체로 충분히 처리가 가능하지만 둘 이상 의 데이터베이스에 걸친 트랜잭션 처리 및 다른 애플리케이션이 포함된 트랜잭션 처리 작업은 쉽지 않다. MTS는 이러한 이질적 시스 템에 대한 분산 트랜잭션을 지원하므로 아주 쉽게 처리할 수 있다. 또한 컴포넌트 모델과 트랜잭션 모델을 통합시켰으므로 클라이언트 는 트랜잭션에 대한 어떠한 고려를 하지 않아도 된다.
컴포넌트를 제작할 때 트랜잭션에 대해 충분히 고려한다면 설 계 단계에서부터 완전히 새롭게 구상해야 한다. 가장 활용도를 높게 하기 위해서는 각 컴포넌트를 분리된 업무 단위로 캡슐화할 필요 가 있다. 이렇게 하면 각 컴포넌트 사이의 트랜잭션 연결을 쉽게 처리할 수 있다.
http://blog.naver.com/saga111/120008481356
'UP! > Web Service' 카테고리의 다른 글
SCTP (0) | 2008.08.21 |
---|---|
분산객체 시스템(COM,COm+,DCOM,MTS) 에 대한 개념 (0) | 2008.08.21 |
분산객체기술종류 (0) | 2008.08.21 |
웹 서비스 개념 및 교육 내용 (0) | 2008.08.21 |
Web Service (0) | 2008.08.21 |