OpenShift 클러스터의 여러 포드에서 변경 로그 잠금을 기다리는 액체 데이터베이스 문제를 해결하는 방법은 무엇입니까?
우리는 스프링 부트를 사용하여 Java로 작성되고 OpenShift에 배포된 여러 마이크로 서비스를 지원합니다.일부 마이크로서비스는 데이터베이스와 통신합니다.단일 배포 환경에서 여러 포드에서 단일 마이크로 서비스를 실행하는 경우가 많습니다.각 마이크로서비스가 시작되면 데이터베이스 업데이트를 시도하는 liquibase가 시작됩니다.문제는 변경 로그 잠금을 기다리는 동안 포드 하나가 실패하는 경우가 있다는 것입니다.프로덕션 OpenShift 클러스터에서 이 문제가 발생하면 변경 로그 잠금 문제와 동일한 문제로 인해 다시 시작하는 동안 다른 포드가 실패할 것으로 예상됩니다.따라서 최악의 경우 모든 포드가 잠금이 해제될 때까지 기다립니다.
우리는 각 포드가 시작될 때 자동으로 데이터베이스 스키마를 준비할 수 있도록 액체 기반을 원합니다.
이 논리를 모든 마이크로 서비스에 저장하는 것이 좋습니까?리퀴드베이스 변경 로그 잠금 문제가 발생했을 때 어떻게 자동으로 문제를 해결할 수 있습니까?데이터베이스 준비 로직을 별도의 배포 환경에 배치해야 합니까?
그래서 제 질문을 다른 말로 표현해야 할 것 같습니다.마이크로서비스 아키텍처 측면에서 DB 마이그레이션을 실행하는 가장 좋은 방법은 무엇입니까?각 포드에서 db 마이그레이션을 사용하면 안 될까요?별도의 배포를 사용하거나 OpenShift에 전혀 포함되지 않은 Jenkins의 추가 작업을 사용하는 것이 더 나을 수도 있습니다.
쿠베르네테스에서 초기 컨테이너로 액체 기반 이동을 진행하고 있습니다.마이크로 서비스에서 Liquibase를 실행할 때의 문제는 구성된 시간 초과 전에 준비 시도가 성공하지 못하면 Kubernetes가 포드를 종료한다는 것입니다.이 경우 대규모 DB 마이그레이션 중에 이러한 현상이 발생할 수 있으며 완료하는 데 몇 분이 걸릴 수 있습니다.Kubernetes가 포드를 종료하고 DATABASE CHANGE LOGLOCK을 잠금 상태로 둡니다.init-containers를 사용하면 이 문제가 발생하지 않습니다.자세한 설명은 https://www.liquibase.org/blog/using-liquibase-in-kubernetes 을 참조하십시오.
업데이트 데이터베이스 잠금을 사용하여 StandardLock 서비스를 대체하는 이 Liquibase 확장을 살펴보십시오. https://github.com/blagerweij/liquibase-sessionlock
이 확장은 MySQL 또는 Postgres 사용자 잠금 문을 사용하며, 이는 데이터베이스 연결이 닫힐 때(예: 컨테이너가 예기치 않게 중지될 때) 자동으로 해제됩니다.확장을 사용하려면 라이브러리에 종속성을 추가해야 합니다.Liquibase는 향상된 잠금 서비스를 자동으로 감지합니다.
저는 도서관의 저자는 아니지만, 해결책을 찾다가 우연히 도서관을 발견했습니다.나는 메이븐 센트럴에 도서관을 개방하여 작가를 도왔습니다.현재 MySQL 및 Postgre 지원SQL. 그러나 다른 RDBMS를 지원하기에는 상당히 쉬울 것입니다.
Spring-boot app 배포 중에 Liquibase가 시작되면 (매우 높은 수준에서) 다음 단계를 수행합니다.
- (금이작성드터코레▁in▁a▁record)(작성▁lock잠▁()에 기록 작성)
databasechangeloglock
) - changeLogs를 실행합니다.
- 데이터베이스 잠금 제거;
따라서 Liquibase가 1단계와 3단계 사이에 있는 동안 애플리케이션 배포를 중단하면 데이터베이스가 잠긴 상태로 유지됩니다.따라서 앱을 다시 배포하려고 할 때 Liquibase는 데이터베이스를 잠긴 것으로 처리하기 때문에 실패합니다.
따라서 앱을 다시 배포하기 전에 데이터베이스의 잠금을 해제해야 합니다.
다음 두 가지 옵션을 알고 있습니다.
databasechangeloglock
테이블 또는 세트locked
false
.어느 것이DELETE FROM databasechangeloglock
또는UPDATE databasechangeloglock SET locked=0
- 실행합니다.
liquibase releaseLocks
지휘권여기와 여기에서 이에 대한 설명서를 찾을 수 있습니다.
우리 회사에서는 Liquibase가 Init Containers에서 제안한 것과 동일한 접근 방식을 사용하여 이 문제를 해결할 수 있었지만, 새로운 컨테이너를 사용하고 Liquibase CLI를 통해 Liquibase 마이그레이션을 실행하는 대신 기존 Spring Boot 서비스 설정을 재사용하고 있지만 Liquibase 로직만 실행하고 있습니다.Liquibase를 사용하여 데이터베이스를 채우기 위해 진입점에서 사용할 수 있는 대체 메인 클래스를 만들었습니다.
InitContainerApplication 클래스는 응용 프로그램을 시작하고 Liquibase를 설정하는 데 필요한 최소 구성을 가져옵니다.
일반적인 용도:
entrypoint: "java -cp /app/extras/*:/app/WEB-INF/classes:/app/WEB-INF/lib/* com.backbase.buildingblocks.auxiliaryconfig.InitContainerApplication"
여기 수업이 있습니다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.context.ApplicationContext;
@SpringBootConfiguration
@ImportAutoConfiguration(InitContainerAutoConfigurationSelector.class)
public class InitContainerApplication implements ApplicationRunner {
@Autowired
private ApplicationContext appContext;
public static void main(String[] args) {
SpringApplication.run(InitContainerApplication.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
SpringApplication.exit(appContext, () -> 0);
}
}
Init 컨테이너로 사용하는 방법은 다음과 같습니다.
spec:
initContainers:
- name: init-liquibase
command: ['java']
args: ['-cp', '/app/extras/*:/app/WEB-INF/classes:/app/WEB-INF/lib/*',
'com.backbase.buildingblocks.auxiliaryconfig.InitContainerApplication']
마지막으로 마이크로서비스 시작 시 리퀴브베이스 마이그레이션을 제거하여 다른 프로젝트에서 이 문제를 해결했습니다.이제 별도의 Jenkins 작업이 마이그레이션을 적용하고 별도의 Jenkins 작업 배포 및 마이그레이션이 적용된 후 마이크로서비스를 시작합니다.이제 마이크로서비스 자체가 데이터베이스 업데이트를 적용하지 않습니다.
제가 관리하는 Java 애플리케이션 중 하나가 갑자기 종료되었을 때 이 문제가 발생했습니다.
응용 프로그램을 시작하려고 할 때 로그에 아래 오류가 표시되었습니다.
Changelock 획득 대기
제가 해결한 방법은 다음과 같습니다.
다음을 통해 이 문제를 해결했습니다.
- 응용 프로그램 중지
- 삭제
databasechangelog
그리고.databasechangelog.lock
응용프로그램에 연결된 데이터베이스의 파일. - 응용 프로그램 다시 시작
저의 경우에는 애플리케이션이 2개의 데이터베이스에 연결되어 있었습니다.나는 삭제해야 했습니다.databasechangelog
그리고.databasechangelog.lock
파일을 저장한 후 응용프로그램을 다시 시작합니다.두 데이터베이스 모두databasechangelog
그리고.databasechangelog.lock
파일이 동기화되어야 합니다.
이후 애플리케이션은 Changelock 파일을 획득할 수 있었습니다.
언급URL : https://stackoverflow.com/questions/61387510/how-to-solve-liquibase-waiting-for-changelog-lock-problem-in-several-pods-in-ope
'bestsource' 카테고리의 다른 글
스크립트 실행 시 sql 오류가 발생했습니다.리포지토리를 만들기 전에 리포지토리 삭제 시도 (0) | 2023.07.13 |
---|---|
스크립트 모듈 종속성을 로드하는 세 가지 방법의 차이점은 무엇입니까? (0) | 2023.07.13 |
java.sql.날짜를 조다 시간으로 변환 (0) | 2023.07.13 |
테이블 검색과 클러스터형 인덱스 검색의 차이점은 무엇입니까? (0) | 2023.07.13 |
문화 정보를 기반으로 날짜 및 시간 형식을 얻으려면 어떻게 해야 합니까? (0) | 2023.07.13 |