[공부 노트] #4

2 minute read

Q1. Java Finally

자바 스터디 9주차로 예외처리에 대해서 공부를 했는데, 라이브 스터디에서 공부하지 못한 부분을 발견했다.

finally 구문 내에서 return을 사용하는 것은 안티 패턴이다.

finally 구문은 엮여있는 try-catch문에 return문이 있더라도 반드시 수행된다.

String word = "a";
try{
  word = "try";
  return word;
}catch{
  word = "catch";
  return word;
}finally{
  word = "finally";
  return word;
}

위의 코드에서 return되는 word의 값은 “finally”이다. 만약 finally의 return문을 주석처리한다면 word의 값은 “try”로 반환된다. finally에서 word의 값을 바꾼다하더라도, try문에서 return값은 다른 레퍼런스에 복사가 된 상태이므로 실제 리턴값이 “try”로 되는 것이다.
예시로는 String 자료형을 사용했지만, 만약 메모리에 직접 접근하는 배열과 같은 자료형을 쓰게 되면 결과가 또 달라지게 된다. 이렇게 finally 내부에 return문을 사용할 경우 원하지 않는 결과를 얻을 가능성이 있고, try-catch문에서 예외가 발생하더라도 return의 제어권을 가져오기 때문에 사용이 지양된다.

Q2. 쿠버네티스

인턴 채용 공고에 팀에서 쿠버네티스를 사용한다는 문구를 보았는데, 쿠버네티스가 뭔지도 모르는게 창피해서 찾아보게 되었다. 사전적 정의는 다음과 같다.

쿠버네티스(Kubernetes)는 컨테이너화된 애플리케이션의 자동 디플로이, 스케일링 등을 제공하는 관리시스템으로, 오픈 소스 기반이다. 원래 구글에 의해 설계되었고 현재 리눅스 재단에 의해 관리되고 있다.

github 블로그를 시작하면서, ruby와 jekyll이 로컬 환경에 깔리는게 괜히 찝찝(?)해서 처음으로 도커(Docker)를 사용해본 경험이 있다. 도커와 컨테이너를 사용하면 다음과 같은 장점이 있다.

  1. 탄력적인 확장성
  2. 격리(-> 로컬 환경에 ruby를 깔지 않기 위해 도커를 사용한 것 처럼)
  3. 이식성

이러한 장점을 얻기 위해 컨테이너를 이용해서 어플리케이션을 구축했는데, load가 많아져서 scale out(서버의 수를 늘리는 능력을 향상시키는 것)이 필요해지면 쿠버네티스가 나설 차례가 된다. 컨테이너화 한 어플리케이션을 여러 서버에 배포하고 관리하는 것을 수월하게 해주는 것이다.

Q3. Kafka

Kafka는 메세징 시스템 중 하나이다. 메세징 시스템이란 AMQP를 구현한 MOM 시스템이다. 정말 모든 용어가 처음 듣는 것 뿐이니, 용어 정리부터 하기로 했다.

  • MOM ( Message Oriented Middleware, 메시지 지향 미들웨어 )
    • 독립된 애플리케이션 간에 데이터를 주고받을 수 있도록 하는 시스템 디자인
    • 함수 호출, 공유메모리 등의 방식이 아닌, 메시지 교환을 이용하는 중간 계층에 대한 인프라 아키텍쳐 개념
    • 분산 컴퓨팅이 가능해지며, 서비스간의 결합성이 낮아짐
    • 비동기로 메시지를 전달하는 것이 특징
    • Queue, Broadcast, Multicast 등의 방식으로 메시지 전달
    • Pub/Sub 구조 -메시지를 발행하는 Publisher(Producer), 메시지를 소비하는 Subscribe(Consumer)로 구성
  • Message Broker -메시지 처리 또는 메시지 수신자에게 메시지를 전달하는 시스템이며, 일반적으로 MOM을 기반으로 구축됨
  • MQ ( Message Queue, 메시지 큐 )
    • Message Broker와 MOM을 구현한 소프트웨어 ( RabbitMQ, ActiveMQ, kafka 등.. )
    • MOM은 메시지 전송 보장을 해야하므로 AMQP를 구현함
  • AMQP ( Advanced Message Queueing Protocol )
    • 메시지를 안정적으로 주고받기 위한 인터넷 프로토콜

예를 들어, 다음과 같이 자동 메일을 발송 시스템이 있다고 가정하면,

  • 회원가입을 했을 때, 이메일을 발송하는 MemberService
  • 주문완료가 되었을 때, 이메일을 발송하는 OrderService
  • 메일을 실제 발송하는 MailService
  1. MemberService에서 회원가입, OrderService에서 주문완료 이벤트가 발생
  2. Messaging Client로 메일 전송에 필요한 데이터( 받는/보내는 사람 이메일 주소, 메시지 제목/내용 등.. )를 API 호출
  3. Messaging Client에서 MOM을 구현한 소프트웨어(ex. kafka)로 메시지를 생산
  4. MailService에서 메시지가 존재하는지 구독하고 있다가 메시지가 존재하면 메시지를 소비
  5. MailService에서 API 정보들을 통해 User에게 메일 발송

의 프로세스를 거친다.
그런데 유독 kafka가 메세징 시스템 중 인기가 많은 이유가 무엇일까? 그 이유는 kafka가 다른 메세징 시스템과 메세지를 소비하는 방식이 다소 다른데, 이 부분에서 성능 차이가 발생하기 때문이라고 한다. RabbitMQ와 Kafka를 비교하자면,

  • RabbitMQ
    • Message Broker가 Consumer에게 메시지를 push하는 방식
    • Broker는 Consumer의 처리여부에 관계없이 push를 하므로, 메시지 소비 속도보다 생산 속도가 빠를 경우 Consumer에 부
  • Kafka
    • Consumer가 Broker로부터 메시지를 pull하는 방식
    • Consumer가 처리할 수 있을 때 메시지를 가져오므로 자원을 효율적으로 사용
    • 메시지를 쌓아두었다가 처리하는 batch Consumer 구현도 가능

물론 pull 방식에도 단점은 있는데, 데이터가 없음에도 정기적인 polling으로 인해 자원을 낭비하게 된다. 이러한 단점을 보완하기 위해 실제 데이터가 도착할 때까지 long poll 대기를 할 수 있는 parameter를 지원한다고 한다. 자세한 내용은 공식문서를 참조하자.

뜬구름 잡는 느낌

쿠버네티스와 카프카에 대한 내용을 조사하여도 쉽게 와닿지 않았다. 한 번도 사용해본 적이 없고, 접해본 적도 없는 기술을 오직 문서로 이해하기 어려웠기 때문이다. 역시 백문이 불여일견이요, 백견이 불여일행이다. 다음주 부터는 무조건 토이 프로젝트라도 시작해서 공부해야겠다.

참고문헌

https://kafka.apache.org/documentation/ https://jbhs7014.tistory.com/81 https://victorydntmd.tistory.com/343

Leave a comment