제목없음

2020. 05. 09

Jaewoo KIM

시작하기 전에

아니!? 왜 제목이 없는거죠??

Go lang

JS function

GraphQL

PKI

gRPC

DBMS

...

제목없음

시작하기 전에

그래서 아무것도 안 하겠다는 건가..?

시작하기 전에

주의사항

1. 누군가에겐 당연한 내용일 수 있음

2. Java 코드가 출현함

3. '저걸 왜 저렇게...' 라는 답답한 마음이 들 수 있음

시작하기 전에

💁‍♂️ 에피소드

1. 메인페이지 로딩 속도가 느려요

원인을 파악하자

메인페이지 로딩 속도가 느려요

  • DB 점검

  • Access log 점검

  • ...

원인을 파악하자

메인페이지 로딩 속도가 느려요

JS 43개, CSS 9개, IMAGE 23개

정적 리소스가 캐싱되지 않고 매번 다운로드 하고 있다

아파치 캐시 설정

메인페이지 로딩 속도가 느려요

<IfModule mod_expires.c>
        ExpiresActive On
        ExpiresByType image/png "access plus 1 week"
        ExpiresByType image/gif "access plus 1 week"
        ExpiresByType image/jpeg "access plus 1 week"
        ExpiresByType text/css "access plus 1 week"
        ExpiresByType application/x-javascript "access plus 1 week"
</IfModule>

mime-type 별로 캐시 기간을 설정할 수 있다

메인페이지 로딩 속도가 느려요

편-안

아파치 캐시 설정

메인페이지 로딩 속도가 느려요

정적 리소스 수정 후 배포시 아파치를 통해서

캐싱 되었기 때문에 수정사항이 반영 되지 않는다..

🤔

메인페이지 로딩 속도가 느려요

<link type="text/css" href="/design/css/default.css?20200507">
<link type="text/css" href="/design/css/main.css?20200505">
<link type="text/css" href="/design/css/popup.css?20200503">

수동으로 변경된 파일에 수정일을 붙여서 배포

Version 전략

메인페이지 로딩 속도가 느려요

스프링에서의 Version 전략

Fixed Version Strategy

Content Version Strategy

chin: 
  strategy:
    fixed:
      enabled: true
      version: 20200508-1
chin: 
  strategy:
    content: true

application.yml 간단한 설정으로 적용이 가능하다

메인페이지 로딩 속도가 느려요

스프링에서의 Version 전략

// Fixed Version Strategy
<link type="text/css" href="/20200508-1/design/css/default.css">
<link type="text/css" href="/20200508-1/design/css/main.css">
<link type="text/css" href="/20200508-1/design/css/popup.css">


// ContentVersion Strategy
<link type="text/css" href="/design/css/default-235452j3skclxl87879789b.css">
<link type="text/css" href="/design/css/main-268bj3skclxl8780b789b.css">
<link type="text/css" href="/design/css/popup-gee97j3skclxl87879789b.css">

2. 외부 API가 간헐적으로 실패나요

대부분 서비스들은...

외부 API가 간헐적으로 실패나요

우리 서비스

외부 서비스A

외부 서비스B

외부 서비스C

외부 API가 간헐적으로 실패나요

외부 API 통신이 무조건 성공한다고 보장 할 수 있을까 🤔

 

ReadTimeout, HandshakeTimeout 등..

예상치 못한 오류는 언제든지 발생할 수 있다

외부 API 호출 실패

외부 API가 간헐적으로 실패나요

외부 API 통신이 실패하더라도 재시도 할 수 있도록 개선해보자

우리 서비스

외부 서비스

재시도 처리

외부 API가 간헐적으로 실패나요

for (int i = 1; i <= RETRY_MAX_COUNT; i++) {
  try {
    Response response = apiCall() // 외부 API 호출
    return response.result();
    
  } catch(RuntimeException e) {
    if (i == RETRY_MAX_COUNT) {
      throw e;
    }
    Thread.sleep(100);
  }
}

간단하게 생각해보면 대략 이런 코드가 나올 것 같다...

외부 API가 간헐적으로 실패나요

만약 위와 같이 코드를 작성한다면

외부 API를 호출 하는 코드에 중복코드를 발생시킬 것이다...

 

조금 더 나아가 생각 했을 때

재시도라는 기능은 범용적으로사용될 수 있다.

재시도 처리

외부 API가 간헐적으로 실패나요

// retry(수행 메서드, 재시도 횟수, 메서드 인자);
retry(AService::call, 3, aServiceRequestDto);
retry(BService::call, 4, bServiceRequestDto);
retry(CService::call, 5, CServiceRequestDto);

재시도 처리 유틸 클래스를 만들어 보자

재시도 처리

외부 API가 간헐적으로 실패나요

 

 

생각보다 쓸만하군

3. 이건 언제 삭제되는 파일인가요?

이건 언제 삭제되는 파일인가요?

서비스를 운영하다 보면 다양한 파일 데이터가 저장된다.

 

문의사항 첨부파일

포토 발송 이미지

....

이건 언제 삭제되는 파일인가요?

사용자 데이터 (UserData)

  • 사용자가 직접 지우지 않으면 계속 유지 (문자 보관함..)
  • 회원 탈퇴시 삭제됨

서비스 데이터 (ServiceData)

  • 서비스 정책에 따라 관리되는 데이터 (문의 내역, 증빙 서류..)
  • 페이지를 벗어나면 사용하지 않는 임시 데이터
  • 특정 기간동안 유지 후 일괄 삭제됨, N일 유지

파일데이터 분류

이건 언제 삭제되는 파일인가요?

00님 A 파일은 언제 삭제되나요?

93일 유지 후 파일이 삭제 될거야

파일 삭제가 안되고 있는데요?

아... 파일 삭제를 깜빡했네 ㅅㅂ

파일 삭제처리 누락

이건 언제 삭제되는 파일인가요?

파일 삭제처리 누락

1. 파일 데이터를 사용하는 기능 개발 

2. 일별 배치를 통해 유지기간이 지난 DB 데이터 조회

3. DB 데이터 삭제 후 연관된 파일 데이터 삭제 

이건 언제 삭제되는 파일인가요?

이런 일이 또 발생 할 수 있는 가능성은 충분히 있다고 판단됨 🤔

 

이미 DB데이터가 지워젔다면

사용하지 않는 파일을 찾기도 번거로움

이건 언제 삭제되는 파일인가요?

ServiceData 디렉토리 구조 개선

개선 전 (1depth)

개선 후 (2depth)

photoImage(dir)
 ㄴ 1_image.jpg
 ㄴ 2_image.jpg
 ㄴ 3_image.jpg
 ㄴ 4_image.jpg
 
photoImage(dir)
 ㄴ 20200506(dir)
   ㄴ 1_image.jpg
   ㄴ 2_image.jpg
 ㄴ 20200507(dir)
   ㄴ 3_image.jpg
   ㄴ 4_image.jpg
 

이건 언제 삭제되는 파일인가요?

파일 데이터 삭제 배치코드 개선

개선 전 파일삭제 코드

개선 후 파일삭제 코드

// DB 저장된 데이터를 읽어와서 삭제
List<Path> deleteList = 
  findByFileType(FileType.PHOTO_IMG);

deleteList.forEach(path -> {
  File.delete(path);
  
  if (File.exists(path)) {
    //error: 파일이 존재함
  }
})
 // FileType에 해당하는 RootPath를 찾고
 // YYYYMMDD 디렉토리 기준으로 유지기간이 지났으면
 // 삭제하도록 함
 deleteFile(
   FileType.PHOTO_IMG, 
   93, 
   (Path path) -> {
     return DateUtil.of(
       path.getFileName(), 
       DateTimeFormat.YYYYMMDD
     ).getLocalDateTime();
 });

4. 파일 데이터 권한 처리

 👨‍💻부록 

 Jvm 구조

 Jvm 구조 - 클래스 로더 시스템

  • .class 에서 바이트코드를 읽고 메모리에 저장

  • 로딩: 클래스를 읽어오는 과정

  • 링크: 레퍼런스를 연결하는 과정

  • 초기화: static 값들 초기화 및 변수에 할당

 Jvm 구조 - 메모리

  • 메소드: 클래스 수준의 정보 저장, 공유 자원

  • 힙: 객체를 저장, 공유 자원

  • 스택: 쓰레드 마다 런타임 스택을 만들고. 메소드 호출을 스택 프레임이라 부르는 블럭으로 쌓는다.

 Jvm 구조 - 실행 엔진

  • 인터프리터: 바이트 코드를 한줄 씩 실행

  • JIT 컴파일러: 인터프리터 효울을 높이기 위해 반복되는 코드를 발견하면 네이티브 코드로 바꿔둔다.

  • GC: 더이상 참조되지 않는 객체를 모아서 정리

 Jvm 구조 - JNI

  • 자바 애플리케이션에서 C, C++, 어셈블리로 작성된 함수를 사용할 수 있는 방법 제공

  • Native 키워드를 사용한 메소드 호출

📚Contents

1. 시작하기 전에...

2. 에피소드

3. 부록

Made with Slides.com