WEB BE Repository 42

[코틀린 코루틴] 플로우

플로우는 코루틴을 기반으로 한 리액티브 스트림이다. 플로우를 사용하면 시간이 지남에 따라 나타나는 여러 값을 다루는 상황에서 코루틴의 동시성 매커니즘을 활용할 수 있다. 플로우의 여러 유형과 이를 생성/변환/소비하는 방법을 알아보자.목차플로우란 무엇인가?콜드 플로우핫 플로우플로우란 무엇인가?일시 중단 함수는 스트림 형태의 데이터에는 취약하다.다음 코드를 실행해보자.private var zeroTime = System.currentTimeMillis() fun log(message: Any?) = println("[${System.currentTimeMillis() - zeroTime} ms] ${Thread.currentThread().name}: $message") suspend fun create..

[코틀린 코루틴] 구조적 동시성

코루틴 컨텍스트이전 글에서 Dispatcher를 설정할 때, 이부분에 대해 의구심이 생길 수 있다.우린 분명 launch 의 인자로 Dispatcher를 넘겼는데, launch의 파라미터는 context를 받고 있다.이 컨텍스트는 뭐고, 왜 Dispatcher를 넘겨도 동작할까? 사실 우리가 넘긴 디스패처는 기존 코루틴 컨텍스트에 덮어씌워지는 역할을 수행한다. 코루틴 컨텍스트에는 다양한 정보들이 들어있다.코루틴 디스패처코루틴 생명주기Job 객체코루틴 객체 이름코루틴 ExceptionHandler그리고, 다음과 같이 파라미터로 넘긴 Context로 덮어씌우는게 가능하다.실제로 다음과 같이 코루틴 컨텍스트가 바뀐 것을 확인할 수 있다.구조적 동시성지금까지 코루틴 컨텍스트를 왜 알아봤냐 하면, 구조적 동시성을..

[코틀린 코루틴] 코틀린의 동시성 모델 - 코루틴

코틀린은 동시성 모델로 쓰레드 활용이 아닌, 코루틴을 권장한다.코틀린 코루틴 vs 전통적 스레드코틀린에서는 concurrent.thread 함수를 이용하면, 새 스레드를 간편하게 시작할 수 있다.하지만 이는 커널 스레드를 직접 만드는 형태이기 때문에 비용이 많이 든다.스레드는 계층 개념이 없기 때문에, 계층적 관리를 하기 까다롭다.스레드는 어떤 작업이 완료되길 기다리는 동안에는 블록된다.최신 시스템이라도 한번에 몇 천개의 스레드만 효과적으로 관리할 수 있다.기본적으로 스레드는 굉장히 무거운 자원이다.요청 1개를 처리하는 동안 스레드 1개를 할당하는 구조에서,DB 호출/외부 HTTP/파일 I/O 등으로 스레드가 블로킹되면 그 스레드는 그 시간 동안 유용한 일을 못 하면서도 계속 점유된다.동시 요청이 늘면 ..

Kotlin 문법 - Java와의 차이점

코틀린을 사용하면서, 자바랑 확연히 달라 적응하기 어려웠던 부분들을 기록해둔다.read-only vs mutable 관리read-only vs mutable: 객체 내부 프로퍼티 접근제어코틀린에서 val/var 차이와, 프로퍼티의 getter/setter를 정의하는 방식(특히 private set)을 정리한다.1. val vs varval: 재할당 불가(읽기 전용 참조). 프로퍼티 관점에서는 setter가 없음.var: 재할당 가능. 프로퍼티 관점에서는 getter + setter가 있음.val a = 10// a = 20 // 컴파일 에러var b = 10b = 20 // 가능2. 기본 getter/setter코틀린 프로퍼티는 기본적으로 접근자(accessor)가 자동 생성된다.class User { ..

[번역] Python의 ORM - SQLAlchemy 튜토리얼

ORM 빠른 시작기본 ORM 사용 형태를 빠르게 보고 싶은 신규 사용자를 위해, SQLAlchemy Unified Tutorial에서 사용하는 매핑과 예제를 축약해 보여준다. 이 섹션의 설명은 의도적으로 매우 짧게 작성되어 있으므로, 여기서 다루는 각 개념에 대한 더 자세한 설명은 SQLAlchemy Unified Tutorial을 참고하는 것이 권장된다.목차모델 선언테이블 생성영속화(Create)조회(Read) - 단순 조회 & 조인수정(Update) - 변경 사항 반영삭제(Delete)모델 선언(Declare Models)여기서는 데이터베이스에서 조회할 구조를 구성하는 모듈 수준 구성 요소를 정의한다.이 구조는 선언적 매핑(Declarative Mapping) 이라고 하며, 파이썬 객체 모델과 함께,..

[FastAPI] FastAPI 기본 컨트롤러 사용 방법

슬슬 Pinit에 "일정 쪼개기" 기능을 붙이고 싶어져, FastAPI로 간단하게 WAS를 구성해보려고 한다.처음엔 DB 접근 + 사용자 요청 받기는 Java+Spring으로 하고, AI 모델부만 gRPC + LangGraph로 수행할까 했는데,요새 LangGraph 관련 도구를 사용하는 기업들이 FastAPI 계열을 사용하기도 하고,자바+스프링 생태계에서 벗어나 새로운 구성과 아키텍처를 경험해보고 싶어서 FastAPI를 선택하게 되었다. 이 글이 WEB BE Repository가 아닌 Article 탭에 들어가게 된 이유는, 단순 FastAPI 기초 지식의 나열이 아닌 "Java+Spring 백엔드 개발자 관점에서의 FastAPI + SQLAlchemy + LangGraph의 이해" 관점으로 접근할 예..

Spring Data JPA - Auditing

소개우리 서비스가 엔티티를 생성/변경할 때, 아래와 같은 변경한 사람과 시간을 추적하고 싶으면 어떤 방법을 이용해야 할까?등록일수정일등록자수정자이를 애플리케이션 서비스 레이어에서 직접 저장할 수 있겠지만, 지정한 필드가 특정 시점에 값을 저장하도록 자동으로 설정하고 싶을 수 있다.보통은 이런 로깅 작업은 도메인(비즈니스) 로직이라기 보단, 인프라를 위한 로직에 가깝다. 이때 스프링 Data JPA는 메소드를 만들어서, 특정 시점에 해당 필드에 값을 자동으로 대입하는 작업을 지원한다. 이와 같이 변경/수정 이력을 감사한 로그를 Audit Log라 하고,이와 같은 감사 로그를 데이터를 자동으로 넣어주는 것을 Auditing이라고 한다.Auditing 적용그럼 이제 Spring Data JPA에서 지원하는 A..

Java - classpath

우리가 특정 데이터를 JVM에 올리고 싶을 때, 이를 안정적으로 업로드할 "마법"이 필요해진다.이 예로는 공개 키 파일과 같은 것들이 있다.만약 키를 평범한 상대경로/절대경로로 가져오고 있다면, 이는 현재 환경에 종속적인 빌드 결과가 된다.(참고로 비밀 키와 같은 secret값들은 엄격한 운영 상황에서는 배포의 범위가 빌드 수준까지 넓어져 클래스패스에 올리지 않는다.)이때, 클래스패스라는 용어를 곧잘 접하게 된다. 클래스패스는 자바의 JVM 이 클래스를 로드할 때 사용하는 클래스로더와도 곧잘 얽히는데, 지금부터 이 클래스패스에 대해 빠르게 알아보자.1. 클래스패스란 무엇인가간단히 말하면JVM이나 컴파일러가 .class 파일과 리소스(예: .properties, .json, .xml)를 찾기 위해 검색하는..

[RabbitMQ] Rabbit MQ의 이름 짓기

개발자에게 가장 중요한 역량은 "이름 짓기"이다. 이름을 잘 지어둬야 나중에 읽을 때 빠르고 헷갈리지 않게 읽을 수 있기 때문인데, RabbitMQ 사용 시에는 이름을 지어야 할 부분이 세 군데나 있다. 생산자 선언ExchangeRouting Key소비자 선언QueueBinding key (routing key에 의존적)나는 딱히 이름 짓기에 재능이 없어서 매번 AI에게 도움을 많이 받는데, 적어도 이름을 짓는데 어느정도 규칙이 있어야 나중에 읽을 때 무리가 없기 때문에, 각각의 수행하는 역할과 책임에 집중해서 이름을 짓는 규칙을 정해본다.과거 scheduleMemberNestedDtoMap 이라는 해괴한 이름을 짓고 팀원에게 쓴소리를 들은적도 있었다... 기본적으로 위 세 요소는 각각 다음과 같은 역할..

DB 설계와 쿼리 최적화

주의: 본 내용은 DB 내용에 대한 기초 지식이 어느정도 있음(DB 스캔의 작동 방식)을 가정하고 작성되었습니다.DB는 백엔드에서 가장 중요한 역할을 수행한다.DB 성능은 연동하는 모든 서버 성능에 영향을 주기 때문에, DB에 존재하는 기능을 전문가 수준으로 깊이 이해할 수 있다면 이상적이겠지만 조금만 신경 써도 DB 성능 문제를 충분히 줄이거나 없앨 수 있다.인덱스 설계예상하지 못한 테이블 풀 스캔은 DB 성능에 좋지 않은 영향을 끼친다.이를 피하기 위해서 보통 인덱스를 사용하는데, 이때 인덱스를 제대로 알고 써야 원하는 성능 효율을 얻을 수 있다.인덱스는 조회 패턴을 기준으로 설계해라.단일 인덱스 vs 복합 인덱스의 차이를 고려해라선택도(Selectivity)를 고려해라가능하다면, 커버링 인덱스를 활..