HTTP는비연결프로토콜입니다. 클라이언트 ( 정확하게는웹브라우저 ) 가서버에특정처리를요청하고나면서버에서그에맞는응답을해주는것으로끝납니다. 연결이계속해서유지되어야하는 FTP와는다른것입니다. 이러한 HTTP통신방식으로인해클라이언트가어떤데이터를서버에요청을할때마다서버는어떻게해서든이사용자가누구인가혹은어떤데이터를다루고자하는가를구분해야할필요가있습니다. 이럴때세션 (Session) 이사용될수있습니다. 다만세션은사용자를구분하기위한유일한방법이아닙니다. 그저사용자를구분하는방법중 ' 하나 ' 에해당할뿐입니다. 세션은쿠키와비교될수있습니다. 쿠키는클라이언트에저장되는반면세션은서버에서저장되고관리됩니다. 쿠키보다훨씬보안적으로우수하지만 ( 쿠키는원한다면얼마든지사용자에의해변조될수있습니다.) 세션은서버의자원을할당해야한다는측면에서성능상으로단점이존재합니다. 1. InProc 세션은기본적으로 InProc모드로관리됩니다. In-Process라는것으로 HttpRuntime 개체 ( 프로세스 ) 의내부캐시에세션을저장하고관리합니다. 이때문에실행속도가가장빠른모드이지만세션을계속참조상태에유지하고있고이에대한가비지컬렉션은별도로이루어지는게없어서메모리를계속점유하고있다는단점이존재합니다. 물론그렇다하더라도메모리점유는만료시간이 20분이경과하거나별도의구성파일에지정된시간이지나면자동으로만료되므로평생세션을저장해두지는않습니다. 참고로 InProc 모드에서의세션은 dll 이빌드되어새로배포되거나 Web.config 와같은구성파일의 변경등과같은이유로프로세스가다시시작하면기존세션은모두손실됩니다. ASP.NET 에서세션은다음과같이읽고쓸수있습니다. Session["aaa"] = "aaabbb"; Response.Write(Session["aaa"].ToString()); 세션은 ASP.NET의모든페이지에서위와같은방법으로엑세스할수있습니다. 만일 "aaa" 라는인덱스의세션을사용하는특정페이지가호출된다면이요청이완료될때까지같은세션을사용하는다른페이지는대기상태에들어가게됩니다.( 사용하는세션의인덱스가다르면영향이없습니다.) 필요하다면특정페이지마다 EnableSessionState 속성을조정함으로서세션접근에대한권한을 http://lab.cliel.com/entry/aspnet-%ec%84%b8%ec%85%98session 1/5 조정할수있습니다.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="web_form_test.Default" EnableSessionState="True" %> True 값은세션에대한읽기 / 쓰기권한을모두부여합니다. 같은세션을사용하는다른페이지에 서는세션이잠기게됩니다. False 값은세션에대한권한을주지않습니다. 만약 False 설정이된페이지에서는세션이접근할 수없습니다. ReadOnly 는세션에대해오로지읽기권한만을부여합니다. 이경우에는세션잠금이설정되지않 기때문에다른페이지에서같은세션의값을읽을수있습니다. 하지만세션에쓰기가시도되는 경우모든읽기또한차단됩니다. 재미있는점은 EnableSessionState 가 False 로설정된페이지는설정이없는페이지요청보다우선 적으로처리하게된다는것입니다. 따라서계획적으로잘만설정된다면성능적으로이익을볼수 있습니다. 극단적으로 Web.config 를아래와같이처리하면 <sessionstate mode="off"></sessionstate> 웹애플리케이션전체에대해세션사용을고려하지않게되므로성능면에서훨씬이득이지만세 션은사용할수없습니다. 2. Out-of-Process Out-of-Process는세션을 aspnet_state.exe라는프로세스에저장하는방식입니다. 다른물리적서버에해당프로세스를띄어놓고세션을관리하는형태 ( 세션을처리하는서버를별도로두는것 ) 이지만원한다면로컬에프로세스를실행하는것또한가능합니다. aspnet_state.exe는자동으로시작되는프로세스가아니므로서비스를수동으로시작해줘야합니다. net start aspnet_state 위와같은명령줄대신 Services 관리자에서시작할수도있습니다. http://lab.cliel.com/entry/aspnet-%ec%84%b8%ec%85%98session 2/5
이프로세스는 TCP 통신을하는데기본포트가 42424 입니다. 이설정은아래레지스트리경로에서 바꿀수있습니다. [HKEY_LOCAL_MACHINE]\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\Port 세션관리를 Out-of-Process 로하기로했다면 Web.config 에서세션설정을바꿔줍니다. <sessionstate mode="stateserver" stateconnectionstring="tcpip=127.0.0.1:42424"> </sessionstate> mode 를 StateServer 로설정하여 Out-of-Process 사용을명시하고 stateconnectionstring 을통해 서연결될서버의 IP 와 Port 를설정합니다. 예제에서는로컬에서사용할것이므로 127.0.0.1:42424 로설정하였습니다. 다른서버라면그에맞는 IP 를지정해주시면됩니다. 이방식은일단이름에걸맞게프로세스를벗어난세션관리형태의방식입니다. 그러니까 ASP.NET 애플리케이션 ( 코드 ) 은 w3wp.exe 프로세스에서동작하는데세션관리는 aspnet_state.exe 프로세스에관리되므로코드에서세션을참조할수있는형태가아닙니다. 그래서세션에단순한문자열을담는경우는상관없지만클래스나구조체등을초기화하고세션에담으려하면오류가발생합니다. 코드의동작과세션관리가다른프로세스로분리되어있기때문입니다. 이들프로세스간통신을수행해서세션처리를정상적으로처리하려면사용하려는클래스에 [Serializable] 특성을선언해야합니다. [Serializable] http://lab.cliel.com/entry/aspnet-%ec%84%b8%ec%85%98session 3/5 public class testclass
public string myname; 클래스를위와같이작성하고 testclass tc = new testclass(); protected void Page_Load(object sender, EventArgs e) tc.myname = "cliel"; Session["aaa"] = tc; protected void Button1_Click(object sender, EventArgs e) Response.Write((Session["aaa"] as testclass).myname); 클래스를세션에담으면정상적으로코드가수행될것입니다. 다만클래스 ( 개체 ) 를 [Serializable] 특성을사용해직렬화하면직렬화되는과정에서크기가다소커질수있습니다. 그만큼 aspnet_state.exe 프로세스는관리해야하는세션의크기가커질수있다는뜻인데 sessionstate 요소의 compressionenabled속성을 true로하면개체를압축해서저장하므로크기에대한부담이다소줄어들수있습니다. <sessionstate mode="stateserver" stateconnectionstring="tcpip=127.0.0.1:42424" compressionenabled="true"></sessionstate> 하지만실제개체를사용하려면어떻게해서든압축된걸푸는과정이필요하므로 InProc 보다는 성능에서불리할수있습니다. 3. SQL 서버세션 세션은필요하다면 SQL 서버에서저장하고관리할수도있습니다. 이방식은이전에말씀드린방 식에비해가장느리지만반면가장안전하게동작하는방식입니다. 심지어는 IIS 전체가재시작되 는경우라하더라도서버에세션정보가저장되므로사용자와의세션은계속유지될수있습니다. SQL 서버를통해서세션을관리하려면특정 DB 안에세션저장을위한구성이추가되어야합니다. 이작업은 aspnet_regsql.exe 를통해서구현할수있습니다. http://lab.cliel.com/entry/aspnet-%ec%84%b8%ec%85%98session 4/5
아래는세션관리를위한 aspnet_regsql.exe 실행예시입니다. aspnet_regsql.exe -S localhost -U sa -P 1234 -ssadd -sstype p 위와같이명령줄을입력하면해당서버에 ASPState DB 를자동으로생성하고세션저장을위한 구성을완료하게됩니다. 참고로 -ssadd 는지정된서버에세션상태저장을위한구성을추가하는옵션이며반대로 - ssremove 는추가된구성을제거하도록하는옵션입니다. -sstype으로지정된 p는데이터와프로시저를 ASPState DB에저장하도록합니다. 물론 DB도알아서만들어주므로일단편리함은최고입니다. p외에 t라는옵션도있는데이옵션은세션을 tempdb에저장하고프로시저는 ASPState에생성하도록합니다. 이는세선을임시테이블에저장하는형태다보니 SQL서버가다시시작되면세션데이터는사라진다는특징이있습니다. 만일 ASPState DB 에세션저장과프로시저가생성되는걸원하지않는다면 c 옵션으로직접세션이 저장되고프로시저가생성되는 DB 를지정해줄수도있습니다. aspnet_regsql.exe 를실행시켜위와같이정상적으로처리되었다면이제 web.config 를수정하여 세션을 SQL Server 에저장하도록해주면됩니다. <sessionstate mode="sqlserver" sqlconnectionstring="data source=127.0.0.1;user id=sa;password=12345"></sessionstate> 참고로 ASPState DB 가아닌다른이름의 DB 를사용한다면위 Web.config 설정에서 database=mydb 형식으로내용을추가해줘야합니다. http://lab.cliel.com/entry/aspnet-%ec%84%b8%ec%85%98session 5/5