저는 다음과 같은 온라인 학습 플랫폼의 열렬한 팬입니다. Udemy. 와인 한 병 가격으로 심리학, 태국 요리부터 프로그래밍 언어, 운영 체제, IT 자격증에 이르기까지 거의 모든 것을 배울 수 있습니다. 최근에 저는 제목이 긴 수업을 듣기로 결정했습니다: "쿠버네티스 실습 - AWS 클라우드에 마이크로서비스 배포". 훌륭한 과정이며 Kubernetes, 마이크로서비스, 클라우드 배포 등의 핵심에 대해 자세히 알고 싶다면 적극 추천합니다.
강의 저자는 Kubernetes에 마이크로서비스를 배포하기 위한 수업 실습 프로젝트로 Fleetman이라는 작은 애플리케이션을 제공했습니다. 이 앱을 사용하면 영국 셰필드라는 대도시를 돌아다니는 트럭(영국식 표현으로는 화물차)을 모니터링할 수 있습니다(한 대의 트럭은 런던의 중심부를 달리고 있지만). 이 앱은 각 트럭에 대한 지리적 위치 데이터를 생성하여 메모리 또는 데이터베이스에 저장하고 위치 데이터를 편리한 지도 기반 웹 UI에 제공합니다. UI에서 각 트럭의 최신 위치, 속도, 현재 이동 경로를 확인할 수 있습니다. 애플리케이션 웹 프런트엔드 스크린샷은 아래와 같습니다.

여러 대의 트럭 위치 보고서
애플리케이션 코드의 내부가 Udemy 강좌의 주된 초점은 아니었지만(어차피 소프트웨어 개발 수업이 아닌 Kubernetes 수업이었기 때문에), 저는 애플리케이션 아키텍처가 상당히 매력적이라는 사실을 알게 되었습니다. 소스 코드 가 일반 대중에게 공개되었습니다. 지속성 데이터베이스 계층으로, 원래 Fleetman 애플리케이션은 트럭에서 오는 간단한 원격 측정 데이터를 JSON 형식으로 저장하고 쿼리하는 데 널리 사용되는 MongoDB를 사용합니다.
그렇다면 Couchbase는 어떨까요? Couchbase 데이터베이스 플랫폼은 N1QL 언어, 분석, 이벤트 및 전체 텍스트 검색과 같은 다양한 기능을 제공합니다. 이러한 기능을 통해 간단한 원격 분석 수집 앱을 더욱 강력하게 만들 수 있습니다. 하지만 애초에 Fleetman 앱이 Mongo 대신 Couchbase를 사용하도록 다시 배선하는 것이 얼마나 어려울까요? 그래서 저는 꽤 오랜 시간을 들여 소스 코드를 살펴보고 Java 프로그래밍 기술을 다시 익혔습니다. Fleetman의 아키텍처를 좀 더 자세히 살펴보는 것부터 시작하겠습니다.
플릿맨 아키텍처
Fleetman 애플리케이션은 다양한 방법과 프로토콜을 사용하여 서로 통신하는 모듈(또는 마이크로서비스)의 집합으로 설계되었습니다. 세 가지 마이크로서비스: 위치 시뮬레이터, 위치 추적기, 게이트웨이 API는 Spring Boot Java 애플리케이션 프레임워크를 사용하여 작성되었습니다. 프런트엔드 모듈은 널리 사용되는 자바스크립트 개발 프레임워크인 Angular로 작성되었습니다. 메시징 시스템과 데이터베이스 계층도 있습니다. 짐작할 수 있듯이, 이러한 각 마이크로서비스는 Kubernetes 배포의 경우 별도의 포드에서 실행됩니다.

플릿맨 아키텍처
- 포지션 시뮬레이터 - 는 위치 좌표가 포함된 구성 파일을 읽어 차량에 있는 40대의 트럭 각각에 대한 차량 원격 분석을 생성합니다. 이러한 위치 보고서는 아래와 같이 JSON 형식으로 메시지 대기열에 기록됩니다.
|
1 |
{시간=2020-06-22T11:35:55.174-0400, 위도=53.4002010, long=-1.4101460, 차량=공장 실행 D} |
- 위치 추적기 - 는 대기열에서 차량 위치를 소비하고 이를 Couchbase에 저장합니다. 또한 새로운 위치 보고서와 이전 위치 보고서를 기반으로 각 트럭의 속도를 계산합니다. 이 마이크로서비스는 특정 트럭의 최신 위치, 모든 트럭의 최신 위치, 트럭의 모든 위치 기록을 가져오는 일련의 메서드를 제공합니다. 이러한 메서드는 REST 인터페이스를 통해 사용할 수 있습니다. K8 포드 중 하나가 재시작되는 경우 기록을 가져오는 것이 유용할 수 있습니다.
- API 게이트웨이 - 는 Angular 프런트엔드를 위한 간단한 게이트웨이입니다. 위치 추적기로부터 최신 차량 위치를 읽어 웹 애플리케이션에 전달합니다.
- 웹 애플리케이션 - 는 지도에서 트럭의 위치를 모니터링하고 특정 트럭 위치로 이동하면서 이동 경로를 표시할 수 있는 Angular 기반 앱입니다. 아래 지도에서 '런던 리버사이드' 트럭의 이동 경로를 확인할 수 있습니다.

"런던 리버사이드" 트럭 여행
Couchbase로의 마이그레이션
마이크로서비스 아키텍처의 모듈식 접근 방식 덕분에 마이그레이션 작업의 대부분은 데이터베이스 계층을 처리하는 위치 추적기 모듈에 집중했습니다. 원래 Fleetman 코드는 몇 년 전에 작성되었기 때문에 모든 Java 마이크로서비스를 최신 버전의 Spring Boot 라이브러리로 다시 컴파일하는 것이 첫 번째 목표였습니다. Spring 프레임워크는 개발자에게 일반 애플리케이션과 웹 애플리케이션을 빠르고 쉽게 설정하고 개발할 수 있는 방법을 제공합니다. Spring Boot는 임베디드 HTTP 서버(Tomcat)와 함께 제공되며 XML을 통한 구성이 필요 없는 Spring 프레임워크의 확장입니다. 한 가지 알아둘 것은 Couchbase가 Spring 통합에 관한 한 일류라는 점입니다. 올해 6월에 최신 버전 4.x의 Couchbase Spring 라이브러리가 출시되었으며 전체 설명서를 사용할 수 있습니다. 여기.
마이그레이션의 일환으로 가장 먼저 구현해야 했던 것 중 하나는 데이터베이스에 문서를 저장하기 위해 코드에 키 생성을 추가하는 것이었습니다. Couchbase의 모든 문서에는 키가 있어야 합니다. Spring Boot는 문서 속성의 조합 또는 UUID 무작위 생성기와 함께 @GeneratedValue 어노테이션을 사용하여 키를 생성합니다. 저는 후자를 사용했습니다. 차량 위치에 대한 엔티티 매핑은 아래와 같습니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public 클래스 차량 위치 구현 비교 가능<VehiclePosition> { @NotNull @Id 생성된 가치(전략 = 유니크) 비공개 문자열 id; @NotNull 필드 비공개 문자열 이름; @NotNull 필드 비공개 BigDecimal 위도; @NotNull 필드 비공개 BigDecimal 경도; @JsonFormat(모양=JsonFormat.모양.문자열, 패턴="yyyy-MM-dd'T'HH:mm:ss.SSSZ", 시간대="UTC") @NotNull 필드 비공개 날짜 타임스탬프; 비공개 BigDecimal 속도; .... } |
또한 호스트 이름, 사용자 이름, 비밀번호 및 좌표에 대한 10진수 값 저장을 처리하기 위해 몇 가지 변환기가 포함된 Couchbase 구성 클래스를 추가해야 했습니다. 기본적으로 Couchbase는 좌표를 배율과 정밀도가 있는 객체로 저장합니다. 이로 인해 애플리케이션에 몇 가지 문제가 발생했습니다.
|
1 2 3 4 5 |
"lat": { "scale": 7, "intCompact": 533783660, "정밀도": 9 }, |
변환기를 사용하여 트럭 위치 데이터를 다음과 같은 형식으로 저장할 수 있었습니다:
|
1 2 3 4 5 6 7 8 |
{ "name": "특급 배송1", "_class": "com.virtualpairprogrammers.tracker.domain.VehiclePosition", "lat": "53.3009490", "속도": "1.333069443260374304264", "경도": "-1.1231240", "timestamp": 1595735263364 } |
카우치베이스 구성 클래스는 다음과 같습니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
public 클래스 커스텀 카우치베이스 구성 확장 추상 카우치베이스 구성 { 오버라이드 보호됨 목록<String> getBootstrapHosts() { 반환 컬렉션.싱글톤 목록("localhost"); } 오버라이드 보호됨 문자열 getBucketName() { 반환 "test"; } 오버라이드 보호됨 문자열 getBucketPassword() { 반환 "couchbase"; } 오버라이드 public 카우치베이스 커스텀 전환 customConversions() { 반환 new 카우치베이스 커스텀 전환(배열.asList(빅디시멀 문자열.인스턴스, 문자열-빅디시멀 변환기.인스턴스)); } @WritingConverter public enum 빅디시멀 문자열 구현 변환기<BigDecimal, 문자열> { 인스턴스; 오버라이드 public 문자열 변환(BigDecimal 출처) { 반환 출처.toString() ; } } 리딩 컨버터 public enum 문자열-빅디시멀 변환기 구현 변환기<문자열, BigDecimal> { 인스턴스; 오버라이드 public BigDecimal 변환(문자열 출처) { 반환 new BigDecimal(출처); } } } |
Couchbase를 구성하기 위해 테스트 버킷을 만들고, 버킷과 이름이 같은 RBAC 사용자를 추가하고, 이 사용자에게 애플리케이션 액세스 권한을 부여했습니다. 또한 이 두 속성이 리포지토리 메서드에서 액세스 패턴으로 사용되므로 이름과 타임스탬프에 대한 인덱스를 추가했습니다. 위치 저장소 인터페이스에는 이름, 타임스탬프 및 두 가지의 조합으로 트럭을 검색하는 세 가지 메서드가 있습니다.
|
1 2 3 4 5 6 7 8 9 |
public 인터페이스 위치 저장소 확장 카우치베이스 페이징 및 정렬 저장소<차량 위치, 문자열> { 트리세트<VehiclePosition> 찾기 이름 및 타임스탬프 후 주문 타임스탬프Asc(문자열 이름, 날짜 타임스탬프); 목록<VehiclePosition> 찾기 이름 주문별 타임스탬프Asc(문자열 이름); 목록<VehiclePosition> 타임스탬프 후 찾기(날짜 이후); } |
요약
전반적으로 Couchbase로의 마이그레이션은 매우 순조롭게 진행되었습니다. 모든 코드를 로컬에서 테스트했지만, Kubernetes용 Couchbase Autonomous Operator를 사용하여 클라우드의 K8에 컨테이너화하여 배포할 수 있습니다. 이러한 예는 다음과 같습니다. 여기. 엔터프라이즈 관점에서 다른 Couchbase 기능을 사용하면 잠재적으로 Fleetman 앱 기능을 확장할 수 있습니다. 예를 들어, N1QL 또는 Analytics 개발자는 특정 기간 동안 이동한 최대 거리를 기준으로 상위 5대의 트럭을 찾는 쿼리를 만들 수 있습니다. 특정 트럭이 제한 속도를 초과할 경우 이벤트 기능을 사용하여 경고를 보낼 수 있습니다. 또 다른 개선의 기회는 카우치베이스 지리공간 쿼리를 사용하는 것입니다. 제가 만든 Fleetman 애플리케이션의 소스 코드는 GitHub에 있습니다. 여기.