출처 블로그 > 거리에 뛰노는 아이들 웃음처럼~ 젬스
원본 http://blog.naver.com/jambeer/90000104051

Tomcat 5 JNDI DataSource
를 통한 DB 커넥션 풀 사용

 

 

 

이미 눈치 채셨겠지만, 요즘 내가 RDBMS 배우기에 열을 올리고 있다.
지금까지는 JSP/Servlet에서 직접 커넥션을 맺거나, 컨텍스트내에 커넥션 라이브러리를 두고 호출에서 사용했는데, 바꿔야겠다.
JNDI
통한 커넥션 사용은 J2EE 표준이고, 현존하는 거의 모든 컨테이너가 지원한다고 한다.

 

JNDI 서버에 설정하는 방법은 WAS 별로 다르지만, 사용하는 것은 모두 동일하므로 호환성에 문제도 없다.

 

글은 Jakarta DBCP 커넥션 Tomcat JNDI 설정을 통해 데이터베이스 커넥션 풀을 사용하는 방법이다.

 

JNDI 커넥션 풀에 관한 자세한 설명이 JavaServer Pages 3rd ed. 실려있다. 너무 좋다. 읽어보라고 강력하게 권하고 싶다.

 

기본적으로 필요한 라이브러리

  • commons-dbcp.jar
  • commons-collections.jar
  • commons-pool.jar

예제 JDBC 드라이버

  • Oracle 9i classes12.jar

JNDI Naming Resource 설정

1.       라이브러리들을 $CATALINA_HOME/common/lib 복사한다. 이외 디렉토리에 두면 안된다. ZIP 파일은 JAR 확장자를 바꿔야 한다. 톰캣은 JAR파일만 클래스패스에 추가한다.

2.       Connection 풀을 이용할 경우에는 ResultSet Connection 객체를 필히 직접 닫아 줘야만 한다.

3.       $CATALINA_HOME/conf/server.xml 혹은 컨텍스트별 XML 파일의 <Context> 자식 요소로 다음을 추가한다.

4.                <Resource name="jdbc/forumDb" auth="Container" type="javax.sql.DataSource"/>

5.                <!-- Resource name 속성을 이용해서 어플리케이션에서

6.                                javax.sql.DataSource 객체를 얻어가게 된다. -->

7.             

8.               

9.                <!-- 자세한 파라미터 설정은

10.               http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html 참조 -->

11.            <ResourceParams name="jdbc/forumDb">

12.              <parameter>

13.                <name>factory</name>

14.                <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

15.              </parameter>

16.         

17.              <parameter>

18.                <name>maxActive</name>

19.                <value>100</value>

20.              </parameter>

21.         

22.              <parameter>

23.                <name>maxIdle</name>

24.                <value>30</value>

25.              </parameter>

26.         

27.              <parameter>

28.                <name>maxWait</name>

29.                <value>10000</value>

30.              </parameter>

31.         

32.                              <!-- DB 사용자명과 비밀번호 설정 -->

33.              <parameter>

34.               <name>username</name>

35.               <value>dbuser</value>

36.              </parameter>

37.              <parameter>

38.               <name>password</name>

39.               <value>dbpasswd</value>

40.              </parameter>

41.         

42.                              <!-- JDBC 드라이버 클래스 -->

43.              <parameter>

44.                 <name>driverClassName</name>

45.                 <value>oracle.jdbc.driver.OracleDriver</value>

46.              </parameter>

47.             

48.                              <!-- JDBC 접속 URL -->

49.              <parameter>

50.                <name>url</name>

51.                <value>jdbc:oracle:thin:@dbhost:1521:ORA</value>

52.              </parameter>

53.         

54.                  <!-- 커넥션에 문제 없는지 테스트하는 쿼리 -->

55.              <parameter>

56.                <name>validationQuery</name>

57.                <value>select sysdate</value>

58.              </parameter>

59.            </ResourceParams>

 

60.    어플리케이션의 web.xml파일에 다음을 추가하여 JNDI 리소스를 사용할 있도록 한다.

61.                              <resource-ref>

62.                                                   <description>Forum DB Connection</description>

63.                                                   <!-- 다음이 바로 리소스의 이름 -->

64.                                                   <res-ref-name>jdbc/forumDb</res-ref-name>

65.                                                   <res-type>javax.sql.DataSource</res-type>

66.                                                   <res-auth>Container</res-auth>

67.                              </resource-ref>

 

JSP/Servlet 에서 사용하기

이제 다음과 같이 JNDI 이용해 DataSource 객체를 얻고, 객체에서 커넥션을 얻어오면 된다.

 

다음은 서블릿을 작성하고, 서블릿에서 DB커넥션을 얻고, 쿼리를 날린 , 결과를 JSP 파일에 포워딩하여 JSTL 이용해 출력하는 것이다.

 

1.       예제 테이블과 데이터 SQL - 오라클 계정으로 다음과 같은 데이터를 생성했다고 가정하면

2.              create table test (

3.                                  num NUMBER NOT NULL,

4.                                  name VARCHAR2(16) NOT NULL

5.              );

6.             

7.              truncate table test;

8.             

9.              insert into test values(1,'영희');

10.          insert into test values(2, '철수');

11.          insert into test values(3, '미숙');

12.          commit;

 

13.    test.JndiDataSourceTestServlet 소스

14.          package test;

15.         

16.          import java.io.IOException;

17.          import java.sql.Connection;

18.          import java.sql.ResultSet;

19.          import java.sql.SQLException;

20.          import java.sql.Statement;

21.          import java.util.ArrayList;

22.          import java.util.HashMap;

23.          import java.util.List;

24.          import java.util.Map;

25.         

26.          import javax.naming.Context;

27.          import javax.naming.InitialContext;

28.          import javax.naming.NamingException;

29.          import javax.servlet.RequestDispatcher;

30.          import javax.servlet.ServletException;

31.          import javax.servlet.http.HttpServlet;

32.          import javax.servlet.http.HttpServletRequest;

33.          import javax.servlet.http.HttpServletResponse;

34.          import javax.sql.DataSource;

35.         

36.          public class JndiDataSourceTestServlet extends HttpServlet {

37.         

38.              protected void doGet(HttpServletRequest request,

39.                      HttpServletResponse response) throws ServletException, IOException {

40.         

41.                  Connection conn = null;

42.                  ResultSet rs = null;

43.                  Statement stmt = null;

44.         

45.                  try {

46.                      // 커넥션을 얻기 위한 전초작업. 부분을 메소드화 하면 되겠다. ------------

47.                      Context initContext = new InitialContext();

48.                      Context envContext = (Context)initContext.lookup("java:/comp/env");

49.                      DataSource ds = (DataSource)envContext.lookup("jdbc/forumDb");

50.                     

51.                      // 커넥션 얻기

52.                       conn = ds.getConnection();

53.                      //------------------------------------------------------------------

54.                     

55.                      String sql = "SELECT * from test";

56.                      stmt = conn.createStatement();

57.                     

58.                      rs = stmt.executeQuery(sql);

59.                     

60.                      List results = new ArrayList();

61.                     

62.                      while (rs.next()) {

63.                          Map row = new HashMap();

64.                         

65.                          row.put("num", rs.getString("num"));

66.                          row.put("name", rs.getString("name"));

67.                         

68.                          results.add(row);

69.                      }

70.                     

71.                      request.setAttribute("results", results);

72.                     

73.                      RequestDispatcher rd = request.getRequestDispatcher("/dbtest.jsp");

74.                      rd.forward(request, response);

75.                     

76.                  } catch (NamingException e) {

77.                      throw new ServletException("JNDI 부분 오류", e);

78.                  } catch (Exception e) {

79.                      throw new ServletException("뭔가 다른 부분 오류", e);

80.                  } finally {

81.                      // 리소스를 필히 반환할 !

82.                      if (rs != null) { try { rs.close(); } catch (Exception ignored) {} }

83.                      if (stmt != null) { try { stmt.close(); } catch (Exception ignored) {} }

84.                      if (conn != null) { try { conn.close(); } catch (Exception ignored) {} }

85.                  }

86.              }

87.          }

88.    web.xml 서블릿 등록

89.                              <servlet>

90.                                                   <servlet-name>dbtest.svl</servlet-name>

91.                                                   <servlet-class>test.JndiDataSourceTestServlet</servlet-class>

92.                              </servlet>

93.                              <servlet-mapping>

94.                                                   <servlet-name>dbtest.svl</servlet-name>

95.                                                   <url-pattern>/dbtest.svl</url-pattern>

96.                              </servlet-mapping>

97.    /dbtest.jsp 소스

98.          <%@ page contentType="text/html" pageEncoding="EUC-KR" %>

99.          <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

100.       <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

101.      

102.       <!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">

103.       <html>

104.       <head>

105.       <title>JNDI DataSource Test</title>

106.       </head>

107.                        <body                  bgcolor="#FFFFFF">

108.                           <h2>Results</h2>

109.                          

110.                           <c:forEach var="row" items="${results}">

111.                                                                    NUM : ${row.num}<br />

112.                                                                    Name : ${row.name}<br />

113.                                                                    <hr />

114.                           </c:forEach>

115.       </body>

116.       </html>

 

117.이제 브라우저에서 "/dbtest.svl" 호출해보면 결과를 있다.

 

전역적인 JNDI 리소스 이용

<Resource> <ResourceParams> 요소를 server.xml <GlobalNamingResources> 자식노드로 옮기면 특정 어플리케이션이 아니라, 톰캣에 설치된 전체 어플리케이션에서 사용 있게 된다. 하지만 어플리케이션 "<Context>" 다음과 같은 설정을 해야 한다.

                    <ResourceLink

                                         name="jdbc/forumDb"

                                         global="jdbc/forumDb"

                                         type="javax.sql.DataSource"

                      />

 

아니면 server.xml에서 <Host> 요소의 자식으로 다음을 추가하면 컨텍스트별 설정 필요없이 전체 어플리케이션 컨텍스트에서 GlobalNamingResources 지정된 JNDI 리소스를 사용할 있다.

 

                    <DefaultContext>

                                         <ResourceLink

                                                             name="jdbc/forumDb"

                                                             global="jdbc/forumDb"

                                                             type="javax.sql.DataSource"

                                           />

        </DefaultContext>

 

문제가 생겼어요!

1.       DB 커넥션이 간혹 끊어져요.
Tomcat
작동중인 JVM 가비지 컬렉션을 , 시간이 JNDI Resource 파라미터로 설정한 maxWait보다 길게 경우 DB 커넥션이 끊어질 있다.
CATALINA_OPTS=-verbose:gc
옵션을 주면 $CATALINA_HOME/logs/catalina.out 가비지 컬렉션 상황이 기록된다. 거기에 GC 작업에 걸린 시간도 나오니 그것을 참조로 maxWait 파라미터를 늘려주면 된다. 보통 10~15초로 주면 된다.
GC
시간은 거의 99% 이상 1 이내에 끝나야 하나보다..

2.       무작위로 커넥션이 close 되요.
그건.. Connection 객체를 이상 close 했기 때문이다.
DB Connection Pool
close() 호출할 정말로 닫는 것이 아니라, 단지 재사용할 있다고 표시만 뿐이다.
커넥션을 사용하다가 close()하면 다른 쓰레드이서 커넥션을 있는데, 이걸 현재 쓰레드에서 계속 잡고 있다가 다시 close() 해버리면, 다른 쓰레드에서 사용중에 close()됐다고 나와 버리게 되는 거다.

3.                  conn.close();

4.                  conn = null;

위와 같이 커넥션을 close() 뒤에 바로 null 설정하여 절대로 다시 사용할 없게 만들면 이런 실수는 생기지 않을 것이다.

Tomcat 5.5 예제

        <Resource name="jdbc/myDbResource" auth="Container" type="javax.sql.DataSource"

               maxActive="10" maxIdle="5" maxWait="10000"

               username="ao" password="ao"

               driverClassName="com.mysql.jdbc.Driver"

               url="jdbc:mysql://localhost:3306/myWebApp"

 

               removeAbandoned="true"

               removeAbandonedTimeout="60"

               logAbandoned="true"

               validationQuery="select 1"

               testOnBorrow="true"

               testWhileIdle="true"

               timeBetweenEvictionRunsMillis="10000"

               minEvictableIdleTimeMillis="60000"

       />

 

저기서 removeAbandoned 리소스 반환에 실패한 (혹은 안한) 커넥션을 자동으로 닫아주는 것이다.

 

validationQuery 커넥션이 살아 있는지 테스트하는 코드이다.

 

MySQL, Connector/J Tomcat 5 예제

http://dev.mysql.com/doc/connector/j/en/cj-tomcat-config.html 나온 내용임.

<Context ....>

 

  ...

 

  <Resource name="jdbc/MySQLDB"

               auth="Container"

               type="javax.sql.DataSource"/>

 

  <!-- The name you used above, must match _exactly_ here!

 

       The connection pool will be bound into JNDI with the name

       "java:/comp/env/jdbc/MySQLDB"

  -->

 

  <ResourceParams name="jdbc/MySQLDB">

    <parameter>

      <name>factory</name>

      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

    </parameter>

 

    <!-- Don't set this any higher than max_connections on your

         MySQL server, usually this should be a 10 or a few 10's

         of connections, not hundreds or thousands -->

 

    <parameter>

      <name>maxActive</name>

      <value>10</value>

    </parameter>

 

        <!-- You don't want to many idle connections hanging around

         if you can avoid it, onl    y enough to soak up a spike in

         the load -->

 

    <parameter>

      <name>maxIdle</name>

      <value>5</value>

    </parameter>

 

    <!-- Don't use autoReconnect=true, it's going away eventually

         and it's a crutch for older connection pools that couldn't

         test connections. You need to decide if your application is

         supposed to deal with SQLExceptions (hint, it should), and

         how much of a performance penalty you're willing to pay

         to ensure 'freshness' of the connection -->

 

    <parameter>

      <name>validationQuery</name>

      <value>SELECT 1</value>

    </parameter>

 

   <!-- The most conservative approach is to test connections

        before they're given to your application. For most applications

        this is okay, the query used above is very small and takes

        no real server resources to process, other than the time used

        to traverse the network.

 

        If you have a high-load application you'll need to rely on

        something else. -->

 

    <parameter>

      <name>testOnBorrow</name>

      <value>true</value>

    </parameter>

 

   <!-- Otherwise, or in addition to testOnBorrow, you can test

        while connections are sitting idle -->

 

    <parameter>

      <name>testWhileIdle</name>

      <value>true</value>

    </parameter>

 

    <!-- You have to set this value, otherwise even though

         you've asked connections to be tested while idle,

         the idle evicter thread will never run -->

 

    <parameter>

      <name>timeBetweenEvictionRunsMillis</name>

      <value>10000</value>

    </parameter>

 

    <!-- Don't allow connections to hang out idle too long,

         never longer than what wait_timeout is set to on the

         server...A few minutes or even fraction of a minute

         is sometimes okay here, it depends on your application

         and how much spikey load it will see -->

 

    <parameter>

      <name>minEvictableIdleTimeMillis</name>

      <value>60000</value>

    </parameter>

 

    <!-- Username and password used when connecting to MySQL -->

 

    <parameter>

     <name>username</name>

     <value>someuser</value>

    </parameter>

 

    <parameter>

     <name>password</name>

     <value>somepass</value>

    </parameter>

 

    <!-- Class name for the Connector/J driver -->

 

    <parameter>

       <name>driverClassName</name>

       <value>com.mysql.jdbc.Driver</value>

    </parameter>

 

    <!-- The JDBC connection url for connecting to MySQL, notice

         that if you want to pass any other MySQL-specific parameters

         you should pass them here in the URL, setting them using the

         parameter tags above will have no effect, you will also

         need to use & to separate parameter values as the

         ampersand is a reserved character in XML -->

 

    <parameter>

      <name>url</name>

      <value>jdbc:mysql://localhost:3306/test</value>

    </parameter>

 

  </ResourceParams>

</Context>

 

Oracle 만을 위한 JNDI 설정

원문 : http://www.microdeveloper.com/html/JNDI_Orcl_Tomcat1p.html

 

1) Modify the server.xml file
In<CATALINA_HOME>/conf/server.xml between <GlobalNamingResources> and </GlobalNamingResources> add the following

   <Resource name="jdbc/<alias>"

   auth="Cont   ainer"

   type="oracle.jdbc.pool.OracleDataSource"

   driverClassName="oracle.jdbc.driver.OracleDriver"

   factory="oracle.jdbc.pool.OracleDataSourceFactory"

   url="jdbc:oracle:thin:@<host>:<port>:<sid>"

   [user=<user>]

   [password=<password>]

   maxActive="20"

   maxIdle="10"

   maxWait="-1" />

   

 

Example

<!-- Global JNDI resources -->

 <GlobalNamingResources>

 

 <!-- Test entry for demonstration purposes -->

 <Environment name="simpl   eVal   ue" type="java.lang.Integer" value="30"/>

 

 <!-- Editable user database that can also be used by

   UserDatabaseRealm to authenticate users -->

 <Resource name="UserDatabase" auth="Container"

   type="org.apache.catalina.UserDatabase"

   description="User database that can be updated and saved"

   factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

   pathname="conf/tomcat-users.xml" />

    <!-- Every connection to 'db1' uses the same user -->

 <Resource name="jdbc/db1"

   auth="Container"

   type="oracle.jdbc.pool.OracleDataSource"

   driverClassName="oracle.jdbc.driver.OracleDriver"

   factory="oracle.jdbc.pool.OracleDataSourceFactory"

   url="jdbc:oracle:thin:@oracle.microdeveloper.com:1521:db1"

   user="scott"

   password="tiger"

   maxActive="20"

   maxIdle="10"

   maxWait="-1" />

    <!-- Every connection to 'db2' must provide a username and password -->  <Resource name="jdbc/db2"

   auth="Container"

   type="oracle.jdbc.pool.OracleDataSource"

   driverClassName="oracle.jdbc.driver.OracleDriver"

   factory="oracle.jdbc.pool.OracleDataSourceFactory"

   url="jdbc:oracle:thin:@oracle.microdeveloper.com:1521:db2"

   maxActive="20"

   maxIdle="10"

   maxWait="-1" />

</GlobalNamingResources>

 

2) Modify the context.xml file
In <CATALINA_HOME>/conf/context.xml between <Context> and </Context> add the following for each entry in the JNDI resource list:

<ResourceLink global="jdbc/<alias>" name="jdbc/<alias>" type="oracle.jdbc.pool.OracleDataSource"/>

 

Example

<!-- The contents of this file will be loaded for each web application -->

 <Context>

 

 <!-- Default set of monitored resources -->

 <WatchedResource>WEB-INF/web.xml</WatchedResource>

 <WatchedResource>META-INF/context.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->

 <!--

 <Manager pathname="" />

   -->

 <ResourceLink global="jdbc/db1" name="jdbc/db1" type="oracle.jdbc.pool.OracleDataSource"/>

 <ResourceLink global="jdbc/db2" name="jdbc/db2" type="oracle.jdbc.pool.OracleDataSource"/>

 </Context>

 

3) Modify the context's web.xml file (5.0.x step only - not necessary for 5.5.x)
In the <CONTEXT>/WEB-INF/web.xml between <web-app> and </web-app> add the following:

<resource-ref>

   <description><Your Description></description>

   <res-ref-name>jdbc/<alias></res-ref-name>

   <res-type>oracle.jdbc.pool.OracleDataSource</res-type>

   <res-auth>Container</res-auth>

</resource-ref>

 

Example

 

<resource-ref>

   <description>Oracle Development Datasource</description>

   <res-ref-name>jdbc/db1</res-ref-name>

   <res-type>oracle.jdbc.pool.OracleDataSource</res-type>

   <res-auth>Container</res-auth>

</resource-ref>

 

<resource-ref>

   <description>Oracle Development Datasource</description>

   <res-ref-name>jdbc/db2</res-ref-name>

   <res-type>oracle.jdbc.pool.OracleDataSource</res-type>

   <res-auth>Container</res-auth>

</resource-ref>

 

 

4) Restart Tomcat

 

Posted by 나비:D
:

출처 : http://blog.naver.com/thinkers09?Redirect=Log&logNo=37787712

0. 설치 버젼

 0.1  JDK        : j2sdk1.4.2_09

 0.2  TOMCAT : tomcat-5.5.23

 0.3  ORACLE : oracle 9i

 

1. 톰캣 다운로드 및 설치

 1.1 톰캣을 다운로드한다. ( http://tomcat.apache.org/download-55.cgi )

 1.2 Core를 다운로드 했을 경우 jdk1.4 버젼에서 구동되지 않으니

      jdk1.4버젼용을 다시 다운받고(아래 있음..ㅋㅋ) Core 압축푼곳에 덮어쓴다.



2. DataSource 설정

 2.1  <CATALINA_HOME>/common/lib 디렉토리에 ojdbc14.jar 파일을 복사한다.(ojdbc14.zip 아님..ㅠㅠ)

 2.2  server.xml  파일 설정

-----------------------------------------------------------------------------------------------

   <!-- Global JNDI resources -->
  <GlobalNamingResources>

    .
    <Resource name="ORCL"
           auth="Container"
           type="oracle.jdbc.pool.OracleDataSource"
           driverClassName="oracle.jdbc.driver.OracleDriver"
           factory="oracle.jdbc.pool.OracleDataSourceFactory"
           url="jdbc:oracle:thin:@127.0.0.1:1521:ORCL"
           maxActive="20"
           maxIdle="10"
           maxWait="-1"
           user="kbs"
           password="0000"
           />

  </GlobalNamingResources>
-----------------------------------------------------------------------------------------------

 2.3 context.xml  설정

-----------------------------------------------------------------------------------------------

<Context>

    . 

    <ResourceLink global="ORCL" name="ORCL" type="oracle.jdbc.pool.OracleDataSource"/>

</Context>

-----------------------------------------------------------------------------------------------

 2.4 web.xml  설정

-----------------------------------------------------------------------------------------------

 <resource-ref>
 <description>Oracle Datasource example</description>
 <res-ref-name>ORCL</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
 <res-auth>Container</res-auth>
</resource-ref>
-----------------------------------------------------------------------------------------------

 2.5 톰캣 시작~~~!!!!


3. ERROR 메세지

 3.1 Cannot create JDBC driver of class '' for connect URL 'null'

  3.1.1 ojdbc14.jar 파일이 혹 zip파일이 아닌지 확인하고, 복사한 위치가

       <CONTEXT>/WEB-INF/lib인지 확인한다. 요기 들어가 있음 위의 메세지를 볼수두 있당.

       확인해보고 <CATALINA_HOME>\common\lib 에만...!!!  복사한다.


 3.2 java.sql.SQLException: 호출에 부적합한 인수입니다

  3.2.1 server.xml에 정의한 <Resource>에 빠진게 있는지 확인한다.. 주로 user, password를 빼먹으니

          url 및 user 등을 확인해본다.


 

4. 의문점

  4.1 왜 추가한 context에 정의하면 안되는지 모르겠당. 블로그들 보면 \tomcat\conf\catalina\localhost\에

       <context>.xml 파일을 추가하고 resource를 넣어주면 되던데.. 이러면 꼭 <CATALINA_HOME>\common\lib

       ojdbc14.jar파일을 넣지 않아도 될것 같은데 말이다.. 휴.. 이틀 해매다.. 구냥 이렇게 설정하는데 혹 아시는분 계신다면

       알려주심 감사하겠습니다.^^



------------------------------------------------------------------------------------------------------------

5.0과 5.5의 설정 방법이 다르다..

server.xml에 있는 내용을 제거하고 \tomcat\conf\catalina\localhost\<context>.xml 파일에 아래와 같이 추가해준다.


<Resource name="ORCL" auth="Container" type="javax.sql.DataSource"
               maxActive="5" maxIdle="2" maxWait="10000"
               username="kbs" password="0000" driverClassName="oracle.jdbc.driver.OracleDriver"
               url="jdbc:oracle:thin:@127.0.0.1:1521:ORCL"/>

Posted by 나비:D
:

BLOG main image
by 나비:D

공지사항

카테고리

분류 전체보기 (278)
Programming? (0)
---------------------------.. (0)
나비의삽질 (5)
Application (177)
SQL (51)
Web (27)
etc. (14)
Omnia (0)
---------------------------.. (0)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

달력

«   2024/04   »
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
Total :
Today : Yesterday :