약 한달 전 쯤인 2010년 7월 2일 마이크로소프트가 닷넷과 자바에 관한 웹 애플리케이션 및 웹 서비스에 관한 성능 비교 자료를 내놓았다. 이름하여 "Microsoft .NET Framework 4.0 vs. IBM WebSphere 7 StockTrader Benchmark Report”로서 이는 작년 2009년 3월에 공개한 성능 비교 자료에 대한 업데이트이다.  작년 비교자료에 대해 올렸던 이전 포스트를 참고하면서 이 포스트와 함께 비교하며 읽으면 한층 재미가 있을 것으로 생각한다. 비교자료에 관한 상세한 정보는 http://msdn.microsoft.com/en-us/netframework/bb499684.aspx 에서 찾을 수 있으며, 이 테스트에 사용된 모든 자바 및 닷넷 소스 코드 또한 이 싸이트에서 다운로드 받을 수 있다. 
예전 비교와 달라진 것은 .NET Framework 버전이 3.5에서 4.0으로 업그레이드 되었고, Windows Server 버전이 2008에서 2008 R2로 달라졌고 따라서 IIS 또한 7.0에서 7.5로 높아졌다. 아울러 모든 테스트 환경은 64 Bit인 것은 작년과 동일하다.

이 테스트는 IBM이 WebSphere 기반으로 J2EE의 베스트 프랙티스를 바탕으로 만든 애플리케이션인 Trader를 닷넷 버전으로 만들어 아키텍처나, 각종 WAS 세팅에 대한 정보를 공개하여 독자 검증을 거치고 있으며, 성능과 확장성을 검증하며 이에 드는 비용을 산정하여 가장 비용 합리적인 애플리케이션 구축 방안을 제시함을 목적으로 한다. (예전 PetStore 관련 비교시와는 전혀 다르며 아키텍처나 소스 코드를 모두 공개하여 자신있게 결과를 공표하고 있다.)

서버 사양
1. IBM Power 570 with IBM WebSphere 7 and AIX 5.3
2. Hewlett Packard BladeSystem C7000 with IBM WebSphere 7 and Microsoft Windows Server 2008 R2
3. Hewlett Packard BladeSystem C7000 with Microsoft .NET 4.0 and Windows Server 2008 R2
JavaEE의 경우 IBM Power 570에서 한번, HP BladeSystem에서 한번, 이렇게 두번 진행하고 .NET의 경우 HP BladeSystem에서 한번 진행했다. (아마도 오해의 소지를 없애기 위해 JavaEE의 경우 IBM H/W에서 한번, 동일한 조건의 HP H/W에서 한번 진행한 것으로 보인다.)

테스트 항목 (작년과 동일)
1. 일반적인 웹 애플리케이션 성능 비교 : 웹 페이지에서 비지니스 로직을 호출하고 데이터베이스에서 가져온 정보를 웹에 뿌리는 일반적인 웹 애플리케이션 성능 비교로서 자바의 경우 JSP + Servlet + JDBC direct 호출 방식으로 오해를 없애기 위해  EJB를 사용치 않았다. 닷넷의 경우 ASP.NET + BLL + ADO.NET의 일반적인 방식을 따른다.
2. 미들티어 웹 서비스 성능 비교 : 클라이언트 부분은 배제하고, 비지니스 로직에서 데이터베이스 접근 로직을 거쳐 가져온 데이터를 SOAP 기반의 표준 웹 서비스로 노출하는 것 까지를 포함한다. 즉, SOAP 메시지로 serialization하는 성능까지만 포함한다.
3. 웹 서비스 벤치마크 (WSTest) : 애초 Sun 만들어 배포한 WSTest를 수정하여 진행하는 것으로 비지니스 로직을 전혀 담지 않고 순수하게  자바와 닷넷의 웹 서비스 스택 성능만을 비교한다. 즉, IBM WebSphere의 웹 서비스 스택 즉 JAX-WS 구현체와 마이크로소프트의 웹 서비스 구현체인 WCF의 성능을 비교한 것이다.

위 세가지 경우에 있어서 공통적으로 적용한 규칙은 테스팅 툴을 사용하여 30분간 부하를 적용하고 유지가능한 최고 TPS (Transaction per second)를 선정하는 것이다. 또한 성능 테스트에서 인프라가 방해를 하지 않도록 데이터베이스 서버의 CPU는 항상 50% 미만을 유지하도록 하였고, 비지니스 로직이 올라가는 서버 (WAS)의 CPU는 96% 정도 유지하여 최상의 성능을 발휘하도록 설정하였다.

시스템 아키텍처
웹 애플리케이션 성능 비교의 경우 Mercury의 LoadRunner를 사용하였으며, 32대의 물리적 클라이언트가 사용되었고, 각 클라이언트는 수백명의 서로 다른 사용자로 부하를 생성했으며, 각 사용자는 매 요청마다 1초의 Think time을 갖는 방식으로 진행되었으며 30분간 진행되었다. 에러 발생 빈도는 측정 기간동안 0.01%이내에 위치하도록 모니터링되었다.

image

미들티어 웹 서비스 성능 비교 및 WSTest 웹 서비스 벤치마크의 경우에는, .NET Capacity Planner 웹 서비스 테스트기를 이용하였고, 0.1초의 Think Time을 갖는 10개의 서로 다른 클라이언트에서 부하를 생성하였다.

image

공정한 벤치마크 테스팅을 위한 고려사항
1. 자바의 경우, Java EE 5 기반의 WebSphere 7에서 최적화되고 가장 빠른 Trader 애플리케이션 적용하였으며, EJB사용하지 않고 직접 JDBC를 호출하여 데이터베이스 작업하는 방식으로 JSP 와 Servlet 만을 이용하여 개발되었다. 또한 최적의 성능을 위해 WebSphere의 경우 쓰레드 풀, 커넥션 풀, queue connection factory, Heap size 등등에 대한 튜닝이 진행되었으며 결과적으로 최고 TPS 측정시 CPU 사용량이 96~100%이 될 수 있도록 하였다.
2. 캐쉬의 경우 양쪽 모두 적용하였다. 자바의 경우 WebSphere Servlet Caching을 적용하였고 닷넷의 경우 .NET Cache API를 적용하였다.
3. 데이터베이스의 부하 측면에서는 StockTrader를 만든 IBM의 기본 부하보다 더 현실적으로 하기 위해 500,000계정으로 각 계정마다 5개의 주문, 100,000 quote를 기본으로 가져가도록 했다.
4. 데이터베이스 구성은 IBM WebSphere 7의 경우 All-IBM 구성을 따랐으며 IBM DB2 v9.5 (Enterprise Edition), 최신의 IBM DB2 v9.5 JDBC 드라이버가 사용되었다. .NET의 경우 SQL Server 2008 (Enterprise Edition)을 사용하였다. 이 벤치마크는 데이터베이스 성능 비교가 아니기 때문에 데이터베이스때문에 결과가 왜곡되지 않도록 충분한 성능을 발휘하는 H/W를 제공되었다. (자세한 H/W 사양은 결과 리포트를 참고하시길...)
5. 총 36페이지 보고서에 공정한 테스트를 위한 고려사항 무려 6페이지를 차지할 정도로 닷넷과 자바 양 진영에서 모두 수긍할 수 있는 수준을 유지하려 했다.
6. 뒷 부분 부록에는 6페이지에 걸쳐 이 테스트에 사용된 각종 하드웨어, 소프트웨어에 대한 목록과 가격표를 제공한다. 또한 부록 B에는 3장에 걸쳐 WebSphere와 IIS에 대해 설정한 각종 설정값 및 튜닝한 정보를 상세히 제공하여 오해의 소지를 없앴다.

벤치마크 결과
1. 일반 웹 애플리케이션 성능 비교
앞서 기술한 대로 IBM WebSphere 7의 경우 EJB 없이 JSP/Servlet만으로 직접 JDBC 호출한 것이며, .NET의 경우 ASP.NET/Web Forms에서 ADO.NET을 통해 데이터베이스 호출한 경우이다.  작년 결과와 비교하면, 약간 의외의 사실도 발견할 수 있다. 전반적인 결과는 작년과 비슷하나 TPS 측면에서 Windows Server 2008 기반의 WebSphere의 성능은 향상되었고, IIS의 성능은 약간 내려가서 오히려 Windows Server 2008 R2 기반에서 WebSphere가 IIS보다 TPS숫자는 아주 약간 높게 나왔다. 물론 Power 570 보다는 Windows Server 2008 R2기반일 때 성능이 훨씬 좋다.

image

위와 같은 TPS를 달성하기 위해 지출된 비용을 산정하여, 역으로 하나의 TPS를 달성하기 위한 지불된 비용을 계산하면 아래와 같다.

image

이를 통해 다음과 같은 사실을 알 수 있다.
1. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 기반의 Java EE에 비해 37% 성능이 우수함을 알 수 있으며, 서버를 구성하기 위해 들어간 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 .NET / Windows Server 2008 / HP BladeSystem C7000 에 비해 419% 더 지출된 것을 알 수 있다.
2. IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000 의 성능이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 에 비해 성능이 39% 더 나은 것을 알 수 있으며, 서버 구성에 들어간 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합이 IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000조합보다 198% 더 비싼 것을 알 수 있다.
3. 전반적으로 Windows Server 2008 R2 기반의 닷넷이 비용 성능 측면에서 훨씬 우수함을 알 수 있다. IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합은 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합보다 성능 대비 비용이 8배 높은 것으로 나타났다. 이는 결국, 같은 부하를 감당하는 시스템을 구축할 경우 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합이 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합에 비해  비용을 8배나 더 지출해야함을 의미한다.

2. 미들티어 웹 서비스 테스트
이 테스트는 StockTrader의 비지니스 서비스 앞단에 웹 서비스를 위한 Facade를 만들고 이 Facade부터 데이터베이스 단까지의 성능을 비교한 것이다. 앞의 웹 애플리케이션 성능 비교와 다른 점은 전체 페이지가 아닌 개별 SOAP 요청이 처리되는 것을 기준으로 TPS가 산출된다는 것이다.
IBM WebSphere의 경우 웹 서비스 Facade는 JAX-WS로 구현되었고 표준 SOAP/WSDL 기반의 서비스를 노출하며, 사용자의 요청을 IBM HTTP Server가 WebSphere상의 웹 서비스 티어로 전달하는 구조로 되어 있다. .NET의 경우 WCF를 사용하여 웹 서비스 Facade를 구현하였고 SOAP/WSDL 기반의 표준 웹서비스를 노출하며, IIS 7.5가 사용자의 요청을 WCF 기반의 서비스에 전달한다.
.NET Capacity Planner 웹 서비스 테스트 툴을 이용하여 SOAP 요청을 생성하여 테스트를 진행하였다.

image

비용 대비 성능비 (Price Performance Ratio) 는 아래와 같다.

image

결과를 통해 다음과 같은 사실을 알 수 있다.
1. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합에 비해 웹 서비스 성능이 111% 더 우수함을 알 수 있다. 반면, 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 서버의 경우가 .NET / Windows Server 2008 / HP BladeSystem C7000 의 경우보다 419% 더 지출된 것을 알 수 있다.
2. IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000 조합의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우보다  성능이 37% 더 우수함을 알 수 있다.  반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000의 경우보다 198% 더 지출된 것을 알 수 있다.
3.전반적으로 비용 대비 성능 측면에서 Windows Server 2008 R2 기반의 닷넷 시스템이 훨씬 나은 결과를 보여주고 있다. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우에 비해 비용 대비 성능 측면에서 10배 우수함을 보여준다. 이는 결국 같은 웹 서비스 성능을 내는 시스템을 구축할 경우, IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 을 사용할 경우 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 을 사용할 때보다 10배 비싼 구축 비용을 지불해야 함을 의미한다.

3. WSTest 벤치마크
WSTest는 뒷단 비지니스 로직이나 데이터베이스 엑세스 없이 순수하게 구현 플랫폼의 웹 서비스 스택 성능 (즉, XML Serialization/Deserialization, http 네트웍 접근 등) 을 비교하는 것이다. WSTest는 원래 썬마이크로시스템즈에서 고안한 것으로 마이크로소프트가 보완하여 적용하였다.
IBM WebSphere 7의 경우, 앞의 미들티어 웹 서비스 성능 벤치마크에서와 마찬가지로 JAX-WS 기반의 웹 서비스 스택에서  SOAP/WSDL 기반의 표준 웹 서비스로 노출시켜 진행하였으며, 전달된 요청은 IBM Http Server가 IBM WebSphere 7 서버내의 웹 서비스 구현체에 전달하는 구조로 되어있다.
.NET의 경우, WCF를 이용하여 SOAP/WSDL 기반의 표준 웹 서비스를 노출시켰고, 전달된 요청은 IIS 7.5이 WCF 기반의 웹 서비스 구현체에 전달하는 형태로 되어 있다. 표준 기반의 웹 서비스이기 때문에 IBM WebSphere 7기반의 자바 구현체와 .NET 기반의 구현체 사이에 상호 운용이 가능하다.

image

비용 대비 성능비 (Price Performance Ratio)로 환산한 결과는 다음과 같다. 비용 산출에 대한 근거는 리포트의 Appendix에 상세히 설명되어 있다.

image

위 결과를 통해 다음과 같은 사실을 알 수 있다.
1. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합의 경우에 비해 최소 120% 성능이 더 우수함을 알 수 있다. (WSTest의 각 Operation별로 조금씩 다르다.) 반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 서버의 경우가 .NET / Windows Server 2008 R2 / HP BladeSystem C7000의 경우보다 419% 더 지출된 것을 알 수 있다.
2. IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000 조합의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우보다  성능이 51% 더 우수함을 알 수 있다.  반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000의 경우보다 198% 더 지출된 것을 알 수 있다.
3. 전반적으로 비용 대비 성능 측면에서 Windows Server 2008 R2 기반의 닷넷 시스템이 훨씬 나은 결과를 보여주고 있다. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우에 비해 비용 대비 성능 측면에서 10배 우수함을 보여준다. 이는 결국 같은 웹 서비스 성능을 내는 시스템을 구축할 경우, IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 을 사용할 경우 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 을 사용할 때보다 10배 비싼 구축 비용을 지불해야 함을 의미한다. (최대 TPS 달성시 기준으로 단위 TPS당 드는 비용 산출)

결론
웹 애플리케이션을 구축할 경우, Windows Server 2008 R2 기반의 닷넷 시스템이 IBM Power 570 기반의 WebSphere 7 기반 Java EE 시스템에 비해 가격은 1/5 수준으로 성능은 37% 더 나은 시스템을 구축할 수 있음을 알 수 있다. 같은 WebSphere 7 기반의 웹 애플리케이션 시스템 구축의 경우에도 Windows Server 2008 R2 / HP BladeSystem C7000 위에서 구동하는 것이 IBM AIX 5.3 / IBM Power 570 위에서 구동하는 것에 비해 가격은 1/3 수준으로, 성능은 39%  더 나은 결과를 제공할 수 있음을 알 수 있다.
웹 서비스를 구축할 경우에도, Windows Server 2008 R2 기반의 닷넷 시스템이 IBM Power 570 기반의 WebSphere 7 기반 Java EE 시스템에 비해서 가격은 1/5 수준으로 성능은 111% 더 나은 웹 서비스를 구축할 수 있음을 알 수 있다. 같은 WebSphere 7 기반의 자바 웹 서비스 시스템 구축의 경우에도 Windows Server 2008 R2 / HP BladeSystem C7000 위에서 구동하는 것이 IBM AIX 5.3 / IBM Power 570 위에서 구동하는 것에 비해가격은 1/3 수준으로 성능은 37%  더 나은 결과를 제공할 수 있음을 알 수 있다.

image

Posted by 장현춘

마이크로소프트가 2년에 한번씩 IDC를 통해 엔터프라이즈에서 미션 크리티컬 애플리케이션의 운영 상황을 조사한 결과를 공개하고 있는데, 며칠전 2009년 8, 9월에 진행한 조사 결과를 발표했다.

image

"Mission Critical Application Platform Study"라는 이름으로 진행한 조사는 다음과 같은 절차를 통해 진행되었다.
- 1,000명 이상의 임직원을 가진 회사로 미국, 영국, 프랑스, 독일 기업을 대상으로 하였다.
- 마이크로소프트는 참여자의 신분이나 선택에 일체 관여하거나 영향력을 행사하지 않았다.
- 참여자는 메일이나 전화를 통해 엄격한 선발 기준을 통해 선별되었다.
- 참여 기업은 임직원수 1,000명 이상 기업이며, 참여 기업의 60%이상의 기업이 임직원 5,000명을 넘었고, 참여 회사 전체의 평균 임직원 수는 6,000명이었다.
- 참여자는 IT Decision Maker, Developer 혹은 Architect이어야하며, 조직내에서 기술 관련된 결정에 어느 정도 영향력을 행사하는 사람들이다.
- 회사당 1명씩 조사를 하였다.
- Analyst나 시장 조사 전문가는 배제되었다.

이러한 절차에 의해 총 920개 기업이 조사에 참여하여 다음과 같은 결과가 도출되었다.
1. 현재 Mission-critical application이 가장 많이 deploy되어 있는 OS는 Windows Server (52.7%)이다. (23 page)
2. 현재 Mission-critical application이 가장 많이 배포되어 있는 application server는 Windows Server & .NET (54.1%)이다. (35 page)
3. 규모에 상관없이 조사 대상 기업 전부에서 Mission-critical application 구현시 닷넷이 자바보다 많이 사용되었다. (49 page)
4. 자바로 구현된 Mission-critical application이 가장 많이 deploy된 OS는 Windows Server (46%) 이다. (51 page)
5. primary project에서 포털 솔루션을 사용하는 경우 가장 많이 적용된 솔루션은 Sharepoint Server이다. (72 page)
6. primary project에서 사용하는 메인 데이터베이스로는 SQL Server가 가장 많이 사용한다. (81 page)
7. primary project에서 웹 서비스 벤더로 가장 많이 사용하는 벤더는 마이크로소프트이며 (85 page), SOA 기반의 primary project 시에도 가장 많이 사용하는 벤더로  역시 마이크로소프트가 선정되었다.  (90 page)

image

보고서의 뒷부분에서는 Mission-critical application 현황을 지난 2005, 2007, 2009년에 각각 조사하였는데, 그 결과를 비교하여 그 추이를 한 눈에 볼 수 있도록 제공하고 있다.

image

아울러, 자료 중에는 자바나 자바 WAS 각각에 대한 조사 결과도 포함하고 있어 자바 쪽 정보가 궁금한 사람도 보면 좋을 듯 하다. 가령, 회사 규모별, 나라별 가장 많이 사용하는 자바 개발 프레임웍은 무엇인지 등...

2009년 조사 보고서는 여기에서 다운로드 할 수 있다.
2007년 조사 보고서는 영문은
여기, 한글은 여기에서 다운로드 할 수 있다.

Posted by 장현춘

.NET Framework 4 Beta 2의 일부인 .NET Framework 4 Client Profile이 일부 변경된 것이 있어 공유하고자 한다. 일반적인 .NET Framework 3.5 SP1의 Client Profile에 대해서는 이전 포스트를 참고하면 좋을 듯 하다.
.NET Framework Client Profile
.NET Framework Client Profile 정리

.NET Framework 4 Client Profile은 .NET Framework 4 Beta 2의 일부로서 제공되며 일반적으로 많이 사용되는 WPF, WCF, Windows Forms, ClickOnce 등의 기능을 포함하고 있다. .NET Framework 3.5 SP1 Client Profile과 .NET Framework 4 Client Profile의 차이를 정리하면 다음과 같다.

.NET Framework 3.5 SP1 Client Profile .NET Framework 4 Client Profile
웹을 통한 설치만 지원한다. 웹 및 로컬 패키지를 통한 설치 모두 지원한다.
Windows XP SP3/SP3 w/ x86 아키텍처만 지원한다. IA64를 제외한 .NET Framework 4 Beta 2가 지원하는 모든 플랫폼과 CPU 타입 지원한다.
.NET Framework과 별도 패키지로 존재한다. .NET Framework의 일부이다. 즉, .NET Framework은 Client Profile과 확장 부분으로 구성되어 있어서 제어판에서 별개로 설치 및 제거 가능하다.
Windows Update 실행하며 풀버전 .NET Framework으로 업그레이드된다. .NET Framework과 독립적인 패키지로 볼 수 있으며, 각각 따로 서비스된다.

.NET Framework 4 Client Profile에 포함되어 있는 기능은 다음과 같다.

  • Common Language Runtime (CLR)

  • ClickOnce

  • Windows Forms

  • Windows Presentation Foundation (WPF)

  • Windows Communication Foundation (WCF)

  • Entity Framework

  • Windows Workflow Foundation

  • Speech

  • XSLT support

  • LINQ to SQL

  • Runtime design libraries for Entity Framework and ADO.NET Data Services

  • Managed Extensibility Framework (MEF)

  • Dynamic types

  • Parallel-programming features, such as Task Parallel Library (TPL), Parallel LINQ (PLINQ), and Coordination Data Structures (CDS)

  • Debugging client applications

위에서 언급한 대로 .NET Framework 4 Client Profile Beta 2는 이전 버전과 다르게 재배포 패키지로도 제공되며 아래에서 다운로드 가능하며, 다운로드 용량은 .NET Framework 3.5 SP1 때보다 약간 커진 30.9 MB이다.
Microsoft .NET Framework 4 Client Profile Beta 2

Posted by 장현춘

어떤 이에게 있어 자바 대 닷넷은 아주 식상한 주제일 수 있고, 또 어떤이에게 있어서 아직도 그런 걸 따지는 데가 있냐고 반문할 수도 있다. 하지면 여전히 엔터프라이즈 시장에서 개발 플랫폼 선정을 할 경우에 한번쯤은 따지고 넘어가야 어딘지 모르는 불안한 기운을 잠재울 수 있다.

이번 글은 마이크로소프트가 몇 년간 꾸준히 테스트를 진행하면서 결과 리포트를 MSDN에 발간하는 .NET StockTrader 애플리케이션에 관한 것이다. 최신 결과는 지난 3월에 발간한 것으로 “Benchmarking IBM WebSphere 7 on IBM Power6 and AIX vs. Microsoft .NET on Hewlett Packard BladeSystem and Windows Server 2008”이라는 문서이다.

벤치마크는 스펙이 아니라 구체적인 구현물간의 비교가 되어야 하기에, Java EE의 구현체로서 StockTrader를 만든 IBM의 최신 WAS인 WebSphere 7을 활용하여 Java EE의 일반적인 웹 애플리케이션 성능 및 웹 서비스 성능과 이에 따른 비용을 산정하고 .NET의 경우 Microsoft의 최신 WAS라 할 수 있는 Windows Server 2008 기반의 .NET 3.5하에서의 동일한 값들을 산정하여 비교한 것이다.

여기에 사용된 자바 및 닷넷 소스 코드는 이곳에서 다운로드 가능하다.

서버 사양
1. IBM Power 570 with IBM WebSphere 7 and AIX 5.3
2. Hewlett Packard BladeSystem C7000 with IBM WebSphere 7 and Microsoft Windows Server 2008
3. Hewlett Packard BladeSystem C7000 with Microsoft .NET and Windows Server 2008
즉, JavaEE의 경우 IBM Power 570에서 한번, HP BladeSystem에서 한번 두번 진행하고 .NET의 경우 HP BladeSystem에서 한번 진행했다. (아마도 오해의 소지를 없애기 위해 JavaEE의 경우 IBM H/W에서 한번, 동일한 조건의 HP H/W에서 한번 진행한 것으로 보인다.)

테스트 항목
1. 일반적인 웹 애플리케이션 성능 비교
2. 미들티어 웹 서비스 성능 비교 (클라이언트 단 제외)
3. 웹 서비스 벤치마크 (WSTest)

위 세가지 경우에 있어서 공통적으로 적용한 규칙은 테스팅 툴을 사용하여 30분간 부하를 적용하고 유지가능한 최고 TPS (Transaction per second)를 선정하는 것이다.

시스템 아키텍처
웹 애플리케이션 성능 비교의 경우 Mercury의 LoadRunner를 사용하였으며, 32대의 물리적 클라이언트가 사용되었고, 각 클라이언트는 수백명의 서로 다른 사용자로 부하를 생성했으며, 각 사용자는 매 요청마다 1초의 Think time을 갖는 방식으로 진행되었으며 30분간 진행되었다. 에러 발생 빈도는 측정 기간동안 0.01%이내에 위치하도록 모니터링되었다.
image 

미들티어 웹 서비스 성능 비교 및 WSTest 웹 서비스 벤치마크의 경우에는, .NET Capacity Planner 웹 서비스 테스트기를 이용하였고, 0.1초의 Think Time을 갖는 10개의 서로 다른 클라이언트에서 부하를 생성하였다.
image

공정한 테스트를 위한 고려사항
1. 자바의 경우, Java EE 5 기반의 WebSphere 7에서 최적화되고 가장 빠른 Trader 애플리케이션 적용하였으며, EJB사용하지 않고 직접 JDBC를 호출하여 데이터베이스 작업하는 방식으로 JSP 와 Servlet 만을 이용하여 개발되었다. 또한 최적의 성능을 위해 WebSphere의 경우 쓰레드 풀, 커넥션 풀, queue connection factory, Heap size 등등에 대한 튜닝이 진행되었으며 결과적으로 최고 TPS 측정시 CPU 사용량이 96~100%이 될 수 있도록 하였다.
2. 캐쉬의 경우 양쪽 모두 적용하였다. 자바의 경우 WebSphere Servlet Caching을 적용하였고 닷넷의 경우 .NET Cache API를 적용하였다.
3. 데이터베이스의 부하 측면에서는 StockTrader를 만든 IBM의 기본 부하보다 더 현실적으로 하기 위해 500,000계정으로 각 계정마다 5개의 주문, 100,000 quote를 기본으로 가져가도록 했다.
4. 데이터베이스 구성은 IBM WebShpere 7의 경우 All-IBM 구성을 따랐으며 IBM DB2 v9.5 (Enterprise Edition), 최신의 IBM DB2 v9.5 JDBC 드라이버가 사용되었다. .NET의 경우 SQL Server 2008 (Enterprise Edition)을 사용하였다. 이 벤치마크는 데이터베이스 성능 비교가 아니기 때문에 데이터베이스때문에 결과가 왜곡되지 않도록 충분한 성능을 발휘하는 H/W를 제공되었다. (자세한 H/W 사양은 결과 리포트를 참고하시길...)

벤치 마크 결과

1. 웹 애플리케이션 성능 비교
앞서 기술한 대로 IBM WebSphere 7의 경우 EJB 없이 JSP/Servlet만으로 직접 JDBC 호출한 것이며, .NET의 경우 ASP.NET/Web Forms에서 ADO.NET을 통해 데이터베이스 호출한 경우이다.
image 
이러한 최고 TPS를 달성하기 위해 지출된 비용을 산정하면 아래와 같다. 비용 산정과 관련된 상세한 사항은 리포트의 Appendix를 참고하시길...
image

이를 통해 다음과 같은 사실을 알 수 있다.
1. .NET / Windows Server 2008 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 기반의 Java EE에 비해 57% 성능이 우수함을 알 수 있으며, 서버를 구성하기 위해 들어간 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 .NET / Windows Server 2008 / HP BladeSystem C7000 에 비해 419% 더 지출된 것을 알 수 있다.
2. IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000 의 성능이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 에 비해 성능이 37% 더 나은 것을 알 수 있으며, 서버 구성에 들어간 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합이 IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000조합보다 198% 더 비싼 것을 알 수 있다.
3. 전반적으로 Windows Server 2008기반의 닷넷이 비용 성능 측면에서 훨씬 우수함을 알 수 있다. IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합은 .NET / Windows Server 2008 / HP BladeSystem C7000 조합보다 성능 대비 비용이 8배 높은 것으로 나타났다. 이는 결국, 같은 부하를 감당하는 시스템을 구축할 경우 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합이 .NET / Windows Server 2008 / HP BladeSystem C7000 조합에 비해  8배 높은 비용을 지출해야함을 의미한다.

2. 미들티어 웹 서비스 벤치마크
이 테스트는 StockTrader의 비지니스 서비스 앞단에 웹 서비스를 위한 Facade를 만들고 이 Facade부터 데이터베이스 단까지의 성능을 비교한 것이다. 앞의 웹 애플리케이션 성능 비교와 다른 점은 전체 페이지가 아닌 개별 SOAP 요청이 처리되는 것을 기준으로 TPS가 산출된다는 것이다.
IBM WebSphere의 경우 웹 서비스 Facade는 JAX-WS로 구현되었고 표준 SOAP/WSDL 기반의 서비스를 노출하며, 사용자의 요청을 IBM HTTP Server가 WebSphere상의 웹 서비스 티어로 전달하는 구조로 되어 있다. .NET의 경우 WCF를 사용하여 웹 서비스 Facade를 구현하였고 SOAP/WSDL 기반의 표준 웹서비스를 노출하며, IIS 7.0이 사용자의 요청을 WCF-기반의 서비스에 전달한다.
.NET Capacity Planner 웹 서비스 테스트 툴을 이용하여 SOAP 요청을 생성하여 테스트를 진행하였다.
image 
비용 대비 성능비 (Price Performance Ratio) 는 아래와 같다.
image

결과를 통해 다음과 같은 사실을 알 수 있다.
1. .NET / Windows Server 2008 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합에 비해 웹 서비스 성능이 111% 더 우수함을 알 수 있다. 반면, 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 서버의 경우가 .NET / Windows Server 2008 / HP BladeSystem C7000 의 경우보다 419% 더 지출된 것을 알 수 있다.
2. IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000 조합의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우보다  성능이 37% 더 우수함을 알 수 있다.  반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000의 경우보다 198% 더 지출된 것을 알 수 있다.
3.전반적으로 비용 대비 성능 측면에서 Windows Server 2008 기반의 닷넷 시스템이 훨씬 나은 결과를 보여주고 있다. .NET / Windows Server 2008 / HP BladeSystem C7000 의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우에 비해 비용 대비 성능 측면에서 10배 우수함을 보여준다. 이는 결국 같은 웹 서비스 성능을 내는 시스템을 구축할 경우, IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 을 사용할 경우 .NET / Windows Server 2008 / HP BladeSystem C7000 을 사용할 때보다 10배 비싼 구축 비용을 지불해야 함을 의미한다.

3. WSTest 벤치마크
WSTest는 뒷단 비지니스 로직이나 데이터베이스 엑세스 없이 순수하게 구현 플랫폼의 웹 서비스 스택 성능 (즉, XML Serialization/Deserialization, http 네트웍 접근 등) 을 비교하는 것이다. WSTest는 원래 썬마이크로시스템즈에서 고안한 것으로 마이크로소프트가 보완하여 적용하였다.
IBM WebSphere 7의 경우, 앞의 미들티어 웹 서비스 성능 벤치마크에서와 마찬가지로 JAX-WS 기반의 웹 서비스 스택에서  SOAP/WSDL 기반의 표준 웹 서비스로 노출시켜 진행하였으며, 전달된 요청은 IBM Http Server가 IBM WebSphere 7 서버내의 웹 서비스 구현체에 전달하는 구조로 되어있다.
.NET의 경우, WCF를 이용하여 SOAP/WSDL 기반의 표준 웹 서비스를 노출시켰고, 전달된 요청은 IIS 7.0이 WCF 기반의 웹 서비스 구현체에 전달하는 형태로 되어 있다. 표준 기반의 웹 서비스이기 때문에 IBM WebSphere 7기반의 자바 구현체와 .NET 기반의 구현체 사이에 상호 운용이 가능하다.
image 
비용 대비 성능비 (Price Performance Ratio)로 환산한 결과는 다음과 같다. 비용 산출에 대한 근거는 리포트의 Appendix에 상세히 설명되어 있다.
image 
위 결과를 통해 다음과 같은 사실을 알 수 있다.
1. .NET / Windows Server 2008 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합의 경우에 비해 최소 112% 성능이 더 우수함을 알 수 있다. (WSTest의 각 Operation별로 조금씩 다르다.) 반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 서버의 경우가 .NET / Windows Server 2008 / HP BladeSystem C7000의 경우보다 419% 더 지출된 것을 알 수 있다.
2. IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000 조합의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우보다  성능이 52% 더 우수함을 알 수 있다.  반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000의 경우보다 198% 더 지출된 것을 알 수 있다.
3. 전반적으로 비용 대비 성능 측면에서 Windows Server 2008 기반의 닷넷 시스템이 훨씬 나은 결과를 보여주고 있다. .NET / Windows Server 2008 / HP BladeSystem C7000 의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우에 비해 비용 대비 성능 측면에서 10배 우수함을 보여준다. 이는 결국 같은 웹 서비스 성능을 내는 시스템을 구축할 경우, IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 을 사용할 경우 .NET / Windows Server 2008 / HP BladeSystem C7000 을 사용할 때보다 10배 비싼 구축 비용을 지불해야 함을 의미한다. (최대 TPS 달성시 기준으로 단위 TPS당 드는 비용 산출)

결론적으로 웹 애플리케이션을 구축할 경우, Windows Server 2008 기반의 닷넷 시스템이 IBM Power 570 기반의 WebSphere 7 기반 Java EE 시스템에 비해 가격은 1/5 수준으로 성능은 57% 더 나은 시스템을 구축할 수 있음을 알 수 있다. 같은 WebSphere 7 기반의 웹 애플리케이션 시스템 구축의 경우에도 Windows Server 2008 / HP BladeSystem C7000 위에서 구동하는 것이 IBM AIX 5.3 / IBM Power 570 위에서 구동하는 것에 비해 가격은 1/3 수준으로, 성능은 37%  더 나은 결과를 제공할 수 있음을 알 수 있다.
웹 서비스를 구축할 경우에도, Windows Server 2008 기반의 닷넷 시스템이 IBM Power 570 기반의 WebSphere 7 기반 Java EE 시스템에 비해서 가격은 1/5 수준으로 성능은 111% 더 나은 웹 서비스를 구축할 수 있음을 알 수 있다. 같은 WebSphere 7 기반의 자바 웹 서비스 시스템 구축의 경우에도 Windows Server 2008 / HP BladeSystem C7000 위에서 구동하는 것이 IBM AIX 5.3 / IBM Power 570 위에서 구동하는 것에 비해가격은 1/3 수준으로 성능은 37%  더 나은 결과를 제공할 수 있음을 알 수 있다.
image

Posted by 장현춘

기업의 비지니스 환경이 복잡해지고 고객의 요구사항이 까다로와질수록 기업 내 전산 환경은 Heterogeneous한 양상을 띄게 된다. 고객에게 전달할 최상의 서비스가 무엇인지를 고민하고 그러한 서비스를 위해 어떠한 인프라가 가장 적합한지, 또한 그러한 인프라가 IT 자산 합리화 차원에서 적절하게 관리 운영되고 있는지를 끊임없이 체크한다. 고객에게 전달하는 가치의 극대화 측면에서 내부 IT 인력과 자산을 활용하는 것이 합리적인지, 외부의 서비스 소위 SaaS 형태의 서비스를 통해 가치를 전달하는 것이 고객의 요구에 어느 정도 부합하는 것인지 고민하게 되고 결과적으로 Software와 Services가 적절한 배합 비율로 섞인 환경으로 IT 인프라가 변모하게 된다. 또한 급변하는 비지니스 환경에서 기업에게 요구되는 Agility를 확보하기 위해 기존에 개발되어 있는 시스템을 활용하여 새로운 서비스를 고객 요구에 맞추어 빠른 time-to-market을 달성할 수 있다면 그만큼 시장에서 경쟁력을 확보할 수 있게 된다. 고객의 눈높이에 맞는 서비스를 고객이 원하는 시점에 가장 합리적인 방식으로 제공하기 위해 플랫폼 및 개발 언어가 혼용되는 추세가 확산되고 있다.

JEE 기반의 시스템과 연동하여 Silverlight 기반의 더 나은 사용자 경험을 전달하고자하는 시도가 점차 늘고 있다. 아래와 같이 JEE 기반의 시스템이 구축되어 있다고 할 때, Silverlight와 연동할 수 있는 방안을 살펴보자

 image

많이 기업들이 성능상의 이유로 Web Server와 App Server를 물리적으로 한 머신에 넣는 경우가 많은데, 설명의 편의를 위해 분리한 것이며, 이것이 물리적인 분리일 수도 논리적인 분리일 수도 있다. 대부분의 JEE 시스템은 프리젠테이션 레이어에는 Struts과 같은 Servlet기반의 MVC 프레임웍이 위치하여 HTTP 요청을 받아 들이고, 이를 적절한 매핑 매커니즘에 의해 뒷단 비지니스 레이어의 Facade에 전달하게 된다. 뒷단의 Facade는 Session EJB 기반의 Session Facade가 일반적이나 Message-driven Bean일 수도 있고, 같은 머신인 경우 POJO (Plain Old Java Object) 기반의 프레임웍이 많이 사용되는 추세이다. 프리젠테이션 레이어와 비지니스 레이어 사이의 통신은 일반적으로 EJB 호출(RMI/IIOP)이거나, 같이 티어에 위치할 경우 직접 호출을 한다. 사용자의 요청이 비지니스 레이어에서 처리되어 그 응답이 다시 프리젠테이션의 MVC에 도착하면 이를 사용자에게 전달하기 위해 프리젠테이션 레이어에서 뷰 역할을 하는 JSP 혹은 이 기반의 UI 프레임웍에 전달하여 렌더링 엔진에 의해 HTML로 최종 브라우저에 보여지게 된다. 여기에 Silverlight를 넣어보자.

image

Silverlight가 지원하는 통신 방식은 SOAP 기반의 XML 웹 서비스 (WS-Security까지 지원), REST 기반의 웹서비스 및 소켓 통신 (port : 4502 ~4534) 등 세 가지이며 모두 비동기 전송 방식을 지원한다. 따라서 이 세가지 방식으로 자바쪽 구현체와 통신하면 된다. 위 그림에서는 향후 확장성을 고려하여 웹 서비스 통신 방식을 채택한 것이며, 이를 위해 자바 구현체에서도 SOAP 및 REST 웹 서비스를 위한 장치가 마련되어야 한다. 자바에서 SOAP 기반 웹 서비스는 JAX-WS를 통해 Servlet이나 EJB를 통해 제공하고, REST 기반 웹 서비스는 JAX-RS를 통해 Servlet으로 구현된다. 위 그림은 프리젠테이션 레이어에서 Servlet 기반으로 SOAP 및 REST 기반 웹 서비스를 제공하는 모습을 보여준다. JSP 페이지내에 <object> 태그를 통해 embed 된 Silverlight 애플리케이션은 사용자 머신에 다운로드 되어 서버측 자바 구현체와 직접 통신을 하게 되며 이때부터는 일반적인 표준 웹 서비스 개발 방식에 따라 개발 및 통신을 하면 된다.

image

위 그림은 사용자 브라우저내의 Silverlight 애플리케이션이 서버측 프리젠테이션 레이어가 아닌 비지니스 레이어의 EJB와 직접 웹 서비스 통신을 하는 경우를 보여준다. REST 기반의 웹 서비스를 제공하기 위해서는 App Server에 별도의 Servlet 컨테이너가 설치되어야 하며, 그림에서는 이미 설치되어 있는 EJB 컨테이너 기반의 JAX-WS 구현체를 통해 통신하는 모습을 보여준다.

근래에 모 파트너사의 MES 솔루션을 본 적이 있었는데, 자바로 구현된 백엔드와 통신하면서 사용자에게 보여지는 화면을 WPF로 구현하려 하고 있었다. 백엔드는 메시지 기반 통신을 위해 메시지큐를 사용하고, 자바로 구현한 JMS 리스너가 있어 전달되는 메시지를 수신하여 비지니스를 구현하고 있으며 백엔드 전체에 대한 조율을 위해 ESB가 위치해 있다. JMS에 대한 접근을 원활하게 하기 위해 닷넷에서 사용할 수 있는 ESB 어댑터를 구현하였고 WPF 애플리케이션에서는 이 어댑터를 통해 JMS와 아무 문제없이 통신하는 모습을 보여주었다.

우리가 숱하게 되뇌고 있지만 정작 놓치기 쉬운 것이 바로 비지니스 포커스 혹은 고객 포커스 관점에서 접근하는 것이다. 비지니스를 위해, 고객을 위해 가장 바람직한 서비스가 무엇인지, 그 다음에 그것을 구현하기 위해 합리적인 선택이 무엇인지 접근하다 보면 점차 많은 영역에서 이기종 플랫폼 및 언어를 접하게 될 것이다. 이 때문에 공개 표준 기반의 상호운용성이 그 어느 때보다 중요하며, 이를 염두해두고 시스템을 설계하는 것이 필요하다.

Posted by 장현춘

예전 블로그에 썼던 글인데, 필요해서 예전 싸이트가 사라지기 전에 가져왔습니다.
--------------------------------------------------------------------------------------------------------------------------------

Service Component Architecture (SCA)에 잠시 살펴보자. SCA는 IBM, BEA 등이 주축이 되어 Sun의 입김이 강한 JCP (Java Community Process)를 거치지 않고 독자적으로 표준화를 진행한 SOA 기반의 서비스 구축에 관한 스펙이다. 당시 자바 표준을 정하는 JCP를 거치지 않고 독자 행보를 한 이들 업체들에 대해 곱지 않은 시선이 있었지만, 이들 외에도 그 당시에 JCP를 벗어나 독자 스펙을 제정하는 일이 여럿 있었다. (가령 볼랜드가 주축이 됐던 툴 표준화라던가...) 그만큼 JCP에 대한 Sun 역할에 불만이 적지 않았던 것이 사실이다.  현재 SCA는 Oasis에 넘겨져 표준화 절차를 밟고 있으며 SCA의 홈페이지는 http://osoa.org이다. SCA는 현재 자바만을 위한 스펙은 아니나 자바가 주축을 이루고 있다. SCA는 서비스를 제공할 애플리케이션을 컴포넌트 기반으로 어떻게 작성하고 이들 컴포넌트를 어떻게 엮어서 좀 더 복잡한 Composite Application을 만드는 가에 관한 스펙이다. 예전에 한국마이크로소프트가 주최한 아키텍트 포럼에서 강연한 David Chappell (http://davidchappell.com)이 언급한 바와 같이 SCA는 WCF와 여러 면에서 유사하다.

가장 큰 유사성은 하나의 비지니스 기능을 구현한 후 다양한 Binding을 제공하는 것이 Configuration 파일에서 선언하는 것만으로 가능하다. 필요한 모든 요소는 SCA 벤더가 제공하는 런타임이 다 제공한다. 차이점이라면 WCF는 닷넷 진영에서 제공해왔던 다양한 분산 환경에서의 통신 기술들은 통합한 전혀 새로운 표준 개발 방식이라면, SCA는 새로운 분산 환경에서의 통신 표준이라기 보다는 자바 진영의 기존 분산 환경 통신 기술들을 쉽게 사용할 수 있게 중간에서 매개 역할을 하며 필요한 것들을 자동화한다는 것이다.
서비스를 제공하는 컴포넌트를 만드는 방식에서도 WCF의 ABC (Address,Binding,Contract) 기법이 그대로 적용된다. 다만 약간의 용어가 다를 뿐....uri, binding, service 라고. 다른 점이라면 SCA는 컴포넌트들을 조합하여 좀 더 복잡한 컴포넌트를 만들기 위한 스펙이 있어서 서비스를 노출하는 인터페이스 외에 서비스를 참조하는 인터페이스를 기술하도록 하고 있다. 즉, 내가 필요로하는 서비스는 이런 이런 기능을 갖춘 서비스입니라..라는 식의 인터페이스를 기술하여 툴을 통해 비주얼하게 서비스를 해당 컴포넌트에 엮을 수 있게 하고 있다.
둘의 가장 큰 차이는 구현 언어에 있다. WCF는 당연 닷넷 언어로 구현하여야 하나, SCA는 자바 외에 C++, BPEL 등이 가능하며 Container 형태로 추가가 가능하다. 아울러 Spring Framework과 궁합이 잘 맞아 구현 Container로 Spring을 바로 적용할 수도 있다.

자바에는 SCA외에도 이와 유사한 기능을 하도록 만든 스펙 및 프레임웍이 존재한다. JBI (Java Business Integration)과 ESB (Enterprise Service Bus)가 그것이다. 이 셋을 어떻게 자리매김하는 가에 대해 상이한 의견이 있는 듯 하며 이들이 향후에 어떻게 교통정리가 되어 자리매김할 지 추측해보자.

SCA의 홈페이지에서는 SCA와 JBI에 대해 언급하면서 이 둘은 서로 충돌하여 하나가 배제되는 것이 아닌, 필요하면 함께 구현 가능하고 혹은 별개로 사용 가능하다고 밝히고 있으며, JBI가 애플리케이션 서버를 만드는 업체에서 JBI Container 만드는데 사용되는 것이며, SCA는 벤더가 아닌 개발자 및 배포자가 컴포넌트를 어떻게 만들고 조작하는가에 중점을 둔 스펙이라고 하고 있다. 이 둘의 아키텍처는 아주 유사하여 런타임이 있고 이를 기반으로 각종 container 형태의 것들이 실제 서비스를 구현한 컴포넌트를 담고 있고, 이들간 혹은 이들과 외부 서비스간의 통신은 binding을 통해 제공되는 형태이다. 하여 SCA입장에서 JBI는 SCA 런타임 위에 올라가는 각종 container를 구현하는 표준 API로서 역할로 자리매김하는 듯 하다. 하지만, JBI를 자세히 들여다 보면 SCA 만큼이나 개발 영역에도 할 말이 많음을 알게 된다. JBI 런타임 혹은 서버 구현은 물론 서비스 모니터링 기능 및 서비스 조합을 위한 에디터 등 컴포넌트 개발과 운영에 관해 큰 그림을 그리고 있음을 알 수 있다. 하지만, 대체적인 분위기는 SCA가 앞단에서 서비스를 조합하는 역할에 치중하고 JBI는 뒷단에서 서버 구현을 표준화시켜 3rd party가 만든 container를 맘껏 올릴 수 있게 하는 것으로 자리매김되고 있는 듯 하다. 썬이 엔터프라이즈 웹 서비스 분야에서의 좁아진 입지를 만회하고자 JCP를 통해 강력히 밀고 있는 JBI는 SCA의 구현을 원활히 하는 표준화 쪽으로 가닥을 잡을 것 같다. 현재 SCA를 구현한 오픈 소스 런타임으로는 아파치의 Tuscany와 Codehaus에 올라있는 Fabric3가 대표적이며 이들은 JBI와 무관하게 구현되어 있다.

그럼 ESB와 SCA 혹은 JBI와는 어떤 관련이 있을까 ?
ESB는 SCA,JBI와 달리 스펙이 아니다. 마케팅 용어로 시작되어 현재는 SOA 기반 개발 표준 프레임웍으로 자리잡고 있으며 SOA 기반의 제품을 표방한 서버 치고 ESB를 언급하지 않은 업체가 없을 정도이다. ESB의 아키텍처는 JBI와 유사하며 다수의 구현에 따라 얼마든지 바뀔 수 있다. JBI의 아키텍처에는 명시적으로 런타임의 가운데에 NMR (Normalized Message Router)라는 메시지 버스가 있고 이 주변에 서비스 구현체에 해당하는 Service Engine과 바인딩을 위한 Binding Component라는 것이 있어서 서비스간 바인딩을 제공한다. ESB는 표준이 없으나 태생이 MOM (Message-oriencted Middleware) 업체의 마케팅 용어이기 때문에 아키텍처 또한 메시지 기반의 백본에 (웹) 서비스를 표준 바인딩 수단으로 하고 중간에 메시지 변환 및 addressing, routing, 메타데이터 관리 등을 제공하는 형태로 되어 있으며 근래에는 BPM 기능도 ESB의 요소로 간주하고 있다. 현재 오픈 기반의 ESB 구현체로 썬 주도의 JBI 스펙 기반의 OpenESB, apache의 ServiceMix 등이 있다.
결국, ESB 제품을 구현함에 있어서 SCA 기능을 제공할 수도 있고 JBI 스펙 기반으로 ESB 서버를 만들 수도 있는 것으로 보인다. 현재 일부 ESB 제품이라고 얘기하는 자바 진영의 서버 가운데 SCA 스펙 제정을 주도한 업체들은 대부분 SCA를 지원하는 ESB를 선보이고 있고, 썬의 애플리케이션 서버는 OpenESB를 지원하며 SCA 기능은 제공하지 않는 것으로 보인다. 참고로 썬도 Open SOA 그룹 (http://osoa.org)의 늦깍이 회원이 되었다.

애초 생각은 WCF와 기능면에서 유사한 SCA에 대해 살펴보고자 했는데, SCA 이전부터 썬이 JBI 기반 구현체를 오픈/상용 형태로 개발 중이었고, 이를 애플리케이션 서버에 Servlet 컨테이너, EJB 컨테이너와 나란히 JBI 컨테이터 형태로 올리려했다는 것을 알고 있었기에 JBI까지 언급하기에 이르렀다. 현재 JBI 입장에서 JEE 컨테이너와의 연동은 중간에 브릿지 역할을 하는 JEE용 Service Engine을 통해 이루어지고 있다. ESB를 또 끌어들인 이유는, 서비스 기반 개발 방법에는 소위 ESB 서버를 빼 놓고는 현재 시장에서 관심을 끌지 못하고 있는게 현실이며, 많은 소위 SOA 제품군들이 ESB를 핵심 백본으로 그리고 있어서 결국 SCA가 하고자 하는 일이 이루어지는 바탕은 ESB가 구현된 SOA 제품군 위에서이다. 속 깊은 내용은 알 길이 없으나 표면적으로 볼때 현재 ESB를 표방한 IBM의 SOA 제품군은 예상대로 SCA를 지원하며 특히 컴포넌트 조합을 위한 개발 툴을 통합시킨 형태로 가고 있고 JBI에 대해서는 그다지 관심이 없어 보인다. 반면 썬의 경우 JCP를 통해 표준화한 JBI관점에서 접근하며 OpenESB (http://open-esb.dev.java.net) 라는 구현체를 통해 JBI를 구현하여 자신들의 오픈 소스 애플리케이션 서버인 Glassfish (http://glassfish.dev.java.net) 에서 OpenESB를 지원함으로써 JBI를 드라이브하고 있고 SCA에 관해서는 그다지 큰 관심을 보이는 것 같지는 않다.

밖에서 보는 입장에서 그리고 상용 벤더 입장에서 보면 SCA가 훨씬 많은 매력적으로 보인다. 컴포넌트를 WISWIG형태로 조합해서 서비스를 만드는 개발 툴과 이를 자신들의 ESB 서버에 바로 디플로이하게 함으로써 개발을 쉽게 할 수 있고, JBI는 ESB 서버를 구현할 때 확장팩 형태로 각종 자바 관련 기술들을 엮는 방식으로 지원하는게 합리적일 듯 싶다. 언제까지 SOA가 시장을 지배할지, 그리고 ESB가 SOA의 핵심이 될 지 모르겠으나, 이런 추세라면 중첩된 기능을 통합하여 SCA + JBI = ESB 스펙으로 통합 제정함이 어떨까..닷넷하는 사람으로서 대응하기 힘들어서 .... ;)

위 내용은 개인의 생각을 적은 것으로 의도적으로 사실을 왜곡하는 내용은 없을 듯 하나 일부 부정확한 내용이 있을 수 있다.

Posted by 장현춘
TAG esb, JBI, SCA, SOA

Mastering EJB 책의 PDF 버전을 무료로 배포하며 EJB 초창기에 닷넷과의 각종 비교를 통해 유명세를 탔던 TheServerSide.com (TSS) 에 이어, 엔터프라이즈 닷넷 커뮤니티를 표방하고 오픈한 TheServerSide.NET에 위와 같이 엔터프라이즈에서 닷넷의 페이스가 자바를 앞지르고 있다는 글이 올라왔다. 지금껏 자바에 편향된 데이터를 수집 발표하여 자바 진영에서만 주로 인용되어 왔던 Evans Data Corp에서 독자적으로 조사를 수행하였는데 모집단은 평균 직원수 1000명 이상의 기업의 350 여 개발자를 상대로 조사한 것이다.

조사에 따르면 응답자의 60% 정도가 닷넷 투자를 늘리고 있으며 50%의 응답자는 닷넷 인력을 추가하였다고 밝히고 있다. 이는 닷넷 애플리케이션이 점차 엔터프라이즈 영역에서 확산되어 받아들여지고 있으며 이에 대한 의존성이 점차 높아지고 있다는 것을 의미한다는 CA Wily의 director의 말을 인용하고 있다. 이러한 추세는 점차 기업내 IT 인프라가 heterogenous 한 환경으로 급속히 변모함을 의미하므로, 이러한 환경에 적합한 통합 APM (Application performance Management) 시장의 전망 또한 밝다는 것을 의미한다고.... (국내는 이원영씨의 Jennifer가 APM 시장을 꽉잡고 있는데.... ^^) 기업내 닷넷 조직의 구성은 자바 인력 구성을 본 따 만들어지고 있으며 APM 관점에서의 효율성을 위해 같은 조직 내에 서브 조직으로 닷넷과 자바 팀을 운영하는 형태로 나타나고 있다.

좀 더 자세한 사항은 TSS를 방문하시길..
.NET outpacing Java?

Evans 조사 결과를 볼 수 있으면 좋으련만...

Posted by 장현춘

같은 인스턴스에 접근하는 모든 쓰레드는 해당 클래스의 멤버 변수로 선언된 값을 공유하기 때문에 멀티 쓰레드 애플리케이션 작성시 항상 공유 자원 보호 문제가 대두되기 마련이다. 즉 다수의 쓰레드가 동시에 한 인스턴스를 접근할 경우 해당 인스턴스의 멤버 변수에 저장되어 있는 값을 어떻게 thread-safe하게 관리할 것인가하는 문제가 발생하게 된다. 닷넷에서는 다양한 방법을 통해 동기화 문제를 유발할 수 있는 코드에의 접근을 serialize시킨다. 즉, 한번에 한 쓰레드(mutual exclusion)만이 해당 코드 블럭을 수행할 수 있게 바꾸는 방식으로 이 문제에 대한 답을 제공하고 있다.

1. Interlocked 클래스와 Monitor 클래스
한 프로세스내의 다수의 쓰레드 사이의 동기화 문제를 해결하기 위해 닷넷 이전부터 제공되어 오던 Win32 API를 닷넷버전으로 매핑한 경우이다. Interlocked 클래스는 Win32 API에서 제공하는 많은 메소드를 묶어 static 메소드로 노출하는 닷넷 클래스이다. Interlocked.Increment, Interlocked.Decrement, Interlocked.Exchange 등의 메소드를 가지고 있다. Monitor 클래스는 Win32 API의 CRITICAL_SECTION 구조체를 다루는 메소드를 닷넷 버전으로 모아 놓은 것이다. Win32 API의 EnterCriticalSection은 Monitor.Enter()로, LeaveCriticalSection은 Monitor.Exit()으로 형상화되었다.
Interlocked 클래스와 Monitor 클래스 중에 Interlocked를 쓰는 것이 성능상의 잇점이 있다. 즉 좀 더 가볍다.
2. lock 키워드
가장 일반적이면서 쉽게 쓰레드 동기화 문제를 해결할 수 있는 키워드가 lock이다. 공유자원에 대한 접근 중에 동기화 문제를 유발할 수 있는 블럭을 선택하여 lock을 통해 여러 쓰레드의 동시 접근을 막고 한번에 하나씩 수행을 하도록 하는 기능, 즉 mutual exclusion을 제공한다. lock은  컴파일 시점에 위에서 언급한 Monitor.Enter()와 Monitor.Exit()을 통해 코드가 재 해석되어 변경된다. 즉, lock()은 Monitor 클래스를 통해 구현된다.
private Object theLock = new Object();
lock (theLock) {
.....
}
3. ReaderWriterLock / ReaderWriterLockSlim
Read를 위한 쓰레드인지, Write를 위한 쓰레드인지를 구분하여 다수의 쓰레드가 Read만을 원할 경우 동시에 데이터에 접근하도록 허용하되, Write를 원하는 쓰레드가 작업중이면 모든 Read를 원하는 쓰레드는 대기상태에 들어가게 되는 원리이다. Reader를 위한 대기큐와 Writer를 위한 대기큐를 두어 좀 더 효과적인 리소스 활용이 가능하다. ReaderWriterLock클래스가 성능상의 문제가 있어서 .NET Framework 3.5부터 ReaderWriterLockSlim 클래스를 별도로 제공하는데, 가급적 언제나 새로 제공되는  ReaderWriterLockSlim을 쓰도록 한다.
ReaderWriterLockSlim theLock = new ReaderWriterLockSlim();
theLock.EnterReadLock() / theLock.ExitReadLock()
theLock.EnterWriteLock() / theLock.ExitWriteLock() 등의 메소드를 이용한다.
4. Mutex
앞에 열거한 기법들이 하나의 프로세스내의 다수 쓰레드 사이의 공유 자원 동기화를 위한 장치들이라면, Mutex는 이들과는 약간 다르게 여러 프로세스들 사이의 공유 자원 접근 문제를 해결하기 위한 장치이다.
5. Semaphore
Semaphore는 앞의 기법들이 한 프로세스 내의 쓰레드 동기화이거나 혹은 여러 프로세스 내의 쓰레드 동기화건 mutual exclusion 기반의 동기화 장치인데 반해 Semaphore는 동기화 관련된 코드 블럭에 접근 가능한 쓰레드의 수를 일정하게 유지하는 기법이다. 즉, 여러 쓰레드가 동시에 접근 가능하다. 아래는 최대 5개의 쓰레드가 동시 접근 가능한 semaphore를 설정하는 것이다.
private Semaphore semaphore = new Semaphore(0, 5);
semaphore.WaitOne();
try {
....
} finally {
  semaphore.Release();
}

lock(), Monitor, Interlocked 등이 사용자 모드에서 쓰레드 동기화를 처리하는 것인데 반해, Mutex와 Semaphore는 OS레벨의 커널 모드 객체들을 통해 구현되므로 훨씬 무겁기 때문에 가능하다면 언제나 좀더 가벼운 기능을 사용하도록 하는 것이 필요하다.

Posted by 장현춘

대부분의 경우에, 언어나 플랫폼에 상관없이 쓰레드의 동작 방식을 이해하고 이를 활용하여 멀티쓰레드 애플리케이션을 구현할 수 있을 때 그 사람을 중급 이상의 개발자로 보게된다. 닷넷 혹은 자바와 같이 managed 환경하의 개발 방식을 지원하는 경우 쓰레드를 생성하여 활용하는 것이 생각보다 쉽다. 다만 어디까지 활용할 것인가는 개발자 선택의 몫이다. 쓰레드를 논할 때 간과하는 것이 소위 말하는 green thread vs. native thread이다. OS 레벨에서 나름대로의 방식으로 생성하여 관리하는 native thread와, managed 환경 즉, CLR이나 JVM 레벨에서 제공하는 green thread가 있다. 당연하게도 green thread가 결국은 OS 레벨에서 process로 매핑이 되건 native thread로 매핑이 되어 실행된다. 하지만, CLR의 green thread와 OS의 native thread가 일대일 매핑될 것이라는 가정은 금물이다. 하나의 OS native thread가 여러 애플리케이션의 여러 green thread를 동시에 처리할 수도 있기 때문이다. (닷넷은 덜 하겠지만, 자바의 경우 한때는 Windows, Unix, Linux에서 green thread가 다르게 표현되기도 했다. Windows에서는 native thread와 매핑되고, Linux에서는 한 때 process로 매핑되어 애플리케이션에서 쓰레드 생성마다 java process가 지속적으로 늘어나기도 했고, Solaris의 경우 lightweight process내의 user thread에 매핑되기도 했다.) 어쨌거나 디버깅 필요에 의해서 native thread 레벨까지 뒤져보는 것은 필요하나 일반적으로 green thread와 native thread 사이의 연관 관계에 대해서 일체의 가정을 두고 애플리케이션을 작성하는 것은 위험하다. 왜냐하면 CLR의 green thread  관련된 구현이 바뀔 경우, 애플리케이션이 기반한 가정이 치명상을 입을 수 있기 때문이다.

쓰레드 생성
쓰레드의 생성은 sealed 클래스라서 상속이 불가능한 System.Thread 클래스와 ThreadStart delegate을 이용한다.
new Thread(new ThreadStart(name_of_method)).Start();  // C# with delegate
new Thread(o => name_of_method(x));   // C# with lambda operator
ThreadStart delegate의 signature를 보면 public delegate void ThreadStart()로 되어 있어서 리턴값과 파라메터가 없는 메소드를 받을 수 있다. 이는 흡사 자바의 Runnable 인터페이스에서 public void run()을 구현하게 하는 것과 유사하다.
new Thread(new Runnable{ public void run() { ..... }} ).start();   // java.. 자바에는 delegate도, anonymous method도 없어서 anonymous class를 이용해야 한다.
쓰레드가 필요시마다 위에서 처럼 생성하게 되면 오버헤드가 발생하므로 대부분의 경우 System.Threading.ThreadPool 클래스의 static 메소드인 QueueUserWorkItem()을 이용한다.
ThreadPool.QueueUserWorkItem(o => name_of_method (x));   // C# with lambda operator

쓰레드 라이프싸이클
쓰레드는 다음과 같은 life cycle을 가진다.
 
주의할 점은, 한번 일을 끝낸 쓰레드 (그림에서 Finished 혹은 Aborted 상태)는 다시 활성화되지 않는다. Running 상태에 있는 쓰레드는 그림에서 보듯이 현 쓰레드를 잠시 쉬게 하는 Thread.Sleep(), 다른 쓰레드가 끝날 때까지 기다리겠다는 otherThread.Join(), 동기화 필요에 의한 Monitor.Wait() 등에 의해 WaitSleepJoin 상태로 가게되며 이 상태에서는 interruption을 받을 수 있다. 즉, 쉬는 상태에서 interruption을 받아 ThreadInterruptionException을 발생시키고 이를 처리하면서 Running 상태로 복귀할 수 있다. 또한 Thread.Abort()을 이용하여 쓰레드를 종료시킬 수 있는데, 이 메소드를 받은 쓰레드는 그림에서 처럼 ThreadAbortException을 발생시키며 AbortRequested 상태에 빠지게 된다. 재밌는 것은 이 상태에서 ResetAbort()를 이용하여 Abort() 명령을 무력화시키고 다시 Running 상태로 갈 수도 있다는 것이다.

Foreground thread vs. Background thread
쓰레드에는 foreground thread와 background thread가 있다. 이 둘은 모든 면에서 동일하나, 다른 점은 한 프로세스상의 모든 foreground thread가 완료되면 해당 프로세스는 종료되는 반면, background thread는 이런 기능이 없어서 foreground thread가 완료되어 프로세스가 끝나면 background thread는 실행 도중에 종료된다. 따라서 background thread가 데이터베이스나 네트웍 연결을 담당하고 있다면 도중 종료로 인해 해당 자원이 불안정한 상태에 빠질 수 있다. C#에서 Main() 쓰레드는 해당 프로세스 내의 하나의 쓰레드일 뿐이라서 Main() 쓰레드가 종료되었지만 다른 foreground thread가 살아 있다면 해당 프로세스는 다른 모든 foreground thread가 종료될 때까지 종료되지 않는다. 물론 다른 쓰레드가 모두 background thread라면 Main() 쓰레드 종료와 더불어 프로세스가 종료된다. background thread는 Thread.IsBackground 라는 property를 true로 설정함으로 적용할 수 있다.

Thread별 변수 저장
멀티 쓰레드 애플리케이션을 작성시 가끔 고민하는 부분이, 다수의 쓰레드가 하나의 인스턴스에 접근할 경우 각 쓰레드별 고유한 값을 저장할 수 있는 변수의 필요성을 느끼게 된다. 이 경우 사용할 수 있는 장치가 ThreadStatic attribute이다. System.ThreadStaticAttribute로 정의되어 있으며, 작성하고자 하는 클래스의 static 멤버에 이 속성을 추가함으로써 해당 static 멤버는 접근하는 모든 쓰레드에 대해 고유한 변수를 갖게 된다. static 멤버 변수는 해당 클래스의 모든 인스턴스 사이에 공유되는 값인데 반하여, ThreadStatic static 멤버 변수는 해당 클래스 및 인스턴스에 접근하는 모든 쓰레드에 고유한 값을 저장하는 변수가 되는 것이다.

아래는, ThreadStatic으로 지정된 Hey에 대해, thread1과 thread2는 같은 인스턴스에 대해 메소드를 호출하고, thread3는 클래스 메소드(static method)를 호출할 경우 ThreadStatic 변수인 static string Hey에 저장된 값이 무엇인지를 출력하는 간단한 프로그램이다.

using System;
using System.Threading;

public class ThreadStaticTest
{
    public static void Main(string[] args)
    {
        MyThreadField a = new MyThreadField();
        Thread thread1 = new Thread(new ThreadStart(a.SayHello1));
        thread1.Start();

        Thread thread2 = new Thread(new ThreadStart(a.SayHello1));
        thread2.Start();

        Thread thread3 = new Thread(new ThreadStart(MyThreadField.SayHello2));
        thread3.Start();
    }
}

public class MyThreadField
{
    [ThreadStatic]
    public static string Hey = "babo";
    public void SayHello1()
    {
        for (int i = 0; i < 10; i++)
        {
            Hey = Hey + Thread.CurrentThread.GetHashCode();
            Console.WriteLine("Thread {0} starting... {1}", Thread.CurrentThread.GetHashCode(), Hey);
            Thread.Sleep(100);
        }
    }
    public static void SayHello2()
    {
        for (int i = 0; i < 10; i++)
        {
            Hey = Hey + Thread.CurrentThread.GetHashCode();
            Console.WriteLine("Thread {0} starting... {1}", Thread.CurrentThread.GetHashCode(), Hey);
            Thread.Sleep(100);
        }
    }
}

결과는 예상대로 쓰레드 간에 간섭없이 Hey 값이 쓰레드 별로 해당 쓰레드에 의해서만 변경되고 있다.
Thread 3 starting... 3
Thread 4 starting... 4
Thread 5 starting... 5
Thread 5 starting... 55
Thread 4 starting... 44
Thread 3 starting... 33
Thread 5 starting... 555
Thread 3 starting... 333
Thread 4 starting... 444
Thread 5 starting... 5555
Thread 3 starting... 3333
Thread 4 starting... 4444
Thread 3 starting... 33333
Thread 4 starting... 44444
Thread 5 starting... 55555
Thread 3 starting... 333333
Thread 5 starting... 555555
Thread 4 starting... 444444
Thread 4 starting... 4444444
Thread 5 starting... 5555555
Thread 3 starting... 3333333
Thread 3 starting... 33333333
Thread 4 starting... 44444444
Thread 5 starting... 55555555
Thread 3 starting... 333333333
Thread 5 starting... 555555555
Thread 4 starting... 444444444
Thread 4 starting... 4444444444
Thread 5 starting... 5555555555
Thread 3 starting... 3333333333

ThreadStatic 속성을 제거하면 아래처럼 쓰레드간 간섭에 의해 Hey에 저장되는 값이 불규칙하게 증가하는 것을 알 수 있다.
Thread 3 starting... babo3
Thread 4 starting... babo34
Thread 5 starting... babo345
Thread 3 starting... babo3453
Thread 4 starting... babo34534
Thread 5 starting... babo345345
Thread 4 starting... babo3453454
Thread 3 starting... babo34534543
Thread 5 starting... babo345345435
Thread 4 starting... babo3453454354
Thread 3 starting... babo34534543543
Thread 5 starting... babo345345435435
Thread 4 starting... babo3453454354354
Thread 3 starting... babo34534543543543
Thread 5 starting... babo345345435435435
Thread 4 starting... babo3453454354354354
Thread 3 starting... babo3453454354354354
Thread 5 starting... babo34534543543543545
Thread 4 starting... babo345345435435435454
Thread 3 starting... babo345345435435435453
Thread 5 starting... babo3453454354354354535
Thread 3 starting... babo34534543543543545353
Thread 4 starting... babo345345435435435453534
Thread 5 starting... babo3453454354354354535345
Thread 4 starting... babo34534543543543545353454
Thread 3 starting... babo345345435435435453534543
Thread 5 starting... babo3453454354354354535345435
Thread 4 starting... babo34534543543543545353454354
Thread 3 starting... babo34534543543543545353454353
Thread 5 starting... babo345345435435435453534543535

Posted by 장현춘

닷넷에서 C/C++로 작성된 dll을 사용하고자 할 경우 다음과 같은 방법이 있다.

1. 일반적인 native dll의 경우 - P/Invoke (Platform Invoke)를 써서 직접 호출
닷넷에서 Win32 API를 호출하거나 C/C++로 작성된 native dll을 호출할 경우, native dll이 제공하는 메소드의 signature나 타입에 대해 닷넷에서 인식하고 호출할 수 있도록 이에 대한 선언을 해야 한다. 크게 보면 세 단계로 구성되는데, 첫째 DllImport하여 필요한 dll 로딩하는 부분, 둘째 원하는 메소드 signature를 extern으로 선언하는 부분(즉, 이 메소드가 외부 native dll에서 정의되어 있다고 선언하는 부분), 마지막으로 이 메소드를 호출하여 원하는 값을 취하는 부분으로 되어 있다.

Win32 API에 대한 선언을 일일이 기억하기란 쉽지 않기 때문에 웹에 이에 대한 데이터베이스 형태의 wiki로서 PInvoke.net이 존재한다. 아래 화면은 http://www.pinvoke.net 에서 볼 수 있다.pinvoke 
아울러 PInvoke.net에서는 Visual Studio 2005에 대한 플러그 인을 제공하여 무료로 다운받아 설치할 수 있으며 아래 그림에서 처럼 VS내에서 원하는 선언문을 검색하여 바로 붙여 넣을 수 있다.
image 

이보다 좀 더 나은 방식으로 간단한 애플리케이션 형태의  AppViewer가 존재하여 편리하게 원하는 API에 대한 선언문을 사용할 수 있다. 아래 그림에서 보듯이 다양한 언어, 심지어 delphi나 MASM에서 사용할 수 있는 기능까지 제공하고 있다.
 image image

자바에서도 이와 동일한 세 단계 방식의 호출 방법이 있는데, JNI (Java Native Interface)라고 부른다. System.loadLibrary()하여 dll을 메모리에 올리는 부분, 호출하고자 하는 메소드의 signature를 native라는 modifier를 써서 선언하는 부분(역시 이 메소드의 구현은 native하게 외부에 정의되어 있다고 선언하는 부분), 마지막으로 이 메소드를 호출하는 부분으로 구성된다. 자바가 호출하는 메소드를 C/C++에서 구현하기 위해서는 각 언어에 맞는 헤더파일이 필요한데 이를 위해 javah -jni 명령어를 써서 *.h 파일을 생성하며 이렇게 생성된 *.h를 C/C++에서 include하여 개발하는 과정을 거치게 된다.

2. COM 서버 접근 - RCW (Runtime-Callable Wrapper)를 이용하는 방법
COM 객체에 대한 wrapper를 만들어서 닷넷에서는 마치 일반적인 닷넷 객체를 호출하듯 프로그래밍할 수 있도록 지원하는 방법이다. Visual Studio에서 Add Reference기능을 클릭하며 아래에서 처럼 COM 컴포넌트를 선택할 수 있으며 OK를 누르는 순간 레퍼런스가 추가되면서 이 COM 컴포넌트에 대한 닷넷 Wrapper가 생성된다. 생성되는 wrapper는 Interop.xxx.dll의 어셈블리가 된다. 따라서 개발자는 닷넷 프로그래밍 하는 방식으로 COM 객체를 생성하고 호출할 수 있게 된다.
image
Visual Studio를 사용하지 않는 경우에는 .NET SDK에 들어있는 TlbImp.exe 명령어를 사용하여 wrapper를 생성할 수도 있다.
COM 객체가 대단히 크거나 복잡할 경우 생성되는 Wrapper의 크기 또한 부담스러우며, COM 내부에서 사용하기 위해 만든 인터페이스를 wrapper에서 숨길 수 있는 방안도 없기 때문에, 간편하게 생성하여 사용할 수 있는 장점이 있지만  COM 객체의 특성에 따라 이 방법이 적합한지 한번쯤은 생각해 볼 필요가 있다. 아울러 사용이 끝난 COM 객체는 해당 wrapper가  GCed될 때까지 살아 있기 때문에, wrapper가  Garbage Collector에 의해 GCed될 때까지 기다리지 말고 System.Runtime.InteropServices.Marshal.ReleaseComObject()를 이용하여 즉시 해제해주는 것이 좋다.

Posted by 장현춘