Technical Note/SERVER PERFORMANCE

Needs에 맞는 패턴 활용

켄트 벡의 구현 패턴 : 가까운 시일내에 읽어볼 예정임

VO패턴이나 Service-Locator패턴은 반드시 사용하자

리팩토링

마틴 파울러의 리팩토링 : 역시 가까운 시일내에 읽어볼 예정임

garbage collection에 대한 이해

메모리(변수, 객체) 할당/해제에 대해 신경을 써야 한다

절대 System.gc()를 써서 명시적으로 gc를 요청하면 안된다

JVM의 gc 관련 옵션으로 상황에 맞는 gc방법을 지정하여 성능 향상을 꾀할 수 있다

gc 모니터링/분석을 위한 Tool과 방법

  • jvmstat : SUN에서 제공하는 무료 툴, jdk1.4.2이상이면 바로 사용가능, jdk1.4.1이면 -XX:+UsePerfData 옵션을 사용하면 됨
  • visualgc : SUN에서 제공하는 무료 툴
  • java -verbosegc옵션
  • jps : jvm 프로세스를 보여줌
  • jstat : jvm 통계수치를 보여줌
  • jstatd : 원격으로 jstat을 사용하기 위한 데몬
[참고]/lib/security/java.policy에 다음을 추가해야 jstatd 사용가능함

grant codebase "file:${java.home}/../lib/tools.jar" {
        permission java.security.AllPermission;
};

프로파일링과 APM 툴의 활용

  • 프로파일링 툴(Profiling Tool) : 소스 레벨 분석용, DevPartner for Java, JProbe, TPTP(Eclipse용)
  • APM(Application Performance Monitoring or Management) : 애플리케이션 실행 상황 모니터링/문제점 진단용, Jennifer, IntroScope, I3, Vantage Analyzer

System Class 활용

arraycopy

Property관련 : getProperties, getProperty, setProperties, setProperty

Native Library 관련 : load, loadLibrary

gc관련 : gc, runFinalization

시간 관련  : currentTimeMilis, nanoTime

String, StringBuffer, StringBuilder

  • String : 짧은 문자열 더할때
  • StringBuffer : Thread-Safe가 필요할 때
  • StringBuilder : Thread-Safe가 필요없을때

Collection & Map

적절한 자료구조를 선택해서 사용하라

대용량 데이타가 아닌 경우 성능차이는 그다지 크지 않다, 대용량 데이터의 경우는 간략한 테스트 후 선택한다

Sun의 추천 목록 : HashSet, ArrayList, HashMap, LinkedList

종류

  • Collection : 최상위 클래스
  • Set : 중복불허 집합
  • SortedSet : 오름차순 정렬 Set
  • List : 순서가 있는 Set
  • Queue : FIFO구현, 객체 순차 처리용으로 많이 사용
  • Map : 키-값 쌍으로 구성된 객체 Set, 중복키 불허
  • SortedMap : 키를 오름차순 정렬하는 Map
  • HashSet : 데이타를 Hash Table에 저장, 순서없슴
  • TreeSet : red-back 트리에 저장
  • LinkedHashSet : 저장된 순서대로 순서가 결정되는 HashSet
  • Vector : 크기 지정필요없는 배열
  • ArrayList : 동기화 처리 안됨, Vector와 비슷
  • LinkedList : ArrayList와 동일 + Queue인터페이스 구현
  • HashTable : 데이터를 해쉬테이블에 저장, 동기화됨
  • HashMap : null값 허용 + 동기화안됨을 제외하고는 HashTable과 동일
  • TreeMap : red-back 트리에 데이터를 저장, TreeSet과 다른 점은 키에 의해 순서가 정해짐
  • LinkedHashMap : Double-Linked List방식을 제외하고 HashMap과 동일
  • PriorityQueue : 큐에 추가된 순서가 아니라 객체 생성 순서대로 Pop되는 Queue
  • LinkedBlockingQueue : FIFO기반의 Linked 노드를 사용하는 Blocking Queue
  • ArrayBlockingQueue : 크기 정해짐, FIFO기반 Blocking Queue
  • PriorityBlockingQueue : 크기 안 정해짐, 객체 생성 순서대로 Pop되는 Queue
  • DelayQueue : 대기시간을 정할 수 있는 Queue
  • SynchronousQueue : put()호출하면, 다른 thread에서 take()해줄때까지 대기하는 Queue

동기화 여부

  • 동기화됨 – Vector, HashTable
  • 동기화안됨 – HashSet, TreeSet, LinkedHashSet, ArrayList, LinkedList, HashMap, TreeMap, LinkedHashMap

동기화안된 Collection을 위한 메쏘드 : Collections.synchronizedXXX (XXX = Set, SortedSet, List, Map)

Loop 성능 향상

if나 switch나 성능은 비슷, 가독성 측면만 고려하면 됨

Loop안에서의 쓸데없는 변수/객체 생성, 메쏘드 호출을 최대한 제거

for loop 구현방법 : 속도 : Code #1 < Code #2 < Code #3

Code #1

for(int i = 0; i < arrData.length(); i++)

Code #2

Vector v = …

for(String str : v )

Code #3

int intLength = arrData.length();

for(int i = 0; i < intLength; i++)

static

static 선언된 변수 : 객체가 아니라 클래스에 속함, 모든 객체가 동일한 변수 1개를 참조하게 됨, gc도 이뤄지지 않음

static 블럭 : 생성자와 상관없이 최초 1회 실행됨

자주 사용, 절대 변하지 않는 변수는 final static으로 선언

설정파일정보도 static으로 관리하는 것이 좋다

code성 데이타는 DB에서 1회 읽도록 한다

synchronized

하나의 객체를 여러 Thread에서 사용해야 하는 경우 -> 해당 객체에 접근하는 method에 synchronized 선언

static으로 선언된 객체를 여러 Thread에서 사용해야 하는 경우 -> 해당 객체에 접근하는 method에 static synchronized 선언

java.util.Concurrent 패키지를 이용해서 Thread관리 – Lock, Executors, Concurrent Collection, Atomic 변수

reflection class를 통해 클래스 정보 등을 얻을 수 있다

Class, Method, Field

JMX와 함께 모니터링 부분 구현 가능

IO병목 해결

설정파일 사용시 매번 갱신여부 확인하는 대신에 데몬 쓰레드로 주기적 점검하는 식으로 구현

파일 복사 or 네트워크 작업시 NIO이용

개인적으로는 Netty 이용할 예정

Logging

상용 배포전에 모두 제거하는 게 Best

로깅여부 Flag(final로 선언)를 둬서 Logging

System.out.println대신에 Logger or Log4j를 이용

Exception처리시에도 printStackTrace대신에 Exception에서 필요한 부분만 로깅하도록 구현

DB사용

Connection Pool or Data Source 사용하여 Connection 관리

사용가능할 경우, Statement보다 PreparedStatement를 주로 사용

Connection, Statement, ResultSet 관리 철저 : 생성시 Connection – Statement – ResultSet순, 닫을때는 역순

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
        ...
} catch (Exception e) {
        ...
} finally {
        try { rs.close(); rs = null; } catch ( Exception e ) {}
        try { stmt.close(); stmt = null; } catch ( Exception e ) {}
        try { conn.close(); conn = null; } catch ( Exception e ) {}
}

ResultSet의 last()는 절대 사용불가 : 차라리 데이터 개수 확인을 위해 쿼리를 날려라 or 배열 대신에 Vector를 사용해서 데이타를 리턴

데이터 조작없이 조회만 하는 경우는 setAutoCommit()를 사용하지 말자

배치성 작업을 위해서는 executeBatch()를 이용하자

setFetchSize()를 이용해서 적당한 개수를 Fetch하도록 직접 지정하자

1건이 필요하면, 1건만 쿼리하라

XML 관련

SAX : 이벤트에 맞춰 순차적으로 처리, 트리 따라다니기기 쉽지 않음, 메모리 사용량은 적음

DOM : 전체 xml 내용을 트리로 만들어 메모리에 적재, 전체를 메모리에 올리므로 메모리 사용량 많음

웹서버 관련

httpd.conf 설정내용

Include conf/extra/httpd-mpm.conf

KeepAlive On

KeepAliveTimeout 15

HostnameLookups는 무조건 off

로그 포맷에 %D(요청처리시간을 마이크로초 단위로 표시), %T(요청처리시간을 초 단위로 표시)

httpd-mpm.conf

<IfModule mpm_worker_module>

StartServers : 최초에 띄울 프로세스의 수

MaxClients : 최대 처리 가능한 클라이언트의 수

MinSpareThreads : 최소 여유 쓰레드 수

MaxSpareThreads : 최대 여유 쓰레드 수

ThreadsPerChild : 프로세스당 쓰레드 수

MaxRequestsPerChild : 프로세스당 최대 요청 수

</IfModule mpm_worker_module>

웹로그 분석 : Analog, AWStats, Webalizer

정적인 내용(이미지, 플래시, 자바스크립트 등)이 많을 경우에는 따로 서버를 두어 해결하는 방안도 고려

DB Connection Pool 설정

Thread수는 Connection 개수보다 10개 정도 많게 설정

session timeout을 설정하자

JVM설정

jvm에 메모리 설정 -Xmx는 최대 메모리, -Xms는 최소 메모리

inspection tool

Hammurapii, PMD. CheckStyle

모니터링 API JMX

Jconsole은 JMX 모니터링용 툴(Sun에서 제공)

JMX 원격 모니터링을 위한 VM옵션

-Dcom.sun.management.jmxremote.port=9003

-Dcom.sun.management.jmxremote.password.file=/파일위치

-Dcom.sun.management.jmxremote.access.file=/파일위치

-Dcom.sun.management.jmxremote.ssl=false

문제 진단을 위한 참고사항

http://java.sun.com/javase/6/webnotes/trouble/other/matrix6-Windows.html

http://java.sun.com/javase/6/webnotes/trouble/other/matrix6-Unix.html


Related posts:

  1. 자바 코딩 규약 정리 한 줄에 한 문장만 써라 //가독성이 떨어짐 int i; System.out.println("Hello...
  2. Netty 사용에 관한 몇가지 Tip ClientBootStrap 설정 샘플 bootstrap = new ClientBootstrap( new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));...
  3. 안드로이드 어플의 VersionName (버전 번호)을 AndroidManifest.xml에서 가져오기  public static String getVersionName(Context context) {     try {        ...
  4. ImageButton with selector & style 상속 http://www.androidpub.com/55225   <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/navy"...
  5. java 서버용 어플리케이션의 자동 업데이트, 자동 재실행, db/config변경 및 프로세스 종료시 자동 시작 구현을 위한 아이디어 실행할 프로세스를 직접 실행시키지 않고 별도의 매니지먼트용 프로세스를 두어서 매니지먼트...