Connection pool 엑셈컨설팅본부 /APM 팀박종현 Connection pool 이란? 사용자의요청에따라 Connection을생성하다보면많은수의연결이발생했을때서버에과부하가걸리게된다. 이러한상황을방지하기위해미리일정수의 Connection을만들어 pool에담아뒀다가사용자의요청이발생하면연결을해주고연결종료시 pool에다시반환하여보관하는것이다. [ 그림 1] Connection pool - Note DB Connection Pool 매니저가일정의 Connection 을연결하고있다가요청이들어오 면 Connection 을할당해주고없으면기다리게한다. 클라이언트는 Connection 을다쓰면 다시반납하는구조로이루어진다. 따라서속도나 performance 부분이향상된다. 보통의경우 DB 에연결을하고결과를가져온후에 close 시켜버린다. DB 에연결하는과정은 시간이많이소요되는 Cost 가비싼연산이며 performance 도많이떨어진다. 이러한문제점 Part 2 APM 383
을해결하기위해 DB Connection pool 을사용한다. 한번맺은 DB Connection 을바로 close 시키지않고 pool 에저장한뒤에다음번에동일한 Connection 을요청하면바로 pool 에서 꺼내제공을함으로써빠른 DB Connection Time 을보장해준다. Connection pool 의구조 DBMS로의연결이오래걸리며 DB 작업을할때마다 Connection ~ Close까지의반복작업이비효율적이기때문에 Connection pool에 Connection 객체를생성해놓고 DB 작업시 pool에서빌려사용후다시반납하는구조로되어있다. Connection pool을구현하기위해 spec을정해놓은 interface인 DataSource를사용하여구현할수있다. DataSource : 데이터베이스에대한연결을제공하는서비스이다. 다양한방식의데이터베이스연결을제공하고, 이에대한추상화계층을제공함으로써, 업무 logic 과데이터베이스연결방식간의종속성을배제한다. [ 그림 2] Connection pool 의구조 384 2013 기술백서 White Paper
예전에는 Connection pool 을직접개발하기도하였으나최근에는 JDBC Driver 내에자체적 으로내장되어있는경우가많다. OJDBC 의경우도 Connection pool 이내장되어있다. Container 에포함된 Connection pool 을사용하기도한다. - Note 각 Database 별로사용하는 JDBC 가다르다. 오라클은 ojdbc, MSSQL 은 sqljdbc 를사 용하며 DBMS 의버전, JDK 의버전에맞추어 JDBC Driver 를사용하여야한다. Connection pool 처리과정 [ 그림 3] Connection pool 흐름도 Part 2 APM 385
1. 미리 Connection 을일정수만큼생성시킨뒤 Connection 을빌려주고다시반환받 는형식으로 Connection 을관리한다 2. Connection pool 에서필요한만큼 Connection 을미리생성 3. Connection 이필요할때 Connection pool 에서빌려서사용 4. 사용이끝난다음에는 Connection 을 Connection pool 에반환 동기화 Connection을얻는과정에서 Connection을여러곳에서사용하는것을전제로하기때문에 Connection pool 내에존재하는 Connection들의동기화를맞춰야한다. 동기화를통하여 Connection 객체가중복되어할당되는것을방지한다. synchronized 키워드로 method 를동기화하여동시에 Connection 객체를획득할수없도록한다. synchronized statement 로사용중인 pool 을동기화시킨다. LOCK 회피 시스템의 I/O 에관련된문제에의해 Lock 에걸릴경우 Timer 를풀어주어 Connection pool 의 다른동작에영향을주지않도록해야한다. Timeout 으로 pool 을해제할수있다. 이름 Orphan Timeout Idle Timeout 기능 pool에서가져온 DB Connection을사용한후제대로반납하지않고끝냈을경우다시 pool로보내는기능. Connection pool에서사용되지않는 Connection을시간이지나면 close 시키는기능. [ 표 1] Timeout 의종류와기능 386 2013 기술백서 White Paper
[ 그림 4] Lock 을회피하는예 위그림과같이 Timer 가정지되면해당 Process 를중단시켜서 Lock 을피할수있다. Process 단위로제공 Process 단위로제공된다는것은 Process가시작되어종료될때까지 Connection pool을제공한다는것이다. 소스상에서동일한 Connection String( 연결시문자열이같을때 ) 동일한 Connection pool을제공한다. 문자열의구조가다를경우각각의 pool을제공한다. Connection 생성과정 Connection 한다는것은 Database 에대한 Connection 객체를취득하는것이다. WAS 설정 접속할 Database 의 JDBC 를 WAS 의 lib 폴더에복사한다. JDBC Driver 의이름및접속할 JDBC Part 2 APM 387
URL 을설정한후 load 하여 DBMS 연결한다. [ 그림 5] Connection 생성과정 1 해당 WAS의 JNDI( 클래스객체에이름을부여하고원격으로접속하여클래스를사용할수있게하는기술 ) 를사용하기위해필요파일을 (commons-collections-x.x.x.jar, commonsdbcp-x.x.jar, commons-pool-x.x.jar) lib에옮기고나서 context.xml 파일을생성한다. webcontent/meta-data/context.xml <Context> <Resource name = "jdbc/oracledb" //context 인터페이스의 lookup 에서찾는이름 auth = "Container" // 권한설정 driverclassname = "oracle.jdbc.driver.oracledriver" type = "javax.sql.datasource" url = "jdbc:oracle:thin:@1.232.2.212:1521:java2" username = "FLOWER" //user name 을넣는다. password = "JAVA2" //password 를넣는다. maxactive = "20" // 최대 Connection 의생성개수 maxidle = "10" // 기본 Connection 의생성개수 maxwait = "-1" /> // 서비스지연시간 </Context> web.xml 에다음과같은내용을추가해주어야한다. webcontent/web-inf/web.xml 에추가 <resource-ref> <description>connection</description> <res-ref-name>jdbc/oracledb</res-ref-name> <res-type>javax.sql.datasource</res-type> <res-auth>container</res-auth> 388 2013 기술백서 White Paper
</resource-ref> ** Resource name 과 res-ref-name, auth 와 res-auth, type 과 res-type 이같아야함. WAS에 DataSource 객체들을등록하고 DataSource에서 Connection 객체를획득하여사용한다. (DBCP에서 Database와 Connection을맺기위해 lookup하여가져오는객체.) DataSource <data-source class="com.evermind.sql.drivermanagerdatasource" name=" jdbc/oracledb" location="jdbc/oracledb" connection-driver="oracle.jdbc.driver.oracledriver" username="flower" password="java2" inactivity-timeout="3000" //timeout 시간 min-connections="10" max-connections="10" stmt-cache-size="5" /> 애플리케이션설정 애플리케이션은 DBMS 에 Driver(Connection Provider) 로연결되어있다. 애플리케이션은 DBMS 에연결을수행하거나연동을하기위해서는 Driver 를통해야한다. JAVA 의 DriverManager 는 DBMS 와애플리케이션사이에있는 Driver 를관리하는클래스이다. [ 그림 6] Connection 생성과정 2 Part 2 APM 389
DriverManager가애플리케이션과 Driver 사이에위치하여 DriverManager Class의 method 를이용하여 Connection을구현한다. DriverManager의 Class의 method는모두 static이다. 객체로생성하지않아도해당 method를사용할수있다. method 를이용하여 Connection 구하기 static Connetion getconnection (String url) // 지정된 Database 의 URL 에접속 static Connection getconnection (String url,properties info) static Connection getconnection (String url, String user, String password) DriverManager의 getconnection은 function overloading 기법에의한 3가지형태가있다. 인수의종류가다르기때문에각상황에맞추어서사용해야한다. [ 그림 7] Connection 생성과정 3 위에서작성한 getconnection method 를호출하기위해서는 URL, user, password 의 3 가지 parameter 가필요하다. 390 2013 기술백서 White Paper
URL의경우단순히 IP 뿐만아니라 localhost, domain name base address가있다. IP address url = jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:orcl localhost url = jdbc:oracle:thin:@localhost:1521:orcl domain name base url = jdbc:oracle:thin:@aaa.bbb.com:1521:orcl [ 표2] URL 연결방식 Connection 할당받기 Class.forName( oracle.jdbc.driver.oracledriver ); //OracleDriver : 오라클 Database Driver 를사용할수있다. String usl = jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:orcl ; Connection conn = DriverManager.getConnection(url, user, password); Connection의연결이성공적으로이루어지면해당 Connection 객체를취득한다. 사용이끝난 Connection은 conn.close( ) 로닫아주어야한다. Connection pool 을사용하는이유 웹애플리케이션은정보저장이필요할때주로 DB를이용한다. DBMS나기타외부와의접속이빈번하게필요한시스템에는반드시있어야하는기능가운데하나이다. Java Program 에서 Database로 Connection을맺는일은매우느리며자원을많이소모하는작업이다. 불특정다수의사용자들이동시에 Database의 Connection을요구한다면최악의경우 server가 down되기도한다. 이것을해결하기위해 Connection pool을이용한다 Connection pool 을사용하지않았을때 : 동시접속해서사용하려는 client 수만큼 Connection 객체를생성해야한다. Connection pool 을사용하였을때 : 최대로동시에빌려줄수있는 Connection 을설정하였을시그이상접속하였을경우 Connection 을다른클라이언트가반납할때까지대기한다. Connection 객체의수를제한할수있다. Connection pool은 Database와의연결을효율적으로관리하는역할을한다. Connection 클래스는객체화될때 LOGIN을위한인증시간이필요하다. 사전에이러한시간이걸리는 Connection객체를일정량생성하여공유된장소에둠으로써속도향상을기대할수있다. 사용이끝난 Connection객체를다시공유된장소에넣어둔다. Part 2 APM 391
- Note 최초 Database 접속시 TCP/IP Socket 통신을하여연결부분에서많은시간이지체된 다. 동시접속자수가많아지면접속시간이지연되고, 접속 Error 등이발생할수있다 또다른측면에서살펴보면, Database에대한 Connection은우리의시스템이가지고있는자원 (CPU, MEMORY, 네트워크대역폭등 ) 을일정량사용하고있다. 시스템의자원은한정되어있기때문에사용자수가많다고해서무제한 Database Connection을만들수는없다. 만일시스템이가지고있는자원을초과해서 Connection을생성하고사용한다면전체시스템의성능은크게떨어질것이다. 또한갑자기시스템이정지하는등예측할수없는상황을불러일으킬수도있다. 이런상황을막기위해서시스템이허용가능한수만큼의 Database Connection을만들어놓은후공유해서사용하면전체시스템의성능을향상시키고안정된시스템의운영을할수있다. - Note pool 을너무크게해놓으면메모리의소모가크고, 너무작게하면대기시간이길어 진다. Connection pool 의이점 Database 접속설정객체를미리만들어연결을하여메모리상에등록해놓아클라이언트가빠르게 Database 접속을할수있다. Database Connection 수를제한할수있어과다한접속으로인한서버의자원고갈을막을수있다. Database 접속모듈을공통화해 Database 서버의환경이바뀔경우유지보수를쉽게할수있다. 연결이끝난 Connection 을재사용함으로써새로객체를만드는비용을줄일수있다. Connection pool 관리 Connection pool 은일반적으로최소수준의연결을접속된상태로유지한다. 연결에대한요 구가많으면새롭게연결을맺어서제공하고, 요청이많지않으면기존에맺어진연결들을 392 2013 기술백서 White Paper
해제 (Close) 해서접속대상이불필요하게많아져부하가발생하는것을차단한다. Connection pool은새로운접속을맺을수있는연결제공자 (Connection Provider or Connection Factory) 를가지고있어야하고, 이제공자를통해서새로운연결을필요에따라만들어낼수있어야한다. Connection Provider : ODBC, OLEDB, ADO.NET 등의 Database 접속표준규격 Connection Factory : Database 에접속하기위해서는 Connection 을생성해야한다. 자주 Database 에접속하고, 접속하는 Database 가다르고, 접속하는사람이다르다면, 접속할때마다새롭게 cording 해야한다. 이러한불편함을덜고, 클래스의재사용성을높이기위해 Connection Factory 을두는것이다. Connection 을얻어오는부분을별도의클래스로만들어사용하는것이다. Connection 을생성할필요가있으면구현할때마다 Connection 을생성구문을사용하는것이아니라, ConnFactory 클래스를이용해서 Connection 을대신생성하게하는것이다. 연결실패시접속해야할애플리케이션이내려갔거나아니면네트워크가잘못된경우 Connection pool 을관리하는데어려움이발생한다. 이이외에도접속을받아줄애플리케이션이너무바쁜경우에는 Connection이되는것도아니고안되는것도아닌상태로빠져들수있다. 이런상태에서는접속을시도했으나확실하게되는것인지안되는것인지결론이나지않는상황으로빠져들가능성이크다. 위와같은경우 Timeout을정하여정해진시간이지날때까지연결이맺어지지않거나접속중일경우시도하는단계에서취소를한다. Timeout으로해결이되지않을때는외부에별도의 Timer Thread를두고시간이지난접속시도를확인하여강제로접속과정을중단시킨다. 연결지속시키기맺어진연결이잘유지되면문제가없겠지만때에따라서연결의상태가지속되지않을수있다. 연결이갑자기끊어지게되면 Connection pool을빌려가는 logic에문제가생길수있기때문에연결자체를안정적으로유지할수있는방안이준비되어야한다. 대부분의애플리케이션들은아무요청도없는연결을지속적으로유지하지않는다. 사용하 는사람이없는경우에는 Connection pool 이제공할수있는연결의개수를줄여야하지만 모든연결을다끊어버릴수는없기때문에최소한의연결은정상적으로유지해야한다. Part 2 APM 393
아무요청이없으면접속을받아주는쪽 ( 애플리케이션 ) 에서연결을끊어버리기때문에연결이끊어지지않도록어떤작업을해야한다. 시스템에피해를주지않고간단히요청을하고응답을받을수있는작업들은각접속대상애플리케이션특성에따라존재한다. 예를들어오라클 DBMS의경우에는 "select sysdate from dual" 과같은실행문장이부담을주지않는동작이다. 이런동작을유지시켜야하는연결들에일정시간동안사용되지않을때날려주는 Idle Processing으로만들수있다. Connection pool 사용중유의사항 Connection pool을이용할때 Connection pool의개수와 thread의수, Connection pool의재사용시초기화가제대로되는지등을확인해야한다. 그렇지않으면메모리부족또는응답시간초과로인한에러가발생하거나입력한값이제대로나오지않을수있기때문이다. WAS의 thread 수와 Connection pool 수의관계 WAS에서성능에많은영향을주는부분은 thread 와 Connection pool의개수이다. thread와 pool 개수는직접적으로메모리와관련이있기때문에, 많이사용할수록메모리를많이점유하게된다. 반대로메모리를위해적게지정한다면, 서버에서는많은요청을처리하지못하고대기해야한다. - Note 대부분의 WAS 또는 DBCP API 에서는 Connection pool 의개수를최소치, 최대치, 증 가치설정할수있다. 실제 DBCP 값이너무큰값으로설정되어있거나, thread 수가 Connection pool 의개수보다 더적게설정되어있다면문제가발생할수있다. thread의개수가 Connection pool의개수보다많아야하는이유는사용자의 request는하나지만 WAS thread는여러개생길수있기때문이다.( Servlet, jsp, ejb등등 ) DB와의연결이한번만일어나는것이아니라여러번일어날수있다. 업무프로세스에따라 WAS DB thread와 DB 세션은 N:1이나 N:N이될수있다. 또한모든어플리케이션이 DB에접근하는 394 2013 기술백서 White Paper
것이아니기때문에 Connection pool 의개수보다여유있게설정해두는것이좋다 Connection pool은경우에따라다르지만보통 40~50개로지정하면 thread는이보다 10개정도더지정하는것이좋다. 하지만최적의성능의위해서는실제요청이얼마나들어오는지파악하는것이중요하며, 가장좋은방법은성능테스트를통하여알맞은값을구하는것이다. [ 그림 8] thread 와 Connection pool Autocommit 문제 Update 문을실행했을때애플리케이션에 Row 가 0 으로나오고오류가발생후오류가난 Data 를조회해보면 DB 상에존재할때가있다. Connection pool 을사용하는프로세스는각요청마다여러개의 thread 를생성하여각각의 business logic 을처리한다. 각비즈니스컨트롤러마다트랜잭션을자동으로처리하는경우 도있고, 코드상에서직접 commit, rollback 을하는부분도있다. 커넥션관리자가 Connection pool에서 Connection을가져올때 AutoCommit 설정을초기화시켜주지않은것이다. 특정 business logic에서자동 commit을 false로놓고처리후반환한커넥션을다시 true로초기화 (Java에서 Connection의자동 commit 초기값은 true이다.) 시켜주지않은것이문제였다. Autocommit이 false로세팅된채로반환된 Connection을 Autocommit을요구하는프로세스에서받아와서 true로다시초기화시키지않은채사용하고있던것. 결국해당프로세스에서처리한결과는이후다른프로세스에서해당커넥션을 commit시켜주는시점에서일괄적용이되는것이었다. Part 2 APM 395
이러한문제는커넥션관리자에서반환혹은요청시점에서해당커넥션을다시초기화시켜 주는코드를넣어해결해야할부분이다. Connection pool 에서가져오는커넥션이항상초기 상태를유지하고있지않다는것을알수있다. [ 그림 9] Connection pool 의재사용 정리 Connection은부하가큰작업이기때문에시스템응답속도에큰영향을미친다. Connection pool에미리필요한수만큼connection을생성해놓고요청이올때마다바로연결을해줄수있다. 시간이오래걸리는작업을생략할수있는좋은기능이라고생각한다. 애플리케이션과 Database간의 Connection은자주발생하기때문에 Connection pool은큰효과를얻을수있는기능이라생각한다. 각 DBMS회사마다 WAS에맞추어 Driver를제공해주기때문에 Connection pool을사용하기도더욱편해지고대부분의사이트에서 Connection pool을사용할것이라고생각한다. 또한 Connection pool의개수에따라메모리사용량도미리예측할수있어서버의메모리 396 2013 기술백서 White Paper
관리를하기도좋아졌다. 이번에백서를제작하면서얻은지식으로 WAS 분석을할때 Connection pool 까지도같이생각해볼수있게되어시야가더욱넓어졌다. Connection pool을사용할때생길수있는문제들에대해서도미리알아보고고민을해보았기때문에비슷한문제발생시빠르게대처할수있게되었다고생각한다. Part 2 APM 397