손상 방지 레이어 패턴 - AWS 규범적 지침

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

손상 방지 레이어 패턴

Intent

손상 방지 계층 (ACL) 패턴은 도메인 모델 시맨틱스를 한 시스템에서 다른 시스템으로 변환하는 중재 계층 역할을 합니다. 업스트림 팀이 설정한 통신 계약을 사용하기 전에 업스트림 경계 컨텍스트 (모노리스) 모델을 다운스트림 경계 컨텍스트 (마이크로서비스) 에 적합한 모델로 변환합니다. 이 패턴은 다운스트림 바운드 컨텍스트에 핵심 하위 도메인이 포함되어 있거나 업스트림 모델이 수정할 수 없는 레거시 시스템인 경우에 적용할 수 있습니다. 또한 통화를 대상 시스템으로 투명하게 리디렉션해야 할 때 발신자가 변경되지 않도록 하여 변환 위험과 비즈니스 중단을 줄여줍니다.

동기부여

마이그레이션 프로세스 중에 모놀리식 애플리케이션을 마이크로서비스로 마이그레이션할 때 새로 마이그레이션된 서비스의 도메인 모델 시맨틱이 변경될 수 있습니다. 이러한 마이크로서비스를 호출하기 위해 모놀리스 내의 기능이 필요한 경우 호출 서비스를 변경할 필요 없이 통화를 마이그레이션된 서비스로 라우팅해야 합니다. ACL 패턴을 사용하면 모노리스가 호출을 새로운 시맨틱으로 변환하는 어댑터 또는 파사드 레이어 역할을 하여 마이크로서비스를 투명하게 호출할 수 있습니다.

적용 가능성

다음과 같은 경우 이 패턴을 사용하는 것이 좋습니다.

  • 기존 모놀리식 애플리케이션은 마이크로서비스로 마이그레이션된 함수와 통신해야 하며, 마이그레이션된 서비스 도메인 모델 및 의미는 원래 기능과 다릅니다.

  • 두 시스템은 의미 체계가 다르고 데이터를 교환해야 하지만 한 시스템이 다른 시스템과 호환되도록 수정하는 것은 실용적이지 않습니다.

  • 빠르고 단순화된 접근 방식을 사용하여 영향을 최소화하면서 한 시스템을 다른 시스템에 맞게 조정해야 합니다.

  • 애플리케이션이 외부 시스템과 통신하고 있습니다.

문제 및 고려 사항

  • 팀 종속성:시스템의 여러 서비스를 여러 팀이 소유하는 경우 마이그레이션된 서비스의 새로운 도메인 모델 시맨틱으로 인해 호출 시스템이 변경될 수 있습니다. 하지만 팀마다 다른 우선순위가 있을 수 있기 때문에 조정된 방식으로 이러한 변경을 수행하지 못할 수도 있습니다. ACL은 수신자를 분리하고 호출을 새 서비스의 의미와 일치하도록 변환하므로 호출자가 현재 시스템을 변경할 필요가 없습니다.

  • 운영 오버헤드:ACL 패턴은 운영 및 유지 관리에 추가적인 노력이 필요합니다. 이 작업에는 ACL을 모니터링 및 알림 도구, 릴리스 프로세스, 지속적 통합 및 지속적 전달 (CI/CD) 프로세스와 통합하는 작업이 포함됩니다.

  • 단일 장애 지점:ACL에 장애가 발생하면 대상 서비스에 연결할 수 없게 되어 애플리케이션 문제가 발생할 수 있습니다. 이 문제를 완화하려면 재시도 기능과 회로 차단기를 내장해야 합니다. 더 보기백오프로 재시도회로 차단기패턴을 통해 이러한 옵션에 대해 자세히 알아볼 수 있습니다. 적절한 경고 및 로깅을 설정하면 평균 해결 시간 (MTTR) 이 개선됩니다.

  • 기술 부채:마이그레이션 또는 현대화 전략의 일환으로 ACL이 임시 솔루션인지 임시 솔루션인지 아니면 장기 솔루션인지 고려하십시오. 임시 솔루션인 경우 ACL을 기술적 문제로 기록하고 모든 종속 발신자가 마이그레이션된 후에 ACL을 사용 중지해야 합니다.

  • 지연 시간:추가 계층으로 인해 한 인터페이스에서 다른 인터페이스로 요청이 변환되어 지연 시간이 발생할 수 있습니다. ACL을 프로덕션 환경에 배포하기 전에 응답 시간에 민감한 애플리케이션의 성능 허용 오차를 정의하고 테스트하는 것이 좋습니다.

  • 스케일링 병목 현상:서비스를 최대 부하까지 확장할 수 있는 고부하 애플리케이션에서는 ACL이 병목 현상이 발생하여 확장 문제가 발생할 수 있습니다. 대상 서비스가 필요에 따라 확장되는 경우 그에 따라 확장되도록 ACL을 설계해야 합니다.

  • 서비스별 또는 공유 구현:ACL을 공유 객체로 설계하여 호출을 여러 서비스 또는 서비스별 클래스로 변환하고 리디렉션할 수 있습니다. ACL의 구현 유형을 결정할 때 지연 시간, 규모 조정 및 장애 허용 범위를 고려하십시오.

구현

모놀리식 애플리케이션 내에서 ACL을 마이그레이션되는 서비스 전용 클래스로 구현하거나 독립 서비스로 구현할 수 있습니다. 모든 종속 서비스를 마이크로서비스 아키텍처로 마이그레이션한 후에는 ACL을 해제해야 합니다.

고수준 아키텍처

다음 예제 아키텍처에서 모놀리식 애플리케이션에는 사용자 서비스, 카트 서비스, 계정 서비스라는 세 가지 서비스가 있습니다. 카트 서비스는 사용자 서비스에 종속되며 애플리케이션은 모놀리식 관계형 데이터베이스를 사용합니다.

세 가지 서비스가 포함된 모놀리식 애플리케이션

다음 아키텍처에서는 사용자 서비스가 새 마이크로서비스로 마이그레이션되었습니다. 카트 서비스는 사용자 서비스를 호출하지만 모놀리스 내에서는 더 이상 구현을 사용할 수 없습니다.  또한 새로 마이그레이션된 서비스의 인터페이스가 모놀리식 애플리케이션 내에 있었을 때의 이전 인터페이스와 일치하지 않을 수도 있습니다.

하나의 서비스가 마이크로서비스로 이전되는 모놀리식 애플리케이션입니다.

카트 서비스가 새로 마이그레이션된 사용자 서비스를 직접 호출해야 하는 경우 카트 서비스를 변경하고 모놀리식 애플리케이션을 철저히 테스트해야 합니다. 이로 인해 혁신 위험과 비즈니스 중단이 증가할 수 있습니다. 목표는 모놀리식 애플리케이션의 기존 기능에 대한 변경을 최소화하는 것이어야 합니다.

이 경우 이전 사용자 서비스와 새로 마이그레이션된 사용자 서비스 간에 ACL을 도입하는 것이 좋습니다. ACL은 통화를 최신 인터페이스로 변환하는 어댑터 또는 파사드 역할을 합니다. ACL은 모놀리식 애플리케이션 내에서 클래스로 구현될 수 있습니다 (예:UserServiceFacade또는UserServiceAdapter) 이는 마이그레이션된 서비스에만 해당됩니다. 모든 종속 서비스를 마이크로서비스 아키텍처로 마이그레이션한 후에는 부패 방지 계층을 해제해야 합니다.

손상 방지 레이어 추가

를 사용한 구현AWS서비스

다음 다이어그램은 를 사용하여 이 ACL 예제를 구현하는 방법을 보여줍니다.AWS서비스.

다음을 사용하여 ACL 패턴 구현AWS서비스.

사용자 마이크로서비스는 ASP.NET 모놀리식 애플리케이션에서 마이그레이션되어 다음과 같이 배포됩니다.AWS LambdaAWS에서 작동합니다. Lambda 함수에 대한 호출은 다음을 통해 라우팅됩니다.아마존 API 게이트웨이. ACL은 모놀리스에 배포되어 호출을 변환하여 사용자 마이크로서비스의 의미에 맞게 조정됩니다.

언제Program.cs사용자 서비스를 호출합니다 (UserInMonolith.cs) 모노리스 내부에서 통화가 ACL로 라우팅됩니다 (UserServiceACL.cs). ACL은 호출을 새로운 시맨틱 및 인터페이스로 변환하고 API Gateway 엔드포인트를 통해 마이크로서비스를 호출합니다. 발신자 (Program.cs) 는 사용자 서비스 및 ACL에서 이루어지는 변환 및 라우팅을 인식하지 못합니다. 발신자가 코드 변경을 인식하지 못하기 때문에 비즈니스 중단이 줄어들고 혁신 위험이 줄어듭니다.

샘플 코드

다음 코드 스니펫은 원래 서비스에 대한 변경 사항과 구현을 제공합니다.UserServiceACL.cs. 요청이 수신되면 원래 사용자 서비스가 ACL을 호출합니다. ACL은 소스 객체를 새로 마이그레이션된 서비스의 인터페이스와 일치하도록 변환하고, 서비스를 호출하고, 호출자에게 응답을 반환합니다.

public class UserInMonolith: IUserInMonolith { private readonly IACL _userServiceACL; public UserInMonolith(IACL userServiceACL) => (_userServiceACL) = (userServiceACL); public async Task<HttpStatusCode> UpdateAddress(UserDetails userDetails) { //Wrap the original object in the derived class var destUserDetails = new UserDetailsWrapped("user", userDetails); //Logic for updating address has been moved to a microservice return await _userServiceACL.CallMicroservice(destUserDetails); } } public class UserServiceACL: IACL { static HttpClient _client = new HttpClient(); private static string _apiGatewayDev = string.Empty; public UserServiceACL() { IConfiguration config = new ConfigurationBuilder().AddJsonFile(AppContext.BaseDirectory + "../../../config.json").Build(); _apiGatewayDev = config["APIGatewayURL:Dev"]; _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); } public async Task<HttpStatusCode> CallMicroservice(ISourceObject details) { _apiGatewayDev += "/" + details.ServiceName; Console.WriteLine(_apiGatewayDev); var userDetails = details as UserDetails; var userMicroserviceModel = new UserMicroserviceModel(); userMicroserviceModel.UserId = userDetails.UserId; userMicroserviceModel.Address = userDetails.AddressLine1 + ", " + userDetails.AddressLine2; userMicroserviceModel.City = userDetails.City; userMicroserviceModel.State = userDetails.State; userMicroserviceModel.Country = userDetails.Country; if (Int32.TryParse(userDetails.ZipCode, out int zipCode)) { userMicroserviceModel.ZipCode = zipCode; Console.WriteLine("Updated zip code"); } else { Console.WriteLine("String could not be parsed."); return HttpStatusCode.BadRequest; } var jsonString = JsonSerializer.Serialize<UserMicroserviceModel>(userMicroserviceModel); var payload = JsonSerializer.Serialize(userMicroserviceModel); var content = new StringContent(payload, Encoding.UTF8, "application/json"); var response = await _client.PostAsync(_apiGatewayDev, content); return response.StatusCode; } }

GitHub저장소

이 패턴에 대한 샘플 아키텍처의 전체 구현은 다음을 참조하십시오.GitHub리포지토리 주소https://github.com/aws-samples/anti-corruption-layer-pattern.

관련 콘텐츠