Synchronized로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

Synchronized로 검색한 결과
등록일:2008-06-05 10:25:18
작성자:
제목:웹로직 개발자 가이드


2001 1 3

                                                                                                                       김 태 전 ( tjkim@itplus.co.kr )

                                                                                                                       Version 1.0.3

 

 

자바/웹로직 프로그램밍

 

1.      package명을 정한다.

 

업무구분 및 기능별 또는 구현기술별로 구분이 쉽도록 naming rule을 정한다.

이는 후에 javadoc를 이용한 자바 API를 구현할 때 필수적이다.

EJB를 사용한다면 화면당 name의 상위 package명이 EJB명이 되도록하여

하나의 EJB가 여러화면을 서포트하는 형태를 만드는 것이 좋다.

또는 USE CASE당 하나의 EJB를 만들 수도 있다.

 

2.      공통 class 가능한 많이 만든다.

 

모든 서블릿 또는 EJB들이 같이 사용하는 로직을 가능한 많이 공통 class로 만들어 낸다.

또한 READ ONLY 멤버변수/메소드에 대하여는 static 멤버변수/메소드를 활용한다.

공통 class 도출시에는 유연성을 생각하여 향후 확장성을 염두에 두고 생성한다.

(getInitialConext(),getConnection() 등등)

 

3.      System.out.println( ) 사용을 최소화한다.

            

             개발이외의 운영시에는 가능한 최소화한다. 또는 verbose와 같은 환경변수를 지정하여

             debug log on/off를 가능케 한다.

 

4.      문자열 연결시에 “+=” 사용보다는 StringBuffer 객체를 사용한다.

 

             문자열 연결은, 다량의 임시 객체를 생성하도록하여 성능의 저하를 유도하므로, 이의 사용은

근본적으로 좋은 습관이 아니다. 문자열(String) 변경될 없으므로, 문자열의 연결은

임시 객체의 생성을 초래하고 이는 GC(garbage collection) CPU 부담을 준다.

그러나 StringBuffer 객체를 너무 크게 잡으면 다량의 사용자가 접근시에

             메모리를 할당 받지 못하는 경우가 생길 수 있으므로 StringBuffer의 사이즈를

             너무 크게 잡지는 말아야 한다.

 

5.      JDBC 커넥션 풀링을 사용한다.

            

             웹로직은 데이터베이스 커넥션 풀링 기능을 제공한다. 이는 프로그램상에서 직접 데이터베이스에

접속하는 시간이 2-3초 인 것을 감안하여 웹로직이 미리 커넥션 풀을 통하여

             데이터베이스와 연결을 맺고 있으므로 서블릿 또는 EJB에서는 웹로직의 커넥션 풀에

miliSecs 만에 접속할 수 있도록하여 데이터베이스에 접속하는 시간을 줄여준다.

 

6.      JDBC 커넥션을 사용한후 JDBC 자원을 반드시 반환한다.

 

             JDBC 커넥션을 close()하지 않을 경우, 웹로직은 JDBC 커넥션을 아직도 사용하는 것으로

             인식하여 다른 사용자가 사용하지 못하도록 한다. 이는 웹로직으로 요청되어지는 request들이

             데이터베이스와 연결을 하지 못하여 큐에 쌓이게 되고 이것이 쌓이다 보면 웹로직의 hang

야기시키는 직접적인 원인을 제공하게 된다. 그러나 GC(garbage collection)수행시에는

자원 반납이 이루어 진다.

 

           public void doGet( . )

             {

                           try

        {

                       conn = getConnection();

                                    stmt = conn.createStatement();

                                    stmt.executeQuery(sql);

                                        ……

                           }

        catch (Exception e) {

                                        …….

        }finally {

                           try{        rs.close(); } catch (Exception e){ }

                                       try{        stmt.close();} catch (Exception e){ }

                                        try{        conn.close();} catch (Exception e){ }

        }

             }

 

서블릿,JSP 프로그래밍

 

1. HttpSession

 

가.    웹로직은 4가지 type Session Persistence 제공한다.

 

Memory (single-server, non-replicated)

File system persistence

JDBC persistence

In-memory replication (across a cluster)

            

. 어떠한 방식을 사용할 것인가.

 

가장 성능이 좋은 것은 Memory를 사용하는 것이다(cluster일때는 In-memory replication).

             여러머신이 클러스터링 되어 있을 경우 하나의 웹로직이 shutdown 또는 kill 되어질때

또 다른 웹로직서버로 session 데이터가 옮겨지게 된다(failover 기능).

기존의 방식이었던 JDBC persistence방식은 session의 수와 Object size에 따라 엄청난

성능차이를 보이며 매번 데이터베이스 트랜잭션이 발생하므로 데이터베이스 및 웹로직에

부하를 주게된다.

   

. HttpSession 언제 만들 것인가.

 

서블릿일 경우

 

HttpSession을 체크하는 일반적인 로직일 경우 HttpSession의 데이터를 가지고 체크하는

것보다는 HttpSession의 존재여부를 가지고 체크하는 것이 성능을 더 향상 시켜준다.

매번 새로운 HttpSession을 만드는 것은 피해야 한다.

 

//로직화면시(새로운 HttpSession이 만들어진다)

HttpSession session = req.getSession(true);

 

//로직화면이 아닌 경우(이미 만들어진 HttpSession을 가져다 사용한다)

HttpSession session = req.getSession(false);

if ( session == null || session.getValue("juminid") == null)

       resp.sendRedirect("/Login");  // 로긴화면으로 분기

 

JSP일 경우

 

JSP에서 HttpSession을 디폴트로 생성시키므로 이는 피해야 한다.

 

<%@ page session = “false” %>

 

. HttpSession 넣는 객체의 size 가능한 적게 한다.

 

. HttpSession 사용한 후에는 제거한다.

 

웹로직의 기본 HttpSession 유지시간은 최종 사용한 시간에서 1시간(3600)동안이다.

weblogic.httpd.session.timeoutSecs=3600 (weblogic.properties내에 설정)

그러나 이전에 HttpSession 이상 사용하지 않을 것이라면 제거시켜준다.

 

HttpSession session = req.getSession(false);

if ( session != null )

Session.invalidate();

 

2. 서블릿에서 동기화(Synchronization) 가능한 사용하지 않는다.

 

서블릿은 멀티쓰레드로 동작되기에 하나의 코드에 대하여 많은 쓰레드들이

작업을 수행한다. 그러나 코드가 동기화가 되어있다면 동기화된 코드에 대하여는

실제적으로 한번에 한 쓰레드밖에 작업을 수행할 수가 없다.

따라서 멀티쓰레드방식이 아닌 싱글쓰레드방식이 되는 것이다.

그러나 순차적으로 update되어야 하는 코드와 같이 동기화가 반드시 필요하다면

동기화되는 코드의 양을 최소화 시켜준다.

 

Public void doGet(..)

{

       Synchronized(this)

       {

                     동기화가 필요한 코드;

       }

}

 

3. SingleThreadModel 사용하지 않는다.

 

SingleThreadModel사용자 마다 각각의 서블릿 인스턴스를 만듦으로써

서블릿의 수행능력을 떨어뜨린다. 이는 웹로직 4.5.1 이전버젼에서의 ServletServlet 사용할 때와

같다.

                 

4. 한번만 처리하면 되는 작업들은 HttpServlet init() 메소드 또는 JSP jspInit()메소드를 사용한다.

 

                  서블릿 또는 JSP init(),jspInit() 메소드는 한번만 수행되어지므로 이를 활용하게 되면

                  서블릿에서 동일한 작업들이 여러 반복 수행되는 것을 피할 있다.

 

한번만 호출하여도 되는 작업에는 어떠한 것이 있나. ?

 

1)      JDBC class 얻기

 

public class JDBCServlet extends HttpServlet

{

               private javax.sql.DataSource ds = null;

              

public void init(ServletConfig config) throws ServletException {

                          super.init(config);

                                                   Class.forName("weblogic.jdbc.pool.Driver").newInstance();

             }

                                        public void deGet(HttpServletRequest req, HttpServletResponse res)

                                                                 throws ServletException, IOException

                                                     Connection conn = getConnection();

                                                     ..

                                        }

 

                           }

 

2)      DataSource 얻기

 

public class JDBCServlet extends HttpServlet

{

               private javax.sql.DataSource ds = null;

              

public void init(ServletConfig config) throws ServletException {

                          super.init(config);

                          Context ctx = getInitialContext();

                            ds = (javax.sql.DataSource)ctx.lookup(connPool);

                            ctx.close();

                                        }

                                        public void deGet(HttpServletRequest req, HttpServletResponse res)

                                                                 throws ServletException, IOException

                                                     Connection conn = ds.getConnection();

                                                     ..

                                        }

                           }

 

3)      Context, Home 얻기

 

여기에는 개발환경에 따라 어디까지를 init()메소드에서 얻을 것은가를 정해야 한다.

소스는 위(2))와 동일하다.

(Context 얻기, Home interface 얻기)

 

주의사항) RemoteObject freepool에 다수의 인스턴스로 서비스를 한다.

그러나 init()에서 RemoteObject까지 얻었을 경우는 하나의 RemoteObject만이

서비스를 하게되므로 다수의 사용자가 동시 접근시 성능저하의 원인이 될 수있다.

            

4)      해당 서블릿에서만 사용 되어지는 코드성의 데이터

 

코드성 데이터객체를 멤버변수로 만들어 init()에서 DB의 코드 테이블을 조회한 후에

그 객체를 생성시켜 이후에 호출되어지는 서블릿의 service()들은 DB에서 조회하지 않고

멤버변수의 코드성 데이터객체를 참조하여 코드값을 가져온다.

 

EJB 프로그래밍

 

1.      EJB Entity Bean 접근은 EJB Session Bean 통해서 접근한다.

 

클라이언트 또는 서블릿에서 EJB Entity Bean의 접근은 절대적으로 피해야 한다.

그보다는 EJB Session Bean안에서 접근해야만 한다. 이렇게 함으로써 클라이언트가

Entity Bean Remote 메소드의 호출 횟수를 감소시킬 수 있다. 클라이언트는

Session Bean만을 호출하고 Session Bean Entity Bean을 호출한 후 그 결과를

모아 Entity,Vector 또는 특정한 객체형태로 클라이언트에 반환하게 된다.

또한 트랜잭션과 관련되어서 여러 Entity Bean을 하나의 Session Bean에서 모아

하나의 트랜잭션으로 관리할 수가 있다.

 

2.      EJB Home 재사용

 

위에서 이미 설명했듯이 경우에 따라 Context, Home를 재 사용하여

성능향상을 기대할 수 있다.

(웹로직 클러스터링이 적용된 경우는 EJB Home을 재 사용하게 되면 EJB bean

 HotDeploy시 문제가 발생하게 된다.)

 

3.      한번만 처리하면 되는 작업들은 ejbCreate() 메소드를 사용한다.

 

서블릿과 같은 원리로 단 한번만 처리하면 되거나 또는 코드성의 데이터 객체들은 EJB

ejbCreate() 메소드에서 처리한다.

코드성 데이터객체 사용시의 주의사항)

stateless Session Bean을 예를 들어 max-beans-in-free-pool의 갯수가 100개라고

가정했을 때 코드성 데이터 객체의 사이즈가 1M 라고 한다면 최대 100M 까지의 메모리를

Session Bean이 점유할 수도 있다. 따라서 서블릿과는 달리 EJB에서 사용시에는 주의가 요구된다.

 

4.      Entity Bean사용시에도 조회는 Session Bean 이용한다.

 

Entity Bean은 데이터 로직처리 및 트랜잭션 처리를 위한 것이므로 트랙잭션과 관련된

사항들(, 입력,수정,삭제) Entity Bean을 사용하는 것이 효율적이다. 그러나,

조회와 같이 트랜잭션이 없는 사항에 대해서는 Entity Bean보다는 Session Bean에서

직접 JDBC 커넥션 풀을 사용하여 수행하는 것이 성능이 좋다.

Entity Bean사용시 특히 많은 row을 조회할 때 각각의 row 마다 Entity Bean 객체가

만들어지므로 성능 저하의 원인이 된다.

 

5.      EJB Entity Bean에서 Read-Only 메소드를 사용한다.

 

EJB Entity Bean 관한 배치 명세서(deployment descriptor) 설정시, Read-Only 혹은 Const

getter 메소드를 마크할 있다. Read-Only 메소드만으로 구성된 트랜잭션이 수행시에는

Entity Bean 상태동기화(state synchronization) 데이타베이스에 요청되지 않는다.

 

6.      Transaction Isolation Level 적절히 조정한다.

 

기본적으로, 대부분의 개발자는 트랜잭션 isolation level TRANSACTION_SERIALIZABLE

설정하여 EJBs 배치한다. 웹로직 또는 웹게인의 EJB 배치 툴에서의 기본 값이다. 이것은 최고의

오버헤드를 지닌  최상의 제한적인 트랜잭션 isolation level이다.

대부분의 어플리케이션에서는 TRANSACTION_READ_UNCOMMITTED만으로도

충분한 isolation level 것이다.

EJB 트랜잭션 isolation level 배치 명세서 내에서 설정을 하기 때문에, 같은 EJB 다른 트랜잭션

isolation level으로 다른 어플리케이션 상에서 재사용될 있다.

isolation level 필요조건과 성능향상을 위하여 적절한 조정을 검토하라

 

7.      Stateful Session Bean 사용후에는 제거한다.

 

stateful session bean의 인스턴스는 특정한 클라이언트와 연관되어 있다. bean들은 클라이언트에

의해서 명시적으로 제거될 때까지 혹은 타임아웃시에 컨테이너에 의해서 제거될 때까지 컨테이너에

존재할 것이다. 그 동안에, 컨테이너는 디스크로 비활성화된 stateful session bean

passivate할 필요가 있을 지도 모른다. 이것은 컨테이너에 대한 오버헤드를 요구하게 되고

어플리케이션에 대한 performance hit를 야기시키다. 만약 passivate stateful session bean

바로 뒤이어 어플리케이션에 의해 요청되어진다면 컨테이너는 디스크로부터 읽어들어 활성화되어

질 것이다.

종료시 stateful session bean을 명시적으로 제거함으로써 어플리케이션은 비활성화(passivation)

대한 요청이 감소할 것이고 컨테이너에 대한 오버헤드를 줄일 수 있다.

 

출처 : http://cafe.naver.com/lastjavaclass.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=10