달력

42024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

ASP.NET 웹 서비스, Enterprise Service 및 .NET Remoting의 성능

 

Ingo Rammer
thinktecture.

Richard Turner
Program Manager
Microsoft Distributed Systems Group

2005년 8월

요약: ASP.NET 웹 서비스, .NET Enterprise Service 구성 요소 및 .NET Remoting 구성 요소의 성능 특성을 실제 상황에서 비교 및 대조하고, 이들 기술의 활용도를 극대화하는 방법에 대한 권장 사항을 확인하십시오(34페이지/인쇄 페이지 기준).

관련 코드 샘플인 ASMXvsEnterpriseServicesvsRemotingPerformanceTests.msi를 다운로드하십시오.

목차

소개
목적
   벤치마크 이상의 목표
   테스트
결과
   테스트 1: 주문 만들기 및 저장
   테스트 2: Northwind 제품 데이터 검색
   테스트 3: 고객 정보 검색
.NET Framework 2.0 성능
결론
   권장 사항
부록 A: 종합 기준 - 빈 메서드 테스트
부록 B - 세부 테스트 결과
   주문을 개체로 저장
   주문을 데이터 집합으로 저장
   제품을 개체로 로드
   제품을 데이터 집합으로 로드
   고객을 개체로 로드
   고객을 데이터 집합으로 로드
   빈 메시지(크로스 프로세스)
   빈 메시지(크로스 컴퓨터)
부록 C: 테스트 응용 프로그램 정보
   테스트 응용 프로그램 실행
   흥미로운 사실 - 기술 독립적인 테스트 응용 프로그램
부록 D: 소프트웨어 및 하드웨어 설치
   응용 프로그램 환경
   인프라 환경

소개

절대 성능은 여러 가지 기술 영역(장치, 하드웨어 컨트롤러, 생명 및 보건 서비스, 특정 재무 시스템)에서 최고의 관심사 중 하나지만 경시되는 경향이 있습니다. 대부분의 업무용 응용 프로그램의 1차적 목표는 "정확성", "배달 시간", 그리고 필요한 만큼 빠른 속도를 갖추는 것입니다. 절대 성능이 극대화된 엔지니어링 응용 프로그램을 만들려면 엄청난 비용과 노력이 필요할 수 있을 뿐 아니라, 업무 시스템에는 대개 이러한 성능 최적화를 위해 막대한 시간과 기술을 투입할 필요가 없는 경우가 많습니다. 그러나 절대 성능을 최적화하려는 노력이 과도한 경우도 있지만 투자 수익을 극대화하려는 대다수 기업에서는 여전히 전체 시스템 성능을 높은 수준으로 유지하고자 합니다.

이 백서에서는 .NET에서 사용할 수 있는 다음 세 개의 분산 구성 요소/서비스 기술 내에서 각각 호스트되는 실제 구성 요소/서비스의 상대 성능을 비교 분석하겠습니다.

  • COM+에서 호스트되는 .NET ES(Enterprise Service)
  • IIS에서 호스트되는 ASMX(ASP.NET 웹 서비스)
  • IIS 및 사용자 지정 호스트에서 호스트되는 .NET Remoting
(참고 System.Messaging과 MSMQ COM API의 성능 비교는 System.Messaging Performance(영문) 백서에서 다룰 예정입니다.)

목적

"어떤 Microsoft 분산 응용 프로그램 기술이 가장 빠른가?"에 관한 논란이나 "특정 기술은 사용하기에 너무 느리다" 같은 의견은 끊임없이 제기되고 있습니다. 본 백서의 주된 목적은 Microsoft 분산 기술의 성능과 관련된 많은 문제, 오해, 정확하지 않은 부분, 그리고 잘못된 정보를 바로잡고 이를 명확히 설명하는 데 있습니다.

또한 이 백서를 통해 Microsoft의 각 분산 구성 요소/서비스 기술의 상대 성능 특성에 대해 현재 알려진 오해를 해결하는 것은 물론, 설명이 추가된 명확한 테스트 및 테스트 결과를 비롯하여 고객의 요구에 가장 적합한 기술을 선택하는 데 도움이 될 만한 간단한 지침을 제시하고자 합니다.

본 백서의 목적을 요약하면 다음과 같습니다.

  1. 대부분의 업무용 응용 프로그램에서 나타나는 이들 세 기술 간의 상대 성능 차이 확인
  2. 현재 알려진 기술 상호 간 성능 저하 문제에 대한 몇 가지 오해 정정
  3. 각 기술의 활용도를 최적화하는 상황, 시기 및 방법을 손쉽게 결정하도록 유도
  4. 이러한 테스트를 각자의 시스템과 환경에서 실행할 수 있도록 테스트 응용 프로그램 제공 가급적 이 테스트 환경을 직접 빌드하고 실행하여 이들 기술의 성능 특성을 확인 및 분석하는 것이 좋습니다. 이렇게 하면 분산 시스템의 성능에 영향을 미치는 많은 요소를 완벽하게 이해할 수 있습니다.

벤치마크 이상의 목표

이 백서에 나와 있는 테스트는 테스트 대상인 특정 기술들 사이에 일관된 비교 결과를 제공하기 위해 명시적으로 디자인되었습니다. 이러한 테스트는 각 기술의 최적화된 절대 성능을 측정하기 위한 것이 아닙니다.

테스트 드라이버(클라이언트) 응용 프로그램은 단일 스레드 응용 프로그램이므로 호출한 서비스가 응답하는 즉시 연속해서 동기식으로 호출합니다. 이 디자인의 경우 서버에서 CPU를 사용하는 과정에 병목 현상이 항상 발생하지는 않습니다.

여러 클라이언트 즉, 멀티스레드 클라이언트를 사용하면 서버측 처리에서 초당 호출 수가 늘어날 수 있습니다. CPU를 많이 사용하는 서버 응용 프로그램 테스트의 경우 여러 클라이언트를 사용해도 테스트하는 기술의 절대 또는 상대 성능이 크게 변화하지 않습니다.

여러 클라이언트를 사용하면 상당히 높은(2배) 집계 서버 처리량을 얻어 테스트를 간소화할 수 있으며 다양한 기술의 상대 성능이 어느 정도 변화하는 효과도 얻을 수 있습니다.

단일 클라이언트와 여러 클라이언트 중 어느 쪽이 더 현실적인지는 웹 서비스를 배포하는 상황과 방법에 따라 다릅니다. 단일 클라이언트로 측정하려는 결정이 본 백서의 결론에 영향을 미치지는 않습니다.

테스트

다음 성능 테스트에서는 종합 기준과 실제 시나리오를 모두 살펴보고 있습니다. 여기서 검토할 일반적인 질문은 다음과 같습니다.

  1. .NET Remoting이 ASMX보다 빠릅니까?
  2. ES는 .NET Remoting보다 느립니까?
  3. ASMX가 많이 느려 실제 시나리오에서는 사용할 수 없습니까?
  • 이러한 의견을 검토하기 위해 다양한 테스트를 수행했습니다. 첫 번째 테스트에서는 대규모의 요청을 받아들여 많은 작업을 수행하거나 많은 작업을 수행하여 소규모 또는 대규모의 결과 집합을 반환하도록 요청 받는 작업에 대한 성능을 검토합니다. 이러한 테스트를 수행하는 목적은 시스템을 빌드하면서 경험할 수 있는 일반적인 업무 시나리오의 성능을 설명하는 데 있습니다.

본 백서의 모든 테스트는 아래 나와 있는 각 기술의 프로토콜에 대해 실행되었습니다.

  • enterprise service(Just-In-Time 활성화 사용)
    • 인증 없음
    • 호출 수준 인증 및 역할 액세스 검사 적용
  • ASP.NET 웹 서비스
    • 인증 없음
    • 사용자 이름 및 암호 인증
    • 통합 인증
  • .NET Remoting
    • TCP/Binary(보안되지 않음)
    • HTTP/Binary(보안되지 않음)
    • HTTP/SOAP(보안되지 않음)
    • IIS의 HTTP/SOAP(보안되지 않음)
    • IIS의 HTTP/Binary(보안되지 않음)
    • IIS의 HTTP/SOAP(HTTP 기본 인증)
    • IIS의 HTTP/Binary(HTTP 기본 인증)
    • IIS의 HTTP/SOAP(통합 인증)
    • IIS의 HTTP/Binary(통합 인증)

다음 테스트는 모두 서버측 메서드를 반복해서 호출하는 단일 클라이언트 응용 프로그램을 기반으로 하고 있습니다. 여기서는 집합의 각 테스트에 대해 초당 평균 원격 호출/메서드 수를 계산하고 전체 집합을 10번 반복하여 전체 다단계 테스트 실행에 대한 평균 및 표준 편차를 구했습니다.

결과

테스트 1: 주문 만들기 및 저장

이 첫 번째 테스트는 호출되는 작업으로 많은 작업을 수행하는 대부분의 최적화된 상황에서 기술별로 나타나는 성능 특성을 시뮬레이트하도록 디자인되었습니다. 호출되는 작업은 데이터베이스에 주문을 저장하고 트랜잭션 내의 두 테이블에 레코드를 작성하여 많은 작업을 수행합니다.

호출자는 다음과 같은 Order 클래스의 인스턴스를 만듭니다.

[Serializable]public class Order{   public int OrderID;   public String CustomerID;   public int EmployeeID;   public DateTime OrderDate;   public Address ShippingAddress;   public Address BillingAddress;   public int ShipVia;   public decimal Freight;   public LineItem[] LineItems;}

Order 클래스에는 Address 형식의 자식 개체 하나와 LineItem 20개로 구성된 배열이 포함되어 있습니다.

[Serializable]public class Address{   public String Name;   public String Street;   public string City;   public string Region;   public string PostalCode;   public string Country;}[Serializable]public class LineItem {   public int ProductID;   public double UnitPrice;   public short Quantity;   public double Discount;}

이 데이터 개체는 메서드를 호출하는 동안 호출자에게서 서버로 전달되며 테스트 대상 기술에 의해 네트워크에서 serialize됩니다.

서버측 구현은 다음과 같습니다.

SqlConnection _conn;private void InitializeComponent(){   // ... 생성된 코드 대부분 생략    _conn = new SqlConnection();   // ... 생성된 코드 대부분 생략}public void StoreOrder(Order o){   using (_conn)   {      _conn.Open();      using (SqlTransaction tx = _conn.BeginTransaction())      {         using (SqlCommand cmd = new SqlCommand(@"INSERT INTO Orders(EmployeeID, " +                       "CustomerID, OrderDate, RequiredDate, ShipVia, ShippedDate, " +                       "ShipName, Freight, ShipAddress, ShipCity, ShipRegion, " +                       "ShipCountry, ShipPostalCode) VALUES (@EmployeeID, @CustomerID, " +                      "@OrderDate, @RequiredDate, @ShipVia, @ShippedDate, @ShipName, " +                        "@Freight, @ShipAddress, @ShipCity, @ShipRegion, @ShipCountry, " +                       "@ShipPostalCode); SELECT @@IDENTITY", _conn,tx))         {            cmd.Parameters.Add("@EmployeeID", o.EmployeeID);            cmd.Parameters.Add("@CustomerID",o.CustomerID);            cmd.Parameters.Add("@OrderDate",o.OrderDate);            cmd.Parameters.Add("@RequiredDate",o.OrderDate.AddDays(10));            cmd.Parameters.Add("@ShipVia",o.ShipVia);            cmd.Parameters.Add("@ShippedDate",o.OrderDate.AddDays(5));            cmd.Parameters.Add("@ShipName",o.ShippingAddress.Name);            cmd.Parameters.Add("@Freight",o.Freight);            cmd.Parameters.Add("@ShipAddress",o.ShippingAddress.Street);            cmd.Parameters.Add("@ShipCity",o.ShippingAddress.City);            cmd.Parameters.Add("@ShipRegion",o.ShippingAddress.Region);            cmd.Parameters.Add("@ShipCountry",o.ShippingAddress.Country);            cmd.Parameters.Add("@ShipPostalCode",o.ShippingAddress.PostalCode);                        decimal orderID = (decimal) cmd.ExecuteScalar();            o.OrderID = (int) orderID;         }         using (SqlCommand cmd = new SqlCommand(@"INSERT INTO [Order Details] (OrderID, " +                      "ProductID, UnitPrice, Quantity, Discount) VALUES (@OrderID, " +                       "@ProductID, @UnitPrice, @Quantity, @Discount)", _conn,tx))         {            cmd.Parameters.Add("@OrderID",SqlDbType.Int);            cmd.Parameters.Add("@ProductID",SqlDbType.Int);            cmd.Parameters.Add("@UnitPrice",SqlDbType.Money);            cmd.Parameters.Add("@Quantity",SqlDbType.SmallInt);            cmd.Parameters.Add("@Discount",SqlDbType.Real);            foreach (LineItem itm in o.LineItems)            {               cmd.Parameters["@OrderID"].Value = o.OrderID;               cmd.Parameters["@ProductID"].Value = itm.ProductID;               cmd.Parameters["@UnitPrice"].Value = itm.UnitPrice;               cmd.Parameters["@Quantity"].Value = itm.Quantity;               cmd.Parameters["@Discount"].Value = itm.Discount;               cmd.ExecuteNonQuery();            }         }                  tx.Commit();      }      _conn.Close();(참고: 프로그래머 코멘트는 샘플 프로그램 파일에는 영문으로 제공되며 기사에는 설명을 위해 번역문으로 제공됩니다.)   }}

테스트 실행이 완료되면 서버측 논리에서는 두 번째 트랜잭션을 사용하여 삽입된 레코드를 삭제하고 테스트의 실행 횟수와 관계없는 "동등한 조건의 환경"을 제공합니다.

그림 1. 실제 서버측 구현으로 프로세스 간에 "주문" 전달

그림 1의 테스트 결과를 보면 73 CPS인 ES와 63 CPS인 ASP.NET 웹 서비스의 차이는 14%에 불과하며 최고 속도 프로토콜과 최저 속도 프로토콜의 최대 차이는 45%라는 것을 알 수 있습니다. 이 결과는 수행하는 작업량이 데이터를 전송하는 데 걸리는 시간에 비례하여 증가하면 다른 전송에 대한 특정 전송의 이점이 줄어든다는 것을 분명하게 보여 줍니다.

또한 그림 2에 정의된 DataTable이 들어 있는 형식화된 DataSet을 빌드하여 동일한 조건의 ADO.NET DataSet 테스트를 수행했습니다.

그림 2. 이 DataSet은 구매 주문서를 나타냅니다.

이 DataSet은 생성된 SqlDataAdapter와 함께 사용되며 여기에는 위의 코드 조각에 나타난 것과 유사한 SqlCommand가 들어 있습니다.

주문이 호출자에서 서버로 DataSet 형태로 전달된 후 저장되면 그림 3과 같은 결과를 얻게 됩니다.

그림 3. 구매 주문서를 DataSet으로 저장

여기서 DataSet을 사용하면 성능에 큰 영향을 미치게 되며(50% 속도 감소) 프로토콜 간의 차이는 계속해서 추가로 줄어든다는 점에 유의하십시오. 또한 데이터 개체를 전달하여 얻는 최저 속도의 결과가 ADO.NET DataSet을 전달할 때의 최고 성능을 뛰어넘는다는 점을 기억해야 합니다.

이 결과는 시스템 계층 사이에 ADO.NET DataSet을 전달하면 성능이 크게 저하된다는 사실을 분명하게 보여 줍니다.

테스트 2: Northwind 제품 데이터 검색

이 테스트의 목적은 많은 작업을 수행하지 않는 서비스에서 비교적 많은 분량의 데이터가 반환되는 경우의 기술별 성능 특성을 설명하는 데 있습니다.

이 시나리오를 모델링하기 위해 잘 알려진 SQL Server "Northwind" 샘플 데이터베이스에서 "product" 레코드 목록을 검색하여 반환하는 메서드를 빌드했습니다.

이 테스트에서는 이진 serialization 기술(ES/COM+ 및 Remoting Binary/TCP)의 성능이 가장 뛰어날 것으로 예상됩니다. SOAP 기반 기술은 많은 양의 데이터를 전송하는 데다 serialization 및 deserialization 메커니즘이 복잡하기 때문에 낮은 성능 수준을 나타낼 것으로 보고 있습니다.

첫 번째 테스트에서는 XML Serializer와 호환되는 공용 멤버가 포함된 [Serializable] 클래스를 정의했습니다.

[Serializable]public class Product{   public int ProductID;   public string ProductName;   public int SupplierID;   public int CategoryID;   public string QuantityPerUnit;   public decimal UnitPrice;   public short UnitsInStock;   public short UnitsOnOrder;   public short ReorderLevel;   public bool Discontinued;}

서버측 구현에서는 SQL Server에 대한 데이터베이스 연결을 열고 데이터베이스에 대해 쿼리를 실행한 다음, ADO.NET SqlDataReader를 사용하여 이 클래스의 Product 인스턴스 77개가 포함된 ArrayList를 채웠습니다. 그런 다음 ArrayList는 호출자로 반환되었습니다.

결과는 그림 4에 나와 있습니다.

그림 4. Northwind 제품 카탈로그를 개체로 검색

이 결과는 Enterprise Service(DCOM 사용)와 TCP 기반의 이진 Remoting이 보안되지 않는 호출에 대해 동일한 수준의 성능을 제공한다는 것을 보여 줍니다. 또한 ASP.NET 웹 서비스의 성능이 Enterprise Service의 62% 수준이며 최저 속도 프로토콜은 최고 속도에 비해 초당 호출 수를 17%밖에 사용할 수 없다는 사실도 알 수 있습니다.

이 테스트와 이어지는 모든 테스트에서는 일반적으로 SOAP 서비스를 빌드하는 데 .NET Remoting SoapFormatter를 사용하는 것이 바람직하지 않은 이유가 ASP.NET Web Service 스택의 속도가 세 배 정도 빠르기 때문이라는 점을 분명하게 보여 줍니다.

이 테스트의 두 번째 접근 방식에서는 요청된 데이터를 원본으로 사용하는 테이블 레이아웃에 직접 기반을 둔 ADO.NET DataSet 개체에 반환하고 SqlDataAdapter를 사용하여 DataSet의 DataTable을 채우는 메서드를 구현했습니다. 테이블 정의는 그림 5에 설명되어 있습니다.

그림 5. 제품 카탈로그에 액세스하는 형식화된 DataSet

그림 6에는 다음과 같은 결과가 설명되어 있습니다.

그림 6. Northwind 제품 카탈로그를 DataSet으로 검색

이 테스트 결과는 서비스에서 호출자로 DataSet을 반환하면 성능이 크게 떨어진다는(이진 전송의 경우 약 75%) 것을 분명하게 보여 줍니다. 또한 네 개의 최고 속도 프로토콜 성능이 완전히 같다는 것은 네 기술의 성능이 모두 DataSet의 serialization, deserialization 및 전송에 의해 좌우됨을 나타냅니다. 게다가 최고 속도(ASMX : 39 cps)와 최저 속도(Remoting HTTP/SOAP(IIS) 통합 보안 : 25 cps) 사이의 성능 범위는 14 cps로 구분되며 이는 30%에 불과한 하강 수준을 나타냅니다.

이 결과를 통해 DataSet을 사용하여 응용 프로그램 계층 사이에 정보를 전달하면 편리하지만 그 과정이 성능에 큰 영향을 미치게 된다는 것을 확실히 알 수 있습니다. 이에 대해서는 나중에 다시 살펴보겠습니다.

또한 단순히 ADO.NET DataSet을 호출자에게 반환하기보다는 ADO.NET DataSet을 반복하고 데이터 개체 컬렉션을 만들어 이 컬렉션을 serialize하는 것이 더 빠른 방법이라는 점도 알아 두어야 합니다. 이것이 서버와 호출자 사이에 DataSet을 전달하기 위해 구현된 실제 시스템이었다면 작은 양의 작업으로도 이 부분의 시스템 성능을 4배 가까이 끌어올릴 수 있었을 것입니다.

테스트 3: 고객 정보 검색

다음 테스트에서는 "Northwind" SQL Server 샘플 데이터베이스에서 단일 고객 레코드를 검색하여 서버에서 클라이언트로 매우 작은 양의 데이터를 전송하는 경우의 기술별 상대 성능 특성을 살펴보기로 했습니다.

검색된 데이터를 다시 클라이언트에서 서버로 돌려보내기 위해 다음과 같은 [Serializable] Customer 클래스를 만들었습니다.

[Serializable]public class Customer{   public String CustomerID;   public String CompanyName;   public String ContactName;    public String ContactTitle;   public string Address;    public string City;   public string Region;   public string PostalCode;    public string Country;   public string Phone;   public string Fax;}

다음은 SqlDataReader를 사용하여 Customer 클래스의 새 인스턴스를 채우는 서버측 구현의 일부입니다.

public Customer GetCustomer(string id){   using (SqlConnection conn = new SqlConnection(...))   {      conn.Open();      String sql = "SELECT CustomerID, CompanyName, ContactName, "                   "ContactTitle, Address, City, Region, " +                   "PostalCode, Phone, Fax, Country FROM " +                    "Customers WHERE (CustomerID = @CustomerID)";      using (SqlCommand cmd = new SqlCommand(sql,conn))      {         cmd.Parameters.Add("@CustomerID", id);         SqlDataReader rdr = cmd.ExecuteReader();         if (rdr.Read())         {            Customer c = new Customer();            c.CustomerID = (string) rdr[0];            c.CompanyName = (String) rdr[1];            c.ContactName = (String) rdr[2];            c.ContactTitle = (String) rdr[3];            c.Address = (String) rdr[4];            c.City = (String) rdr[5];            c.Region = rdr.IsDBNull(6) ? "" : rdr[6] as string;            c.PostalCode = (String) rdr[7];            c.Phone = (String) rdr[8];            c.Fax = (String) rdr[9];            c.Country = (String) rdr[10];            return c;         }         else         {            return null;         }      }   }}

성능 비교 결과는 그림 7에 나와 있습니다.

그림 7. 고객 데이터를 개체로 검색

이 결과는 각 기본 기술 간의 성능 차이를 좀 더 확실하게 보여 줍니다. 이 테스트에서는 전체 호출 비용에서 단일 레코드를 검색하고 반환하기 위해 수행 중인 작업이 차지하는 비중이 훨씬 낮으며 그에 따라 전송 비용이 보다 중요한 역할을 하기 때문에 성능 차이가 이처럼 두드러지게 나타나는 것입니다. 따라서 SOAP/HTTP는 Binary/DCOM보다 전송 비용이 높기 때문에 SOAP 전송은 이진 메커니즘보다 처리량 수준이 훨씬 낮습니다.

다음에는 그림 8에서처럼 형식화된 DataSet을 반환하는 동일한 작업을 테스트했습니다.

그림 8. 고객 정보에 액세스하는 형식화된 DataSet

이 DataSet은 다음과 같은 서버측 구현을 사용하여 채웁니다.

SqlDataAdapter _customerAdapter;SqlCommand _customerSelect;SqlConnection _conn;private void InitializeComponent(){   // ... 생성된 코드 대부분 생략    _conn = new SqlConnection();    _customerAdapter = SqlDataAdapter();    _customerSelect = SqlCommand();    _customerSelect.CommandText = "SELECT CustomerID, CompanyName, " +               "ContactName, ContactTitle, Address, City, Region, " +               "PostalCode, Phone, Fax, Country FROM Customers WHERE " +                "(CustomerID = @CustomerID)";_customerSelect.Connection = _conn;_customerSelect.Parameters.Add(new SqlParameter("@CustomerID",                SqlDbType.NVarChar, 5, "CustomerID"));    _customerAdapter.SelectCommand = this.sqlSelectCommand3;    _customerAdapter.TableMappings.AddRange(new DataTableMapping[] {           new DataTableMapping("Table", "Customers", new DataColumnMapping[] {                  new DataColumnMapping("CustomerID", "CustomerID"),                  new DataColumnMapping("CompanyName", "CompanyName"),                  new DataColumnMapping("ContactName", "ContactName"),                  new DataColumnMapping("ContactTitle", "ContactTitle"),                  new DataColumnMapping("Address", "Address"),                  new DataColumnMapping("City", "City"),                  new DataColumnMapping("Region", "Region"),                  new DataColumnMapping("PostalCode", "PostalCode"),                  new DataColumnMapping("Phone", "Phone"),                  new DataColumnMapping("Fax", "Fax"),                  new DataColumnMapping("Country", "Country")})});   // ... 생성된 코드 대부분 생략}public PerfTestDataSet GetCustomerAsDataset(string id){   using (_conn)   {      _conn.Open();      customerAdapter.SelectCommand.Parameters["@CustomerID"].Value = id;            PerfTestDataSet ds = new PerfTestDataSet();      _customerAdapter.Fill(ds,"Customers");      return ds;   }}

이 코드를 테스트 프레임워크 내에서 실행하자 그림 9와 같은 결과가 나타났습니다.

그림 9. 고객 데이터를 DataSet으로 검색

앞의 테스트와 마찬가지로 ADO.NET DataSet을 교환하면 성능에 좋지 않은 영향을 미칠 뿐 아니라, 모든 기술의 처리량 차이도 ADO.NET DataSet을 통해 처리량이 조절되고 있음을 나타내는 serialize된 개체를 반환하는 경우보다 줄어든다는 것을 확실히 알 수 있습니다.

.NET Framework 2.0 성능

이 백서를 작성할 당시 Microsoft는 다음과 같은 수많은 개선 및 향상된 기능과 새로운 기능이 포함된 .NET Framework 2.0(이전 코드 이름: "Whidbey")을 선보이고 있었습니다.

  • x64 및 IA64 기반 시스템 완벽 지원
  • System.Transactions를 통한 새로운 트랜잭션 지원
  • 연결 인식 및 프록시 지원 같은 System.Net의 향상된 기능
  • Windows Form 및 Web Form의 대폭 향상된 기능
  • "ClickOnce" 자동 응용 프로그램 배포 인프라

.NET Framework 2.0는 이처럼 향상된 새로운 기능이 추가된 것 외에도 많은 개선 작업이 이루어져 BCL, XML Serialization, 네트워킹 처리량, ADO.NET, ASP.NET 등과 같은 많은 영역에서 성능이 대폭 개선되고 메모리 사용이 향상되었습니다.

이러한 성능 및 처리량 개선 부분에 대한 초기 예는 다음 백서에서 확인할 수 있습니다.

.NET Framework 2.0이 계속해서 RTM(Release To Manufacturing) 쪽으로 옮겨감에 따라 향후 몇 개월 동안 성능 분석 및 비교와 관련된 백서가 추가로 게시될 예정입니다. 항상 최신 백서를 확인하려면 다음 온라인 리소스를 참조하십시오.

결론

위의 실제 테스트 결과는 표 1에 나와 있습니다.

표 1. 결과 요약

초당 호출 수
(반올림)
enterprise serviceASP.NET 웹 서비스.NET Remoting TCP Binary
테스트 1: 주문 저장
a) serialize된 데이터
b) DataSet

73
35

63
34

72
34
테스트 2: 제품 검색
a) serialize된 데이터
b) DataSet

147
39

93
39

149
39
테스트 3: 고객 검색
a) serialize된 데이터
b) DataSet

618
90

289
83

682
91

위의 결과는 여러분이 실제 응용 프로그램에서 예상할 수 있는 성능 특성을 보여 주며, 이를 통해 실제 응용 프로그램에서는 웹 서비스(일반적으로 매우 느린 것으로 파악된)와 DCOM(이 테스트에서 가장 빠른 분산 응용 프로그램 기술 중 하나로 확인된) 간의 차이가 매우 작다는 것을 알 수 있습니다.

테스트 대상 기술에 대한 Microsoft의 견해는 다음 섹션에 보다 자세히 나와 있으며 요약하자면 다음과 같습니다.

  • ASMX가 현재 Microsoft에서 제공하는 기술 중 가장 빠른 것은 아니지만 그 성능은 대부분의 업무 시나리오에 매우 적합한 수준입니다. ASMX 서비스는 확장이 용이할 뿐 아니라 상호 운용성 및 향후 호환성 같은 다양한 이점을 제공하므로 오늘날 서비스를 빌드하는 데 선택할 수 있는 가장 적합한 기술은 ASMX입니다.
  • 절대 성능이 주된 관심사인 경우 enterprise service 구성 요소를 사용하여 시스템에서 성능이 가장 중요한 부분을 빌드해야 합니다. COM+는 전체적으로 가장 뛰어난 성능을 나타냈으며 분산 구성 요소를 위한 안전하고 안정적인 보안 호스팅 환경으로 사용할 수 있습니다. 또한 ES/COM+는 Indigo 서비스와 완벽하게 통합되며 ES 구성 요소를 Indigo 서비스로 변환하는 과정도 비교적 간단히 수행할 수 있을 것입니다.
  • .NET Remoting은 TCP상에서 이진 serialization을 사용할 때 가장 성능이 뛰어나지만 Remoting 구성 요소를 IIS에서 호스트하거나 SOAP 메시지를 주고 받으면 성능이 저하됩니다. .NET Remoting 구성 요소는 .NET Remoting 끝점을 제외한 다른 기술과는 상호 운용할 수 없으므로 가능하면 Remoting보다는 ASMX나 ES를 고려하는 것이 좋습니다.

이 결과에서 도출한 중요한 견해 한 가지는 서버에서 수행되는 작업량이 각 호출의 전체 지속 시간에서 큰 비중을 차지하지 않는 경우 전송 시간에서 호출 시간이 상당 부분을 차지하게 된다는 점입니다. COM+ 기술에서의 DCOM 같은 "고속" 전송에서 ASMX 기술에서의 SOAP/HTTP 같은 "비용이 많이 드는" 전송으로 옮겨갈 경우 성능에 큰 영향을 미칠 수 있습니다. 이를 통해 메서드를 호출할 때마다 서버에서 가능한 많은 작업을 수행하고 불필요한 네트워크 이동을 피해야 한다는 점을 더욱 분명히 알 수 있습니다.

각 기술의 상대적인 성능 이점은 호출된 서비스에서 수행하는 작업량이 줄어듦에 따라 감소하게 됩니다. 이러한 견해는 .NET Enterprise Services Performance (영문)를 비롯한 많은 기사에서 확인할 수 있습니다.

또한 이번 테스트를 통해 이들 기술 간의 성능 차이는 DataSet 또는 serialize된 구조를 사용하는 것 같은 응용 프로그램 관련 결정 간의 차이보다 작다는 것이 분명해졌습니다.

이 백서에서는 성능 수치에 큰 중점을 두었지만 개발 프로젝트를 계획할 때 고려해야 할 요소가 성능만 있는 것은 아닙니다. 보안, 확장성, 관리, 개발자 생산성, 상호 운용성, 그리고 Microsoft 분산 기술의 향방 같은 다른 요소도 모두 고려해야 합니다. Developing Distributed Services Today (영문)에는 각 기술의 활용 시기와 상황을 가장 효율적으로 선택하는 방법과 그 발전 가능성을 담은 규범적인 지침이 나와 있습니다.

권장 사항

이번 테스트 결과를 토대로 향후 기술의 방향과 최적의 방법에 따라 다음 권장 사항을 준수하면 성능 문제에 취약하지 않은 시스템을 빌드할 수 있을 것입니다.

가능한 한 ASMX를 사용합니다.

서비스 범위를 극대화하려면 가능한 한 ASMX를 사용하여 서비스를 게시하는 방법을 고려하십시오. ASMX를 사용하면 시스템에서 실행되거나 구현될 수 있는 플랫폼, 장치 또는 언어에 관계없이 모든 시스템에서 HTTP를 통해 SOAP를 전달하여 서비스를 호출할 수 있게 됩니다. 단일 스레드 응용 프로그램에서 호출하는 단일 프로세스 시스템의 경우에도 ASMX는 초당 63회의 많은 작업을 처리할 수 있으며, 이는 동일한 ES 구성 요소보다 초당 호출 수가 10회 적은 수준에 불과합니다. 프로덕션 환경의 경우 단일 시스템에서 ASMX 서비스를 호스트하면 훨씬 뛰어난 성능을 기대할 수 있으므로 ASMX를 채택하도록 유도하는 가장 큰 요인은 무엇보다도 성능이라 할 수 있습니다.

웹 서비스에는 다음을 포함하여 여러 가지 유용한 특징과 기능이 있습니다.

  • 확장성-Windows 네트워크 로드 균형 조정 같은 로드 균형 조정 기술이나 Cisco 및 F5 같은 공급업체의 하드웨어 장치를 사용하면 웹 서비스를 매우 손쉽게 확장할 수 있습니다. 자세한 내용은 다음과 같습니다.
  • 가용성-ASMX 웹 서비스는 로드 균형 조정 같은 기술과 함께 Windows 2003 Server에 내장된 IIS6 인프라의 강력한 기능(예: 실패한 서비스의 자동 재활용 및 다시 시작)을 사용하여 높은 가용성을 갖추도록 구성할 수 있습니다.
  • 상호 운용성-웹 서비스는 개별적인 이종 시스템 간에 자유롭게 통신할 수 있도록 하는 상호 운용 가능한 안전하고 트랜잭션 처리된 통신 프로토콜을 표준화하는 움직임의 핵심입니다.
  • 생산성-대부분의 개발자는 몇 가지 특성을 신중하게 사용하고 일부 권장 사항을 준수하여 ASMX 웹 서비스를 매우 손쉽게 빌드할 수 있습니다.

웹 서비스에 ASMX를 사용합니다.

prescriptive guidance (영문)에는 ASMX가 서비스를 빌드 및 배포하는 데 뛰어난 플랫폼인 다양한 이유가 나와 있으며, 본 백서의 결과를 통해서도 ASMX는 일반적으로 SOAP를 전달할 때 Remoting보다 뛰어난 성능을 발휘한다는 것을 알 수 있습니다.

.NET Remoting도 SoapFormatter 및 HttpChannel을 통해 SOAP/HTTP를 지원할 수 있지만 Remoting을 사용하여 웹 서비스를 노출하는 방법은 가급적 피하는 것이 좋습니다. .NET Remoting SoapFormatter는 더 이상 SOAP의 표준 인코딩 방식이 아닌 RPC-Encoding(대부분의 공급업체 기술 및 플랫폼에서 사용될 미래의 표준 인코딩 메커니즘은 문서-리터럴임)을 사용하므로 Remoting 서비스와의 상호 운용성이 매우 제한적입니다.

확장성을 고려하여 웹 서비스를 선택합니다.

위에서 언급하지 않았지만 이번 설명과 매우 관련성이 높은 내용으로, 웹 서비스는 주로 로드 균형 조정이 간단한 상태 비저장 통신 기술인 HTTP를 통해 통신합니다. 따라서 TCP 또는 HTTP(즉, IIS 내에서 호스트되는)를 사용해도 Remoting 구성 요소의 로드 균형 조정을 수행할 수 있지만 세션 상태가 필요한 경우 복잡해질 뿐 아니라 문제를 일으킬 수 있습니다.

ES/COM+ 구성 요소의 로드 균형 조정을 수행하려면 Application Center 2000의 기능인 CLB(구성 요소 로드 균형 조정)를 사용해야 합니다. 그러나 아쉽게도 AppCenter 2000은 2006년 7월 지원이 확장되며 2011년이면 지원이 종료됩니다. 따라서 더 이상 CLB에 의존하지 않기 위해 2011년 전에 시스템을 다시 설계하는 수고를 피하려면 새로운 개발에 이 기술을 사용하지 않고 가능한 한 빠른 시일 내에 다른 전략으로 마이그레이션해야 합니다. 효과적인 마이그레이션 전략은 현재 COM+ 구성 요소에 ASMX 웹 서비스를 연결하는 것입니다. 이렇게 하면 COM+ 구성 요소로 직접 호출을 전달하고 위에 설명된 것처럼 웹 서비스의 로드 균형 조정을 수행할 수 있습니다.

Enterprise Service는 서비스 내에서만 사용합니다.

.NET Enterprise Service는 COM+에서 제공하는 다양한 서비스에 대한 액세스 및 지원을 제공하는 .NET Framework 계층입니다. 여러 가지 개체/서비스, 미세 조정 보안, JITA 및 개체 풀링을 포괄하는 분산 트랜잭션 같은 다양한 COM+ 서비스가 필요한 경우에는 Enterprise Service를 선택해야 합니다. Enterprise Service와 COM+는 적절한 테스트를 거쳐 높은 수준으로 최적화된 기술로, 매우 빠르고 대기 시간이 낮은 크로스 프로세스 및 크로스 컴퓨터 호출을 제공합니다.

그러나 Enterprise Service 구성 요소를 광범위하게 노출해서는 안 되며 서비스 경계 내에서만 이 기술을 사용해야 합니다. 서비스에 대한 액세스를 제공하려면 ASMX를 사용한 웹 서비스를 통해 서비스의 기능을 노출하는 것이 좋습니다. ES/COM+ 코드 기반을 설정한 경우에는 가급적 COM+ 서비스와 ASMX 웹 서비스를 연결하는 것이 좋습니다.

직접 빌드하기보다는 호스트되는 인프라를 사용합니다.

위에서 설명한 것처럼 ASP.NET은 상호 운용성이 뛰어날 뿐 아니라 IIS(특히, Windows 2003 Server의 IIS6)에서 제공하는 뛰어난 호스팅 기능을 통해 이점이 발휘되는 탁월한 성능의 웹 서비스를 제공합니다.

COM+는 enterprise service 및 COM+ 구성 요소에 신뢰할 수 있고 안전하며 안정적인 호스팅 환경을 지원하고 Microsoft 플랫폼에 가장 빠른 구성 요소 성능을 제공합니다. 또한 분산 트랜잭션 지원, 보안(인증 및 암호화), 안정성, 가용성, 관리 서비스 등을 제공하므로 서비스 내에서 복잡한 구성 요소 기반 시스템을 호스트하는 데 매우 적합합니다.

TCP상에서 이진 serialization을 사용하는 .NET Remoting도 성능이 뛰어나지만 호스팅 환경, 보안, 안정성, 가용성 또는 "즉시 적용할 수 있는" 관리 기능은 제공하지 않습니다. TCP를 사용하는 Remoting 구성 요소를 호스트하려면 호스팅 응용 프로그램을 직접(보안, 확장성, 안정성) 작성해야 하는데, 이는 그리 간단한 작업이 아닙니다. HTTP상에서 Remoting을 사용하려는 경우 IIS를 호스트로 사용할 수도 있지만, 앞서 살펴보았듯이 IIS에서 Remoting 구성 요소를 호스트하여 SOAP/HTTP 통신을 수행하면 Remoting 성능이 크게 떨어지며 대개는 ASMX를 사용하는 것보다 못하게 됩니다!

따라서 Remoting을 사용하기보다는 IIS에서 호스트되는 ASMX나 COM+ 내의 enterprise service 구성 요소에 서비스를 전달하는 것이 바람직합니다.

서비스 간 DataSet을 전달하지 않습니다.

이번 테스트에서 서비스와 호출자의 데이터 교환하는 방법(DataSet 또는 serialize된 구조로)을 선택한 결과 특정 분산 시스템 기술을 서로 비교하여 선택하는 것보다 성능에 훨씬 더 많은 영향을 미쳤습니다.

성능 측면에서 보면 DataSet을 데이터 전송 메커니즘으로 사용하는 것은 응용 프로그램에서 꼭 필요한 부분으로 제한하고 가능한 [Serializable] 구조를 선택하는 것이 좋습니다.

ADO.NET DataSet에서는 데이터를 검색, 조작, 정렬하고 구조를 지정하며 오프라인에서 사용하도록 로컬에 저장하고 변경 내용을 중앙 데이터베이스와 다시 동기화하는 뛰어난 방식을 제공합니다. 이 방식이 응용 프로그램의 요구 사항이라면 당연히 선택해야 합니다. .NET Framework 1.x의 DataSet 값은 항상 XML로 serialize되고(이 값을 이진으로 serialize하거나 ES 또는 Remoting과 함께 사용하길 원하더라도) 데이터를 설명하는 XSD가 포함되어 있는데 이 역시 성능에 영향을 미칩니다.

또한 DataSet은 .NET 관련 기술이고 다른 플랫폼에서 serialize된 DataSet이 포함된 데이터를 반드시 serialize 및 구문 분석할 필요는 없으므로 상호 운용성을 크게 제한합니다.

대신 serialize된 데이터 구조를 교환하면 성능을 크게 개선하는 효과를 얻을 수 있습니다. 이 작업은 위의 테스트에서처럼 기본 제공된 런타임 서식 지정 및 XML serialization 프레임워크를 사용하여 간단히 수행할 수 있습니다.

인증된 연결 공유를 사용합니다.

통합 보안과 함께 IIS(Internet Information Server)를 호스트로 사용하는 모든 테스트는 ASP.NET 클라이언트 및 .NET Remoting에 사용할 수 있는 useAuthenticatedConnectionSharing 및 useUnsafeAuthenticatedConnectionSharing을 옵션으로 실행하도록 구성되어 있습니다. 이 설정을 사용하면 클라이언트와 서버에서 기존 NTLM 인증 연결을 다시 사용할 수 있습니다.

처음에 그림 1(구매 주문서를 개체로 저장)에서 소개한 테스트를 수행하면서 그림 10의 이 옵션을 설정한 경우 나타나는 성능 결과를 확인할 수 있습니다. 이 설정은 IIS를 서버로 사용하고 가상 디렉터리 구성에서 "Windows In Security"를 지정하는 경우에만 적용된다는 점에 유의하십시오.

MSDN Magazine 2004년 9월호의 Web Q&A: Caching Transforms, Connection Sharing, and More (영문) 칼럼에서는 이러한 상호 균형에 대해 설명하고 있습니다.

그림 10. UnsafeAuthenticatedConnectionSharing의 영향

이 설정은 다음과 같이 ASP.NET 웹 서비스 내에서 Windows의 통합 보안과 함께 사용할 수 있습니다.

MyWebService svc = new MyWebService();svc.Credentials = System.Net.CredentialCache.DefaultCredentials;svc.UnsafeAuthenticatedConnectionSharing = true;

또한 .NET Remoting과는 다음과 같이 사용합니다.

IMyRemote rem = (IMyRemote) Activator.GetObject(typeof(IMyRemote), "HTTP://...");IDictionary snkprops = ChannelServices.GetChannelSinkProperties(rem);snkprops["unsafeauthenticatedconnectionsharing"] = true;

부록 A: 종합 기준 - 빈 메서드 테스트

이 테스트는 검토 대상인 기본으로 포함되는 기술들 간의 성능 차이에 대한 기준이 됩니다. 이러한 테스트에서는 매개 변수를 받아들이지 않고 작업을 수행하지 않으며 결과를 반환하지 않는 작업에 대해 호출합니다. 서버측 구현은 다음과 같이 간단합니다.

public void TransferEmpty(){   // 명령을 입력하지 마십시오.}
참고 이러한 종합 기준 수치는 검토 대상인 각 기술의 통신 인프라에 대한 상대 성능 수준을 나타내기 위해서만 제공되며, 실제 시스템에서 예상되는 성능 특성을 반영하지는 않습니다.

그림 11. 프로세스 간 매개 변수 없이 메서드 호출(종합 기준)

그림 11의 테스트 결과는 COM+ 및 DCOM을 비롯하여 고성능 LPC(Lightweight Procedure Call) 시스템상 통신 인프라를 사용하는 ES가 훨씬 최적의 성능을 제공한다는 일반적인 가정에 매우 근접하게 일치했습니다. .NET Remoting 통신 프로토콜은 2위를 차지했습니다. ASP.NET 웹 서비스는 3위를 차지했지만 여전히 IIS에서 호스트되는 .NET Remoting 구성 요소보다는 빠릅니다.

두 번째 단계로 이 테스트를 크로스 컴퓨터 환경에서 실행했습니다. 여기서는 "Url" 속성을 설정하여 생성된 ASP.NET을 리디렉션하고 COM+/enterprise service 구성 요소에 대해 응용 프로그램 프록시를 내보냈으며 이 테스트의 .NET Remoting 부분에 Activator.GetObject()를 사용했습니다. 그 결과 이전 테스트와 매우 유사했지만 네트워크 이동이 포함된 탓에 초당 호출 수가 약간 적었습니다.

그림 12. 컴퓨터 간 매개 변수 없이 빈 메서드 호출(종합 기준)

컴퓨터 간 네트워크 이동은 본래 가장 빠른 전송(ES 및 Remoting Binary/TCP)을 조절하는 한편 보다 느린 전송에는 좀처럼 영향을 미치지 않습니다. 이 결과는 주로 네트워크 트래픽 서비스를 위해 빌드된 기술(즉, IIS 및 ASMX)과 비교해 COM+의 크로스 프로세스 통신 메커니즘이 얼마나 효과적인지 분명하게 보여 줍니다.

또한 앞에서 언급한 것처럼 이 테스트는 매우 인위적이며 전송 성능을 설명하기 위한 것이라는 점에 유의합니다.

부록 B - 세부 테스트 결과

주문을 개체로 저장

테스트평균 초당 호출 수표준 편차
enterprise service730.39
enterprise service(인증)730.34
Remoting TCP/Binary722.71
Remoting HTTP/Binary680.86
Remoting HTTP/Binary(IIS)660.31
ASP.NET 웹 서비스632.71
Remoting HTTP/Binary(IIS) 암호630.39
Remoting TCP/SOAP561.97
Remoting HTTP/SOAP530.57
Remoting HTTP/Binary(IIS) 통합510.28
Remoting HTTP/SOAP(IIS)500.16
ASP.NET 웹 서비스 - 통합500.30
Remoting HTTP/SOAP(IIS) 암호490.29
Remoting HTTP/SOAP(IIS) 통합400.84

주문을 DataSet으로 저장

테스트평균 초당 호출 수표준 편차
enterprise service350.54
enterprise service(인증)350.51
ASP.NET 웹 서비스340.43
Remoting TCP/Binary340.85
Remoting HTTP/Binary320.77
Remoting HTTP/Binary(IIS)321.10
Remoting TCP/SOAP320.77
Remoting HTTP/Binary(IIS) 암호311.47
Remoting HTTP/SOAP300.68
Remoting HTTP/SOAP(IIS)300.48
Remoting HTTP/SOAP(IIS) 암호300.46
ASP.NET 웹 서비스 - 통합290.37
Remoting HTTP/Binary(IIS) 통합280.37
Remoting HTTP/SOAP(IIS) 통합260.31

제품을 개체로 로드

테스트평균 초당 호출 수표준 편차
Remoting TCP/Binary1493.05
enterprise service1472.29
enterprise service(인증)1462.49
Remoting HTTP/Binary1182.13
Remoting HTTP/Binary(IIS)1140.63
Remoting HTTP/Binary(IIS) 암호1061.19
ASP.NET 웹 서비스931.04
Remoting HTTP/Binary(IIS) 통합760.81
ASP.NET 웹 서비스 - 통합670.35
Remoting TCP/SOAP330.34
Remoting HTTP/SOAP300.32
Remoting HTTP/SOAP(IIS)300.25
Remoting HTTP/SOAP(IIS) 암호290.16
Remoting HTTP/SOAP(IIS) 통합260.14

제품을 DataSet으로 로드

'.NET' 카테고리의 다른 글

테스트평균 초당 호출 수표준 편차
ASP.NET 웹 서비스390.12
enterprise service390.26
enterprise service(인증)390.21
Remoting TCP/Binary391.16
Remoting HTTP/Binary(IIS)360.24
Remoting HTTP/Binary351.10
Remoting HTTP/Binary(IIS) 암호350.17
Microsoft patterns & practices Home...  (0) 2005.12.25
[msdn 펌] AOP...  (0) 2005.11.29
[펌]Repearter 사용시 이벤트..  (0) 2005.10.28
[C#] Reqeust.Form 은 짜증나 -.-  (0) 2005.10.12
[펌] ASP.NET 마스터하기: 사용자 지정 엔터티 클래스 소개  (0) 2005.10.12
Posted by tornado
|