PaaS2014. 8. 10. 09:34

ASP.NET Custom Loader (코드 네임 Helios)는 기존의 System.Web 기반의 전통적인 ASP.NET 프레임워크를 대체하는 기술로, IIS 파이프라인에 직접 관여하여 System.Web에 의존적이지 않은 최신 ASP.NET 개발 프레임워크들 (OWIN, Nancy, FubuMVC 같은)의 실행에 필요하지 않은 System.Web 및 관련 파이프라인을 생략하고 직접 이들 프레임워크를 중개할 수 있도록 도와주는 도우미입니다.

 

 

이 글을 작성 중인 2014년 8월 현재 최신 버전은 1.0 알파 버전으로, 조만간 출시될 ASP.NET vNext와 함께 릴리즈가 될 것으로 예상되는 기술입니다. 현재는 Windows Server 2008 R2 및 Windows 7 이상의 운영 체제를 정식으로 지원하며, IIS 및 IIS Express의 경우 7.5 버전 이상을 지원합니다. 정식 출시에 맞추어, Windows Server 2008과 Windows Vista, 그리고 IIS 7도 지원 대상에 포함될 것으로 예상됩니다.

ASP.NET Custom Loader의 실행 성능 개선 효과에 대해서는 여러 블로그 아티클이 있지만, http://blogs.msdn.com/b/webdev/archive/2014/02/18/introducing-asp-net-project-helios.aspx 의 내용을 살펴보실 것을 권합니다.

이 글에서는 ASP.NET Custom Loader의 동작 원리에 대해서 간단하게 설명을 하려고 합니다.

ASP.NET Custom Loader의 구성 파일 내역

ASP.NET Custom Loader는 다음과 같이 구성됩니다.
•AspNet.Loader.dll
•Microsoft.AspNet.Loader.IIS.dll
•Microsoft.AspNet.Loader.IIS.xml
•x86\Microsoft.AspNet.Loader.IIS.Interop.dll
•amd64\Microsoft.AspNet.Loader.IIS.Interop.dll

일단 위의 파일들이 bin 폴더에 복사되면, 특별히 web.config에서 수정하는 내용 없이 곧바로 기능이 활성화됩니다. 또한 이름에서도 알 수 있듯이, 지원 가능한 아키텍처는 x86과 amd64 아키텍처만 가능하며, 아이태니엄 및 ARM 아키텍처는 지원되지 않습니다.

실제 웹 프레임워크와의 연결

이제 중요한 것은 위의 Loader가 그 다음으로 주선할 웹 프레임워크를 지정하는 과정인데, 각 웹 프레임워크 별로 HttpApplicationAttribute를 어셈블리 수준에 적용하여 자신들의 웹 프레임워크 기술을 사용하는 개발자들을 위한 부트스트랩을 제공합니다. ASP.NET Web Loader는 이 정보를 찾아 연결을 시도하게 됩니다.

대강 아래와 같은 모양새를 가진 부트스트랩이 있어야 합니다. (물론 필요하다면 직접 만들 수도 있습니다.)

[assembly: HttpApplication(typeof(YourClass))]
 public class YourClass : HttpApplicationBase
 {
 }

이런 목적에 부합하는 기능과 관련된 종속 기능들을 OWIN에서는 아래 어셈블리들에 나누어 제공하고 있습니다.
•Microsoft.Owin.Host.IIS.dll
•Microsoft.Owin.Host.IIS.xml
•Microsoft.Owin.Host.IIS.Security.dll
•Microsoft.Owin.Host.IIS.Security.xml
•Microsoft.Owin.Hosting.dll
•Microsoft.Owin.Hosting.xml

기존에 OWIN 기반으로 배포한 응용프로그램이 있다면 ASP.NET Custom Loader를 배포한 다음 위의 어셈블리 파일들을 추가로 복사해야 ASP.NET Loader가 OWIN 시작 클래스를 연결해줄 수 있습니다.

주의 사항

이 글을 작성하는 현 시점에서 ASP.NET Custom Loader는 알파 버전을 릴리즈한 상태입니다. 그리고 이에 관하여 다음의 제약 사항들이 있습니다.
•Windows Server 2008과 Windows Vista, 즉 IIS 7의 경우 로더 실행 시 보안 알고리즘 관련 알 수 없는 HRESULT가 발생했다는 예외가 나타나면서 초기화가 이루어지지 않습니다. 공식 개발팀의 언급에 따르면, 정식 버전에서 해결할 예정이라고 합니다.
•Web.config에 configSource 애트리뷰트를 사용하여 나누어놓은 구성 파일이 있을 경우, 잘못된 경로 문자열이라면서 역시 Helios 초기화 도중 예외가 발생합니다. 불편하더라도 알파 버전의 테스트를 위해서는 구성 파일을 web.config 하나로 통합하셔야 테스트할 수 있습니다.

위와 같은 문제점에도 불구하고, 상당한 수준의 성능 개선은 개인적으로 만족스러웠습니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2014. 8. 3. 09:33

OWIN과 미들웨어

OWIN은 .NET Framework를 이용하여 코드를 실행할 수 있는 서버 환경이면 어디서든 사용이 가능한 이식이 편리한 코어 웹 프레임워크입니다. 기본적으로 OWIN은 웹 요청을 받아들이면 주어진 순서대로 구성된 미들웨어 체인을 따라 응답을 만들어내게 됩니다.

.NET Framework를 이용한 웹 응용프로그램 개발도 요즈음에는 다양한 프레임워크를 결합하여 개발하는 것이 요구 사항으로 자리잡고 있으며, 초창기의 .NET과는 달리 더 이상 System.Web 기반의 기술만으로 모든 것을 구현하지는 않습니다.

 

 

대표적으로, 최근 소개된 비동기 양방향 웹 소켓 호환 통신을 지원하는 SignalR의 경우 버전 2.0부터는 System.Web과 독립적으로 움직일 수 있도록 OWIN 위에서 실행되는 구조를 취하게 되었습니다. SignalR을 도입하는데 뜬금없이 OWIN Startup이라던지 하는 코드를 보면서 생소하다는 느낌을 받으셨다면 그게 바로 이것입니다.

재미있는 것은 OWIN 스택 전체는 기존에 ASP.NET을 실행하던 환경과 독립적인 관계를 가집니다. 기존 ASP.NET 환경 위에서 호스팅하는 경우 ASP.NET 환경보다 가장 먼저 앞서서 실행되는 형태로 되어있습니다. 이전처럼 Visual Studio 도구에 종속적인 방식으로 프로그래밍하는 것이 아니라, 내가 어떤 웹 기술을 사용할 것인지 Startup 클래스에서 정하여 선택적으로 사용할 수 있게 됩니다.

OWIN 기반의 응용프로그램 처음 만들어보기

앞에서 잠시 이야기한 것처럼 OWIN은 흔히 콘솔이나 클라이언트 응용프로그램처럼 시작점이 존재합니다. ASP.NET 기반의 응용프로그램으로 말할 것 같으면 Global.asax 같은 역할을 담당한다고 할 수 있습니다. 이것을 OWIN Startup 클래스라고 하며, OWIN Startup 클래스에서 내가 어떤 미들웨어를 사용하여 웹 요청을 처리할 것인지 프로그래밍할 수 있습니다.

빠르게 예제를 만들어보기 위하여, Visual Studio에서 비어있는 ASP.NET 프로젝트를 하나 만들어보도록 하겠습니다. (MVC나 Web Form 등은 일절 필요하지 않습니다.)

참고로, 이번 아티클에서 사용하는 Visual Studio 버전은 2013 버전이지만 2012로도 큰 차이 없이 작업할 수 있습니다.

새 웹 프로젝트를 만들면서 아래와 같이 One ASP.NET 프로젝트 대화 상자가 나타나는데, 빈 템플릿으로 하나 만들도록 합니다.

 

그러면 아래와 같이 최소 수준으로 구성된 웹 프로젝트가 만들어지게 됩니다.

 

프로젝트 항목 (위 그림 기준으로 OwinExample)을 마우스 오른쪽 버튼으로 클릭하고 NUGET 패키지 관리 메뉴를 클릭하면 아래와 같이 패키지 설치 대화 상자가 나타납니다. 우측 항목들 중 온라인 항목을 선택하고, 검색어에 “system.web owin”이라고 입력하여 검색합니다.

만약 이 기능을 찾을 수 없는 경우 Visual Studio에 NuGet 패키지 관리자가 설치되어있지 않은 것이므로, http://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c 에서 익스텐션을 내려 받아 설치하시면 됩니다.

 

나타나는 검색 결과 항목들 중 Microsoft.Owin.Host.SystemWeb 항목을 클릭하고 Install 버튼을 클릭하면, 종속성 관계에 따라 추가 설치가 필요한 패키지에 대한 정보나 라이선스 동의 등의 추가 확인 대화 상자가 나타날 수 있고, 여기에 모두 승인하시면 ASP.NET 프로젝트에서 OWIN을 사용할 수 있게 준비가 완료됩니다.

설치가 마무리되면 새 클래스를 만듭니다. 아래와 같이 클래스의 내용을 작성하도록 합니다. 혹은 Visual Studio 2013을 사용하는 경우 새 파일 템플릿 중에 OWIN 시작 클래스라는 항목도 있는데 이 항목을 대신 사용해도 됩니다.
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(OwinExample.Startup1))]

namespace OwinExample
{
    public class Startup1
    {
        public void Configuration(IAppBuilder app)
        {
        }
    }
}


위에 보시는 것이 처음 OWIN 프로그램을 시작할 때 사용되는 시작 클래스입니다. 여기서 Configuration 부분에 OWIN에서 사용할 미들웨어 등에 대한 구성을 추가하면 됩니다.

OWIN 패키지로 설치되는 라이브러리에 대한 이해

엄격하게 말해서 OWIN 어셈블리는 IAppBuilder라고 불리는 인터페이스 하나만을 가지고 있습니다.

 

보시는 것처럼 정말 IAppBuilder라는 인터페이스를 하나만 가지고 있을 뿐입니다. 그런데 이 인터페이스가 OWIN 기반의 응용프로그램을 만들기 위한 여러 가지 기본 사항들을 정의하고 있습니다. 각 멤버들에 대해서 간단히 살펴보면 다음과 같습니다.

•Build(System.Type): 이 인터페이스를 구현하는 클래스의 재량이며, 주어진 Type 형식에 대응되는 객체의 참조를 반환합니다. Microsoft OWIN 구현체의 경우, Map과 MapWhen 관련 기능을 소화하기 위한 목적으로 이 메서드를 활용합니다.

 

•New(): 역시 인터페이스를 구현하는 클래스의 재량이며, 또 다른 IAppBuilder 인터페이스 형식의 객체의 참조를 반환합니다. Microsoft OWIN 구현체의 경우, Map과 MapWhen 관련 기능을 소화하기 위한 목적으로 이 메서드를 활용합니다.

 

•Use(object, params object[]): OWIN 초기 구성에 있어서 가장 중요한 메서드입니다. 요청을 처리하고자 하는 미들웨어를 필요한 만큼 추가할 수 있으며, Use 메서드를 구성 과정에서 부른 순서대로 내부적으로 배열이나 리스트 안에 Use 메서드를 통해 전달받은 미들웨어 진입점들을 보관하고 순서대로 호출이 이루어질 수 있게 합니다.

 

OWIN 기반으로 프로그램을 만드는 과정에서 가장 첫 단추는 바로 이 IAppBuilder의 Use 메서드를 적절하게 활용하는 것입니다.

하지만 이 인터페이스 만으로 프로그래밍을 한다는 것은 정말 최소한의 수준을 만족하는 프로그래밍 기법을 사용하는 것으로, 실제 우리가 관심을 가져야 할 부분과는 거리가 상당히 멀리 떨어져 있습니다. 호스팅 환경이나 웹 프로그래밍에서 응당 필요한 요청과 응답 과정에서의 파이프라인 처리 등 필요한 것이 많습니다. 이런 부분들을 적절히 제공하는 것이 바로 Microsoft가 제안하는 Katana 프로젝트를 통한 프로그래밍입니다. Microsoft.Owin 이라는 이름으로 시작하는 어셈블리들의 시리즈이며, 이것을 사용하여 좀 더 웹 프로그래밍 다운 웹 프로그래밍을 할 수 있게 됩니다.

지금 여러분이 만든 ASP.NET 프로젝트에서 OWIN을 실행할 수 있도록 해준다는 것은 Katana 프로젝트의 일부인 System.Web Loader 프로젝트의 기능입니다. 어떻게 해서 이 클래스가 별다른 설정도 없이 자동으로 모든 요청을 받아들일 수 있는 시작점이 되는가에 대해서는 지금은 자세히 알지 못해도 괜찮습니다.

Hello World 미들웨어 작성

이제 본격적으로 Hello World 메시지를 출력하는 간단한 미들웨어를 하나 작성해보도록 하겠습니다.

Configuration 메서드 안에 다음과 같이 코드를 작성합니다.
app.Run(async (context) =>
{
    await context.Response.WriteAsync("Hello, World!");
});

앞에서 살펴본 Use 메서드를 응용하는 도우미 메서드로 Run 메서드를 Katana에서 제공하고 있습니다. 이 메서드를 사용하면 다른 미들웨어를 실행하지 않고 자기 선에서 요청에 대한 응답을 끝낼 수 있는 미들웨어를 간단한 코드로 쉽게 작성할 수 있게 해줍니다. 여기서는 Hello World라는 문자열을 HTTP 응답으로 내보내도록 하는 코드를 작성해보았습니다.

이 코드를 실행하면 다음과 같이 웹 브라우저에 Hello, World! 라는 문구가 나타날 것입니다.

 

HTTP Query String 받아서 처리하기

Response 속성을 통해 응답을 내보내는 것 말고, 조금 더 나가보기로 하겠습니다. 이번에는 Query String을 입력으로 받아들여 이름을 출력하는 코드를 조금 더 작성해보기로 하겠습니다.

문자열을 다루는 코드를 조금 추가할 것이므로 네임스페이스에 대한 참조가 다음과 같이 추가되어야 합니다.


using Microsoft.Owin;
using Owin;
using System;
using System.Globalization;

 


그리고 앞에서 작성한 Hello, World! 메시지를 내보내는 미들웨어의 코드를 다음과 같이 변경하겠습니다.


var query = context.Request.Query;
var name = query.Get("name");

if (name == null)
    name = "Stranger";

var message = String.Format(
    CultureInfo.InvariantCulture,
    "Hello, {0}!",
    name);

await context.Response.WriteAsync(message);

 


Query 속성의 Get 메서드를 사용하여 Query String 형태로 전달되는 매개 변수의 값을 가져오도록 할 수 있는데, 만약 값을 가져오지 못한다면 NULL 참조를 대신 반환합니다. 이 경우 기본값으로 Stranger로 설정하도록 코드를 작성하였습니다. 그 다음은 익히 잘 아시는 String.Format 메서드를 사용하여 문구를 완성하는 것이고, 응답에 이를 사용하게 됩니다.

그럼 이제 다시 한 번 코드를 실행해보겠습니다. 이름을 지정하지 않은 상태에서는 다음과 같이 실행될 것입니다.

 

그리고 주소 뒤에 ?name=David 라고 입력해봅니다.

 

그런데 여기서 한 가지 궁금한 점이 생깁니다. 보통 웹 프로그래밍을 할 때 흔히 어떤 파일에 대해서 작업을 하고 그 파일을 열어보면 실행된다는 식인데 지금 이 화면을 띄우기까지 어떤 파일 위에서 작업한 것이 아니라 그냥 프로그래밍을 했을 뿐입니다. 다시 말해, 어떤 URL을 경유해서 들어오든 지금 보는 화면과 동작이 적용됨을 뜻합니다. 임의로 아무렇게나 주소를 한 번 넣어보시면 어떤 의미인지 금방 알 수 있습니다. 예를 들어, http://localhost:37339/askbvkkewr?name=David 라고 없는 주소를 임의로 써봅니다.

 

그렇습니다. 어디서 어떻게 들어오든 모든 웹 요청을 전부 방금 만든 미들웨어가 소화를 하도록 되어있는 것입니다. 전통적인 ASP.NET 또는 웹 프로그래밍 환경과는 다르게, OWIN 안에서는 HTTP 서비스 전체를 자유자재로 통제할 수 있습니다.

HTTP POST URL Encoded Form 다루기

마지막으로 한 가지 더 살펴보도록 하겠습니다. Query String도 쉽게 처리할 수 있었는데, 그렇다면 POST로 보내는 요청들도 Katana에서 쉽게 처리할 수 있을까요?

간단하게 요약하면, Katana가 제공하는 Request에 대한 처리는 Request Body를 실시간으로 읽을 수 있는 System.IO.Stream 구현체를 사용하거나, ReadFormAsync() 메서드를 사용하여 URL Encoded Form을 받아들이는 정도를 우선 활용할 수 있습니다. 그러나 흔히 사용하는 Multipart 데이터는 자체적으로 소화할 수 있는 방법은 따로 없고, ASP.NET MVC Web API v2의 도우미 클래스를 사용하여 처리하는 방법을 사용할 수 있습니다. 일단 여기서는 URL Encoded Form의 형태로 받아서 처리할 수 있는 예를 한 번 다루어보도록 하겠습니다.

URL Encoded Form으로 들어오는 요청을 손쉽게 만들기 위하여, 아래와 같이 간단한 웹 페이지를 하나 만들어보도록 하겠습니다. <FORM> 태그의 ACTION 속성 값에 들어갈 URL은 현재 여러분이 만든 OWIN 응용프로그램의 웹 주소로 적절하게 치환하셔야 정상적으로 전송이 됩니다. 이 주소를 확인하는 방법은 방금 만든 프로젝트의 속성을 연 다음, 웹 탭을 클릭하는 것입니다. 참고로 이 주소는 프로젝트 생성 시점에 동적으로 할당되어 프로젝트 설정으로 저장되는 값으로, 개발 과정 중에는 계속 같은 포트 값을 유지할 수 있습니다.

 

위의 주소를 확인하여 아래와 같이 HTML 페이지를 작성하도록 합니다.

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Hello, World!</title>
</head>
<body>
    <form action="http://localhost:37339/" method="post"
          enctype="text/plain">
        <label for="name">Your Name: </label>
        <input type="text" name="name" id="name" />
        <input type="submit" value="Hello?" />
    </form>
</body>
</html>

 

여기서 중요한 것은 <FORM> 태그의 METHOD 속성의 값이 POST라는 것과 ENCTYPE 속성이 “application/x-www-form-urlencoded”로 지정된 것입니다. 이렇게 지정해야 OWIN에서 데이터를 가져올 수 있습니다.

그리고 Form 데이터를 받아서 처리할 수 있도록 아래와 같이 수정합니다.

//var query = context.Request.Query;
var form = await context.Request.ReadFormAsync();
var name = form.Get("name");

 


특별히 바뀐 것은 없습니다. context.Request.Query 속성 대신 context.Request.ReadFormAsync() 비동기 메서드를 호출하여 얻은 결과로 나오는 객체를 활용하도록 하는 것이고 그 이후는 동일한 로직을 사용합니다.

테스트를 위해서 앞에서 만든 HTML 페이지를 브라우저로 열어봅니다. 텍스트 상자 안에 임의의 이름을 넣고 Hello? 버튼을 클릭하면 다음과 같이 입력한 문자열이 반영된 응답이 나오게 됩니다.

 

만약 HTML 폼에서 “application/x-www-form-urlencoded” 대신 “multipart/form-data”를 지정할 경우 ReadFormAsync() 비동기 메서드는 비어있는 컬렉션을 반환합니다.

다음 아티클에서는

다음 아티클에서는 이 특성을 사용하여 좀 더 세밀하고 다양한 미들웨어 프로그래밍을 다루어보도록 하겠습니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2014. 7. 15. 09:32

OWIN 개요

요즈음 .NET 기반 웹 개발에서 주목을 받고 있는 것은 ASP.NET MVC나 ASP.NET Web API가 아니라 사실 OWIN이 아닐까 생각합니다. OWIN은 Open Web Interface for .NET을 줄여서 쓴 말로 .NET Framework 기반의 웹 개발 프레임워크들을 더 다양하게 고르고 조합할 수 있도록 도와주는 표준화된 인터페이스를 말합니다. (http://owin.org/ 에서 자세한 정보를 볼 수 있습니다.)

왜 OWIN인가?

OWIN이 주목을 받는 이유는, 이전에 다루던 웹 응용프로그램 개발 환경과는 달리, 목적과 상황에 맞게 더 정밀하고 더 세세한 웹 프로그래밍이 가능하기 때문입니다. 이전의 ASP.NET 만을 사용하던 개발 환경에서 가장 큰 문제가 되었던 것은 의외로 단순한 부분들로부터 나타나는 것들이 많았는데, 예를 들어 파일 업로드에 대한 것이 가장 큰 문제였습니다.

 

 

인터넷 속도가 빠르지 않은 지역에서의 사용을 기준으로 잡혀있는 파일 업로드 제한과 공간 할당 정책이 기본값이었기 때문에, 대용량 파일 업로드가 필요한 때에는 이것을 처리하기 위해 ASP.NET의 파일 업로드 제한을 다시 정의할 수 밖에 없었고, 사실 이것은 면밀하지 못한 설정이 되어서 보안 리스크가 될 수 밖에 없었습니다. 그리고 .NET Framework 2.0 서비스팩 적용 이전까지는 놀랍게도 파일 업로드를 임시 저장소가 아닌 메모리 공간에 저장하는 방식이어서 대용량 파일 업로드를 할 경우 서버 자원이 고갈되는 (!) 문제까지 있었습니다.

지금은 임시 디스크에 저장한 후에 파일 업로드가 다 되었음을 알려주는 식이 되었지만, 여전히 세밀한 파일 업로드 제어는 하기 어려운 상태입니다. 그리고 제일 큰 문제는, 환경 설정에서 지원하는 최대 파일 업로드 크기가 여전히 부호있는 32비트 정수값 (.NET의 표준은 부호있는 정수 사용을 권합니다.)의 범위에 있어서 최대 업로드가 2GB 밖에 가능하지 않습니다. 이를 해소하기 위해서 청크 방식의 업로드 등을 이용해야 하지만 웹 브라우저가 지원하지 않으면 별도 클라이언트를 이용할 수 밖에 없는 상태입니다. 다시 말해, 간단한 파일 업로드를 필요로 한다면 ASP.NET이 여전히 편리하지만, 복잡해진 요구 사항을 맞추기 위해서는 턱없이 커스터마이징 변수가 부족한 것입니다.

비단 이 문제 뿐 아니라 ASP.NET이 편의를 위하여 제공하는 기능이 요즈음에 들어서는 오히려 복잡한 요구 사항 개발에 방해 요소가 되는 일이 많습니다. 그리고 이러한 요구 사항을 만족하기 위해 ASP.NET의 기본 설정을 변경하는 것 자체가 보안 리스크가 됨은 물론, ASP.NET 자체에 대한 강력한 커플링이 발생하여 유지 보수에 큰 문제가 되곤 합니다. 왜냐하면 커플링이 강력해질수록 ASP.NET에 사소한 업데이트나 패치 하나가 전체 프로그램에 큰 영향을 줄 개연성이나 확률이 더 높아지기 때문입니다. 그래서 기존 ASP.NET의 영역을 유지하면서, 안전하고 더 편리하게 복잡한 요구 사항을 쉽게 맞출 수 있는 방법이 필요해지게 되는데, OWIN이 여기에 대한 확실한 답이 됩니다.

OWIN의 기본 개념

OWIN 그 자체는 HTTP 요청을 받아들이고, 응답을 결정하는 행위를 규정하는 스펙을 .NET 4.0을 기반으로 제공하는 것이 전부이며, 모든 처리 과정은 미들웨어를 통해 이루어지는데, 미들웨어 간의 호출에 사용되는 것은 아주 단순한 Dictionary 자료 구조입니다. (http://owin.org/spec/owin-1.0.0.html)

OWIN-5

OWIN이 하는 일 자체는 위의 그림 (클릭하면 크게 볼 수 있습니다.)이 전부입니다. 여러 개의 미들웨어 구성 요소를 OWIN 프로그램을 시작할 때 등록하고, 미들웨어의 입장에서는 자신이 처리할 수 있는 요청인 경우에만 요청을 가로채고, 그 외에는 다음 미들웨어로 호출을 넘겨주는 것이 전부입니다. 만약 모든 미들웨어를 지나 끝까지 도착했음에도 불구하고 처리할 수 있는 미들웨어가 없다면, OWIN을 어떤 환경에서 사용하는지에 따라 다음 동작이 결정됩니다.
•만약 OWIN 그 자체를 바로 호스팅하는 베어본 서버 환경이라면 익히 알려진대로 404 오류 코드를 내보내거나 빈 응답을 반환할 수 있습니다.
•만약 ASP.NET 환경에서 OWIN을 얹어서 사용하는 형태라면, OWIN 환경 자체가 다른 ASP.NET 모듈보다 먼저 실행되는 ASP.NET 모듈이기 때문에, 다음 ASP.NET 모듈로 넘어가게 됩니다. 기존에 개발한 ASP.NET 웹 프로젝트 위에 OWIN을 추가 장착하게 되면 이런 형태가 됩니다.
•만약 ASP.NET Native Loader 위에서 OWIN을 얹어서 사용하는 형태라면, OWIN 환경 자체를 완전히 분리된 환경에서 실행하는 것을 의미합니다.

각각의 경우를 따로 설명하는 데에는 이유가 있습니다. 이어서 말씀드리면 다음과 같습니다.

세 가지 실행 환경과 가능성

첫 번째는 OWIN과 미들웨어들을 묶어서 어디에서든 웹 서비스를 시작할 수 있음을 말씀드리고 싶어서입니다. 즉, 정상적인 .NET Framework 실행 환경을 갖추고 클라이언트와 서버 사이의 연결을 정확하게 처리하도록 만들어주기만 한다면 서버 OS가 윈도우이든 리눅스이든 맥이든 상관이 없으며 (리눅스와 맥은 Mono 덕분이라고 할 수 있겠습니다.), 전혀 다른 형태로 구현된 웹 서버일지라도 OWIN으로 정확하게 연결을 전달할 수 있다면 이론상으로 .NET 기반이 아닌 서버 플랫폼 환경에서도 얼마든지 .NET 서버 응용프로그램을 호스팅할 수 있는 상태가 됩니다.

두 번째는 기존에 가지고 있던 ASP.NET 웹 프로젝트에 얼마든지 OWIN 응용프로그램을 추가 장착할 수 있음을 의미합니다. System.Web이라고 불리는 레거시 ASP.NET 웹 프레임워크의 종속성에서 완전히 벗어나지는 못하지만, 그 규칙 안에서라면 기존 ASP.NET의 기술과 완전히 무관하게 독자적인 미들웨어를 개발하고 수행하는 것이 가능하므로, 전송 프로토콜 수준에서 HTTP 응답을 재정의하는 것도 가능하고, 실시간으로 파일 업로드에 개입할 수도 있습니다. 기존 ASP.NET 웹 프로젝트를 해치지 않고 얼마든지 복잡한 기능을 쉽게 추가할 수 있음을 뜻합니다.

마지막 세 번째 방법은 기존의 ASP.NET 실행 환경을 사용하지 않고, IIS에 최소 버전의 .NET 실행 환경을 직접 주입하여 실행 속도를 획기적으로 개선하고, 기존의 System.Web 관련 설정을 모두 무시하는 방식입니다. 이것은 Project Helios라고 불리던 것을 제품화한 것으로, 실행 속도와 메모리 점유율을 획기적으로 개선하여 응답 성능을 비약적으로 개선시킬 수 있습니다. 기존 ASP.NET 프로젝트와 독립된 형태로 웹 프로젝트를 개발하면서 IIS 위에서 OWIN 프로그램을 실행하려는 경우 이 방식을 이용하여 성능을 극대화할 수 있습니다.

다음 아티클에서는 OWIN의 내부 구조와 미들웨어를 프로그래밍하는 방법을 몇 가지 살펴보도록 하겠습니다.

이미지 출처: http://byterot.blogspot.kr/2013_08_01_archive.html

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

IaaS2014. 7. 7. 09:30

Microsoft Azure에서 실행되는 VM은 Azure BLOB Storage를 사용하여 VHD 디스크를 동적으로 연결하여 사용합니다. 이것은 광의로 해석하면 Storage Area Network 위에서 실시간으로 호스팅되는 가상 디스크를 마운트하여 사용하는 셈인데, 실제로 Microsoft Azure의 VM이 시험판 단계일 때에는 예기치 않은 문제들이 제법 많았습니다. (물론 지금은 그런 일도 없고, 또 그렇게 되어서는 안되겠죠.)

 

 

Azure BLOB Storage 그 자체도 내부적으로 상당히 많은 추상화가 이루어져있는 복잡한 기술이지만, 이것을 기반으로 하는 VHD를 사용한다는 것은 어떻게 생각하면 추상화의 극을 달린다는 느낌에 가깝습니다. 물론, 이토록 고도화된 시스템을 사용하기 때문에 얻을 수 있는 이점으로는 무중단 상태에서 같은 지역은 물론 여러 지역에 걸쳐 VHD를 실시간으로 미러링하여 백업하거나 VHD 자체를 로드밸런싱하는 등의, 종전의 클라우드 서비스 공급자들도 상상하기 어려운 스케일의 서비스를 제공할 수 있게 된 점은 있습니다. 하지만 흔히 기대하는 베어메탈급의 고성능 서버와는 거리가 멀리 떨어진 듯한 느낌을 지울 수는 없겠지요.

엄밀히 말해서, 정말 빠른 디스크 I/O를 필요로 한다면 오히려 클라우드 환경에 의존하기 보다는 직접 고성능 서버를 구입하여 구축하는 것이 훨씬 더 이치에 맞습니다. 하지만, 단순히 디스크 I/O가 빨라야 하는 요구 사항을 고려하는 것이 아니라면, 대부분의 인프라의 가치는 장애 대비와 적시 복구인 경우가 많습니다. 이런 점을 고려하여, 어느정도 만족할만한 수준의 디스크 성능과 안정성을 동시에 거둘 수 있는 간단한 팁을 하나 올립니다.

Azure에서 VM을 만들고 디스크를 추가로 생성하여 연결할 때, 다음 그림과 같이 질문을 받습니다.

001

여기서 제일 아래쪽의 호스트 캐시 기본 설정이라는 항목이 제가 오늘 말씀드리려는 내용에 대한 것입니다.

호스트 캐시란 앞에서 이야기한 대로 실제 디스크 I/O를 처리하기 위한 과정에서 중간에 관여하는 구성 요소로, 원칙대로라고 한다면 Azure Storage의 VHD에 대해 발생하는 디스크 I/O를 Azure Storage가 완전히 처리해서 응답을 되돌려주기까지의 과정을 운영 체제의 입장에서는 기다려야 하는 셈입니다. (물론 여기서 다 설명하기에는 어려울 정도로 복잡한 메카니즘이 있어서 정말 순진하게 캐시를 사용하지 않는다고해서 무작정 기다리기만 하는 것은 아닙니다.)

그러나 좀 더 적극적으로 개입해서, 실제로 디스크 I/O가 저멀리 있는 Azure Storage에 전달이 되기 이전이라고 하더라도, 확실하게 디스크 I/O에 대한 요청이 접수되었고 처리가 되었음을 기억하여 정확한 응답을 되돌려주면서, 다른 한편으로는 그 내용을 실제 Azure Storage의 VHD에 지속적으로 보내주는 역할을 따로 수행하게 됩니다.

다르게 말하면, 만약 Azure Storage와 연결이 끊어지거나 문제가 발생하는 경우 캐시의 유효성이나 지속성에 문제가 생겨서 서비스 장애로 이어지는 불상사가 벌어질 수 있습니다. 그러나 바꾸어 말하면 캐시를 사용하지 않을 때에는 이것이 직접적으로 VM 위에서 돌아가는 프로그램에 대한 OS의 IO API 호출에 대한 실패로 직격탄이 되어버립니다. 이런 점을 고려해보면, 문제의 전파나 영향 범위를 최소화하는 관점에서 캐시가 미미하지만 어느정도 역할을 수행하는 것도 가능합니다.

이러한 성격의 캐시를 사용할 수 있는 방안은 두 가지가 있는데, 읽기 작업을 위한 캐시만 사용하는 경우와, 읽기/쓰기 작업을 모두 관리하는 캐시를 사용하는 경우입니다. 운영 체제용으로 만들어지는 VHD는 읽기/쓰기 작업을 모두 관리하는 캐시를 기본으로 사용하도록 하고 있습니다. 그리고 추가 연결하는 디스크에 대해서는 디스크 I/O 빈도가 높지 않을 것임을 가정하고 기본적으로는 캐시 없이 직접 Azure BLOB Storage와 연결되도록 하는 것이 기본입니다.

이러한 상황에서, 만약 디스크의 읽기 성능이 중요하다면 읽기 캐시를 사용하도록 해주는 것이 필요합니다. 이렇게 하면 최초로 캐시에서 가지고 있지 않은 데이터 영역에 대한 요청이 들어왔을 때, 이를 캐시에 저장하고 다음 회차 요청 때 좀 더 빠르게 전달할 수 있도록 해주는 식이 됩니다. 물론 쓰기나 다른 동작에 의해 변경이 발생하게 되면 이에 맞추어 당연히 캐시도 다시 형성됩니다.

여기에 쓰기 캐시를 사용하는 것 까지 포함하게 되면, 쓰기 캐시에 들어오는 요청과 읽기 캐시의 내용을 병합하여 중간 버퍼를 형성하고 Azure Storage의 VHD와 동기화하는 작업을 적극적으로 개입하여 수행하게 됩니다.

결론을 이야기하면, 쓰기 작업이 많은 응용프로그램을 위해 디스크를 추가할 때는 읽기/쓰기 캐시 사용을, 웹 사이트나 읽기 작업이 많은 응용프로그램을 위해서는 읽기 캐시 사용을 권할 수 있습니다.

사실 클라우드 서비스를 사용한다는 것이 어떤 의미인지 본질적으로 잘 이해하고 계시다면, 그리고 필연적으로 사람이 하는 일에 있을 수 있는 결함성을 인정하신다면, 이러한 아키텍처 속에서 갑작스럽게 나타날 수 있는 예외 상황은 항상 관리해야 할 리스크가 될 수 있습니다.

적절한 설정을 확인하고 검증하는 단계를 통해 더 성공적으로 클라우드 서비스를 현업에 투입할 수 있게 될 것입니다.

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2014. 6. 7. 09:29

Visual Studio에서 제공하는 테스트 도구에 NUNIT을 결합해서 사용할 수 있다면 정말 유용할 것입니다. 이번 웹 캐스트는 Visual Studio에서 제공하는 테스트 도구와 NUNIT 간의 연동을 도와주는 NUNIT Test Adapter의 사용 방법과 함께, Windows Forms 기반 응용프로그램에서 Visual Studio와 NUNIT Test Adapter를 결합하여 테스트를 진행할 수 있는 방법을 소개합니다.

(비디오 콘텐츠로 올렸던 게시물이었으나 아티클로 조만간 복원할 예정입니다.)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요