서비스를 사용하는 응용 프로그램의 성능 고려 사항

Visual Studio 2010

업데이트: 2007년 11월

이 항목에서는 ASP.NET 멤버 자격, 역할, 프로필 속성, 세션 상태, 웹 파트 개인 설정 및 사이트 탐색을 사용할 때의 성능 최적화에 대해 설명합니다.

이 단원에서는 ASP.NET 멤버 자격을 효율적으로 사용하는 방법에 대해 설명합니다.

효율적인 멤버 자격 목록 수집

Membership 클래스의 메서드를 호출할 때는 PageIndexPageSize 멤버를 사용하는 오버로드된 메서드를 호출합니다. 이러한 오버로드는 웹 서버에서 데이터를 적게 전송하도록 하므로 실행 속도가 더 빠릅니다. Membership 클래스의 GetAllUsers 메서드를 예로 들 수 있습니다. 매개 변수를 지정하지 않고 GetAllUsers 메서드를 호출하면 모든 멤버 자격 사용자가 반환됩니다. 반면 GetAllUsers 오버로드를 호출하면 한 페이지 분량의 사용자만 반환되므로 페이지에서 처리하는 데이터의 양이 줄어듭니다.

온라인 사용자 수를 확인할 때 결과 캐시

GetNumberOfUsersOnline 메서드를 호출하여 웹 사이트에서 활성 상태로 간주되는 사용자 수를 표시할 수 있습니다. 이 메서드를 호출할 때마다 멤버 자격 테이블의 각 행이 검사되므로 데이터베이스에 포함된 사용자 수가 많으면 성능이 크게 저하될 수 있습니다. 필요한 경우에만 이 메서드를 호출하고, 결과가 정확하지 않아도 되는 경우에는 일정 기간 동안 값을 캐시하십시오.

기본적으로 GetRolesForUser 메서드는 페이지를 로드할 때마다 자동으로 호출되고 사용자에게 할당된 역할을 반환합니다. 이 역할은 RolePrincipal 개체의 사전에 저장됩니다. 웹 페이지가 실행되는 동안 이 사전을 사용하여 역할 검사가 수행됩니다. 페이지를 로드할 때마다 공급자에 액세스하지 않도록 하여 서버 처리 시간을 단축하려면 응용 프로그램의 Web.config 파일에서 CacheRolesInCookie 특성을 true로 설정합니다. 이렇게 하면 사용자 역할의 목록이 쿠키에 저장됩니다. 이후에 페이지를 로드할 때는 공급자에 대한 호출을 사용하는 대신 쿠키에서 역할 정보를 읽을 수 있습니다.

코드에서 GetRolesForUser 메서드, IsInRole 속성 및 GetRoles 메서드를 사용하여 역할의 멤버 자격을 확인할 수 있습니다. 이들 메서드가 상호 작용하는 방식을 이해하면 필요한 작업을 응용 프로그램이 가장 효율적으로 수행할 수 있도록 코드를 작성할 수 있습니다.

GetRolesForUser 메서드는 항상 공급자에 액세스합니다. 쿠키 캐싱이 활성화되어 있지 않은 경우 IsInRole 메서드를 호출하면 페이지를 처음 요청할 때마다 항상 GetRolesForUser 메서드가 호출됩니다. 쿠키 캐싱이 활성화되어 있는 경우 IsInRole 메서드를 호출하면 쿠키에 캐시된 역할 정보가 대신 사용됩니다. GetRoles 메서드를 처음 호출하면 쿠키 캐싱의 활성화 여부와 상관없이 GetRolesForUser 메서드가 호출됩니다. 그러나 이후에 이 페이지에서 GetRoles 메서드를 호출하면 RolePrincipal 내에 캐시된 역할 정보가 사용됩니다.

ms228100.alert_note(ko-kr,VS.100).gif참고:

중요한 정보를 쿠키에 저장하면 이 정보가 사용자에게 노출될 위험이 있습니다. 보안을 강화하려면 쿠키 캐싱을 사용하지 말아야 합니다.

코드에서 프로필 속성에 액세스하는 경우 페이지를 로드하면 프로필 공급자가 현재 사용자에 대한 모든 프로필 속성을 읽습니다. 특히 이 공급자는 해당 프로필 공급자와 관련된 모든 속성을 읽습니다. 임의의 프로필 속성 값이 변경되면 페이지를 언로드할 때 새 정보가 공급자 데이터 저장소에 다시 기록됩니다. ASP.NET에서는 정수나 문자열 같은 내장 형식이 변경되었는지 확인할 수 있지만 내장 형식이 아닌 경우에는 해당 형식의 변경 여부를 확인할 수 없습니다.

프로필 속성이 저장되었는지 확인하는 알고리즘은 다음과 같습니다.

  • 모든 프로필 속성이 내장 형식이고 어떠한 속성도 변경되지 않은 경우에는 프로필이 데이터 저장소에 기록되지 않습니다.

  • 모든 프로필 속성이 내장 형식이고 속성이 하나라도 변경된 경우에는 모든 프로필 속성 값이 데이터 저장소에 기록됩니다.

  • 속성이 하나라도 내장 형식이 아닌 경우에는 ASP.NET에서 값이 변경되었는지 확인할 수 없습니다. 코드에서 이 속성에 액세스하는 경우에는 속성 값이 데이터 저장소에 기록됩니다.

    ms228100.alert_note(ko-kr,VS.100).gif참고:

    어떠한 경우이건 결정 사항은 해당 공급자에 대한 모든 프로필 속성에 적용됩니다.

내장 형식이 아닌 속성 형식을 사용하는 경우에는 각 페이지 요청 마지막에 프로필 데이터를 기록하느라 시간이 걸립니다. 다음 방법으로 이 오버헤드를 줄일 수 있습니다.

  • 프로필에 내장 형식만 사용합니다.

  • <profile> 구성 요소의 automaticSaveEnabled 특성을 Off로 설정합니다. 대신 변경을 감지한 다음 필요한 경우에만 속성 값을 저장하는 사용자 지정 코드를 작성합니다.

  • ProfileAutoSaving 이벤트를 처리하는 사용자 지정 코드를 작성하고, 이벤트 코드에서 프로필 속성에 대한 변경 사항이 발생했는지 확인합니다. 어떠한 속성도 변경되지 않았으면 자동 저장 작업을 취소하고 이벤트의 ContinueWithProfileAutoSave 속성을 false로 설정합니다.

  • 자세한 내용은 다음을 참조하십시오. 개별 사용자용 웹 사이트 만들기(Visual Studio).

Out-of-process 세션 상태 모드를 사용할 때는 성능을 고려해야 합니다. 이 모드에 대한 자세한 내용은 세션 상태 모드를 참조하십시오. 이 단원에서는 세션 상태의 성능을 최적화하는 방법에 대해 설명합니다.

세션 상태 읽기 및 쓰기 오버헤드 줄이기

기본적으로 페이지를 로드할 때마다 세션 상태 정보가 로드됩니다. @ Page 지시문의 EnableSessionState 특성을 사용하면 다음과 같은 설정으로 로드되는 세션 상태를 제어할 수 있습니다.

  • True   페이지를 로드할 때마다 세션 상태 데이터를 읽고 변경된 데이터를 저장합니다. ASP.NET에서는 정수나 문자열 같은 내장 형식의 변경 여부를 확인할 수 있습니다. 세션 상태 값이 모두 내장 형식이고 이들 중 어떠한 값도 변경되지 않았으면 세션이 저장되지 않습니다. 이 값 중 하나라도 내장 형식이 아니고 내장 형식이 아닌 세션 값에 액세스한 경우에는 세션 상태 정보가 모두 저장됩니다. 이와 같이 작동하는 이유는 ASP.NET에서 내장 형식이 아닌 다른 형식의 변경 여부를 추적할 수 없으므로 데이터를 모두 저장하는 가장 안전한 방법을 선택한 데 있습니다.

  • False   페이지를 로드할 때 세션 상태 데이터를 읽지 않습니다.

  • ReadOnly   페이지를 로드할 때마다 세션 상태 데이터를 읽지만 데이터를 저장하지는 않습니다. 코드에서 세션 상태 값을 변경한다고 해도 마찬가지입니다.

세션 상태에 대한 잠금 경합 방지

세션 상태가 필요한 페이지에는 <IFRAME> 요소를 사용하지 않도록 합니다. 동일한 세션 상태 식별자를 사용하여 ASP.NET에 전달된 요청이 여러 개 있는 경우 모든 요청이 대상으로 삼고 있는 ASP.NET 페이지의 EnableSessionStatetrue로 설정되어 있으면 Out-of-process 세션 상태와 연결된 잠금에 대해 이러한 동시 요청 간에 경합이 발생합니다. <IFRAME> 요소의 경우 이는 한 페이지의 여러 <IFRAME> 요소에 표시되는 ASP.NET 페이지가 동일한 세션 데이터를 얻기 위해 경합을 벌일 수 있음을 의미합니다. 이 경우 각각의 개별 요청이 서버에서 연속되는 결과가 발생합니다.

페이지를 실행하면 ASP.NET 개인 설정 정보가 로드됩니다. 변경된 웹 파트 개인 설정 정보가 있는지 확인하기 위해 ASP.NET에서는 Equals 메서드를 호출하고 PersonalizableAttribute 특성으로 표시된 속성의 이전 값과 새 값을 비교합니다.

변경된 개인 설정 속성 값이 있으면 개인 설정 데이터가 저장됩니다. 정수 같은 내장 형식의 경우 Equals 메서드는 이전 속성 값과 새 속성 값을 직접 비교합니다. 그러나 비내장 형식의 경우 ASP.NET은 참조 값을 비교할 뿐 형식 인스턴스에서 유지하는 데이터는 비교하지 않습니다.

예를 들어, ArrayList 형식의 속성에 대해 Equals 메서드는 ArrayList 참조의 이전 값과 새 값을 비교하지만 ArrayList 개체의 내용은 비교하지 않습니다. 새 항목이 목록에 추가되었더라도 ArrayList 참조가 변경되지 않았다면 Equals 메서드는 true를 반환합니다. 이 경우 ArrayList 데이터는 저장되지 않습니다.

비내장 형식에 대한 이와 같은 알고리즘은 효율적이기는 하지만 데이터를 저장하지 않는다는 측면에서 문제가 있습니다. ArrayList 개체와 같은 비내장 형식의 데이터를 저장하려면, 컨트롤이 WebPart에서 파생된 경우 IsDirty 속성을 true로 설정하고 그렇지 않으면 컨트롤을 매개 변수로 사용하는 SetPersonalizationDirty 메서드를 호출합니다.

사이트 맵이 크면 크기가 작은 사이트 맵에 비해 성능이 저하됩니다. 예를 들어, 노드 수를 100개에서 1000개로 10배 늘리는 테스트 시나리오에서는 페이지 로드 시간이 1/3 정도 늘어날 수 있습니다.

역할을 기반으로 노드를 필터링하는 보안 트리밍을 사용하면 노드 수를 늘리는 경우보다 성능이 크게 저하됩니다. 예를 들어, 노드가 1000개인 사이트 맵에서는 노드가 100개인 사이트 맵에 비해 처리 오버헤드가 10배 증가합니다.

이러한 영향을 줄이려면 다음과 같은 몇 가지 지침을 따르는 것이 좋습니다.

  • 보안 트리밍을 사용할 때는 최대 노드 수를 150으로 설정하는 것이 좋습니다.

  • 사이트 맵의 각 노드에 Roles 특성을 설정합니다. 이 역할 특성이 있으면 이 특성에 나열된 역할 중 하나에 사용자가 속하는 경우 ASP.NET에서 SiteMapNode와 연결된 URL에 대한 URL 및 파일 권한 부여 과정을 생략할 수 있습니다. 그러나 지정된 역할에 사용자가 속하지 않는 경우에는 ASP.NET에서 다시 느린 속도로 파일 및 URL 권한 부여 검사를 수행합니다.

  • SiteMapProvider 클래스에서 상속하는 클래스를 만들고 사이트 맵의 각 노드에서 Roles 특성만 검사하도록 IsAccessibleToUser 메서드를 재정의합니다. 이렇게 하면 URL 및 파일 권한 부여 과정이 생략되므로 필터링 과정이 빨라집니다. 그러나 이 방법을 사용하려면 웹 응용 프로그램에 두 가지 보안 사항이 나란히 정의되어 있어야 합니다. 첫 번째 보안 정의는 Web.config 파일의 권한 부여 정보입니다. Windows 인증을 사용하는 경우 파일 권한 부여를 위한 NTFS 액세스 제어 목록도 여기에 해당합니다. 두 번째 보안 정의는 사이트 맵의 역할 정보입니다. 보안 정보를 분할하면 사이트 맵 처리 성능은 향상되지만 보안 관리 오버헤드는 증가하므로 신중히 고려해야 합니다.

자세한 내용은 ASP.NET 사이트 맵 보안 트리밍ASP.NET 권한 부여를 참조하십시오.

표시: