Story 24-1 패턴과 아키텍처는 잘 구성되어 있는가?

1. 패턴과 아키텍처는 잘 구성되어 있는가?

너무 많은 패턴을 적용하면 유지보수성이 떨어지고, 문제가 발생했을 때 추적하기가 어려워진다.
좋은 패턴이라고 무작정 사용하기 보다는 꼭 필요한 패턴만을 사용해야 한다.

2. 데이터를 리턴할 때 TO (혹은 VO) 패턴을 사용하였는가? 
    아니면 Collectioon 관련 클래스를 사용 하였는가?


데이터를 주고 받는 시간을 적약하기 위해서 TO 패턴을 일반적으로 사용한다.
그리고 때에 따라서는 Collection 관련 클래스를 사용하기도 한다.
이러한 패턴을 적용하지 않거나 관련 표준을 정하지 않고 개발을 할 경우 시스템의 응답시간도 
영향이 있겠지만, 유지보수성이 떨어진다. 게다가 HashMap 으로 데이터를 주고 받으면, 
소스를 완전히 뜯어 보지 않는 이상 개발자만 어떤 키와 값이 들어 있는지 알게 된다.

3. 서비스 로케이터 (Service Locator) 패턴은 적용 되었는가?

서비스 로케이터 패턴을 사용하면 어플리케이션에서 필요한 대상을 찾는 룩업(Lookup) 작업을 할 때 소요되는 대기 시간을 줄일 수 있다. 만약 서버의 CPU 사용량이 높지 않을 때 응답 속도가 느리다면, 서비스 로케이터를 적용해야 하는 부분이 있지 않은가 한번쯤 확인을 해 봐야 한다.



Story 24-2 기본적인 어플리케이션 코딩은 잘 되어 있는가?

1. 명명규칙은 잘 지켰는가? 

옛날 코딩방식처럼 AC0018 같은 클래스로 되어 있다면, 장애가 발생했을 때 정확히 인지하기 힘들어 진다.
시스템의 장애가 발생하면 클래스명과 업무명이 매핑되어 있는 문서를 일일이 보면서 확인 할 시간이 없다.
문제에 더 빨리 접근 할 수 있도록, 제발 자바의 기본 명명규칙을 따라주기 바란다.

2. 필요한 부분에 예외처리는 되어 있는가?

예외 처리를 제대로 하지 않으면 사용자는 아무런 응답을 받지 못하고, 
여러분이 운영하는 시스템을 더이상 사용하지 않을 수도 있다. 
문제가 발생했을 때 원인을 밝히기 위해서 예외 처리는 필수다.

3. 예외 화면은 지정되어 있는가?

예외 화면에 대한 표준이 있는지 확인해 보아야 한다.
만약 예외 화면을 구성하지 않고 지정하지도 않는다면, 사용자는 여러분이 사용하는 서버의 종류가 어떤 것인지 알게 될 것이다.
때에 따라서는 시스템에 어떤 클래스가 있는지도 확인할 수 있을 것이다.

4. 예외 정보를 혹시 e.printStackTrace() 로만 처리하고 있지 않은가?

e.printStackTrace() 메소드를 호출하면 서버에서 스택 정보를 취합하여야 하리 때문에
서버에 많은 부하가 발생하게 된다. 만약 여러분의 어플리케이션이 복잡하게 구성되어 있다면,
최대 100개의 스택 정보가 프린트 되기 위해서 서버에 부하를 줄 것이다.

5. system.gc() 메소드가 소스에 포함되어 있지 않은가?

만약 아무리 많은 요청이 들어오더라도 힙 메모리의 사용량이 전혀 늘어나지 않고 일직선을 유지하고 있다면,
System.gc() 메소드가 소스 안에 있는지 확인해 보기 바란다.
그리고 이 메소드를 웹 어플리케이션에서 사용하면 WAS 의 CPU 사용량은 상상도 못할 만큼 급격히 증가한다.

6. System.exit() 메소드가 소스에 포함되어 있지 않은가?

이 메소드가 수행되면 WAS 의 프로세스가 죽는다.
스레드가 죽는 것이 아니라 프로세스가 죽는 것이다.

7. 문자열을 계속 더하도록 코딩하지 않았는가?

String 클래스는 더할 경우 새로운 객체를 생성한다.
한두개를 더하는 것은 큰 문제가 안되겠지만, 
몇십 페이지 정도 되는 쿼리를 더하기로 처리할 경우 서버는 GC 를 하느라 바빠질 것이다. 

JDK 5.0 이상을 사용하면 자동으로 StringBuilder 클래스로 변환을 해 주기는 한다.
하지만, 루프를 수행하면서 문자열을 더할 경우에는 컴파일러도 어쩔 수가 없으니 반드시 필요에 따라서 StringBuffer 나 StringBuilder 클래스를 선택하여 사용하기 바란다.

8. StringBuffer 나 StringBuilder 클래스도 제대로 사용 했는가?

StringBuffer 나 StringBuilder 클래스 안에서 문자열을 더하면,
이 두개 클래스를 쓸 필요하 전혀 없다.
즉, StringBuffer의 객체가 sb 라고 했을때 sb.append("aaa"+"bbb"); 는 제대로 이해를 하지 못하고 사용 하는 것이다.

9. 무한루프가 작동할 만한 코드는 없는가?

for 루프는 일반적으로 반복 횟수를 지정하고 사용하기 때문에 큰 문제가 발생하지 않지만,
while(true) 의 구문을 사용한다면, 해당 루프는 언제 끝날지 아무도 보장 할 수 없다.
"해당 구문 안에서 조건을 만족시키지 못하고 무한 루프를 돌게 된다면" 이라는 가정을 할 필요가 없도록 코딩하자.

10. static 을 남발하지 않았는가?

메모리를 아낀다고 static 을 남발하다가는 시스템이 심각한 오류를 발생시킬 수 있다.
초급개발자라면 반드시 같이 일하는 중급이상의 경험이 많은 개발자나 
PL 에게 해당 static 의 사용이 적절한지 확인 받기를 권장한다.

11. 필요한 부분에 synchronized 블록을 사용하였는가?

그냥 동시에 해당 메소드가 호출 될 것 같아서 synchronized 블록을 사용한 것은 아닌지 확인해야 한다.
필요 없는 부분에서 synchronized 블록을 사용하게 될 경우 성능저하를 발생시킬 수 있다.

12. IO 가 계속 발생하도록 개발되어 있지 않은가?

가장 많이 실수하는 부분이 설정파일을 매번 파일에서 읽도록 개발하는 것이다.
한두명의 사용자가 사용하는 시스템이라면 상관 없을 수도 있겠지만,
100명 이상의 사용자가 사용하는 시스템에서 해당 설정파일을 매번 읽기 위해 IO 를 발생 시키면서
시스템의 아까운 자원을 낭비하지 말자.

13. 필요 없는 로그는 다 제거 했는가?

프린트하지도 않을 로그 데이터를 문자열로 만들기 위해서 아까운 메모리를 사용하고,
그 메모리를 청소하기 위해서 GC 를 해야 하는 불쌍한 JVM 을 생각해 보라.

14. 디버그용 System.out.println 은 다 제거 했는가?

로그 레벨을 바꾼다고 해도 지워지지 않는 것이 System.out.println 로그이다.
본인이 만든 어플리케이션이 조금이라도 빨라지기를 원한다면 이 디버그용 로그도 제발 지워주기 바란다.



Story 24-3  웹 관련 코딩은 잘 되어 있는가?

1. JSP 의 include 는 동적으로 했는가? 아니면 정적으로 했는가?

JSP 를 동적으로 include 하면 서버에도 부하를 줄 뿐만 아니라 응답 시간에도 영향을 준다.
꼭 필요한 부분에만 동적 include 를 하기 바라며, 그렇지 않은 경우에는 정적 include 의 사용을 권장한다.
그렇다고 무조건 정적으로 include 를 하면 변수를 공유하게 되어 예기치 못한 문제가 발생 할 수 있으므로 유의해서 사용하기 바란다.

2. 자바 빈즈를 너무 많이 사용하지 않았나?

하나의 화면에서 자바 빈즈를 수십 개씩 사용하지 않는가?
하나의 TO (Transfer Object) 를 사용해서 처리할 수도 있는 데이터라면, 여러개의 자바 빈즈를 사용해서 응답시간에 영향을 주는 일이 없도록 하자.

3. 태그 라이브러리는 적절하게 사용했나?

많은 양의 데이터를 태그 라이브러리로 처리할 경우에는 성능에 많은 영향을 끼친다.
데이터의 양이 적을 경우에는 상관이 없겠지만 무조건 태그 라이브러리를 사용한다면,
10,000 건이 넘는 여러분의 데이터 처리는 대부분 JSP 에서 소요될 것이다.

4. EJB 를 적절하게 사용 하였나?

EJB 하나 하나는 일반 클래스보다 많은 메모리를 점유해야 하며, 서버를 기동할 때에도 많은 시간이 소요된다.
반드시 필요한 경우에만 EJB 를 사용하자.

5. 이미지 서버를 사용할 수 있는 환경인가?

이미지, 자바스크립스 , css, 플래시 등 정적인 컨텐츠가 많고 사용자의 요청이 많은 경우에는
웹 서버 이외의 이미지 서버를 사용할 수 있다.
정적인 컨텐츠만을 제공하는 서버로서 , 웹 서버에서 파일을 읽어서 처리하는 것보다 효율적이다.

6. 사용중인 프레임웍은 검증되었는가?

검증되지 않은 프레임웍에서 많은 문제가 발생 할 수 있다.
가장 좋은 방법으로는 검증된 프레임웍을 사용하는 것이지만, 
만약 새로 개발된 프레임웍을 사용할 경우 에는 성능 테스트 및 메모리 프로파일링을 통해서 해당 프레임웍의 
안정성을 확인해 놓아야 한다.



Story 24-4  DB 관련 코딩은 잘 되어 있는가?

1. 적절한 JDBC 드라이버를 사용하였는가?

현재 DB 에 맞는 버전의 JDBC 를 사용하고 있는가?
간혹 버그가 있는 JDBC 를 사용하여 성능이 나오지 않는 경우가 발생한다.
되도록이면 가장 최신의 WAS 및 DB 벤더에서 추천하는 문제 없는 JDBC 를 사용하기를 권장한다.

2. DB Connection, Statement, ResultSet 은 잘 닫았는가?

"알아서 잘 닫히겠지" 하는 생각은 버려라.
반드시 finally 구문을 사용해서 Connection, Statement, ResultSet 을 명시적으로 닫아 주기 바란다.
그렇지 않으면 사용 가능한 연결이 부족해져 여러분들이 개발한 시스템이 사용 불가능한 상태가 되는 것은 시간 문제다.

3. DB Connection Pool 은 잘 사용하고 있는가?

프로젝트의 규모가 크면 클 수록 표준을 따르지 않을 확률도 커진다.
DB 연결 부분을 개발자의 역량에 맡기면 여러 가지 형태로 DB 에 연결하게 될 것이다.
관련되는 표준을 반드시 정하고,
DB Connection Pool 은 반드시 사용해야 DB 의 리소스를 보다 효율적으로 사용할 수 있다.


4. 자동 커밋 모드에 대한 고려는 했는가?

기본 커밋 모드는 자동커밋으로 되어 있다.
하지만 조회성 프로그램도 자동커밋 여부를 지정하게 되면, 약간의 응답시간 저하가
발생하게 된다. 반드시 필요하지 않은 경우에는 자동 커밋을 하도록 하자.

5. ResultSet.las() 메소드를 사용하였는가?

전체 건수를 처리하기 위해서 last() 메소드를 사용했는지 확인해 봐야 한다.
데이터의 건수가 많을수록 응답시간이 느려진다.
쿼리를 두번 수행하더라도 전체 건수를 가져오기 위해서 last() 메소드의 사용을 자제해 주기 바란다.


6. PreparedStatements 를 사용하였는가?

Statement 를 사용하면 매번 쿼리를 수행할 때마다 SQL 쿼리를 컴파일 하게 된다.
이작업은 DB 에 많은 부하를 준다.
그러므로 쿼리 문장이 계속 동적으로 변경되어야 하는 경우를 제외한 대부분의 경우에는
PreparedStatements 를 사용 하기를 바란다.




Story 24-5 서버의 설정은 잘 되어 있는가?

1. 자바 VM 관련 옵션들은 제대로 설정되어 있는가?

64 비트 기반의 시스템을 사용하면서 -d64 옵션을 사용하지 않는다면, 그냥 32 비트로 시스템이 운영된다.

클래스 패스는 순차적으로 인식된다.
여러 JAR 파일 중 만약 같은 패키지명에 같은 클래스가 존재할 경우에는 앞에 명시한 클래스 패스에 우선권이 있다.

2. 메모리는 몇 MB 로 설정해 놓았는가?

가끔 서버의 메모리 설정을 하지 않고, 성능이 나오지 않는다고 이야기하는 사이트가 있다.
설정하지 않으면 서버는 기본 64MB 로 시작한다는 사실을 반드시 기억하길 바란다.

3. GC 설정은 어떻게 되어 있는가?

혹시 -client 로 설정되어 있는지 확인해 보자.
GC 방식에 따라서 서버의 성능이 엄청난 차이가 발생할 수 있다.
가능하면 성능 테스트를 통해서 우리의 시스템과 서버에 맞는 GC 옵션을 설정하자.

4. 서버가 운영모드인지 개발모드인지 확인하였는가?

서버가 개발모드라면 WAS 는 주기적으로 변경된 클래스가 있는지 확인할 것이다.
이 작업은 서버에 많은 부하를 주게 된다.
서버가 주기적으로 느려진다면,  이 부분은 반드시 확인하자.

5. WAS 의 인스턴스가 몇 개 기동되고 있는가?

WAS 에서 하나의 인스턴스당 적어도 한 개는 있어야 제대로 된 운영이 가능하다.
CPU 는 4장인데, 인스턴스가 30개 정도 있는건 아닌지 확인하기 바란다.
자바는 코볼이나 포트란이 아니다.

WAS 의 CPU 개수가 적을 경우, 인스턴스 개수를 증가시키면 서버의 처리량이 증가될 수 있다.
이 인스턴스의 개수에 대해서는 정답이 없다.
그러므로 서버 및 어플리케이션의 상황에 맞게 성능 테스트를 통해서 시스템의 적절한 인스턴스 개수를 도출해야 된다.

6. JSP Precompile 옵션은 지정해 놓았는가?

서버를 기동할 때 JSP 를 미리 컴파일 하도록 해 높으면 사용자는 JSP 가 수정이 되었는지 여부와 상관없이 일정한 응답속도를 느낄 것 이다. 하지만 이 옵션을 지정해 놓으면 서버가 기동될 때 JSP 를 컴파일 하기 위한 시간도 많이 소요되기 때문에 상황에 맞게 옵션을 지정해야 한다.

7. DB Connection Pool 개수와 스래드 개수는 적절한가?

스래드 개수가 DB Connection Pool 의 수보다 절대로 적어서는 안된다.
스래드의 개수는 DB Connection Pool 의 개수보다 보통 10 개 정도 더 많이 설정한다.
만약 DB Connection Pool 의 설정을 서버 기본설정으로 해 놓고 운영을 한다면,
서버의 리소스도 별로 사용하지 않고 10명 이상의 동시 사용자를 처리하지 못할 것이다.
대부분의 WAS 의 DB Connection Pool 초기값을 10~ 20 개 이다.

8. 세션타임아웃 시간은 적절한가?

세션을 더이상 사용하지 않을 때 세션 정보는 삭제되어야 한다.

만약 세선타임아웃 시간을 하루 이상의 큰 값으로 지정하고, 해당 서버를 재시작하지 않으면
해당서버는 메모리 릭이 발생하여 더이상 사용할 수 없는 상황이 될 것이다.

9. 검색 서버가 있다면, 검색 서버에 대한 설정 및 성능 테스트를 하였는가?

일반적으로 검색 서버에서 주기적으로 데이터를 모으기 위해서 서버의 리소스를 많이 사용하게 된다.
만약 검색 서버의 세팅을 점검하지 않고,
성능 테스트를 하지 않는다면, 예기치 못한 부분에서 시스템의 리소스를 점유하고 있을지도 모른다.





출처: http://joke00.tistory.com/148 [Smile virus]

+ Recent posts