Aug 12, 2019 - 백업파일 만들기

매일 백업을 해야하는데, 까먹고 배포해서 히스토리를 유실하는 경우가 많습니다.

CI(Continuous Integration)를 하루빨리 도입해야하나, 업무에 치여 항상 치일 피일 미루다가, 어마무지한 실수를 하게 됩니다.

DATE=`date +%Y%m%d-%H%M`

cd /home/data/public_html

# Java source backup
tar cfpz /data/source_backup/WEB-INF_${DATE}.tar.gz ./WEB-INF/*

특정 폴더에 있는 파일을 백업하는 shellscript 를 만들어 대응합니다.

Jul 23, 2019 - [마이크로서비스 따라하기 꿀밋업 시리즈] 2탄 - 도메인 모델에 따른 데이터의 분리 저장과 API 연결

meetup 링크

피보탈에서 진행하는 MSA 따라하기 시리즈 중 2탄을 들었습니다. 아쉽지만, 1탄을 듣지 못했고, 해당 동영상도 없는 거 같습니다.

다양한 프로젝트에서 도메인에 따라 데이터를 분리한 경험이 있는 엔지니어들이 직접 마이크로서비스에 대해 이야기 합니다. 특히 피보탈의 APAC에서 Application Transformation 을 주도하는 팀의 Sumant Singh Rana와, Satya Ranjan 두 수석 엔지니어들, 그리고 이들과 현재 한국에서 함께 프로젝트를 진행하고 계신 피보탈 한국 김영태 상무님이 함께 하십니다.

마이크로서비스에서 도메인 모델에 따른 데이터의 분리와 적절한 데이터 저장소의 선택은 가장 먼저 고려되어야 할 사항입니다. 피보탈은 다양한 엔터프라이즈 고객과의 프로젝트 수행을 통해 체계화된 서비스를 보유하고 있으며, 본 밋업에서는 그 경험과 과정을 공유하는 시간이 될 것입니다.

만약 3탄도 참석할 수 있게 된다면, 간단한 동영상 촬영을 하여 회사분들에게 유투브로 공유할 까 합니다.
30분 가량을 동영상 촬영했고, 남은 부분은 녹음을 했기 때문에 조금더 자세한 내용은 나중에 시간이 날때 정리해서 올려야할 거 같습니다.

이번 2탄은 DDD 관점에서 보는 레거시 리빌드 하는 방법이 진행되었습니다.

보통 1개 Aggregates 마다 1개의 MSA 를 구성하는 것을 원칙으로 합니다. Aggregates 1개가 Boundary Context 들을 가지게 됩니다.

커다란 벽면에 현업, 개발 등 모든 관련자들이 모여서 이벤트를 1개 포스트잇으로 해서 벽에 붙이며, 총 3가지의 산출물이 나와야한다고 합니다.

  1. EventStorm
  2. Boris
  3. SNAP-E

이렇게 3가지의 산출물을 순차적으로 생성한다고 합니다.

  1. EventStorm
    현업에 있는 사람들이 본인들이 사용하는 UI를 포스트잇으로 세분화합니다.
    대략적으로 한 PAGE 의 모든 기능들을 포스트잇으로 붙이게 됩니다.
    회원 아이디, 회원 등록 이런 모든 속성들이 포스트잇으로 붙게 됩니다.

PS. 참고로 해당 포스트잇의 내용은 과거형으로 붙이게 됩니다. 또한 별도 외부 시스템 (ex : 이메일 등) 은 외부 시스템 이벤트로 처리하여 다른 포스트잇으로 붙입니다.

예를들어 유저 등록화면에 대한 포트스잇은 다음과 같습니다.

이벤트 1 - 유저 등록 화면에 왔다
이벤트 2 - 입력을 다하고 등록 버튼을 눌렀다
이벤트 3 - 다른 페이지로 리다이렉트 됐다
이벤트 4 - 등록 완료 이메일이 노티로 발송됐다

또한, 회원 가입하고, 로그인 성공된 뒤 해당 서비스에 대한 조회 및 다른 디스플레이 이벤트 등에서는 다음과 같습니다.

이벤트 - 로그인이 완료되었다
이벤트 - 유저 정보가 디스플레이 되었다

여기서 중요한 점은 정보가 디스플레이 되는것도 하나의 이벤트로 취급해야한다는 겁니다. (그래서 MSA 처럼 해당 서비스에 대한 API를 분기할 수 있겠지요.)

이렇게 이벤트스톰을 통해 분리된 작업을 가지고 보리스 다이어그램을 그립니다.

  1. Boris

보리스를 통해 서비스간 상호 작용 (interaction) 을 보고, 스냅이를 통해서 서비스의 기능을 드릴다운해서 자세히 보게되면,
결론적으로 백로그(저장할 데이터) 가 정리됩니다.

  1. SNAP-E

원래는 API, DATA, RISKS, UI 4개의 항목에 해당하는 내용 하나하나를 포스트잇으로 붙여서 진행한다고 하였으나, 시간이 없는 관계로, 급하게 진행되었습니다.
각각의 api 의 명칭을 부여하면서 포스트잇을 만들며, 그 포스트잇을 테이프 혹슨, 줄, 급하면 펜으로 이어 나가게 됩니다.

API - 보리스를 통해 필요해 보이는 API 를 포스트잇을 붙입니다.
DATA - API 에 사용되는 데이터를 기록합니다.  
RISKS - 서비스가  우려되는 위험 요소들을 기록합니다. 예로, 외부 연동이 지연될 가능성 등
UI - 서비스가 필요한 UI 화면이 있는경우 기록합니다. 예로, 백그라운드 task 만 있는 서비스라면 UI 가 없을것입니다.

이렇게 1단계 ~ 3단계를 걸치면서 모델링에 대한 여러가지 해결책에 대해서 정리할 수 있었습니다.

정리 DDD 와 MSA 를 이용한 서비스 리빌드 - EventStorm, Boris, SNAP-E, Stories 이벤트 스톰 - 발생 가능한 모든 이벤트를 나열해서 Aggregate 단위로 데이터 기준의 이벤트를 묶음 하나의 Aggregate 단위가 하나의 도메인이 되며, 1개 도메인 마다 1개 서비스가 결정됨, 이 서비스들을 서비스 후보자들이라고 칭합니다. 보리스 - 서비스 후보자들간의 상호작용을 표시합니다. 스냅이 - 보리스를 기준으로 서비스 후보자를 구체화 해서 Stories 를 만들어냄, 이 Stories 가 백로그가 될 수 있습니다. 스냅이를 통해 서비스를 구체화 하면, 서비스 후보자 중 불필요한 서비스가 생기거나 합쳐져야 하는 서비스가 생기는 등 서비스 후보자들의 필요성/불필요성이 명확해집니다. 신규 이벤트(기능) 추가 등이 발생할 경우 1번 EventStorm 부터 다시 검토할 필요가 있습니다.

남은 밋업 시리즈

3탄_마이크로 서비스부터 만들어야지?
  - 스프링 부트를 사용한 단일 마이크로 서비스 개발 (로컬 환경) | 페어 프로그래밍 데모 (테스트 작성)
4탄_티끌 모아 태산 만들기
  - 스프링 클라우드를 사용한 마이크로 서비스 연결
5탄_이상하다 내 컴퓨터에서는 잘 됐었는데…
  - 개발된 코드를 변경 없이 로컬에서 클라우드로 (부제: 도커때문에 다들 고생이 많다)
Pivotal Application Service 를 사용한 스프링 애플리케이션과 데이터베이스 배포
6탄_우리는 아마존:애저:구글:센터 서비스 비율 조정할 수 있단다.
  - 대륙을 넘나드는 빠르고 안전한 데이터의 저장과 복제 (부제: 멀티 클라우드 및 멀티 리전에서의 가용성 확보)
7탄_데이터베이스를 끈다니 농담도 잘하셔. (부제: 데이터 베이스를 꺼본다고?)
  - 서비스에 카오스 엔지니어링 적용하기
8탄_마이크로서비스가 기능 단위인지 클래스 단위인지 고만 좀 물어봅시다.
  - API 게이트웨이의 오프로딩을 위한 서버리스 적용
9탄_주가 예측 모델 제공하기
  - 서비스에 데이터 과학의 적용을 통해 필요한 도구를 연동하고 적용하는 기술을 살펴봅니다.

다음 밋업은 다음과 같습니다. 해당 내용에 대한 질문 과 답변에 대해서는 다시 정리해서 올릴 수 있도록 하겠습니다.

Jul 16, 2019 - Constructor DI(Constructor Injection)

spring boot로 코딩 중에, @Autowired를 사용할 때,
inteliJ warning에서

always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies

이런 메시지가 뜰 경우에,

@Autowired
private TestService testService;

위의 경우를

private final PodsService podsService;
public TestController(TestService testService) {
    this.testService = testService;
}

다음과 같이 변경할 수 있습니다.

Spring 4.3부터는 Spring Bean으로 구성된 클래스가 오직 하나의 생성자를 가지면 Autowired 주석을 생략 할 수 있고 Spring은 해당 생성자를 사용하고 필요한 모든 의존성을 주입을 한다고 하네요.

DI도 디자인 패턴 중 하나이며, 의존성 주입이 코드 속에 숨겨질 경우, 의존하는 어떤 클래스가 문제가 생겼는지를 확인하기 위해서는 한번더 해당 클래스를 테스트해야하는 경우가 생깁니다.

Constructor DI 를 권장하는 이유는 다음과 같습니다.

  1. 단일 책임의 원칙 생성자의 인자가 많을 경우 코드량도 많아지고, 의존관계도 많아져 단일 책임의 원칙에 위배됩니다.
    그래서 Constructor Injection을 사용함으로써 의존관계, 복잡성을 쉽게 알수 있어 리팩토링의 단초를 제공하게 됩니다.

  2. 테스트 용이성 DI 컨테이너에서 관리되는 클래스는 특정 DI 컨테이너에 의존하지 않고 POJO여야 합니다.
    DI 컨테이너를 사용하지 않고도 인스턴스화 할 수 있고, 단위 테스트도 가능하며, 다른 DI 프레임 워크로 전환할 수도 있게 됩니다.

  3. Immutability Constructor Injection에서는 필드는 final로 선언할 수 있습니다.
    불변 객체가 가능한데 비해 Field Injection은 final는 선언할 수 없기 때문에 객체가 변경 가능한 상태가 된됩니다.

  4. 순환 의존성 Constructor Injection에서는 멤버 객체가 순환 의존성을 가질 경우 BeanCurrentlyInCreationException이 발생해서 순환 의존성을 알 수 있게 된됩니다.

  5. 의존성 명시 의존 객체 중 필수는 Constructor Injection을 옵션인 경우는 Setter Injection을 활용할 수 있습니다.


참조