riot 프로젝트를 진행하면서 카프카 클러스터를 구축했었는데
새로 산 맥북에서 기존의 환경을 구축하려고 했더니 쉽게 되지 않았다.
관련 내용을 해결했던 과정을 쓰고자 한다.

기존에 도커를 활용하여 카프카 클러스터링을 구축했었는데

기존에 구성했던 카프카 클러스터링의 docker-compose.yml은 다음과 같다.

version: '3.3'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    ports:
    - "2181:2181"
    - "2888:2888"
    - "3888:3888"
    healthcheck:
      test: echo stat | nc localhost 2181
      interval: 10s
      timeout: 10s
      retries: 3
    environment:
    - ZOOKEEPER_SERVER_ID=1
    - ZOOKEEPER_CLIENT_PORT=2181
    - ZOOKEEPER_TICK_TIME=2000
    - ZOOKEEPER_INIT_LIMIT=5
    - ZOOKEEPER_SYNC_LIMIT=2
    - ZOOKEEPER_SERVERS=zookeeper:2888:3888
  kafka1:
    image: confluentinc/cp-kafka:latest
    healthcheck:
      test: ps augwwx | egrep [S]upportedKafka
    depends_on:
    - zookeeper
    ports:
    - "9091:9091"
    environment:
    - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9091
    - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9091
    - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
    - KAFKA_BROKER_ID=1
    - BOOTSTRAP_SERVERS=kafka1:9091,kafka2:9092,kafka3:9093
    - ZOOKEEPER=zookeeper:2181
  kafka2:
    image: confluentinc/cp-kafka:latest
    healthcheck:
      test: ps augwwx | egrep [S]upportedKafka
    depends_on:
    - zookeeper
    ports:
    - "9092:9092"
    environment:
    - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
    - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092
    - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
    - KAFKA_BROKER_ID=2
    - BOOTSTRAP_SERVERS=kafka1:9091,kafka2:9092,kafka3:9093
    - ZOOKEEPER=zookeeper:2181
  kafka3:
    image: confluentinc/cp-kafka:latest
    healthcheck:
      test: ps augwwx | egrep [S]upportedKafka
    depends_on:
    - zookeeper
    ports:
    - "9093:9093"
    environment:
    - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9093
    - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9093
    - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
    - KAFKA_BROKER_ID=3
    - BOOTSTRAP_SERVERS=kafka1:9091,kafka2:9092,kafka3:9093
    - ZOOKEEPER=zookeeper:2181

  kafdrop:
    image: obsidiandynamics/kafdrop
    restart: "no"
    ports: 
      - "9000:9000"
    environment:
      KAFKA_BROKER_CONNECT: "kafka1:9091"
    depends_on:
      - kafka1
      - kafka2
      - kafka3

실행해 보니 kafdrop은 mac os에서는 제대로 지원이 되지 않는 것 같았다.

그래서 먼저 kafdrop을 다른 걸로 대체하기로 하였다.


모니터링하기 위한 다른 ui 도구를 찾다가 해당 kafka-ui를 사용하기로 하였다.

https://hub.docker.com/r/provectuslabs/kafka-ui

 

Docker

 

hub.docker.com

kafka-ui카프카 클러스터링 관리를 위한 무료 오픈소스 웹 UI이다.

깃허브에는 자세한 사용 방법도 나와있다.

https://github.com/provectus/kafka-ui

 

 

kafka-ui:
  image: provectuslabs/kafka-ui
  ports:
    - "10000:8080"
  restart: always
  environment:
    - KAFKA_CLUSTERS_0_NAME=local
    - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka1:9091,kafka2:9092,kafka3:9093
    - KAFKA_CLUSTERS_0_ZOOKEEPER=zookeeper:2181

kafdrop을 제거하고 kafka-ui를 도커 컴포즈에 추가하였다. 다시 도커 컴포즈를 실행하였다.

kafka-ui

kafka-ui는 제대로 실행 됐지만 kafka와의 연결은 실패하였다.

관련 에러를 수정하기 위해 웹 서핑을 하다가 다른 내용을 봐버렸다.
카프카 클러스터링 시에 주키퍼도 클러스터의 안정성을 위해 3개 이상의 노드로 구성하는 것이 권장된다는 글을 보았다.
궁금해서 챗지피티에 검색해 보았는데 챗지피티의 답변은 다음과 같다.

주키퍼 앙상블을 3개 이상의 노드로 구성하는 것은 다음과 같은 이점을 가지게 됩니다:

높은 가용성: 주키퍼 앙상블 내에서 한 노드의 장애가 발생해도 다른 노드가 여전히 서비스를 제공하므로 전체 시스템의 가용성이 유지됩니다.

분산 투표 시스템: 주키퍼는 분산 투표 알고리즘을 사용하여 결정을 내립니다. 이때 홀수 개의 노드가 필요한데, 3개 이상의 노드로 구성하면 다수결을 쉽게 결정할 수 있습니다.

분산 데이터 저장: 주키퍼는 분산 데이터베이스처럼 작동하여 클라이언트의 상태 정보를 저장하고 유지합니다. 노드가 추가되거나 제거될 때에도 데이터의 일관성과 안정성을 유지할 수 있습니다.

일반적으로 카프카 클러스터 내의 주키퍼 앙상블은 3개 혹은 5개 노드로 구성하는 것이 일반적인 모범 사례입니다.

다음과 같은 답변을 받아서 우선 주키퍼를 3개의 노드로 구성하기로 하였다.

zookeeper-1:
  image: confluentinc/cp-zookeeper:latest
  hostname: zookeeper-1
  ports:
    - "12181:12181"
  environment:
    ZOOKEEPER_SERVER_ID: 1
    ZOOKEEPER_CLIENT_PORT: 12181
    ZOOKEEPER_TICK_TIME: 2000
    ZOOKEEPER_INIT_LIMIT: 5
    ZOOKEEPER_SYNC_LIMIT: 2
    ZOOKEEPER_SERVERS: zookeeper-1:12888:13888;zookeeper-2:22888:23888;zookeeper-3:32888:33888

zookeeper-2:
  image: confluentinc/cp-zookeeper:latest
  hostname: zookeeper-2
  ports:
    - "22181:22181"
  environment:
    ZOOKEEPER_SERVER_ID: 2
    ZOOKEEPER_CLIENT_PORT: 22181
    ZOOKEEPER_TICK_TIME: 2000
    ZOOKEEPER_INIT_LIMIT: 5
    ZOOKEEPER_SYNC_LIMIT: 2
    ZOOKEEPER_SERVERS: zookeeper-1:12888:13888;zookeeper-2:22888:23888;zookeeper-3:32888:33888

zookeeper-3:
  image: confluentinc/cp-zookeeper:latest
  hostname: zookeeper-3
  ports:
    - "32181:32181"
  environment:
    ZOOKEEPER_SERVER_ID: 3
    ZOOKEEPER_CLIENT_PORT: 32181
    ZOOKEEPER_TICK_TIME: 2000
    ZOOKEEPER_INIT_LIMIT: 5
    ZOOKEEPER_SYNC_LIMIT: 2
    ZOOKEEPER_SERVERS: zookeeper-1:12888:13888;zookeeper-2:22888:23888;zookeeper-3:32888:33888

다음과 같이 구성하였다.

실행하였더니 정상적으로 컨테이너 실행은 되었으나 여전히 다음과 같이 호스트 머신과 카프카와의 연결이 되지 않았다.

또한 로컬 환경의 인텔리제이에서 카프카와의 연결을 구현한 스프링 부트 모듈을 실행을 해봤을 때도 다음과 같은 타임아웃 에러가 발생했다.

https://github.com/hamwoojo/riot-api

java.util.concurrent.TimeoutException: null
	at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1960) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2095) ~[na:na]
	at org.apache.kafka.common.internals.KafkaFutureImpl.get(KafkaFutureImpl.java:180) ~[kafka-clients-3.1.2.jar:na]
	at org.springframework.kafka.core.KafkaAdmin.initialize(KafkaAdmin.java:214) ~[spring-kafka-3.0.4.jar:3.0.4]
	at org.springframework.kafka.core.KafkaAdmin.afterSingletonsInstantiated(KafkaAdmin.java:183) ~[spring-kafka-3.0.4.jar:3.0.4]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:974) ~[spring-beans-5.3.26.jar:5.3.26]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:920) ~[spring-context-5.3.26.jar:5.3.26]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.26.jar:5.3.26]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.10.jar:2.7.10]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.10.jar:2.7.10]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.10.jar:2.7.10]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.10.jar:2.7.10]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.10.jar:2.7.10]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.10.jar:2.7.10]
	at riot.api.data.engineer.DataEngineerApplication.main(DataEngineerApplication.java:10) ~[classes/:na]

해당 원인은 다음과 같았다.

결론부터 말하면, 호스트 머신과 컨테이너 간의 통신을 하기 위해서는 localhost가 아니라 host.docker.internal 도메인을 사용해야 한다.


host.docker.internal은 macOS 환경에서 Docker 컨테이너 내부에서 호스트 머신을 가리키는 도메인 이름이다.
macOS에서 Docker를 사용할 때, 이 도메인을 사용하여 컨테이너 내부와 호스트 머신 간의 통신을 수행할 수 있다.

 

최종적으로 수정한 docker-compose.yml 파일은 다음과 같다.

version: '3.7'
services:
  zookeeper-1:
    image: confluentinc/cp-zookeeper:latest
    hostname: zookeeper-1
    ports:
      - "12181:12181"
    environment:
      ZOOKEEPER_SERVER_ID: 1
      ZOOKEEPER_CLIENT_PORT: 12181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 5
      ZOOKEEPER_SYNC_LIMIT: 2
      ZOOKEEPER_SERVERS: zookeeper-1:12888:13888;zookeeper-2:22888:23888;zookeeper-3:32888:33888

  zookeeper-2:
    image: confluentinc/cp-zookeeper:latest
    hostname: zookeeper-2
    ports:
      - "22181:22181"
    environment:
      ZOOKEEPER_SERVER_ID: 2
      ZOOKEEPER_CLIENT_PORT: 22181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 5
      ZOOKEEPER_SYNC_LIMIT: 2
      ZOOKEEPER_SERVERS: zookeeper-1:12888:13888;zookeeper-2:22888:23888;zookeeper-3:32888:33888

  zookeeper-3:
    image: confluentinc/cp-zookeeper:latest
    hostname: zookeeper-3
    ports:
      - "32181:32181"
    environment:
      ZOOKEEPER_SERVER_ID: 3
      ZOOKEEPER_CLIENT_PORT: 32181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 5
      ZOOKEEPER_SYNC_LIMIT: 2
      ZOOKEEPER_SERVERS: zookeeper-1:12888:13888;zookeeper-2:22888:23888;zookeeper-3:32888:33888

  kafka1:
    image: confluentinc/cp-kafka:latest
    healthcheck:
      test: ps augwwx | egrep [S]upportedKafka
    depends_on:
    - zookeeper-1
    - zookeeper-2
    - zookeeper-3
    ports:
    - "9091:9091"
    environment:
    - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://host.docker.internal:9091
    - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9091
    - KAFKA_ZOOKEEPER_CONNECT=zookeeper-1:12181,zookeeper-2:22181,zookeeper-3:32181
    - KAFKA_BROKER_ID=1
    - BOOTSTRAP_SERVERS=host.docker.internal:9091,host.docker.internal:9092,host.docker.internal:9093
    - ZOOKEEPER=zookeeper-1:12181
  kafka2:
    image: confluentinc/cp-kafka:latest
    healthcheck:
      test: ps augwwx | egrep [S]upportedKafka
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3
    ports:
    - "9092:9092"
    environment:
    - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://host.docker.internal:9092
    - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092
    - KAFKA_ZOOKEEPER_CONNECT=zookeeper-1:12181,zookeeper-2:22181,zookeeper-3:32181
    - KAFKA_BROKER_ID=2
    - BOOTSTRAP_SERVERS=host.docker.internal:9091,host.docker.internal:9092,host.docker.internal:9093
    - ZOOKEEPER=zookeeper-1:12181,zookeeper-2:22181,zookeeper-3:32181
  kafka3:
    image: confluentinc/cp-kafka:latest
    healthcheck:
      test: ps augwwx | egrep [S]upportedKafka
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3
    ports:
    - "9093:9093"
    environment:
    - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://host.docker.internal:9093
    - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9093
    - KAFKA_ZOOKEEPER_CONNECT=zookeeper-1:12181,zookeeper-2:22181,zookeeper-3:32181
    - KAFKA_BROKER_ID=3
    - BOOTSTRAP_SERVERS=kafka1:9091,kafka2:9092,kafka3:9093
    - ZOOKEEPER=zookeeper-1:12181,zookeeper-2:22181,zookeeper-3:32181

  kafka-ui:
    image: provectuslabs/kafka-ui
    container_name: kafka-ui
    ports:
      - "10000:8080"
    restart: always
    environment:
      - KAFKA_CLUSTERS_0_NAME=local
      - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=host.docker.internal:9091,host.docker.internal:9092,host.docker.internal:9093
      - KAFKA_CLUSTERS_0_ZOOKEEPER=zookeeper-1:12181,zookeeper-2:22181,zookeeper-3:32181

localhost를 host.docker.internal로 수정하였다.
그리고 호스트 머신의 ip를 찾아야 하는데 해당 명령어는 다음과 같다.

ifconfig | grep "inet "

ip를 찾았으면 hosts 파일에 등록한다.

sudo vi /etc/hosts
{ip} host.docker.internal

해당 내용을 제일 마지막 줄에 추가해 준다.

다시 도커 컴포즈를 실행해 보자.

kafka-ui

kakfa-ui를 확인해 보니 제대로 연결된 걸 확인했다. 인텔리제이에서 스프링 부트 모듈을 실행해 보자.

해당 모듈에는 topic이 자동으로 생성되게 해 놓았는데, 정상적으로 실행이 완료된다면 5개의 토픽이 생길 것이다.

kafka-ui

정상적으로 토픽이 생성된 걸 확인할 수 있다.

마지막으로 토픽에 제대로 메시지가 들어오는지 확인하기 위해서

리그 오브 레전드 게임의 item 정보를 가져오는 api를 호출하였다.

아이템 정보가 잘 가져와지는 걸 확인했다. 얼마 안 걸릴 줄 알았는데 구축하는데 생각보다 오랜 시간이 걸렸다. 
아무래도 mac을 처음 써봐서 mac 관련 단축키나 기능을 배우는 데도 시간이 걸려서 그랬던 것 같다.
다음엔 해당 프로젝트에 스웨거(Swagger)를 붙이거나, 아니면 Logstash와 ElasticSearch를 macOS에 구축해보려고 한다.

기존에 riot API를 활용하여 league of legend 게임 데이터를 수집하는 프로젝트를 진행했었다.

https://github.com/hamwoojo/riot-api

 

GitHub - hamwoojo/riot-api: riot-api collect server

riot-api collect server. Contribute to hamwoojo/riot-api development by creating an account on GitHub.

github.com

해당 프로젝트에 아쉬운 부분이 있어 많은 리팩토링을 진행하였었는데 항상 다시 볼 때마다 개선점이 보인다.

그중에 한 문제를 개선해보려고 한다.

이번에 맥북을 구매하면서 내 로컬에 환경 세팅을 하려고 하니 DB에 관한 새로운 세팅을 하는 게 너무 번거로웠다.
해당 문제를 해결하기 위해서 데이터베이스 마이그레이션을 적용해보려고 한다.

데이터베이스 마이그레이션이란?

데이터베이스 마이그레이션이란 데이터베이스 스키마의 버전을 관리하고, 애플리케이션의 변경 사항을 추적하여 데이터베이스 스키마를 업데이트하는 작업을 의미한다.

 

물론 해당 프로젝트는 Spring Data JPA를 활용하여 진행한 프로젝트여서, hibernate의 ddl 생성 옵션

  jpa:
    hibernate:
      ddl-auto: create

을 사용하면 되지만 해당 옵션은 로컬에서 환경 구성할 때는 쓸 수 있지만 운영 서버에서는 데이터 손실의 위험이 있어 너무 위험하여 쓸 수 없다. 또한 추후에 어떤 테이블이 업데이트된다면 그 내용을 관리해야 할 필요도 있다.
해당 이슈들을 방지하기 위해서 데이터베이스 마이그레이션을 적용해보기로 하였다.

 

해당 프로젝트에 사용한 기술 스택 버전은 다음과 같다.

Spring Boot

  • Version 2.7.10

Maven

  • Version : 3.8.1

PostgreSQL

  • Version : 14.1

postgresql 환경 구성하기위해서 도커를 활용하기로 하였다.
postgresql 컨테이너 생성 및 실행을 위해서 docker-compose.yml 파일을 작성하였다.

version: "3.0"

services:
  db:
    image: postgres:14.1
    container_name: postgres
    ports:
      - "5432:5432"
    volumes:
      - ./db_data:/var/lib/postgresql/data
    restart: always
    environment:
      POSTGRES_USER: "root"
      POSTGRES_PASSWORD: "local"
      POSTGRES_DB: "riot"

docker compose up -d 명령어로 postgresql을 실행하였다.

 

Spring Boot에서는 flyway를 활용하면 데이터베이스 마이그레이션을 적용할 수 있다.

flyway를 적용해보자.

pom.xml에 dependency를 추가한다.

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>9.21.1</version>
</dependency>

application.yml에 flyway를 사용한다는 내용을 추가한다.

spring:
  flyway:
    enabled: true

 

src/main/resources/db/migration 디렉터리에 V0__init.sql 파일을 작성한다. 테이블을 생성할 DDL을 써주면 된다.
너무 길어서 테이블 중 하나의 예시만 작성 첨부하겠다.

CREATE TABLE public.api_info (
                                 api_info_id bigserial NOT NULL,
                                 api_name varchar(255) NULL,
                                 api_host varchar(255) NULL,
                                 api_url varchar(255) NULL,
                                 content_type varchar(255) NULL,
                                 description varchar(255) NULL,
                                 http_method varchar(255) NULL,
                                 rate_limit int4 NULL,
                                 rate_limit_interval int4 NULL,
                                 api_scheme varchar(5) NULL,
                                 CONSTRAINT api_info_pkey PRIMARY KEY (api_info_id)
);

그리고 애플리케이션을 실행하였는데, 오류가 발생했다.

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.configureProperties(FlywayAutoConfiguration.java:227)

The following method did not exist:

    'org.flywaydb.core.api.configuration.FluentConfiguration org.flywaydb.core.api.configuration.FluentConfiguration.oracleSqlplus(boolean)'

The calling method's class, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration, was loaded from the following location:

    jar:file:/Users/mac/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.7.10/spring-boot-autoconfigure-2.7.10.jar!/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class

The called method's class, org.flywaydb.core.api.configuration.FluentConfiguration, is available from the following locations:

    jar:file:/Users/mac/.m2/repository/org/flywaydb/flyway-core/9.21.1/flyway-core-9.21.1.jar!/org/flywaydb/core/api/configuration/FluentConfiguration.class

The called method's class hierarchy was loaded from the following locations:

    org.flywaydb.core.api.configuration.FluentConfiguration: file:/Users/mac/.m2/repository/org/flywaydb/flyway-core/9.21.1/flyway-core-9.21.1.jar


Action:

Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration and org.flywaydb.core.api.configuration.FluentConfiguration

 

해당 에러를 찾다가 확인해 보니 무지성으로 flyway 최신 버전을 적용하려다가 스프링 부트의 버전과 호환이 안돼서 생긴 문제였다.

내 스프링 부트의 버전은 2.7.10인데 해당 버전은 8.5 버전의 flyway를 사용해야 한다.

해당 내용은 스프링 페이지에서 확인이 가능하다

https://spring.io/projects/spring-boot#learn

 

Spring Boot

 

spring.io

본인이 사용하는 버전의 Reference Doc을 보면 된다.

본인은 2.7 버전이라서 2.7.15 버전을 택했다.

클릭한 뒤 제일 아래에 있는 Dependency Versions를 선택한다.

찾기(ctrl + f)로 flyway를 찾는다.

8.5 버전을 써야 한다는 걸 알 수 있었다.

8.5 버전으로 pom.xml을 수정하자.

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>8.5.13</version>
</dependency>

DDL이 제대로 됐는지 확인하기 위해서 validate 옵션을 추가하였다.

jpa:
  hibernate:
    ddl-auto: validate

실행해 보면 성공적으로 된 걸 알 수 있다.

db에서도 flyway_schema_history 테이블이 자동으로 생성되어 있는 걸 확인할 수 있는데 이름에서 알 수 있듯이 flyway 히스토리를 관리해 주는 테이블이다. 테이블 내용을 한 번 알아보자.

flyway_schema_history는 Flyway가 관리하는 테이블 중 하나로, 데이터베이스의 스키마 버전 및 마이그레이션 작업에 대한 기록을 저장하는 테이블입니다. 
Flyway는 이 테이블을 사용하여 데이터베이스의 상태를 추적하고, 이미 적용된 마이그레이션 스크립트를 기록하여 중복 실행을 방지합니다.

다음은 flyway_schema_history 테이블 칼럼에 대한 설명이다.
installed_rank: 마이그레이션 스크립트가 설치된 순서를 나타내는 숫자입니다. 낮은 숫자일수록 이전에 실행된 스크립트를 의미합니다.
version: 마이그레이션 스크립트의 버전을 나타냅니다. 버전은 마이그레이션 스크립트 파일 이름에 포함된 숫자 또는 타임스탬프입니다. 
description: 마이그레이션 스크립트의 설명을 나타냅니다. 마이그레이션 스크립트 파일 이름에서 파생될 수 있습니다.
type: 마이그레이션 스크립트의 유형을 나타냅니다. 주로 "SQL" 또는 "BASELINE"이 사용됩니다. SQL은 일반적인 마이그레이션 스크립트를 의미하고, BASELINE은 초기 베이스라인 마이그레이션을 의미합니다.
script: 실행된 마이그레이션 스크립트 파일의 이름을 나타냅니다.
checksum: 마이그레이션 스크립트의 체크섬 값입니다. 체크섬은 스크립트의 내용을 해시한 값으로, Flyway가 스크립트를 변경하지 않았는지 검증하는 용도로 사용됩니다.
installed_by: 마이그레이션 스크립트를 설치한 사용자를 나타냅니다.
installed_on: 마이그레이션 스크립트가 설치된 날짜와 시간을 나타냅니다.
execution_time: 마이그레이션 스크립트 실행에 소요된 시간을 나타냅니다.

flyway_schema_history 테이블을 통해 Flyway는 현재 데이터베이스의 상태와 적용된 마이그레이션 스크립트들에 대한 정보를 추적하며, 이를 통해 중복 실행을 방지하고 데이터베이스 스키마의 버전을 관리합니다.

 

다음은 기초 데이터를 추가로 insert 해보려고 한다.

flyway도 버전을 통하여 관리하는데 버전 관리는 프로젝트나 팀의 네이밍 룰을 따르면 된다.

본인은 다음 버전을 0.1로 작성할 것이다.

INSERT INTO public.api_info (api_name,api_host,api_url,content_type,description,http_method,rate_limit,rate_limit_interval,api_scheme)
VALUES
('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/GRANDMASTER/I','json','Retrieve a list of users in the Grandmaster tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/PLATINUM/IV','json','Retrieve a list of users in the Platinum IV tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/PLATINUM/III','json','Retrieve a list of users in the Platinum III tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/PLATINUM/II','json','Retrieve a list of users in the Platinum II tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/PLATINUM/I','json','Retrieve a list of users in the Platinum I tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/DIAMOND/IV','json','Retrieve a list of users in the Diamond IV tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/DIAMOND/III','json','Retrieve a list of users in the Diamond III tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/DIAMOND/II','json','Retrieve a list of users in the Diamond II tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/DIAMOND/I','json','Retrieve a list of users in the Diamond I tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/MASTER/I','json','Retrieve a list of users in the Master tier.','get',100,120,'https')
,('getUserEntries','kr.api.riotgames.com','/lol/league-exp/v4/entries/RANKED_SOLO_5x5/CHALLENGER/I','json','Retrieve a list of users in the Challenger tier.','get',100,120,'https')
,('getMatchList','asia.api.riotgames.com','/lol/match/v5/matches/by-puuid/{puuid}/ids','json','Retrieve a list of matches by PUUID.','get',100,120,'https')
,('getMatchDetail','asia.api.riotgames.com','/lol/match/v5/matches/{matchId}','json','Retrieve detailed match information by match ID.','get',100,120,'https')
,('getItems','ddragon.leagueoflegends.com','/cdn/{version}/data/ko_KR/item.json','json','Retrieve item information by version.','get',100,120,'https')
,('getChampions','ddragon.leagueoflegends.com','/cdn/{version}/data/ko_KR/champion.json','json','Retrieve champion information by version.','get',100,120,'https')
,('getSpells','ddragon.leagueoflegends.com','/cdn/{version}/data/ko_KR/summoner.json','json','Retrieve summoner spell information by version.','get',100,120,'https')
,('getRunes','ddragon.leagueoflegends.com','/cdn/{version}/data/ko_KR/runesReforged.json','json','Retrieve rune information by version.','get',100,120,'https')
,('getUserInfoDetail','kr.api.riotgames.com','lol/summoner/v4/summoners/{encryptedSummonerId}','json','Retrieve user information details by summoner ID to fetch match information.','get',100,120,'https')
,('getVersions','ddragon.leagueoflegends.com','/api/versions.json','json','Retrieve version information.','get',100,120,'https');

INSERT INTO public.api_params (api_info_id,data_type,description,is_required,"name",api_key,api_value,date_param_required)
VALUES
(13,'Long','Start time',true,'startTime','startTime',NULL,true)
,(13,'Long','End time',true,'endTime','endTime',NULL,true)
,(13,'String','Game type',true,'type','type','ranked',false)
,(13,'int','Page',true,'start','start','0',false)
,(13,'int','Number of items to load per page',true,'count','count','100',false);

V0.1__insert_base_data.sql로 해당 내용을 작성하고 실행하였다.

flyway history 테이블 조회
실제 데이터 조회

잘 된 걸 볼 수 있다.
다음에는 kafka와 연동하는 걸 써보려고 한다.

'Side Project > Riot Project' 카테고리의 다른 글

Mac os에서 kafka clustering 구축하기  (0) 2023.08.13

+ Recent posts