2009년 7월 17일 금요일

EJB는 왜 사용하는가?

from : 차의중 prof21@empal.com

아래는 제가 모 회사의 개발자와 주고받은 메일의 내용입니다.
=============================== 1차 질문 =============================
From : 정**(won***@h*******.com)
To : prof21@empal.com
Sent : Friday, Jan 17, 2003 05:34 PM
Subject: JAVASERVICE에서 글을 보고서...

안녕하세요.

좋은 내용을 많이 올려 주셔서 감사합니다.
시스템 개발에서 고견을 구하고자 이렇게 메일을 보냅니다.
시스템 개발을 하려고 합니다.

기본 구성을 말씀드리면....

데이타 건수 : 1>1일 300만건

2>내용별로 60개 테이블에 분리

Transaction : 1>25000 건/1일 * 2개 TABLE
2>이 TABLE의 데이타을 가지고 메인트 작업이 발생합니다.(납품카드 발행,결과 메인트)
3>업무 집중 시간 : 08:00 ~ 10:00 약80~90% 진행
4>나머지 데이타는 주로 조회/엑셀저장 형태로 이루어 집니다.
5>사용자 700 * 1.5 업무 사용자

문제점 : 짧은 시간에 많은 사용자와 많은 업무 수행

기본 환경은 : UNIX, 0RACLE9, WAS(WEBSPHERE/WEBLOGIC)

** EJB 적용을 하였으면 하는데...

속도 및 안정적 서비스에 촛점을 둔다면 사용을 해야 할지요?
바쁘시지만 검토 후 회신을 부탁 드립니다.

============================= 답 ====================================

최근엔 제가 바빠서 글을 거의 못 올렸네요. '고견'이라고까지 표현해주시니 송구합니다. ^^a
EJB를 사용할까 말까의 문제에 관해 많은 분들이 오해를 하고 계신 것 같습니다.

EJB는 왜 필요할까요?
EJB는 "대규모이고 구조가 복잡한 분산 객체 환경"을 쉽게 구현하기 위해서 등장했습니다.
이것이 과거, 현재, 미래를 통틀어 EJB의 제 1 목표이고, 존재의 의미입니다.

따라서, EJB를 사용할 것인지 말 것인지에 앞서, 개발자들은 전체 아키텍쳐를 분산 객체 환경으로 가져갈 것인가 말 것인가를 고려해야 합니다. 만일, 분산 객체 환경이 필요 없다면, EJB를 써야 할 필요성의 70퍼센트는 감소됩니다.

그렇다면, 분산 환경은 왜 필요한걸까요?
분산 환경은 비즈니스 로직과 UI로직을 서로 다른 머신(또는 프로세스)로 분리시킴으로써 비즈니스 로직의 재사용성과 시스템 아키텍쳐의 유연성을 높이기 위해서 등장했습니다.
이 두 조건은 시스템이 커지고 복잡해질 수록 중요합니다. 그래서 대규모 시스템엔 분산 객체 아키텍쳐가 추천되는 것이고, 분산 객체 환경의 구축을 쉽게 하려다 보니 EJB와 같은 전용 플랫폼이
필요한 것입니다.

자, 그렇다면, EJB의 각 요소들과 기능들이 나오게 된 연유에 대해 좀 더 자세히 알아봅시다.

분산 환경을 쉽게 구현하게 하려다보니, RMI 가 필요합니다. 재사용성을 높이려다 보니 컴포넌트 형태가 적합합니다. 데이트 소스가 어떤 형태이든 간에 비즈니스 로직의 소스가 바뀌지 않게 하기 위해서는 비즈니스 로직 컴포넌트와 데이터베이스 접근 컴포넌트를 따로 나눌 필요가 있었습니다. 그래서 세션 빈이라는 것과 엔터티 빈이라는 것을 만들었습니다.

이들이 데이터베이스에 접근하는 컴포넌트이고, 만들기 쉽게, 재사용하기 쉽게 만들어야 하다보니
자연히 트랜잭션을 최대한 자동화할 필요가 생겼습니다. 그래서 트랜잭션 속성이란 걸 지정해서 트랜잭션을 관리하게 만들었습니다. 컴포넌트가 컴포넌트를 호출하다 보니, 컴포넌트 간에 트랜잭션을 전달하게 할 필요도 있습니다. 그래서, 그런 기능도 넣었습니다. 컴포넌트의 다양한 상태에 따라 사용자가 적절한 조치를 취할 수 있도록 콜백 메소드들도 넣었습니다. 자, 수정사항이 발생할 때마다 컴포넌트를 고치게 하는 것은 용이성, 재사용성의 규칙에 위배되므로, 굳이 로직으로 넣을 필요가 없는 것(비즈니스 로직이 아닌 것)은 설정파일에 담아, 소스 수정이 없이 설정만 하면 적용되도록 만들 필요가 있습니다. 그래서 배치 디스크립터란 설정 파일을 만들고, 그런 것들을 끌어
모아 몽땅 집어넣었습니다....etc....어라? UI 와 비즈니스 로직 컴포넌트 간에 네트웍을 통한 RMI 통신이 들어가고, 게다가 여러 개의 객체가 모여 하나의 컴포넌트를 이루며, 자동화를 위해 개발자 모르게 여러 로직을 실행시키게 하다 보니 이거 원 속도가 장난이 아니게 느리고, 자원을 지나치다 싶을 만큼 잡아먹습니다.
이렇게 무겁고 느린 걸 누가 삽니까. 자, 어떻게든 최대한 자원을 관리할 필요가 있습니다.
세션 빈을 상태유지 세션 빈과 무상태 세션 빈으로 나누고, 무상태 세션 빈 인스턴스는 풀링을 시켰습니다. 같은 맥락으로, 데이터 베이스 커넥션 풀링시키는 건 테크닉이라고 하기도 뭐할 만큼 일반적이며 필수적이므로 이 또한 포함시켰습니다.

자, 그럼 결론.

1. "속도를 위해 EJB를 사용한다?"

=> EJB의 여러 기능들은 "속도" 를 위해서 나온 것이 아니라, "분산 객체 환경" 에서 "개발유지보수의 편의성" 과 "시스템의 유연성"을 높이기 위해 고안되었습니다. "속도" 와 "개발유지보수편의성/시스템유연성"은 서로 반비례 그래프를 그리는 인자들입니다. "속도" 와 "편의성/유연성" 이 대치되어 이들 중 하나를 선택할 필요가 있을 때, EJB의 스펙이나 컨테이너 설계자들은 "편의성/유연성"을 택할것입니다.
따라서, 누군가가 "기능 구현을 위해 꼭 필요한 것은 아니지만, 속도를 높이기 위해 EJB를 끼워넣겠다" 라고 한다면 그는 EJB의 개발 의도를 잘못 이해한것이고, 따라서 심각한 오해를 하고 있다는 것을 말해두고 싶습니다.

2. "안정성을 위해 EJB를 사용한다?"

EJB는 이론적으로 안정성이 높습니다. 왜 그럴까요?

첫째 이유는, EJB가 좋은 프레임웍이기 때문입니다.
비즈니스 로직과 UI가 완전히 분리되어있으므로, 개발자들은 비즈니스 로직 담당자와 UI담당자로 나뉘게 됩니다. 각 개발자들의 관심의 범위가 1/2로 좁아지게 되는 만큼 이들은 각각의 영역에 대해 심리적, 지식적으로 2배만큼 전문화됩니다.
전문가들이 만든 코드는 일관성과 안정성을 갖게 되죠. 또한, 잦은 로직 수정 요구가 있더라도 보다 적은 부분을 수정함으로써, 짧은 시간에, 안정적으로 요구를 반영할 수 있습니다.
또한, EJB는 프로그래밍 상의 제한점을 많이 두었기 때문에(예를 들어 하나의 컴포넌트 인스턴스를 동시에 두 명의 사용자가 사용하지 못한다든지 하는...) 개발자의 실수를 미연에 방지하는 역할도 합니다. (안정성을 저해하는 가장 큰 요인은 설계/개발자의 무지와 OS 및 엔진 역할을 하는 소프트웨어의 버그 때문이라는 거 아시죠?)

둘째, EJB는 3계층의 미들티어에 위치하면서, 한정된 공유자원들 (예를 들어, 데이터 베이스 커넥션)을 효과적으로 관리해줍니다. 이것은 사용자가 많을 경우의 안정성에 지대한 영향을 미치는 요인입니다.

그러나, EJB를 끼워넣어야만 이것이 가능한 것은 아닙니다. 웹서버(WAS포함)와 데이터베이스만으로 이루어지는 구조에서, WAS 즉, 서블릿/JSP 엔진은 데이터베이스 커넥션 풀링이라든지 스레드 풀링등을 통해 나름대로 공유자원을 최대한 활용하는 메커니즘을 제공해 줍니다.

세째, 기본적으로 EJB가 들어가면, 머신은 WebServer단 + EJB 단 + DB 단으로 보통 3계층화 됩니다.
WebServer 단 + DB 단으로 이루어지는 2계층에 비해 머신이 1대 더 많죠. 즉, 한 대의 머신이 UI 와 비즈니스 로직을 모두 처리하는 대신, 두 대의 머신이 비즈니스 로직과 UI를 나눠서 처리하므로 2계층 환경에 비해 더 많은 사용자를 수용할 수 있습니다.

어라? 그럼, EJB서버로 쓸 예정이던 머신을 WebServer 머신으로 쓰고, 2개의 WebServer 머신을 클러스터링 시키면 어떨까?
네, 좋습니다. RMI 와 컴포넌트를 사용하지 않으므로, 같은 수의 사용자에 대해서 이 구조는 자원을 보다 덜 소모합니다. 이는 바꿔 말하면, 같은 양의 자원으로 보다 많은 사용자를 수용할 수 있다는 뜻입니다.
또한, WebServer + EJB 서버 각각 한 대로 된 구조는 클러스터링이 되어있지 않습니다.
클러스터링을 시키려면 각 티어마다 머신을 한 대씩 더 두어서 총 4대의 머신을 마련해야 하죠.
그러나, EJB를 안쓰면 웹서버 단이 두 대가 되므로 이들은 자연스레 클러스터링을 구성할 수 있습니다. 즉, 동일한 물리적 환경에서 이 구조는 페일오버가 된다는 얘기죠. 이렇게 보면, EJB를 쓰지 않은 구조는 오히려 훨씬 안정적인 아키텍쳐가 됩니다.


결론적으로, 분산 객체 환경이 필요하지 않다면, EJB를 쓰는 구조가 쓰지 않는 구조에 비해 갖는 이점은 "좋은 프레임웍을 제공" 한다는 것 뿐입니다.
 
일, 비즈니스 로직과 UI를 완전히 분리시킬 수 있는 좋은 프레임웍이 있다면 EJB를 사용하지 않고,
WebServer 티어 (아...물론, 이 글에서 WebServer 티어라 하는 것은 , JSP 와 서블릿을 포함하여 말합니다.
정확히 말하면, WebServer + WAS를 말한다는 거죠.) 에 모든 것을 두는 것이 안정성이 더욱 높습니다.


3. 더하여, "EJB는 배우기 쉽고, 사용하기 쉽다" 라는 말씀들을 많이 하시는데...그건, CORBA라든지 하는 다른 분산객체용 엔진에 비해 그렇다는 것입니다.
EJB를 능숙하게 사용하려면 적잖은 시간이 걸립니다. 한 일주일 교육받는 걸로 충분한 문제가 아니라는 거죠. 그렇다고, EJB에 대해 철저히 알지 못하고 사용하시는 것은 오히려 사용하지 않는 것만 못합니다.

이는 오히려 개발자의 무지로 인해 시스템의 안정성과 유지/보수의 용이성을 해치게 되죠. 그리고, 나중에 튜닝한다고 시간을 더 뺏기게 될 수도 있습니다. 필요한 만큼 머신을 구입할 수 있는 상황이 안되는 그런 경우에, 성능이 기대만큼 안 나오면 어쩔 수 없이 튜닝작업 들어가야 하지 않겠습니까? 아다시피, 어플리케이션의 정확한 속도는 테스트를 해봐야 아는 거고 보다 정확한 테스트는 개발이 어느 정도 완료된 후에야 할 수 있는 거죠. 그러다보니, 튜닝할 시간은 짧고, 그래서 꼼수에 꼼수를
더해가는 하는 거죠. 이거...쥐약이죠. 잘 만들어 놓은 어플리케이션을 끝에 가서 완전히 꼬아놓을 수도 있습니다. 흔히 말하는 "스파게티 소스" 가 되는거죠. 스파게티 소스에서 안정성을 기대할 수 있겠습니까? 절대 아니죠.

결론적으로, 님의 환경이 어떻든간에 즉, 트랜잭션이 얼마나 많고, 레코드가 얼마나 많건간에 "분산 객체 아키텍쳐"가 필요치 않고, 좋은 프레임웍을 갖고 계시다면, EJB는 넣지 않으시는 것이 좋습니다. 그렇지 않다면, 즉, "분산 객체 아키텍쳐"가 필요하다거나, 좋은 프레임웍이 없다거나, 능숙한 설계/개발자가 없다거나 하실 경우는 EJB가 적극 추천됩니다.

물론, 어플리케이션 개발 후, 성능 테스트의 결과에 따라, 머신은 WebServer 만 사용할 때보다 1.5 내지 2 배정도 증설하실 여력이 있다면 말입니다.

=============================== 2차 질문 =========================

From : 정원식(won***@h*****.com)

To : 차의중(prof21@empal.com)

Sent : Saturday, Jan 18, 2003 10:22 AM

Subject: 감사합니다.추가로..[JAVASERVICE에서 글을 보고서...]


답변에 감사를 드립니다.
죄송하지만 추가 질문을 좀 드리겠습니다.

1> 3tire 로 갈때 꼭 h/w 가 구분이 되어야 한는지요?
webserver tire(weblogic) -- ejb tire(weblogic) -- db

이 경우 결국 weblogic로 tire1 , tire2 를 구현하게 되지 않나요? 아니면, 한 box에서 weblogic으로 (jsp/servlet , ejb) 구현하면 문제점은?

=> H/W를 나누지 않고, 한 서버 내에서 두 JVM으로 이들을 나눌 경우, 두 JVM간에 RMI가 일어납니다. 그런데, 어차피 한 서버 내에 있으면 RMI를 사용해야 할 필요가 없지요. 이것은 부가적인 부담을 서버에게 안겨줍니다. 물론, 머신 수가 충분치 않을 때, 이런 구조로 사용하다가, 나중에 꼭 필요하면 쉽게 머신을 분리시킬 수 있죠.

어쨌건 이것은 "문제"라고 볼 수는 없고, 만일 머신을 분리시킬 계획이 없다면, "쓸 데 없는 일"이 되어버립니다.

물론, EJB 와 WAS를 한 개 JVM에 올리고, 서블릿과 EJB간 통신을 로컬 인터페이스를 이용하여 함으로써 RMI 즉, 네트웍 통신을 하지 않는 아키텍쳐를 택할 수도 있습니다.
그러나, 여전히 EJB 컴포넌트는 무겁습니다. 이건 어쩔 수 없죠. 컴포넌트는 일반 클래스에 비해 당연히 무거운겁니다. 컴포넌트에 대해 사람들이 요구하는 조건은 한 개 클래스만 가지고는 만족시킬 수가 없습니다. 당연히, 보이지 않는 부분에서의일을 수행하기 위해 보이지 않는 클래스들이 중간에 끼어들지요. 그러니, RMI 를 하지 않아도 역시 가벼운 객체로 처리할 수 있는 일을 무거운 컴포넌트로 처리하게 되는 결과가 옵니다.

보통 EJB를 쓰면서 그 장점을 트랜잭션 수행의 편의성과 안정성을 따지시는데, JDBC 커넥션에 begin() 과 commit()을 쓰신다고 해서, EJB에 비해 얼마나 더 복잡하고 어려운 작업을 해야 할 것인가...를 생각해 보면, "일반적인 어플리케이션에서는 그다지 차이가 없다." 라는 것입니다. 데이터 소스가 다양하고, 여러 개이며, 복잡한 구조를 가지고 있으며, 이들을 하나의 트랜잭션으로 묶어야 할 필요가 있다면, EJB 나 JTA의 사용은 꼭 필요합니다.

그러나, 1개 데이터베이스에 대한 접근은 JDBC만으로 처리가 가능합니다. 물론, CMP를 사용하면, SQL 날코딩의 복잡성을 Encapsulation 해주므로 좀 더 소스를 간단하게 만들 수 있습니다. 그러나 이것은 DAO 객체 등을 도입해서, SQL문을 가진 클래스를 따로 분리시킨다든지 함으로써 상당 부분 극복이 가능한 문제입니다.

ps : 하나의 머신에서 WAS 와 EJB를 한꺼번에 돌림으로써 WAS만 돌릴 때보다 사용자를 더 많이, 안정적으로 수용하는 경우도 있을 수 있는데 이것은 다중 CPU 머신에서 JVM의 분리가 가져다주는 효과입니다. WAS-EJB 구조와 WAS-WAS 구조를 비교하자면, 어차피 JVM을 분리시켰기 때문에 WAS-WAS 구조가 역시 수행성능이 낫습니다.

2> 두가지 관점에서 보면..

속도는 2tire 보다 3tire(ejb)에서 어느 정도가 느려 지나요?

=> 동일한 H/W 사양을 두고 측정을 해보면 어쨌든 2배 이상은 느립니다. 이론적으로도 그럴 수 밖에 없죠. 물론, 이것은 관점의 차이일 수도 있습니다. 하나 요청의 총 처리 시간이 10초인데, 이 중 9초가 데이터베이스에서 잡아먹는 시간이라면, 2-Tier 와 3-Tier 간에 처리시간이 길게 차이 나봤자 1초 이내가 나올 수 있을껀데, 이것이 전체 처리 시간에 비해 워낙이 작으므로 "차이가 거의 나지 않는다"라고 볼 수도 있을껍니다.

따라서, 2배라고 하는 것은 "클라이언트-WAS" 간에서의 처리 속도와 "클라이언트-WAS-EJB"간의
처리 속도만을 비교했을 때라는 것을 주지하시기 바랍니다. 속도차이는 동시사용자가 많으면 점점 더 벌어집니다.

하지만 3tire(ejb) 안정적인 서비스(급격한 속도 저하 극복)를 위한 대안으로 될 수 있는지요?
=> 안정성이라는 것은 많은 사용자가 동시에 어플리케이션에 접근할 때에도 시스템이 급격히 느려지거나 다운되는 것을 막아준다는 것이겠지요. 이를 위한 가장 이상적인 방법은 머신의 수를 늘리는 것입니다.
그러나, 우리가 사용할 수 있는 머신의 수는 한정되어있지요.
한정되어있는 머신으로 더 많은 사용자를 수용하려면,머신의 자원을 최대한 활용하는 방법을 찾는 것이 최선의 목표이겠지요. 더 느려지는 것을 감수하고라도 안정성을 꽤하겠다면, 차라리 sleep() 이나 yield()를 두어 하나의 요청이 CPU를 지나치게 오랫동안 점유하는 것을 막고, 그 사이에 다른 요청이 CPU를 사용할 수 있도록 배려하는 것이 머신의 성능을 최대한 활용하는 것이겠지요.
다른 컴포넌트를 끼워넣어 부가적인 일을 그 사이에 하는 것은 답이 아니겠지요. 왜냐하면, 같은 일을 처리하기 위해 더 많은 CPU점유시간이 필요하고,메모리도더 많이 사용하는 것이 되기 때문이지요. 어떤 하나의 일을 처리할 때 CPU 와 메모리등에 대한 단위 요구량을 최소화 시키는 것이
가장 안정성을 높이는 일이 아니겠습니까?

물론, 아다시피 완벽한 안정성이란 없습니다. 사용자가 끝없이 늘어나는 데 어떤 메커니즘을 도입한다 한들 그 모든 사용자를 수용하면서 안정적인 서비스를 할 수 있겠습니까? 하나의 머신이 처리할 수 있는 최대 동시 사용자 수에는 한계가 있죠.
따라서, 그야말로 한계에 다다르면 어쨌든 머신을 늘려야겠죠. 만일, 어떤 경우에도 한정된 머신만으로 안정적인 서비스를 해야겠다면, 한계치 이상의 동시 사용자가 접속할 경우, 그 이상의 사용자에게는 "죄송합니다. 다른 요청을 처리 중이오니 잠시 후에 다시 접속해 주십시요" 라고 메시지를 내보내서 점잖게 돌려보내는 것이 최선입니다.

-----------------------------------------------------------------
본 문서 및 첨부파일은 자유로이 복사/배포가 가능하나 반드시 저자의
이름과 연락처를 명시해주시기 바랍니다.

차의중
prof21@empal.com
(2004-02-27 09:50:59)

댓글 없음:

댓글 쓰기