2023-01-17-TIL
2023-01-17-TIL
Today I Learned
배치 작업을 어떤 도구로 관리할지 후보들을 비교하고, 시계열 데이터, 모듈 구조, 시크릿 관리, API 문서화 도구, 다국어 지원을 정리했다.
Spring Security
Spring Security는 서블릿 필터 체인으로 동작한다. 요청은 DelegatingFilterProxy를 거쳐 FilterChainProxy로 들어가고, 여기에 등록된 보안 필터들(인증 필터, 예외 변환 필터, 인가 필터 등)을 순서대로 통과한다. 인증에 성공하면 Authentication 객체가 SecurityContextHolder에 저장되고, 이후 인가 단계와 컨트롤러에서 이 정보를 꺼내 쓴다.
- https://kimchanjung.github.io/programming/2020/07/02/spring-security-02/
- https://mangkyu.tistory.com/77
AWS Lambda vs Batch
팀원 중 한 명이 모든 배치 작업들을 관리하는데에 있어서 궁극적으로는 AWS 람다의 기능을 이용하여 관리하는 것이 가장 효율적이라고 의견을 제시했다.
Lambda로 배치를 돌릴 때 가장 먼저 확인할 제약은 실행 시간이다. AWS 문서에 따르면 Lambda 함수의 타임아웃은 기본 3초이고 최대 900초(15분)까지만 늘릴 수 있다. 그래서 짧은 작업을 이벤트나 스케줄로 실행하는 데는 적합하지만, 오래 걸리는 대량 처리는 AWS Batch나 컨테이너 기반 작업으로 넘기는 것이 일반적이다. AWS의 Step Functions 샘플 프로젝트도 Lambda로 간단한 전처리를 하고 실제 처리는 AWS Batch 작업으로 넘긴 뒤, 결과에 따라 다음 작업을 이어 붙이는 구성을 보여 준다.
- https://stackoverflow.com/questions/54232183/is-aws-lambda-the-proper-way-of-running-a-batch-job
- https://docs.aws.amazon.com/step-functions/latest/dg/sample-batch-lambda.html
Batch Admin Tools
- Spring Batch
- Spring Batch + Jenkins
- Jenkins
- Airflow
- AWS Batch
- Crontab with Golang
후보는 크게 두 층으로 나뉜다. Spring Batch나 Go 프로그램은 “배치 로직을 어떻게 작성하느냐”를, Jenkins, Airflow, crontab은 “언제 어떤 순서로 실행하고 결과를 어떻게 볼 것이냐”를 담당한다. AWS Batch는 실행 인프라를 관리해 주는 완전관리형 배치 컴퓨팅 서비스다. 그래서 실제 조합은 “작성 도구 + 실행·관리 도구” 형태가 된다.
- https://stackshare.io/stackups/gin-gonic-vs-spring-batch
- https://giuliana-bezerra.medium.com/why-you-should-be-using-spring-batch-for-batch-processing-83f5aafb965f
- https://stackoverflow.com/questions/67150818/aws-batch-vs-spring-batch
- https://aws.amazon.com/ko/batch/
- https://www.saashub.com/best-workflow-automation-software
Spring Batch + Jenkins
Spring Batch는 Job과 Step, ItemReader/ItemProcessor/ItemWriter로 대량 처리를 구조화하고 재시도, 재시작, 병렬 처리 기능을 제공하지만 스케줄러는 아니다. 그래서 링크된 글들처럼 Jenkins로 Job을 실행하는 조합이 자주 쓰인다. Jenkins가 실행 이력, 로그, 실패 알림, 파라미터 입력 UI를 제공하고, 배치 애플리케이션은 jar 실행 한 번으로 Job 하나를 처리하는 구조다.
- https://docs.spring.io/spring-batch/docs/current/reference/html/spring-batch-intro.html
- https://jojoldu.tistory.com/489
- https://bokyung.dev/2021/03/31/jenkins-batch-job/
- https://bkim.tistory.com/23
- https://oingdaddy.tistory.com/38
Spring Batch vs Airflow
스프링 배치가 워크플로우 자동화 부분에서 압도적으로 부족하다.
Airflow는 작업 사이의 의존 관계를 DAG로 정의하고 스케줄링, 재시도, 실행 이력 UI를 제공하는 워크플로 오케스트레이터다. Spring Batch가 하나의 Job 안의 처리를 잘 다루는 도구라면, Airflow는 여러 Job과 외부 시스템을 엮는 상위 계층이라 비교 축이 다르다. 두 도구를 함께 써서 Airflow가 Spring Batch Job을 실행하는 구성도 가능하다.
- https://www.saashub.com/compare-spring-batch-vs-airflow
Jenkins
- https://abbo.tistory.com/314
Batch Processing in Go
Go에는 Spring Batch 같은 표준 배치 프레임워크가 없어서, 고루틴과 채널로 작업을 일정 크기로 묶어 처리하는 패턴을 직접 구현하거나 작은 라이브러리를 쓴다. 바이너리 하나로 배포되고 시작이 빠르다는 점은 crontab이나 컨테이너로 짧게 실행하는 배치에 잘 맞는다.
- https://dzone.com/articles/batch-processing-in-go
- https://pkg.go.dev/github.com/deeptiman/go-batch
- https://medium.com/@herryg91/how-batch-processing-improve-your-service-go-c8215c2c870e
Airflow vs Jenkins
- https://velog.io/@jaylnne/ETL-Airflow-%EC%99%80-Jenkins-%EB%B9%84%EA%B5%90-%EB%AC%B4%EC%97%87%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C
Airflow vs AWS Batch
- https://www.trustradius.com/compare-products/apache-airflow-vs-aws-batch#pricing
Time Series Data (시계열 데이터)
시계열 데이터는 시간 순서대로 쌓이는 측정값이다. 서버 메트릭, 센서 값, 주가처럼 쓰기는 대부분 최신 시각에 추가(append)되고, 조회는 “특정 기간의 집계” 형태가 많다. InfluxDB 같은 시계열 DB는 이 패턴에 맞춰 시간 기준 파티셔닝과 압축, 다운샘플링, 보존 기간 정책을 제공한다. MongoDB도 시계열 컬렉션을 따로 지원한다.
- https://www.tibco.com/ko/reference-center/what-is-time-series-analysis
- https://www.influxdata.com/time-series-database/
- https://mangkyu.tistory.com/188
- https://www.trustradius.com/time-series-databases
- https://www.mongodb.com/basics/time-series-data-management
Java Local Cache
로컬 캐시는 애플리케이션 프로세스 메모리 안에 두는 캐시다. 네트워크 왕복이 없어 빠르지만 인스턴스마다 값이 따로 존재해 서버가 여러 대면 일관성이 깨질 수 있다. 링크한 것은 Oracle Coherence의 LocalCache로, JCache API와 CacheLoader, CacheStore를 지원하는 구현이다. Spring 애플리케이션에서는 보통 Caffeine을 @Cacheable과 함께 쓴다.
- https://docs.oracle.com/middleware/1213/coherence/java-reference/com/tangosol/net/cache/LocalCache.html
Multi Module vs Microservices
멀티 모듈은 하나의 저장소와 빌드 안에서 코드를 모듈로 나누는 것이고, 배포는 여전히 하나일 수도 여러 개일 수도 있다. 마이크로서비스는 독립적으로 배포되고 네트워크로 통신하는 서비스들로 나누는 아키텍처다. 멀티 모듈은 코드 경계를 강제하는 수단이고, MSA는 배포와 운영 단위를 나누는 결정이라 둘은 서로 다른 층위의 선택이다.
- https://stackoverflow.com/questions/60945116/multi-module-maven-vs-micro-service-architecture
Single Module vs Multi Module
단일 모듈은 설정이 단순하고 빌드가 빠르지만, 패키지 경계만으로는 의존 방향을 강제할 수 없다. 멀티 모듈은 모듈 사이 의존을 빌드 설정으로 제한하고 공통 코드를 재사용하기 쉬운 대신, 모듈을 잘못 나누면 공통 모듈에 모든 코드가 몰리는 문제가 생긴다.
- https://stackoverflow.com/questions/24901624/single-module-vs-multi-modules-maven-project
AWS Secret Manager
AWS Secrets Manager는 DB 접속 정보, API 키 같은 비밀 값을 중앙에서 저장하고 관리하는 서비스다. 소개 페이지는 암호화와 중앙 감사, 접근 권한 관리, 비밀 값 자동 교체(rotation), 재해 복구를 위한 복제를 주요 기능으로 든다. 비밀 값을 설정 파일이나 코드에 하드코딩하지 않고 실행 시점에 조회하게 할 수 있다.
- https://aws.amazon.com/ko/secrets-manager/
Swagger vs Spring Rest Docs
Swagger(OpenAPI)는 코드의 애너테이션에서 문서를 만들고 브라우저에서 바로 호출해 볼 수 있는 UI를 제공한다. 대신 문서용 애너테이션이 프로덕션 코드에 섞이고, 문서와 실제 동작이 어긋나도 알 수 없다. Spring REST Docs는 테스트가 만든 스니펫으로 문서를 만들기 때문에 테스트가 통과해야 문서가 생성된다. 링크된 글은 restdocs-api-spec으로 REST Docs 테스트에서 OpenAPI 스펙을 추출해 Swagger UI로 보여 주는 조합을 소개한다.
- https://taetaetae.github.io/posts/a-combination-of-swagger-and-spring-restdocs/
Swagger
Swagger는 OpenAPI 명세를 작성하고 시각화하는 도구 모음이다. Spring Boot에서는 springdoc-openapi 같은 라이브러리가 컨트롤러를 스캔해 OpenAPI 문서를 만들고 Swagger UI를 띄워 준다.
- https://swagger.io/
- https://www.baeldung.com/spring-rest-openapi-documentation
- https://swagger.io/resources/articles/documenting-apis-with-swagger/
Spring Rest Docs
Spring REST Docs 문서에 따르면 목표는 RESTful 서비스에 대한 정확하고 읽기 좋은 문서를 만드는 것이다. 기본으로 Asciidoctor를 쓰고(Markdown도 가능), Spring MVC Test, WebTestClient, REST Assured로 작성한 테스트가 스니펫을 생성한다. 문서는 이 테스트 주도 방식 덕분에 정확성이 보장되며, 스니펫이 틀리면 그 테스트가 실패한다고 설명한다.
- https://techblog.woowahan.com/2597/
- https://huisam.tistory.com/entry/RESTDocs
API Documentation Tools
Swagger UI 외에도 OpenAPI 명세를 정적 문서로 렌더링하는 Redoc(Redocly), 코드 주석에서 문서를 만드는 apiDoc 같은 도구가 있다. 고를 때는 명세를 코드에서 생성할지 먼저 작성할지(code-first, design-first), 호출 테스트 UI가 필요한지, 문서를 어디에 호스팅할지를 기준으로 본다.
- https://blog.hubspot.com/website/api-documentation-tool
- https://velog.io/@city7310/%EB%B0%B1%EC%97%94%EB%93%9C%EA%B0%80-%EC%9D%B4%EC%A0%95%EB%8F%84%EB%8A%94-%ED%95%B4%EC%A4%98%EC%95%BC-%ED%95%A8-6.-API-%EC%8A%A4%ED%8E%99-%EC%84%A4%EA%B3%84%EC%99%80-%EB%AC%B8%EC%84%9C%ED%99%94-%EB%B0%A9%EC%8B%9D-%EA%B2%B0%EC%A0%95-2
- https://learnote-dev.com/java/Spring-A-%EB%AC%B8%EC%84%9C-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0/
- https://redocly.com/
- https://blog.hubspot.com/website/api-documentation-tool
- https://apidocjs.com/
API Documentation Version History
API 문서를 Swagger로 관리하는데에 있어서의 한계점 중 하나는 변경이력이 관리되지 않는다는 것이다. API 규격에 대한 변경이력이 관리되는 도구는 없을까?
가장 단순한 방법은 OpenAPI 명세 파일 자체를 저장소에 커밋해 git 이력으로 관리하는 것이다. 그 위에 swagger-diff 같은 도구를 쓰면 두 버전의 명세를 비교할 수 있다. swagger-diff README는 새 명세가 이전 명세와 하위 호환되는지 판단하는 것을 용도로 밝히고, RSpec 매처를 제공해 CI에서 호환성 검사를 자동화할 수 있다. 호환되지 않는 변경이 불가피하면 URL이나 헤더로 API 버전을 나누는 버저닝 전략을 함께 정해야 한다.
- https://stackoverflow.com/questions/31812241/does-swagger-have-the-ability-to-support-api-change-history-or-is-there-an-open
- https://github.com/civisanalytics/swagger-diff
- https://api-tools.getlaminas.org/documentation/api-primer/versioning
- https://blog.hubspot.com/website/api-versioning
Spring 다국어 지원
Spring은 MessageSource와 LocaleResolver로 다국어를 지원한다. messages_ko.properties, messages_en.properties처럼 로케일별 메시지 파일을 두고, LocaleResolver가 요청의 Accept-Language 헤더나 쿠키, 세션에서 로케일을 결정하면 MessageSource.getMessage()가 그에 맞는 문구를 돌려준다. Spring Boot는 spring.messages.basename 설정으로 메시지 파일 위치를 지정한다.
- https://dkfkslsksh.tistory.com/13
- https://velog.io/@bey1548/Spring%EC%97%90%EC%84%9C-%EB%8B%A4%EA%B5%AD%EC%96%B4-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0
댓글
아직 댓글이 없습니다