참고 : 에버노트에 작성했던 글을 옮겨서 블로그에 작성한건데 양식 유지가 안되서 읽기가 조금 안 좋네요


 

  1. 목적
    1. 서비스를 운영중에 프로세스 재 시작없이 로그 레벨을 변경해야할 경우가 있을 수 있습니다.(Dynamically modify the log level)
      1. 예) 특정 케이스 디버깅을 위해서 프로덕션에서 디버그 레벨로 변경
    2. 여러가지 방법이 있을 수 있는데, alibaba의 arthas라는 프로젝트를 이용해서 변경해보고 arhas의 사용법을 익혀봄으로써 트러블슈팅 역량을 향상해보겠습니다.
  2. 참고 링크(arthas)
    1. github
    2. onlin tutorials
    3. documentation
    4. intellij plugin

3. dzone 참고 링크


  1. arthas 설치 및 실행
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

-- 사용법 확인하고 싶으면 -h옵션
java -jar arthas-boot.jar -h

 

  1. logger command를 이용해서 로그레벨 변경 방법
    1. 주의: 로그레벨을 낮추고 확인이 완료되면 잊지말고 원복 필요
    2. logger command
-- 현재 어플리케이션의 로그 레벨확인
logger

-- search class detail
예) sc -d yourClassName

-- ROOT라는 로거의 레벨을 debug로 변경
-- logger -c 클래스로더의해시--name ROOT --level debug
예) logger -c 51081592 --name ROOT --level debug

 

샘플

  1. arthas에서 로그레벨 변경 명령어
  2. 어플리케이션에서 로그가 변경되어 출력되는 모습
    1. logger 명령어로 ERROR레벨 이상으로 변경한 결과 -> ERROR레벨 이상의 로그만 출력됨을 확인 가능

 

 

 

 
참고 링크
 
  1. 배경 및 목적
    1. 요즘 MSA 등의 형태로 서비스를 만들다보니 외부 API호출하는 경우가 많음(또는 AWS 서비스 호출)
    2. 네트웤 문제나 스로틀링 등의 문제로 가끔 실패가 발생하는 경우가 있음. 실패가 발생할 경우 재 처리가 필요하여 사용
 
 
 
예제 소스 (from AWS)
  •  지수 백오프의 기본 아이디어는 오류 응답이 연이어 나올 때마다 재시도 간 대기 시간을 점진적으로 늘린다는 것.
  • 최대 지연 간격과 최대 재시도 횟수를 구현해야 함. 최대 지연 시간 간격과 최대 재시도 횟수는 고정 값일 필요가 없으며, 수행 중인 작업과 다른 로컬 요인(예: 네트워크 지연 시간)을 기반으로 설정
java 버전의 재 시도 대기시간 구하는 메소드 샘플
* 참고로 jitter를 적용하는게 좋음(위 aws글 참고
Thread.sleep(RetryUtil.getRetrySleepTime(retryCnt, 2, 1000, 2000)); //대기처리

	
/**
* 재 시도시 대기시간(sleep) 구하기
*  - 지수 백오프 알고리즘 기반
*
* @param retryCount 요청하는 재시도 횟수
* @param increaseBase 증가 처리의 지수의 밑(ex. 2^4 에서 2)
* @param increaseMillis 매 재 요청마다 증가하는 시간(밀리시간초)
* @param maxWaitMillis 최대 대기시간(밀리시간초). 매 증가하는 대기 시간은 최대 대기시간을 넘을 수 없음
* @return
*/
public static long getRetrySleepTime(int retryCount, double increaseBase, long increaseMillis, long maxWaitMillis) {

    long waitTime = ((long)Math.pow(increaseBase, retryCount) * increaseMillis); //ex) ((long)Math.pow(2, retryCount) * 100L);  => 100, 200, 400, 800, 1600과 같이 증가함
    return Math.min(waitTime, maxWaitMillis); //두번째 argment은 최대 대기시간(밀리세컨드)
}



 
AWS 샘플 소스
public enum Results {
    SUCCESS,
    NOT_READY,
    THROTTLED,
    SERVER_ERROR
}
 
 
/*
* Performs an asynchronous operation, then polls for the result of the
* operation using an incremental delay.
*/
public static void doOperationAndWaitForResult() {
 
 
    try {
        // Do some asynchronous operation.
        long token = asyncOperation();
 
 
        int retries = 0;
        boolean retry = false;
 
 
        do {
            long waitTime = Math.min(getWaitTimeExp(retries), MAX_WAIT_INTERVAL);
 
 
            System.out.print(waitTime + "\n");
 
 
            // Wait for the result.
            Thread.sleep(waitTime);
 
 
            // Get the result of the asynchronous operation.
            Results result = getAsyncOperationResult(token);
 
 
            if (Results.SUCCESS == result) {
                retry = false;
            } else if (Results.NOT_READY == result) {
                retry = true;
            } else if (Results.THROTTLED == result) {
                retry = true;
            } else if (Results.SERVER_ERROR == result) {
                retry = true;
            }
            else {
                // Some other error occurred, so stop calling the API.
                retry = false;
            }
 
 
        } while (retry && (retries++ < MAX_RETRIES));
    }
 
 
    catch (Exception ex) {
    }
}
 
 
/*
* Returns the next wait interval, in milliseconds, using an exponential
* backoff algorithm.
*/
public static long getWaitTimeExp(int retryCount) {
 
 
    long waitTime = ((long) Math.pow(2, retryCount) * 100L);
 
 
    return waitTime;
}
 

 

tda를 이용했었는데 온라인 사이트도 존재함


https://fastthread.io/index.jsp

  •  요약
    • G1 GC worst-case에서 향상 목적
    • JDK9부터 기본 GC가 G1으로 변경되었는데, concurrent GC에서 full GC가 발생 할 수 있음. 
    • G1 GC의 알고리즘 mark-sweep-compact를 병렬로 수행하도록 변경되었으며 -XX:ParallelGCThreads 옵션을 사용해서 스레드 수 조정 가능


JEP 307: Parallel Full GC for G1

Owner Stefan Johansson
Type Feature
Scope Implementation
Status Closed / Delivered
Release 10
Component hotspot / gc
Discussion hotspot dash gc dash dev at openjdk dot java dot net
Effort M
Duration M
Reviewed by Mikael Vidstedt
Endorsed by Mikael Vidstedt
Created 2017/01/17 11:40
Updated 2018/03/29 07:39
Issue 8172890

Summary

Improve G1 worst-case latencies by making the full GC parallel.

Non-Goals

Match the performance of the parallel collector's full GC for all use cases.

Motivation

The G1 garbage collector was made the default in JDK 9. The previous default, the parallel collector, has a parallel full GC. To minimize the impact for users experiencing full GCs, the G1 full GC should be made parallel as well.

Description

The G1 garbage collector is designed to avoid full collections, but when the concurrent collections can't reclaim memory fast enough a fall back full GC will occur. The current implementation of the full GC for G1 uses a single threaded mark-sweep-compact algorithm. We intend to parallelize the mark-sweep-compact algorithm and use the same number of threads as the Young and Mixed collections do. The number of threads can be controlled by the -XX:ParallelGCThreads option, but this will also affect the number of threads used for Young and Mixed collections.

Testing

  • Full GC time analysis to ensure that the full GC times have improved. Looking at benchmark scores will probably not be good enough since G1 is designed to avoid full GCs.
  • Runtime analysis using VTune or Solaris Studio Performance Analyzer to find unnecessary bottlenecks.

Risks and Assumptions

  • The work is based on the assumption that nothing in the fundamental design of G1 prevents a parallel full GC.
  • The fact that G1 uses regions will most likely lead to more wasted space after a parallel full GC than for a single threaded one.



원인 : 톰캣이 sessionId 등에서 필요한 난수를 생성할때 SecureRandom클래스에 의존되는데, 이 클래스는 디폴트로 /dev/random을 사용(자원 고갈되면 지연 발생할 수 있음)


해결 : urandom을 사용하도록 처리.

       -Djava.security.egd=file:/dev/./urandom 처리하거나 jre설치된 하위 디렉토리의 java.security 파일에서 수정



참고 : https://wiki.apache.org/tomcat/HowTo/FasterStartUp

+ Recent posts