대메뉴 바로가기 본문 바로가기

데이터 기술 자료

데이터 기술 자료 상세보기
제목 ASP.NET 5
등록일 조회수 5239
첨부파일  

ASP.NET 리부트

ASP.NET 5



2014년 2월 취임한 사티아 나델라(Satya Nadella) 마이크로소프트(MS) 최고경영자(CEO)는 ‘모바일 퍼스트, 클라우드 퍼스트(Mobile First, Cloud First)’라는 비전과 함께 변화를 주도했다. 아이패드용 오피스를 출시하고 일부 제품을 무료로 전환하고 닷넷 프레임워크의 소스를 공개하는 등, 이전의 MS라면 상상할 수 없던 변화를 보여줬다. 이 비전엔 어떤 의미가 있을까.



사티아 나델라 CEO가 정의하는 모바일은 단순히 스마트폰, 태블릿을 지칭하는 게 아니라는 점에 주목해야 한다. 장치의 이동성이 아닌 사용자 경험의 이동성이다. 이것은 어떤 환경에서도 비슷한 사용자 경험을 제공할 수 있어야 한다는 의미다. 그 환경은 맥, 리눅스, 윈도우 기반의 데스크톱처럼 플랫폼이 다양할 수도 있고, 스마트폰, 태블릿처럼 장치가 다를 수도 있다.

다른 플랫폼, 다른 장치에서 연속되는 사용자 경험을 제공해야 한다는 관점에서 클라우드는 백엔드로서 자리매김할 수 있다. 클라우드는 클라우드에 최적화한 애플리케이션이 있어야 빛을 발할 수 있다. 이런 상황에서 ASP.NET는 어떻게 바뀌어야 하고, 바뀌게 될까. 잠깐 ASP의 역사를 살펴보자.



ASP의 역사 1996 - Active Server Pages (ASP) 2002 - ASP.NET 2008 - ASP.NET MVC 2010 - ASP.NET Web Pages 2012 - ASP.NET Web API, SignalR 2014 - ASP.NET 5



지난 18년 동안의 역사에서 가장 큰 변화는 ASP.NET의 등장이다. ASP가 소개된 지 6년 뒤의 일이다. ASP.NET의 등장 뒤 6년이 지난 2008년에는 MVC가 새로운 웹 개발의 축으로 등장했다. 올해는 MVC 등장 6년이 되는 해다. ASP.NET5는 또 다른 지각변동을 시사하는 시점에 ASP.NET 등장과 버금가는 변화를 준비하고 있다.

현재 오픈소스 프로젝트(https://github.com/aspnet/Home/)로 진행되고 있는 ASP.NET 프레임워크는 베타 5버전이다. 정확한 버전은 1.0.0 베타 5다. 메인 버전이 시사하는 바가 크다. ASP.NET 5의 변화는 양적으로나 질적으로나 알아볼 내용이 많다. 새롭게 시작하는 ASP.NET 의 중요한 변화를 10가지로 간추려 3부에 걸쳐 살펴볼 것이다.



1. 닷넷 코어

닷넷 프레임워크는 2002년 단일 프레임워크로 등장했다. 바로 이어서, MS는 윈도우 모바일을 위한 경량 버전인 닷넷 컴팩트 프레임워크라는 서브셋(subset)을 출시했다. 이 컴팩트 프레임워크는 닷넷 프레임워크에 기반해서 만들었지만 그 자체로 실행환경(runtime), 프레임워크, 애플리케이션 모델을 갖는 형태로 디자인되었기 때문에 별도의 코드 기반(code base)이라 할 수 있다. 즉, 윈도우 모바일에서 애플리케이션을 작성하기 위해서는 닷넷 프레임워크가 아닌 닷넷 컴팩트 프레임워크를 사용한다는 의미다.

이렇게 실행환경, 프레임워크, 애플리케이션 모델을 모두 갖춘 형태를 버티컬(vertical)이라고 한다. 이런 방식의 지원은 실버라이트, 윈도우 폰, 최근의 윈도우 스토까지 이어져 여러 개의 버티컬들을 만들어 냈고 닷넷 플랫폼은 하나가 아닌 여러 플랫폼의 집합이 됐다.



특별한 환경, 특별한 요구사항을 만족시키기 위해 특화된 버티컬을 제공하는 것이 잘못된 것은 아니다. 그러나, 지금하고 있는 프로젝트의 요구 사항을 한번 살펴보자. 오늘날, 웹 서버를 백엔드로 두고, 관리자를 위해 데스크톱 애플리케이션을 제공하고 일반 사용자를 위해 웹과 모바일 애플리케이션을 제공하는 건 더 이상 특별한 요구사항이 아니다. 여러 버티컬에서 수평적으로 운영할 수 있는 애플리케이션을 효과적으로 만들 수 있는 방법이 필요하다. 버티컬의 경계를 허물기 위해Portable Class Library 를 포함한 여러 가지 노력이 있었고 그런 노력과 실패의 경험들이 닷넷 코어(.NET Core)를 탄생시켰다.



닷넷 코어는 모놀리식(monolithic) 닷넷 프레임워크를 모듈화하고자 하는 접근법에서 비롯되었다. 닷넷 코어는 닷넷 코어 런타임인 CoreCLR과 닷넷 코어 라이브러리인 CoreFX로 구성되고 이들은 버티컬에서 각각 런타임과 프레임워크에 해당한다. 자세한 구조는 <그림 3>과 같다.



CoreCLR을 런타임으로 하는 축을 살펴보면 애플리케이션 모델로 ASP.NET 5가 있다. (ASP.NET 5 앱 모델의 이해하기 쉬운 예는 MVC다) 닷넷 네이티브 런타임(.NET Native Runtime)은 터치기반 장치들의 실행환경이고 애플리케이션 모델을 통해 윈도우 클라이언트용 앱 개발을 지원한다. 주목할 부분은 Unified BCL인데 런타임과 애플리케이션 모델이 달라도 BCL이 같다는 것이다.

이 사실은 <그림 1>의 프레임워크와 근본적인 차이를 갖는다. 프레임워크에서 제공하는 Collection을 예로 들면 <그림 1>의 구조는 모든 버티컬에서 Collection를 똑같이 구현하고 있는 구조라면, 닷넷 코어의 프레임워크는 여러 개가 아닌 통합된 하나의 프레임워크라는 것이다. 닷넷 코어는 하나의 새로운 버티컬을 정의했고 통합된 BCL(현재 닷넷 프레임워크의 BCL이 꾸준히 모듈화되어 NuGet 패키지로 제공되는 CoreFX 라이브러리들)을 중심으로 계속 런타임과 애플리케이션 모델을 추가해 갈 것이다. 개발자 입장에서 생각하면 윈도우 클라이언트용 앱을 개발하든 ASP.NET 5의 앱을 개발하든 NuGet에서 필요한 기능을 골라서 사용(pay-as-play)할 것이고 이 기능들은 모든 런타임에서 동작하기 때문에 사용자에게 훌륭한 모바일 경험을 선사할 것이다. CoreCLR 또한 NuGet 패키지 형태로 애플리케이션에 포함되는데 운영체제에 독립적인 실행환경을 제공하는 것이 목적이다. 자세한 내용은 다음 절에서 소개한다.

닷넷 코어는 일년에 네 번 정도 업데이트를 하며 닷넷 프레임워크 보다 버전이 앞서 갈 것이고 닷넷 프레임워크는 닷넷 코어의 변화를 수용하는 방식으로 일년에 한 번 정도 업데이트가 될 것이다.



2. 병렬 (side-by-side) 수행과 크로스 플랫폼

윈도우 2003 서버에는 닷넷 프레임워크 4.5를 설치할 수 없다. 닷넷 프레임워크는 이전 버전과 호환성을 유지하면서 새로운 기능을 추가하는 방식으로 발전해 왔고 이런 방식에는 여러 가지 내부적인 문제가 있었다. 변경, 확장이 어렵기 때문에 어쩔 수 없이 호환성을 포기해야 하는 시점이 필요했을 것이다.

새 프로젝트를 위해 새 서버를 준비하는 것이 이상적이겠지만 기존 웹 서버에 새 웹 애플리케이션을 추가하는 일이 현실적으로 더 많다. 이 것은 동일 서버에서 다른 버전의 런타임을 실행해야 하는 상황(side-by-side execution)을 유발하기도 한다. 닷넷 웹 애플리케이션은 대상 런타임을 외부환경에 의존하고 있기 때문에 이를 위한 설정이 필요하다. 예를 들어, IIS의 애플리케이션 풀을 새롭게 생성하여 대상 닷넷 프레임워크를 지정한 후, 웹 애플리케이션에서 사용하게 구성 되어 배포되므로, 배포 관점에서는 실행환경이 애플리케이션에 포함되었다고 할 수 있다. 닷넷 프레임워크가 machine-wide 영향력을 갖고 있는 반면 CoreCLR은 application-local수준에 한정된다. 병렬 수행보다 더 큰 혜택은 크로스 플랫폼에 있다. 애플리케이션의 실행환경에 대한 의존성이 CoreCLR 에만 있기 때문에 CoreCLR이 지원하는 모든 운영 체제에서 애플리케이션이 동작한다는 것은 대단한 변화임에 틀림없다.

오픈 소스로 진행되고 있는 CoreCLR 은 리눅스, 윈도우, 맥 OS X, FreeBSD 운영체제를 지원할 예정이다. CoreCLR은 Full CLR의 1/10 정도 크기인 14MB 이며 Hello World를 출력하기 위해 System.Console조차도 패키지로 추가해야 한다. 한편으로는 기존 프레임워크와 새로운 프레임워크를 동시에 고려해 애플리케이션을 컴파일 하고 실행할 필요가 생겼다. 개발 시점에 이렇게 다른 종류, 다른 버전의 프레임워크를 어떻게 관리하여야 할까? 비주얼 스튜디오(Visual Studio)와 같은 개발 도구에 종속적이지 않으면서 런타임을 관리하는 도구가 필요하다. DNVM, DNX, DNU 이렇게 세 가지 도구이다.

이렇게 구성되는 환경을 통칭하여 DNX (umbrella term) 라고도 한다. 따라서 글의 문맥에 따라 CoreCLR과 함께 등장한 런타임 환경, 또는 특정 명령어 도구로 해석할 수 있겠다.



3. 미들웨어

ASP.NET 5의 변화를 알아보기에 앞서 프레임워크의 변화를 먼저 살펴보았다. CoreCLR은 ASP.NET 애플리케이션을 작성할 수 있는 새로운 기반이고 그로 인해 얻는 혜택을 이해하는 것이 중요했기 때문이다. 이제 ASP.NET 개발자들이 보다 흥미로울 주제에 대해 알아보도록 하겠다. ASP.NET에서 System.Web 을 사용하여 http 요청을 처리하는 경우에 많은 정보를 운반하는 HttpContext.Current는 32KB의 메모리를 차지한다. ASP.NET 5의 http 요청 처리는 Node.js 스타일의 raw socket 과 유사하게 변경되어서 3KB 정도의 메모리만 차지한다. 이렇게 90% 감소된 메모리 사용은 로딩 타임을 줄여 사용자 요청에 빠르게 응대하고 동시에 더 많은 요청을 처리할 수 있게 해준다. 그러나 대폭 향상된 성능의 이면에, 반드시 알아야 할 미들웨어란 개념이 도입됐다.



다른 종류, 다른 버전의 프레임워크에서 런타임을 관리하는 세 가지 도구

DNVM(.NET Version Manager)
DNVM은 다른 버전, 다른 아키텍쳐(x86 / x64)의 CLR을 관리한다. ‘런타임들(CLRs)’을 다운로드하고, 설치하고, 업그레이드 하고, 활성화된(Active) 런타임이 무엇인지 기억하고 알려준다. 이전 까지 KVM 으로 불려오다가 Visual Studio 2015 RC 등장과 함께 DNVM으로 공식 이름을 달았고 마찬가지로 Project K에서 시작된 다른 도구들도 D 네이밍으로 공식화됐다.



DNVM은 버전 매니저라는 이름에 걸맞게 list 명령어를 통해 컴퓨터에 설치된 모든 CRL들을 보여준다. 아래 그림은 아키텍쳐에 따라 제공되는 CLR(Full CLR)과 CoreCLR을 보여준다. 런타임을 선택하려면 version, runtime, architecture를 지정해야 하는 번거로움이 있기 때문에 alias를 지정하여 dnvm use default 와 같이 간편하게 사용할 수 있다.

DNX(.NET Execution Environment)
DNX는 SDK(Software Development Kit)로서 애플리케이션을 빌드하고 실행하기까지 모든 것에 대한 실행환경이다. DNX는 또한 Portable CLR Host다. 크로스 플랫폼에서 동작하면서 CLR을 호스팅하고 애플리케이션의 시작점을 찾아 실행한다. dnvm list 명령어를 실행하면 볼 수 있는 목록에서 각 행은 하나의 dnx 를 의미한다.

DNU(.NET Utilities)
마지막 D 도구 그룹의 멤버는 DNU(.NET Utilities) 이다. 이 유틸리티는 여러 가지 다양한 기능을 제공하지만 주로 애플리케이션이 종속성을 갖는 NuGet 패키지를 설치하고 관리하는데 쓰인다.



System.Web을 사용해서 HTTP 요청 파이프라인을 작성하던 방식이 미들웨어를 사용하는 방식으로 정리되었다. 요청 파이프라인을 작성한다는 의미는 사용자 요청을 받는 순간부터 최종 응답을 작성하기까지의 요청의 라이프 사이클을 관리한다는 의미인데 이 과정에서 사용되었던 HTTP 모듈, 핸들러 등이 미들웨어로 바뀐 것이다.



<그림 5>에서 OWIN Server 영역 내에 있는 것은 모두 미들웨어인데 마지막 미들웨어가 최종 응답을 생성하고 있어서 애플리케이션의 역할을 한다고 볼 수 있다. 좋은 예로 MVC 6는 애플리케이션 역할을 하는 미들웨어다. 이렇게 미들웨어의 체인에서 어떤 미들웨어던지 응답을 생성해서 반환하는 것으로 작업을 마칠 수 있어서 아주 유연하고 확장성이 좋은 모델이다.

미들웨어는 OWIN에서 개념을 가져왔지만 HttpContext 와 RequestDelegate만을 높은 수준에서 추상화한 작은 개념이다. 미들웨어는 요청 파이프라인에서 콘텍스트 객체를 통해 정보를 읽고 쓸 수 있다. 또한 응답을 반환함으로써 파이프라인을 종료하거나 또는 다음 미들웨어를 호출하여 작업을 이어갈 수 있다. 미들웨어 간의 호출은 비동기로 이루어지기 때문에 서버 리소스 활용 측면에서도 효율적이다.

미들웨어를 구현하려면 클래스에 HttpContext를 인자로 받고 Task 객체를 반환하는 메소드, 그리고 RequestDelegate를 입력 인자로 받는 생성자를 정의하면 된다.



<리스트 1> 미들웨어 구현 using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using System.Threading.Tasks; namespace WebApplication1 { public class MyMiddleware { private readonly RequestDelegate _next; public MyMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { // do something // ... // call next middleware await _next(context); } } }



Invoke 메서드의 HttpContext는 System.Web이 아닌 Microsoft.AspNet.Http 네임스페이스에 있다. 이것으로 HTTP 요청처리 방식이 변경된 걸 알 수 있다. 또한, 생성자에서 받는 RequestDelegate의 정의를 보면 미들웨어가 되기 위한 요건과 같다는 걸 알 수 있다.

public delegate Task RequestDelegate(HttpContext context);

미들웨어 사용은 Startup 클래스의 Configure() 메서드에서 app.UseMiddleware() 메서드를 사용하여 구성한다. 이런 방식으로 개발자가 직접 요청 파이프라인을 관리하기 때문에 특별한 조치가 없으면 간단한 html 페이지도 브라우저에 보낼 수 없다. 그러나 app.UseStaticFiles() 처럼 많은 확장 메서드들이 편의를 위해 제공되므로 기본적인 작업 때문에 개발자가 수고를 들일 필요는 없다. 요청 파이프라인을 스스로 처리할 수 있는 능력 덕분에 셀프 호스팅이 쉬워졌다. Microsoft.AspNet.Server.WebListener처럼 기본적으로 제공되는 호스팅 환경을 사용할 수도 있지만 닷넷 매니지드 코드로 작성된 모든 애플리케이션에서 ASP.NET 5 앱을 호스팅할 수 있다.

만약 static 파일(image, html 등)을 미들웨어를 통해 처리하지 않는데도 불구하고 브라우저에서 볼 수 있다면 호스팅 환경(특히, IIS)에서 요청을 처리하기 때문이다. 개인적인 의견이지만 전통적인 ASP.NET + IIS 의 강력한 조합은 ASP.NET 5 미들웨어의 등장과 함께 재정리되어야 할 것 같다. 웹 서버의 종속성이 없어진 상황에서 웹 서버의 역할을 어떻게 규정해야 할까.



출처 : 마이크로소프트웨어 7월호

제공 : 데이터 전문가 지식포털 DBguide.net