OperationContext.Current.InstanceContext.ReleaseServiceInstance()

Download Report

Transcript OperationContext.Current.InstanceContext.ReleaseServiceInstance()

WCF Essentials (.NET 3.0 June CTP 기준)
MSDN Magazine 2006-06
WCF Essentials – Discover Mighty Instance Management
Techniques For Developing WCF Apps
2006.07.03
정성태([email protected])
*** 이 문서는 PPT Template 만을 .NETXPERT
를 썼을 뿐, 회사의 공식 문서가 아닙니다.
인스턴스 관리 – Instance management
.NET Remoting 에서부터 이미 Well-known(Single-call,
Singleton), Client-Activated 유형이 있었던 것처럼, WCF
역시 그와 비슷한 인스턴스 관리 성격을 지니고 있습니다.
이 PPT 에서는 WCF 에서 제공하고 있는 Instance
management mode 에 대해서 다뤄보도록 하겠습니다.
목차
0. ServiceBehavior
1. Per-Call 유형의 서비스
2. Per-Session 유형의 서비스
3. Shareable 유형의 서비스
4. Singleton 유형의 서비스
5. OperationContract 세부 설정
6. Instance deactivation 설정
7. Throttling 설정
ServiceBehaviorAttribute
0. 서비스 행동 양식을 지정
이 특성을 통해서 서비스에 대한 다양한 행동 양식을 지정.
ServiceBehavior 를 통해 지정 가능한 속성 중에서,
InstanceContextMode 를 통해서 서비스 활성화 방식을 지정
[표 1] InstanceContextMode
public enum InstanceContextMode
{
PerSession = 0, PerCall = 1, Single = 2 // June CTP 에서 Shareable 제거
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class ServiceBehaviorAttribute : Attribute, ...
{
public InstanceContextMode InstanceContextMode {get;set;}
... // More members
}
1. Per-Call Services
1-1. WCF 기본 인스턴스 모드 : Per-Call Services
- default instantiation mode
- 한번의 클라이언트 호출로 생성되었다가, 호출이 끝나면 제거됨
- 모든 서비스 인스턴스는 호출마다 새롭게 생성됨
- .NET Remoting 에서의 “Well-known SingleCall” 유형과 유
사
- 세션 및 쿠키를 가지지 않은 ASP.NET 웹 서비스 호출 방식과 유사
- COM+ 의 JIT/AutoComplete 메서드 호출과 유사
- 서비스 함수 내에서 비동기 호출을 해서는 안됨. (aspx 와 유사)
- 서비스를 해주는 쓰레드를 가능한 빨리 자유롭게 해줄 때 최상의 성
능을 제공
1. Per-Call Services
1-2. 인스턴스 활성
1. 클라이언트에서 Proxy 를 호출. 프록시는 호출을 그대로 서비스로 전달
2. WCF 는 새로운 서비스 인스턴스를 생성하고, 프록시 호출에 대응하는
메서드를 호출
3. 메서드 호출 완료 후, 해당 개체가 IDisposable 인터페이스를 구현했다
면, WCF 는 IDisposable.Dispose 메서드를 호출.
1. Per-Call Services
1-3. 구현 예
[ServiceContract]
interface IMyContract { ... }
[ServiceBehavior(
InstanceContextMode =
InstanceContextMode.PerCall // 생략 가능
)]
class MyService : IMyContract {...}
1. Per-Call Services
1-4. 상태 관리
-만약, 상태 관리가 필요하다면 Per-Call 서비스는 스스로 구현해
주어야 함.
-서비스 측의 상태유지를 위해서 별도의 storage 를 사용.
예) storage 유형 : Database, File System, static 변수
2. Per-Session Services
2-1. WCF 에 의해서 세션이 제공되는 서비스 유형
-이러한 유형의 서비스에 대해 클라이언트가 프록시를 생성하게 되
면, 전용 서비스 개체가 할당되어짐.
-클라이언트 측에서의 사용이 모두 완료된 이후에야 서버 측에서의
서비스 개체는 제거됨.
-프록시 개체 당 서버 개체 하나 생성. 만약, 클라이언트가 해당 서
비스의 종점(endpoint)에 대한 또 다른 프록시를 생성한다면, 별
도의 서버 개체가 생성됨.
-프록시와 서버간의 전용 세션 유지
-기존의 클라이언트 / 서버 모델과 유사
2. Per-Session Services
2-2. 세션 사용을 지정하는 요소
-Contractual : 클라이언트 측의 WCF 런타임도 해당 서비스가 세
션을 사용하고 있다는 것을 알아야 하므로 반드시 지정해야 함.
Contract 요소 이므로, “ServiceContract” 특성에서 명시.
[
AttributeUsage( AttributeTargets.Interface | AttributeTargets.Class,
Inherited=false)
]
public sealed class ServiceContractAttribute : Attribute
{
public SessionMode SessionMode { get; set; }
// June CTP 에서 SessionMode 로 변경됨.
... // More members
}
2. Per-Session Services
2-3. 세션 사용을 지정하는 요소
-Behavioral : WCF 에 해당 서비스 인스턴스를 세션을 통해 유지
할 수 있도록 지정하고, 세션과 메시지를 연관시켜 처리하도록 지정.
Behavior 요소 이므로, “ServiceBehavior” 특성에서 명시.
[
ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)
]
class MyService : IMyContract
{
...
}
2. Per-Session Services
2-4. 세션 사용 코드 – 서버 측
[ServiceContract(SessionMode = SessionMode.Required)]
interface IMyContract
{
[OperationContract] void MyMethod();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract,IDisposable
{
int m_Counter = 0;
MyService() { Trace.WriteLine("MyService.MyService()"); }
public void MyMethod()
{
m_Counter++;
Trace.WriteLine("Counter = " + m_Counter);
}
public void Dispose() { Trace.WriteLine("MyService.Dispose()"); }
}
2. Per-Session Services
2-5. 세션 사용 코드 – 클라이언트 측
-클라이언트 측 proxy 개체가 닫힐 때 세션이 종료됨.
-만약, 서비스가 IDisposable 을 구현한 개체라면 proxy 개체가
닫힐 때, IDiposable.Dispose 메서드가 호출됨
-per-session 모드는 Application 수준의 세션 환경을 제공
MyContractProxy proxy = new MyContractProxy();
proxy.MyMethod();
proxy.MyMethod();
proxy.Close(); // 세션 종료
2. Per-Session Services
2-5. 세션 사용과 바인딩 모드
-세션 구현으로 인해, 반드시 신뢰할 수 있는 전송 세션
(reliable transport session) 을 지원하는 바인딩 만이 사용
될 수 있음.
-바인딩 검증은 서비스 로드 시에 이뤄지고, 조건을 만족하지 못
하면 “InvalidOperationException” 예외 발생
-클라이언트와 서버 모두에서 신뢰할 수 있는 전송 세션을 사용해
야 하고, 선언적 또는 프로그래밍 적으로 설정되어져야 함.
-“Named Pipe 바인딩”은 신뢰할 수 있는 전송 세션으로 간주
2. Per-Session Services
2-5. 세션 사용과 바인딩 모드
그 외,
msmqIntegrationBinding
netPeerTcpBinding
wsFederationHttpBinding
customBinding
2. Per-Session Services
2-6. 세션 설정 – idle time
-기본값 : 10분
-클라이언트로부터 지정된 idle time 시간 동안 호출이 없다면 종료
-세션 만료 된 프록시를 통해서 접근하면,
“CommunicationObjectFaultedException” 예외 발생
-클라이언트와 서버 모두에서 설정할 수 있으며, 시간이 다른 경우
작은 시간 쪽의 설정 값으로 정해짐.
2. Per-Session Services
2-7. idle time 설정
-프로그래밍
NetTcpBinding tcpSessionBinding = new NetTcpBinding();
tcpSessionBinding.ReliableSession.Enabled = true;
tcpSessionBinding.ReliableSession.InactivityTimeout =
TimeSpan.FromMinutes(25);
-환경 설정
<netTcpBinding>
<binding name="TCPSession">
<reliableSession enabled="true"
inactivityTimeout="00:25:00"/>
</binding>
</netTcpBinding>
3. Shareable Services
3. InstanceContextMode.Shareable
-June CTP 버전에서 없어짐
; 다른 식으로 구현이 바뀌었는지? 아예 없어진 것인지?
-기타, 공유 문제에 대해서도 완전히 변경됨.
; IClientChannel.ResolveInstance 삭제
; instanceContextIdleTimeout 속성 및 그것을 담고 있는
behavior 노드 자체가 삭제 됨
4. Singleton Services
4-1. Singleton 서비스
-단 하나의 서비스 인스턴스만 생성됨
// 초기화가 필요 없는 경우, 특성으로 singleton 개체임을 지정
[ServiceBehavior(InstanceContextMode =
InstanceContextMode.Single)]
class MySingleton : ...
{
...
}
// 초기화가 필요한 경우, 외부에서 생성하여 WCF Host 에 전달
MySingleton singleton = new MySingleton();
singleton.Counter = 42;
ServiceHost host = new ServiceHost(singleton);
host.Open();
4. Singleton Services
4-2. Singleton 서비스 : Host 측에서 접근 가능
서비스 호스트
다음과
같이호스트
정의 측에서 자유롭게 접근 가능
- //
Singleton
개체 에서
서비스는
WCF
public class ServiceHost : ServiceHostBase,...
{
public ServiceHost(object singletonInstance, params Uri[]
baseAddresses);
public virtual object SingletonInstance { get; }
... // More members
}
// 서비스 호스트는 OperationContext 에서 다음과 같이 정의
public sealed class OperationContext : ...
{
public ServiceHostBase Host {get;}
... // More members
}
4. Singleton Services
4-3. Singleton 서비스 : OperationContext 로 접근 예
- 호스트 측에서 OperationContext 를 이용하여 다음과 같이 접근
ServiceHost host = OperationContext.Current.Host as ServiceHost;
Debug.Assert(host != null);
MySingleton singleton = host.SingletonInstance as MySingleton;
Debug.Assert(singleton != null);
singleton.Counter = 388;
- singleton 인스턴스가 없다면, null 반환
4. Singleton Services
4-4. Singleton 서비스 : 동시성 처리
- 단일한 Singleton 서비스에 대한 모든 호출은 동기화가 제공되어, 한
번에 하나의 클라이언트 측 호출만 처리.
5. OperationContract 세부 설정
5-1. OperationContract 특성
- OperationContract 특성이 가진 세부 속성
[AttributeUsage(AttributeTargets.Method)]
public sealed class OperationContractAttribute : Attribute
{
public bool IsInitiating {get;set;}
public bool IsTerminating {get;set;}
... // More members
}
- 위와 같은 속성들을 적절히 사용하게 되면, 세션의 생명 주기 동안 호
출될 메서드 들의 순서를 설정하는 것이 가능.
- 이 속성을 이용하기 위해서는 세션이 사용 가능하도록 명시된 서비스
또는 Singleton 서비스여야 함.
5. OperationContract 세부 설정
5-2. OperationContract.IsInitiating 속성
- true 인 경우, 세션이 최초로 맺어지는 단계에서 호출이 가능.
- false 인 경우, 다른 메서드(Operation)에 의해 서버 측 인스턴스가
생성된 이후에만 호출이 가능.
5. OperationContract 세부 설정
5-3. OperationContract.IsTerminating 속성
- true 인 경우, 메서드가 호출되고 반환되는 시점에 세션 종료.
- false 인 경우, 메서드 종료는 세션에 아무런 영향 없음.
5. OperationContract 세부 설정
5-4. IsInitiating / IsTerminating 기본값
- IsInitiating : true, IsTerminating : false
// 다음의 2가지 인터페이스는 완전히 동일
[ServiceContract(SessionMode = SessionMode.Required)]
interface IMyContract
{
[OperationContract] void MyMethod();
}
[ServiceContract(SessionMode = SesionMode.Required)]
interface IMyContract
{
[OperationContract(IsInitiating = true,
IsTerminating = false)]
void MyMethod();
}
5. OperationContract 세부 설정
5-5. 메서드 호출 순서 정의
- 아래와 같은 메서드는 반드시,
Method1 -> Method2 -> Method3 또는 Method1 -> Method3
순서로 클라이언트 측에서 호출을 해야 함.
[ServiceContract(SessionMode = SesionMode.Required)]
interface IMyContract
{
[OperationContract]
void MyMethod1();
[OperationContract(IsInitiating = false)]
void MyMethod2();
[OperationContract(IsInitiating = false,IsTerminating = true)]
void MyMethod3();
}
6. Instance deactivation
6-1. 인스턴스와 문맥(1)
- 각각의 서비스 인스턴스는 문맥 내에서 호스트 됨.
- 세션은 클라이언트 측의 메시지를 서비스 인스턴스와 연결시키는 것이
아니라, 실제로는 해당 서비스 인스턴스를 담고 있는 문맥에 연관 시킴.
- 세션이 시작될 때, WCF 호스트는 새로운 문맥을 생성하고 세션이 종
료될 때, 문맥을 제거.
6.
Instance deactivation
6-2. 인스턴스와 문맥(2)
- 별다른 설정이 없다면, 인스턴스와 문맥의 생성/제거는 동일한 시기에
발생
- 문맥은 인스턴스 없이도 존재가 가능.
- OperationBehavior특성의 ReleaseInstanceMode 를 지정해서
그러한 문맥과 인스턴스 관계를 최적화 할 수 있음.
- 인스턴스가 문맥내에서 제거될 때, IDisposable 이 구현되어 있다면,
Dispose 메서드가 호출됨.
- 세션은 그대로 유지되고, ReleaseInstanceMode 값에 따라서 동일
한 문맥 내에 인스턴스가 새롭게 생성/종료 됨.
6.
Instance deactivation
6-3. ReleaseInstanceMode
- 문맥 내에서의 인스턴스 비활성화를 조정할 수 있는
OperationBehavior 특성값의 속성
- 기본값 : None
public enum ReleaseInstanceMode
{
None, BeforeCall, AfterCall, BeforeAndAfterCall
}
[AttributeUsage(AttributeTargets.Method)]
public sealed class OperationBehaviorAttribute : Attribute,...
{
public ReleaseInstanceMode ReleaseInstanceMode {get;set;}
... // More members
}
6.
Instance deactivation
6-4. ReleaseInstanceMode 값 의미
- None : 기본값.
- BeforeCall : 해당 세션이 연결된 문맥에 이미
인스턴스가 활성화 되어 있다면, 그것을 종료시키
고 새로운 인스턴스를 그 문맥에서 생성 시킴.
(사용예 : Open – 기존 자원은 해제하고, 새로운
자원을 얻고, 그 이후의 메서드 들은 이때 얻은 리
소스를 기반으로 동작.)
- AfterCall : 메서드 호출이 완료된 후 인스턴스
를 해제. (사용예: Close - 세션이 종료될 때 까
지 기다리지 않고 최대한 빠르게 자원을 해제하려
는 경우.)
- BeforeAndAfterCall : 메서드 호출 전에 인
스턴스를 새로 활성화시키고, 메서드 호출 이후에
는 인스턴스틀 비활성화. ( 세션을 가진 서비스에
서의 Per-Call 서비스 방식과 유사하게 동작 )
6.
Instance deactivation
6-5. ReleaseInstanceMode 런타임에 결정
- ReleaseInstanceMode.AfterCall 의 경우, 런타임 시에도 프로그
래밍 방법을 통해 결정이 가능.
- 임의의 메서드 내에서, 문맥 내의 인스턴스를 해제할 수 있도록
ReleaseServiceInstance 메서드 제공
public sealed class InstanceContext : CommunicationObject,...
{
public void ReleaseServiceInstance();
... // More members
}
public sealed class OperationContext : ...
{
public InstanceContext InstanceContext {get;}
... // More members
}
6.
Instance deactivation
6-6. ReleaseServiceInstance 사용예
- OperationContext.Current 를 통해 WCF Host 개체를 접근해서
그 개체에서 제공하는 InstanceContext 를 이용
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Per
Session)]
class MyService : IMyContract,IDisposable
{
public void MyMethod()
{
//Do some work then
OperationContext.Current.InstanceContext.ReleaseServiceInstance();
}
public void Dispose() {...}
}
7.
Throttling 설정
7-1. 다양한 설정 제어 값
- 서비스 연결 수 제어 (Max Sessions: 기본값 - 10)
- 서비스 인스턴스 수 제어 (Max Instances: 기본값 – Int32.Max)
- 서비스 메서드 동시 호출 수 (Max Concurrent Calls: 기본값 - 64)
- 제어값을 넘어가는 요청이 들어온 경우, WCF 는 자동적으로 큐에 요
청을 보관하고, 순서적으로 처리.
- 서비스 타입 단위로 제어 값 설정.
7.
Throttling 설정
7-2. InstanceContextMode 설정
- Singleton 서비스
; Max Instances 는 의미가 없음.
- Per-session 서비스
; Max Instances 는 동시 활성화 된 인스턴스이면서도 동시 세션
수 모두를 의미, 즉 Max Sessions 값에 대한 설정을 의미.
- Per-call 서비스
; 인스턴스의 수는 동시 호출 수와 동일. 따라서, Max Instances
와 Max Concurrent Calls 값이 모두 설정된 경우, 그 중의 작은 값
이 실제 제어 값으로써의 의미를 가짐.
7.
Throttling 설정
7-3. 설정 방법 – Configuration
<system.serviceModel>
<services>
<service name = “MyService" behaviorConfiguration =
"ThrottledBehavior">
...
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ThrottledBehavior">
<serviceThrottling maxConcurrentCalls = "12"
maxConcurrentSessions = "34" maxConcurrentInstances = "56"
/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
7.
Throttling 설정
7-4. 설정 방법 – 프로그래밍 (1)
- 반드시 WCF Host.Open 메서드 호출 이전에 설정되어야 함.
public class ServiceHostBase : ...
{
public ServiceDescription Description {get;}
... // More members
}
public class ServiceDescription : ...
{
public KeyedByTypeCollection<IServiceBehavior> Behaviors
{ get; }
... // More members
}
7.
Throttling 설정
7-5. 설정 방법 – 프로그래밍 (2)
ServiceHost host = new ServiceHost(typeof(MyService));
// ServiceThrottingBehavior 는 2개 이상 존재할 수 없음.
// Config 에서 이미 설정되어 있는지 검사.
// 만약, 재설정하고 싶다면 기존 config 설정을 제거한 후 추가해야 함.
ServiceThrottlingBehavior throttle =
host.Description.Behaviors.Find<ServiceThrottlingBehavior>();
if(throttle == null)
{
throttle = new ServiceThrottlingBehavior();
throttle.MaxConcurrentCalls
= 12;
throttle.MaxConcurrentSessions
= 34;
throttle.MaxConcurrentInstances
= 2;
host.Description.Behaviors.Add(throttle);
}