MSA 서비스 간 통신 → Kafka → Kafka Connect
MSA에서는 하나의 기능이 여러 개의 독립적인 서비스로 분리되어 있기 때문에 서비스 간 통신이 필수적이다.
예를 들어 주문 서비스가 회원 정보를 조회하려면 User Service에 요청을 보내야 한다.
Order Service
│
HTTP 요청
▼
User Service
이러한 통신 방법으로 RestTemplate와 OpenFeign을 학습하였다.
RestTemplate은 Spring에서 제공하는 HTTP Client이다.
서비스가 다른 서비스의 API를 호출할 때 직접 URL을 작성하여 요청을 보낸다.
restTemplate.getForObject(
"http://USER-SERVICE/users/" + userId,
UserResponse.class
);
OpenFeign은 HTTP 통신을 인터페이스 형태로 사용할 수 있도록 만들어 준다.
@FeignClient(name="user-service")
public interface UserServiceClient {
@GetMapping("/users/{userId}")
UserResponse getUser(@PathVariable Long userId);
}
호출은 다음처럼 일반 메서드를 사용하는 것과 동일하다.
userServiceClient.getUser(userId);
| RestTemplate | OpenFeign |
|---|---|
| URL 직접 작성 | 인터페이스 선언 |
| 코드가 비교적 길다 | 코드가 간결하다 |
| HTTP 요청을 직접 생성 | Spring이 자동 생성 |
| 유지보수가 어려울 수 있음 | 유지보수가 쉽다 |
최근 Spring Cloud에서는 OpenFeign을 많이 사용하는 추세이며, Eureka와 함께 사용하면 서비스 이름만으로도 통신이 가능하다.
RestTemplate나 OpenFeign은 서비스가 즉시 응답해야 하는 동기식(Blocking) 통신이다.
하지만 MSA에서는 모든 작업이 즉시 응답할 필요는 없다.
예를 들어 회원가입이 완료되면
등의 작업은 나중에 처리해도 된다.
이때 사용하는 것이 Kafka이다.
회원가입
│
▼
Kafka Topic
├── Email Service
├── Point Service
├── Logging Service
└── Statistics Service
Producer는 메시지를 Topic으로 전송하고,
Consumer는 필요한 메시지만 가져가 처리한다.
서비스끼리 직접 연결되지 않기 때문에 결합도가 낮아지고 확장성이 높아진다.
Kafka Connect는 Kafka와 외부 시스템을 연결하는 프레임워크이다.
Producer나 Consumer를 직접 구현하지 않고도 Database, File System 등의 데이터를 Kafka와 연결할 수 있다.
외부 시스템 → Kafka
Database
│
▼
Source Connector
│
▼
Kafka Topic
Kafka → 외부 시스템
Kafka Topic
│
▼
Sink Connector
│
▼
Database
JDBC Connector 역시 이러한 Connector 중 하나이며 데이터베이스와 Kafka를 연결하는 역할을 수행한다.
Kafka Connect를 Windows 환경에 설치하고 실행하였다.
실행 명령
.\bin\windows\connect-distributed.bat .\etc\kafka\connect-distributed.properties
connect-distributed.properties에는 Broker 주소, REST API 포트, Plugin Path 등 Kafka Connect 실행에 필요한 설정이 저장되어 있다.
초기 실행 시 Linux 기본 경로(/usr/share/java)가 설정되어 있어 Windows에서 Plugin을 찾지 못하였다.
Windows 환경에 맞게 plugin.path를 수정하여 해결하였다.
초기에는
config/connect-distributed.properties
를 실행하였지만 실제 파일은
etc/kafka/connect-distributed.properties
에 존재하였다.
Confluent 버전에 따라 디렉터리 구조가 달라질 수 있다는 점을 확인하였다.
java.lang.OutOfMemoryError: Java heap space
오류가 발생하였다.
처음에는 Java Heap 자체의 문제라고 생각했지만 실제 원인은 plugin.path를 너무 넓은 범위(share/java)로 지정하여 Kafka Connect가 수많은 라이브러리를 Plugin으로 인식하고 모두 스캔했기 때문이었다.
JDBC Connector를 아직 설치하지 않은 상태였기 때문에 plugin.path를 비워 두고 실행하여 문제를 해결하였다.
실행 과정에서
DEPRECATED: A Log4j 1.x configuration file has been detected
경고가 계속 출력되었다.
처음에는 이 메시지가 실행 실패의 원인이라고 생각했지만 실제 종료 원인은 다른 Exception이었다.
로그를 해석할 때는 가장 마지막에 발생한 Exception을 먼저 확인해야 한다는 점을 배웠다.