/**

 * Spring boot에서 셧다운 이벤트 발생시 리스너 샘플

 * 

 * @author 

 */

@Component

public class StopListener implements ApplicationListener<ContextClosedEvent> {

 

@Override

public void onApplicationEvent(final ContextClosedEvent event) {

System.out.println("셧다운 호출");

}

}

 

 


1.8.4 설치방법은 아래 링크를 참고하세요


설치방법 메모

유저홈/apps 디렉토리를 기준으로 설치 함

#디렉토리 생성
mkdir ~/apps && cd ~apps

#다운로드 후 압축 해제, 심볼릭 링크 처리
wget 'https://github.com/naver/pinpoint/archive/1.8.1-RC1.tar.gz' && tar -xzf 1.8.1-RC1.tar.gz && rm 1.8.1-RC1.tar.gz && ln -s pinpoint-1.8.1-RC1 pinpoint


#인스톨(JAVA 6,7,8, 9 필요)
cd ~/apps/pinpoint && ./mvnw install -Dmaven.test.skip=true

#참고: JAVA설치
* 아래 wget이 인증 만료로 진행되지 않는다면, 각 다운로드 페이지에 로그인 후 fiddler를 통해 다운로드 URL을 구하면 됨

cd ~/apps

chmod 755 jdk-6u45-linux-x64.bin && ./jdk-6u45-linux-x64.bin && rm jdk-6u45-linux-x64.bin

tar -xzf jdk-7u80-linux-x64.tar.gz && rm jdk-7u80-linux-x64.tar.gz

tar -xzf jdk-8u191-linux-x64.tar.gz && rm jdk-8u191-linux-x64.tar.gz && ln -s ~/apps/jdk1.8.0_191 jdk && ln -s ~/apps/jdk1.8.0_191 jdk_8

tar -xf jdk-9.0.4_linux-x64_bin.tar.gz  && rm jdk-9.0.4_linux-x64_bin.tar.gz && ln -s ~/apps/jdk-9.0.4 jdk_9


#환경변수 등록
vi ~/.bashrc 후에

export JAVA_HOME=~/apps/jdk
export JAVA_9_HOME=~/apps/jdk_9
export JAVA_8_HOME=~/apps/jdk_8
export JAVA_6_HOME=~/apps/jdk_6
export JAVA_7_HOME=~/apps/jdk_7
export PATH=$JAVA_HOME/bin:$PATH



#참고 : JAVA DNS TTL Modify
echo 'networkaddress.cache.ttl=60' >> ~/apps/jdk/jre/lib/security/java.security



#참고 : OS 디스크외 AWS EBS를 추가로 마운트해서 데이터를 저장한다면 pinpoint data디렉토리 변경(/data에 EBS 마운트)
cd ~/apps/pinpoint/quickstart && ln -s /data/pinpoint data
sudo su
mkdir /data/pinpoint && chown 유저계정:유저계정 /data/pinpoint



Hbase 설치 및 시작
-- HBase 저장기간을 줄임(1일=86400초로 줄이는데 상황에 따라서 적당한 수치로 조정)
 vi ./quickstart/conf/hbase/init-hbase.txt 후 아래 입력 (2일간 데이터 보관)
 :%s/5184000/172800/g

-- Hbase 다운로드 및 시작
quickstart/bin/start-hbase.sh

-- Hbase 테이블 초기화
quickstart/bin/init-hbase.sh



Pinpoint 데몬들 설정 후 시작

-- 컬렉터로그 레벨을 조정해서 적게 남기도록 함
vi ./quickstart/collector/src/main/resources/log4j.xml
:%s/DEBUG/INFO/g
:%s/TRACE/INFO/g

-- pinpoint 웹의 로그레벨 조정
vi ./quickstart/web/src/main/resources/log4j.xml
:%s/DEBUG/INFO/g

-- 컬렉터(데이터 수집 프로세스)  시작
quickstart/bin/start-collector.sh

-- 웹 UI 시작
quickstart/bin/start-web.sh


agent 수정(해당 agent가 실제 어플리케이션 시작시 사용됨)

agent 홈 경로 : ~/apps/pinpoint/agent/target/pinpoint-agent-버전

cd ~/apps/pinpoint/agent/target/pinpoint-agent-버전

-- agent 로그 조정( 미 조정시 DEBUG레벨로 로그가 남아서 대상 프로그램의 성능 하향이 발생)
vi lib/log4j.xml 후 아래 명령 수행(로그레벨 DEBUG를 INFO로 조정)
:%s/DEBUG/INFO/g

아래내용은 삭제
<appender-ref ref="console" />

-- Collector server의 IP 및 포트 수정


vi ./quickstart/agent/src/main/resources/pinpoint.config
cd ~/apps/pinpoint/agent/target/버전 && vi pinpoint.config

-- 어플리케이션 서버로 복사를 위해서 압축해둠(예)
ex) tar -czf pinpoint-agent-버전블라블라.tar.gz 블라블라

이후 /home/integtool/apps/pinpoint/quickstart/web/target/deploy 경로에 파일을 복사하면 웹에서 다운로드 가능



이후 APM으로 모니터링하고 싶은 서버에 Agent 복사 후 프로세스 실행시 agent 사용하도록 셋팅
 - 방법은 정리 예정이며 필요시 구글 검색하세요




package com.sample;
import java.util.concurrent.TimeUnit;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import lombok.extern.slf4j.Slf4j;

/**
 * Spring RestTemplate 샘플
 *  - 타임아웃 및 pool설정 등의 튜닝버전 
 *
 * @author 
 */
@Slf4j
public class RestTemplateSample {
     private static final String REQ_URL_1 = "https://테스트URL 1번째";
     private static final String REQ_URL_2 = "https://테스트URL 2번째";
    
    private static RestTemplate restTemplate = new RestTemplate();
     
    public static void init() {
          log.info("== Start : restTemplate 초기화");
          HttpComponentsClientHttpRequestFactory crf = new HttpComponentsClientHttpRequestFactory();
          crf.setReadTimeout(7000); //읽기시간초과 타임아웃
          crf.setConnectTimeout(7000); //연결시간초과 타임아웃
          // @formatter:off
          HttpClient httpClient = HttpClientBuilder.create()
               .setMaxConnTotal(300) //커넥션풀적용(최대 오픈되는 커넥션 수)
               .setMaxConnPerRoute(50) //커넥션풀적용(IP:포트 1쌍에 대해 수행 할 연결 수제한)
               .evictIdleConnections(2000L, TimeUnit.MILLISECONDS) //서버에서 keepalive시간동안 미 사용한 커넥션을 죽이는 등의 케이스 방어로 idle커넥션을 주기적으로 지움
               .build();
          crf.setHttpClient(httpClient);
          // @formatter:on
          restTemplate.setRequestFactory(crf);
          log.info("== end : restTemplate 초기화\n\n");
     }
     /**
      * Spring RestTemplate 샘플
      *  - 타임아웃 및 pool설정 등의 튜닝버전
      *  - https URL호출 테스트시, 로그에 SSLConnectionSocketFactory 존재 유무 등을 확인하면 pool이 활용되어 https three hand shake가 발생하는지 알 수 있음
      * 
      * @param args
      * @throws Exception
      */
     public static void main(String[] args) throws Exception {
          init();
          int testReqCnt = 3; //테스트 호출 횟수
          //1번째 요청시 커넥션을 맺어서 pool에 넣고, 2번째 요청부터는 pool을 재사용(로그를 보면 ssl핸드쉐이크 부분이 2번째에서는 없음)
          for (int i = 1; i <= testReqCnt; i++) {
               System.out.println("\n\n" + i + "번째 요청 시작");
               log.info("\n\nURL:{}의 {} 번째 결과. {}\n\n\n", REQ_URL_1, i, restTemplate.getForObject(REQ_URL_1, String.class));
               //evictIdleConnections 확인시 주석 풀어서 실행=> 로그에 "Closing connections idle longer than 2000 MILLISECONDS" 확인 됨
               Thread.sleep(3000);
               if (i != testReqCnt) {
                    log.info("\n\n3초 sleep 후 idleConnection이 pool에서 제거된 후 해당URl을 재 요청해봄\n\n");
               }
          }
          System.out.println("\n\n\n\n");
          System.out.println("=== 2번째 URL호출 테스트 시작 ===");
          for (int i = 1; i <= testReqCnt; i++) {
               System.out.println("\n\n" + i + "번째 요청 시작");
               log.info("\n\nURL:{}의 {} 번째 결과. {}\n\n\n", REQ_URL_2, i, restTemplate.getForObject(REQ_URL_2, String.class));
          }
          System.out.println("\n\n\n\n");
          System.out.println("1번째 URL 재 호출해봄");
          log.info("\n\nURL:{}의결과. {}\n", REQ_URL_1, restTemplate.getForObject(REQ_URL_1, String.class));
     }
}




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


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

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



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


public class GCTest {
     private final static int ALLOC_SIZE = (int)(Runtime.getRuntime().maxMemory() * 0.50);

     public static void main(String[] args) throws InterruptedException {
          System.out.println("Before first allocation");
          byte[] b = new byte[ALLOC_SIZE];
          b = null; //객체 레퍼런스 주소를 반환 처리함으로써 GC대상에 포함되게 됨(null 처리 안하면 full gc 발생하면서 프로그램 종료됨)
          System.out.println("After first allocation");
          //        Thread.sleep(5000);
          System.out.println("Before second allocation");
          byte[] b2 = new byte[ALLOC_SIZE];
          System.out.println("After second allocation");
     }
}

IOS푸시 발송시 ssl관련 에러

-Djavax.net.debug=all
 매개 변수로 디버거를 연결하면 ssl핸드쉐이크 에러 확인 되고..

https://ko.1answer.info/737461636b6f766572666c6f772e636f6d-7a3435353631353535

http://cbsm.tistory.com/10

* 결론: 인증서를 커맨드로 다시 만들어보자

171009 기준 1.7.0 스냅샷버전

* 주기적으로 최신버전을 설치 후 글을 추가하고 있습니다. 블로그에서 pinpoint로 검색해서 가능하면 최신 버전을 설치하세요

유저홈/apps 디렉토리를 기준으로 설치 함

#디렉토리 생성
mkdir ~/apps && cd ~apps

#master(최신) 버전 다운로드 후 압축 해제
wget 'https://github.com/naver/pinpoint/archive/master.zip' && unzip master.zip && rm master.zip

# 심볼링 링크 처리
ln -s pinpoint-master pinpoint

#인스톨(JAVA 6,7,8 필요)
cd ~/apps/pinpoint && ./mvnw install -Dmaven.test.skip=true

#JAVA설치
#jdk 8설치

#jdk 7설치

#jdk6설치
cd ~/apps
chmod 755 jdk-6u45-linux-x64.bin && ./jdk-6u45-linux-x64.bin && rm jdk-6u45-linux-x64.bin

#환경변수 등록
vi ~/.bashrc 후에

export JAVA_HOME=~/apps/jdk
export JAVA_8_HOME=~/apps/jdk_8
export JAVA_6_HOME=~/apps/jdk_6
export JAVA_7_HOME=~/apps/jdk_7
export PATH=$JAVA_HOME/bin:$PATH


#참고 : JAVA DNS TTL Modify
echo 'networkaddress.cache.ttl=60' >> ~/apps/jdk/jre/lib/security/java.security



#참고 : OS 디스크외 AWS EBS를 추가로 마운트해서 데이터를 저장한다면 pinpoint data디렉토리 변경(/data에 EBS 마운트)
cd ~/apps/pinpoint/quickstart && ln -s /data/pinpoint data
sudo su
mkdir /data/pinpoint && chown 유저계정:유저계정 /data/pinpoint



Hbase 설치 및 시작
-- HBase 저장기간을 줄임(1일=86400초로 줄이는데 상황에 따라서 적당한 수치로 조정)
 vi ./quickstart/conf/hbase/init-hbase.txt 후 아래 입력
 :%s/5184000/86400/g

-- Hbase 다운로드 및 시작
quickstart/bin/start-hbase.sh

-- Hbase 테이블 초기화
quickstart/bin/init-hbase.sh



Pinpoint 데몬들 설정 후 시작

-- 컬렉터로그 레벨을 조정해서 적게 남기도록 함
vi ./quickstart/collector/src/main/resources/log4j.xml
:%s/DEBUG/INFO/g
:%s/TRACE/INFO/g

-- pinpoint 웹의 로그레벨 조정
vi ./quickstart/web/src/main/resources/log4j.xml
:%s/DEBUG/INFO/g

-- 컬렉터(데이터 수집 프로세스)  시작
quickstart/bin/start-collector.sh

-- 웹 UI 시작
quickstart/bin/start-web.sh


agent 수정(해당 agent가 실제 어플리케이션 시작시 사용됨)

agent 홈 경로 : ~/apps/pinpoint/agent/target/pinpoint-agent-버전

cd ~/apps/pinpoint/agent/target/pinpoint-agent-버전

-- agent 로그 조정( 미 조정시 DEBUG레벨로 로그가 남아서 대상 프로그램의 성능 하향이 발생)
vi lib/log4j.xml 후 아래 명령 수행(로그레벨 DEBUG를 INFO로 조정)
:%s/DEBUG/INFO/g

아래내용은 삭제
<appender-ref ref="console" />

-- Collector server의 IP 및 포트 수정


vi ./quickstart/agent/src/main/resources/pinpoint.config
cd ~/apps/pinpoint/agent/target/pinpoint-agent-1.7.0-SNAPSHOT && vi pinpoint.config

-- 어플리케이션 서버로 복사를 위해서 압축해둠
ex) tar -czf pinpoint-agent-1.7.0-SNAPSHOT_171023.tar.gz pinpoint-agent-1.7.0-SNAPSHOT




이후 APM으로 모니터링하고 싶은 서버에 Agent 복사 후 프로세스 실행시 agent 사용하도록 셋팅
 - 방법은 정리 예정이며 필요시 구글 검색하세요





import java.io.File;
import java.util.Collection;
import java.util.List;
import org.apache.commons.io.FileUtils;

/**
 * 특정 디렉토리 하위의, 특정 확장자 파일에 대한 처리
 *   - 2번째 줄에 trimDirectiveWhitespaces 처리를 위한 내용 추가
 * 
 * @author 엄승하
 */
public class JspAddTrimWhitespaceTag {
     public static void main(String[] args) throws Exception {
          //jsp파일을 찾기 시작할 디렉토리
          String startDirPath = "파일을 찾기 시작할 디렉토리 경로";
          //파일 확장자 지정
          String[] ext = {"jsp"};
          //해당 파일들을 찾아서 컬렉션에 담음(recursive)
          Collection<File> jspFileList = FileUtils.listFiles(new File(startDirPath), ext, true);
          System.out.println(String.format("총 %s개", jspFileList.size()));
          String addStr = "<%@ page trimDirectiveWhitespaces=\"true\" %>"; //파일에 추가할 내용 : JSTL의 html변경 후 남은 whitespace를 없애는 처리
          for (File jspFile : jspFileList) {
               //System.out.println(file.getAbsolutePath());
              List<String> fileContents = FileUtils.readLines(jspFile, "UTF-8");
              fileContents.add(1, addStr); //2번째줄에 추가할 문자를 컨텐츠 내용에 추가
              FileUtils.writeLines(jspFile, fileContents); //해당 파일에 쓰기
              fileContents = null; //빠른 GC처리
          }
          System.out.println("====  끝  ====");
     }
}

+ Recent posts