포스트

2023-02-13-TIL

2023-02-13-TIL

Today I Learned

JPA ID Long vs Integer

JPA 엔티티의 ID 타입으로 Long을 쓸지 Integer를 쓸지에 대한 질문이다. JLS에 따르면 자바의 int는 -2147483648부터 2147483647까지, long은 -9223372036854775808부터 9223372036854775807까지 표현한다. 자동 증가 키는 삭제된 행의 번호도 다시 쓰지 않으므로 행이 계속 쌓이는 테이블이라면 int 범위는 생각보다 가깝다. 나중에 컬럼과 코드를 함께 바꾸는 비용이 크기 때문에 처음부터 Long을 쓰는 것이 일반적이다. primitive 대신 래퍼 타입을 쓰는 이유는 아직 저장되지 않은 엔티티의 ID를 null로 표현할 수 있어서다.

  • https://docs.oracle.com/cd/E19253-01/817-6223/chp-typeopexpr-2/index.html
  • https://stackoverflow.com/questions/17398192/long-versus-integer-for-the-id-field-of-java-entities
  • https://foxlime.tistory.com/115
  • https://www.inflearn.com/questions/35759/long-%ED%83%80%EC%9E%85%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4
  • https://coderanch.com/t/695720/databases/int-Integer-JPA-entity-Id

Long Type in 64-bit

팀원이 JPA의 Long 타입에 관한 질문을 했다. Long 타입과 Integer 타입이 64비트 환경에서 성능 차이가 있나요? 우선, 래퍼클래스는 참조값만 가지므로 32비트나 64비트나 이 둘 간의 차이는 없을 것이다. 다만, 프리미티브 타입인 int와 long타입은 성능 차이가 어느정도 있을지도 모르겠다. 그렇다고 해도 실제 성능 차이는 거의 없다고 설명되어 있다.

C/C++에서는 long의 크기가 플랫폼의 데이터 모델에 따라 달라진다. IBM 문서의 표처럼 ILP32 환경에서는 int, long, 포인터가 모두 32비트지만, LP64 환경에서는 int만 32비트이고 long과 포인터는 64비트다. 자바는 이와 달리 JLS가 int를 32비트, long을 64비트로 고정해 두었으므로 JVM이 32비트든 64비트든 타입 크기는 같다. 64비트 CPU는 64비트 정수 연산을 한 번에 처리하므로 연산 속도보다는 메모리 사용량(필드와 배열이 차지하는 크기)이 실제 차이로 남는다.

  • https://stackoverflow.com/questions/17398192/long-versus-integer-for-the-id-field-of-java-entities
  • https://joyful-class-maker.tistory.com/119
  • https://stackoverflow.com/questions/39779880/c-int-vs-long-long-in-64-bit-machine
  • https://www.ibm.com/docs/en/zos/2.4.0?topic=environments-ilp32-lp64-data-models-data-type-sizes
  • https://softwareengineering.stackexchange.com/questions/411128/is-using-64-bit-integers-long-long-faster-than-less-bits-ones

Hexagonal Architecture

애플리케이션 코어가 포트(인터페이스)를 정의하고, 웹, DB, 메시징 같은 바깥 기술은 어댑터로 그 포트에 연결하는 구조다. 의존성이 항상 바깥에서 안쪽(도메인)으로 향하게 하는 것이 핵심이다. 강연 영상들은 주로 레이어드 아키텍처에서 이 구조로 옮길 때 패키지를 어떻게 나누는지를 다룬다.

  • https://www.youtube.com/watch?v=Bo8jrZxMAgE
  • https://www.youtube.com/watch?v=MKfSLrwLex8
  • https://www.youtube.com/watch?v=Sfia0T1jt5s
  • https://www.youtube.com/watch?v=L2Wnq0ChAIA&list=PLsUM2ScMfp-r5NOg_bnQurMdd0tv2M5oT
  • https://www.youtube.com/watch?v=wYWh5rg88UE&t=3400s
  • https://www.youtube.com/watch?v=g6Tg6_qpIVc
  • https://www.youtube.com/watch?v=JubdZIdLQ4M
  • https://www.youtube.com/watch?v=7HxwHWUq3zk
  • https://www.youtube.com/watch?v=JugIkibl7xg

Multi Module in Monolithic

하나의 애플리케이션 저장소 안에서 도메인, 인프라, API 같은 모듈을 나누고 Gradle 의존성으로 방향을 강제하는 구조다. 공통 모듈에 모든 것을 몰아넣지 않는 것이 관건이다.

  • https://www.youtube.com/watch?v=ipDzLJK-7Kc
  • https://www.youtube.com/watch?v=nH382BcycHc

Event Driven Architecture

AWS 설명으로 이벤트 기반 아키텍처는 이벤트 생산자, 이벤트 라우터, 이벤트 소비자로 구성된다. 생산자가 라우터에 이벤트를 게시하면 라우터가 걸러서 소비자에게 전달하고, 생산자와 소비자는 서로를 모르므로 독립적으로 확장하고 배포할 수 있다. 여기서 이벤트는 장바구니에 상품이 담긴 것 같은 상태 변화를 말한다. Azure 아키텍처 가이드는 전달 방식을 두 가지로 나눈다. 게시-구독은 구독자에게 이벤트를 보내고 저장하지 않으므로 새 구독자는 과거 이벤트를 받지 못한다. 이벤트 스트리밍은 이벤트를 로그에 기록하고, 클라이언트가 스트림의 원하는 위치부터 읽는다.

우아한형제들의 “회원시스템 이벤트기반 아키텍처 구축하기”는 메시지에 담는 의도를 강조한다. 수신 측에 기대하는 일을 담은 메시지는 메시징 시스템을 이용한 비동기 요청일 뿐이고, 결합이 여전히 남는다. “본인인증 해제됨”처럼 도메인에서 일어난 사실 자체를 이벤트로 발행해야 발행자가 구독자의 정책을 몰라도 된다.

  • https://www.youtube.com/watch?v=STKCRSUsyP0
  • https://www.redhat.com/ko/topics/integration/what-is-event-driven-architecture
  • https://aws.amazon.com/ko/event-driven-architecture/
  • https://learn.microsoft.com/ko-kr/azure/architecture/guide/architecture-styles/event-driven
  • https://cloud.google.com/eventarc/docs/event-driven-architectures?hl=ko
  • https://techblog.woowahan.com/7835/
  • https://medium.com/dtevangelist/event-driven-microservice-%EB%9E%80-54b4eaf7cc4a
  • https://www.tibco.com/ko/reference-center/what-is-event-driven-architecture
  • https://velog.io/@limprove89/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B8%B0%EB%B0%98-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%93%B0%EB%A0%88%EB%93%9C
  • https://velog.io/@youngeui_hong/Event-Driven-Architecture
  • https://www.samsungsds.com/kr/insights/msa_architecture_edm.html

Domain Driven Design

Martin Fowler의 정리로 DDD는 도메인의 프로세스와 규칙을 깊이 반영한 도메인 모델을 중심에 두고 개발하는 접근이고, 이름은 Eric Evans의 책에서 왔다. 핵심은 도메인 용어를 코드에 그대로 담는 유비쿼터스 언어(Ubiquitous Language)다. 큰 시스템 전체를 하나의 모델로 통일하는 것은 현실적이지 않으므로, 시스템을 바운디드 컨텍스트(Bounded Context)로 나누고 각 컨텍스트 안에서만 하나의 일관된 모델을 유지한다. 같은 “상품”이라도 컨텍스트마다 다른 모델을 가질 수 있다.

  • https://www.youtube.com/watch?v=4QHvTeeTsj0
  • https://www.youtube.com/watch?v=ZZp9RQEGeqQ
  • https://www.youtube.com/watch?v=H5–9pMmuK4
  • https://www.youtube.com/watch?v=n_9fBLl1gb4

Multi Threading in Java

자바에서 비동기 작업을 조합하는 기본 도구는 CompletableFuture다. supplyAsync, runAsync로 작업을 시작하고 thenApply, thenCompose, thenCombine으로 결과를 이어 붙인다. Javadoc에 따르면 Executor를 명시하지 않은 async 메서드는 ForkJoinPool.commonPool()에서 실행되므로, 블로킹 I/O가 섞인 작업이라면 별도 스레드 풀을 넘겨야 공용 풀이 막히지 않는다.

JEP 425는 가상 스레드(virtual thread)를 JDK 19에 프리뷰 API로 도입했다. 가상 스레드는 CPU에서 계산하는 동안에만 OS 스레드를 점유하므로, 요청당 스레드 하나 방식으로 작성한 코드도 높은 처리량을 낼 수 있다. JEP는 가상 스레드가 싸고 많이 만들 수 있으므로 풀링하지 말고 작업마다 새로 만들라고 권한다.

  • https://www.baeldung.com/java-completablefuture
  • https://pjh3749.tistory.com/280
  • https://reflectoring.io/java-completablefuture/
  • https://medium.com/@knoldus/executors-in-completable-future-4f3ff0f101a7
  • https://stackoverflow.com/questions/52303472/executorservice-vs-completablefuture
  • https://hamait.tistory.com/612
  • https://honbabzone.com/java/java-thread/
  • https://livebook.manning.com/book/java-8-in-action/chapter-7/1
  • https://www.javacodegeeks.com/2015/09/concurrency-best-practices.html
  • https://medium.com/javarevisited/virtual-threads-java-vs-go-92620e0ab556
  • https://stackoverflow.com/questions/69832291/will-project-loom-virtual-threads-improve-the-perfomance-of-parallel-streams
  • https://blogs.oracle.com/javamagazine/post/java-loom-virtual-threads-platform-threads
  • https://www.infoq.com/articles/java-virtual-threads/
  • https://medium.com/@peterlee2068/concurrency-and-parallelism-in-java-f625bc9b0ca4
  • https://www.baeldung.com/java-when-to-use-parallel-stream
  • https://sas-study.tistory.com/461
  • https://girawhale.tistory.com/131

Oracle Java Magazine의 가상 스레드 글 링크는 지금 페이지를 찾을 수 없다.


Apache POI vs …

xlsx 파일을 만드는 대표 라이브러리는 Apache POI지만, 시트가 커지면 메모리를 많이 쓴다. dhatim/fastexcel은 필요한 요소만 쌓았다가 XML을 출력 스트림으로 흘려보내는 방식으로 메모리 사용을 줄인 대안이다. 프로젝트 README는 자체 벤치마크에서 비스트리밍 POI보다 훨씬 빠르고 힙을 적게 쓰며, POI의 스트리밍 API와는 성능이 비슷하다고 밝힌다. 대신 기능이 POI보다 적으므로 서식이 복잡하지 않은 대용량 내보내기에 맞는다.

  • https://automationqahub.com/top-2-alternatives-to-apache-poi-library-that-can-actually-make-your-life-better/
  • https://www.libhunt.com/compare-fastexcel-vs-poi
  • https://github.com/dhatim/fastexcel

Datadog with Spring

Datadog APM으로 스프링 애플리케이션을 추적하려면 dd-java-agent.jar를 -javaagent JVM 인자로 붙여 실행한다. Datadog 문서의 예시처럼 -Ddd.service, -Ddd.env, -Ddd.version으로 서비스 이름과 환경, 버전을 지정하고, dd.logs.injection을 켜면 트레이스 ID와 스팬 ID가 MDC에 자동으로 들어가 로그와 트레이스를 연결할 수 있다. 올리브영 기술블로그 글은 ECS Fargate 환경에서 이를 구성하는 과정을 다룬다.

  • https://oliveyoung.tech/blog/2022-06-22/How-to-Set-up-Build-ECS-Fargate-And-Datadog/
  • https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/java?tab=containers
  • https://cookiethecat2020.blogspot.com/2021/02/saas-datadog.html
참고한 자료외부 출처 9

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다