목록전체 글 (55)
csct3434

자바에서 네트워크 서버를 구현할 때 사용할 수 있는 두 가지 주요 API가 있다: 전통적인 블로킹 I/O 기반의 ServerSocket과 Java NIO(New I/O)의 ServerSocketChannel. 이 두 클래스는 서버 소켓을 구현하는 다른 패러다임을 제공하며, 각각 고유한 장단점과 사용 사례를 가지고 있다.1. ServerSocket (java.net 패키지)ServerSocket은 자바의 전통적인 네트워킹 API의 일부로, Java 1.0에서 도입되었다. 블로킹 I/O 모델을 기반으로 하며 동기적 접근 방식을 사용한다.주요 특징블로킹 I/O: 클라이언트 연결을 대기하는 accept() 메서드는 클라이언트가 연결할 때까지 현재 스레드를 블로킹한다.스트림 기반: 데이터 전송에 InputStre..
1. Fork Join Framework의 개요Fork Join Framework는 Java 7에서 도입된 병렬 처리 프레임워크로, '분할 정복(divide and conquer)' 알고리즘을 효과적으로 구현할 수 있게 해준다. 이 프레임워크의 핵심 아이디어는 큰 작업을 작은 단위로 재귀적으로 분할(fork)하고, 각각의 결과를 합쳐(join) 최종 결과를 얻는 방식이다.주요 구성 요소ForkJoinPool: 작업 스케줄링과 실행을 관리하는 특수한 ExecutorServiceForkJoinTask: 풀에서 실행되는 기본 태스크 타입 (RecursiveAction, RecursiveTask의 상위 클래스)Work-Stealing 알고리즘: 유휴 스레드가 다른 바쁜 스레드의 작업 큐에서 작업을 '훔쳐와' 처..

Redis를 사용하는 분산 환경에서 동시성 제어는 데이터 일관성을 유지하는 데 매우 중요합니다. 두 가지 주요 접근 방식인 낙관적 락과 분산 락의 차이점과 각각의 사용 사례를 자세히 살펴보겠습니다.1. 개념 및 기본 원리낙관적 락(Optimistic Lock)기본 원리: 충돌이 드물게 발생한다고 가정하고, 실제 업데이트 시점에만 충돌을 검사구현 방식: Redis의 WATCH, MULTI, EXEC 명령어 조합 사용작동 방식: 키를 감시(watch)하고 변경 감지 시 트랜잭션 실패 처리분산 락(Distributed Lock)기본 원리: 자원에 접근하기 전에 명시적으로 락을 획득하고 작업 후 해제구현 방식: Redis의 SET NX PX 또는 Redisson 라이브러리 사용작동 방식: 락을 성공적으로 획득한..
서론: 왜 이벤트 기반 I/O인가?자바 네트워크 프로그래밍에서 높은 동시성과 확장성을 달성하기 위해서는 전통적인 블로킹 I/O 방식에서 벗어나 논블로킹(Non-blocking) I/O 모델을 채택하는 것이 필수적입니다. 이러한 맥락에서 client.write()와 같은 직접적인 I/O 호출 대신 key.attach(response)와 key.interestOps(SelectionKey.OP_WRITE) 패턴을 사용하는 것은 Java NIO의 이벤트 기반 아키텍처를 최대한 활용하는 방법입니다.이 글에서는 이 패턴의 작동 원리와 장점, 그리고 실제 구현 방법에 대해 심층적으로 알아보겠습니다.1. 전통적인 I/O vs 이벤트 기반 I/O전통적인 I/O 모델의 한계전통적인 블로킹 I/O 모델에서는 I/O 작업이..
멀티스레드 환경에서 공유 자원에 대한 안전한 접근을 보장하는 방법은 크게 두 가지로 나눌 수 있다: 블로킹(blocking) 방식과 논블로킹(non-blocking) 방식이다. 이 글에서는 논블로킹 동시성 제어의 핵심 메커니즘인 CAS(Compare-And-Swap)에 대해 심층적으로 살펴보고자 한다.CAS란 무엇인가?CAS(Compare-And-Swap)는 멀티스레드 환경에서 원자적(atomic) 연산을 지원하는 저수준 하드웨어 명령어다. 이름에서 알 수 있듯이, CAS는 두 가지 주요 작업을 수행한다:Compare(비교): 메모리 위치의 현재 값을 예상 값과 비교한다.Swap(교환): 값이 일치하면, 새로운 값으로 교체한다.이 두 작업은 단일 원자적 연산으로 실행되기 때문에, 다른 스레드의 간섭 없이..
최근 자바 동시성 프로그래밍 스터디를 진행하면서 흥미로운 문제 상황을 경험했다. 세탁물 처리 파이프라인을 모델링한 멀티스레드 프로그램에서 무한 Busy Waiting이 발생했는데, 이는 JVM 메모리 모델과 CPU 캐시 가시성(visibility) 문제와 직접적인 관련이 있었다. 이 글에서는 해당 문제의 원인과 다양한 해결책을 살펴보고자 한다.문제 상황: 세탁물 처리 파이프라인먼저 문제가 발생한 코드를 간략히 살펴보자. 아래 코드는 세탁소 파이프라인을 모델링한 멀티스레드 프로그램이다:public class MissionA2 { // 세탁물을 표현하는 레코드 private record Washload(int number) {} // 세탁을 담당하는 스레드 private static c..

미리보기기획 배경 2024 관광데이터 활용 공모전에 참여하면서 야구장 카풀을 주제로 한 서비스를 개발했습니다.카풀이 이루어지기 위해서는 소통 수단이 필요했고, 사용자 편의성을 고려하여 자체적인 채팅 기능을 제공하기로 했습니다. 초기 시스템 설계 과정[ Why : WebSocket 도입 ] Polling, Long Polling, Server Sent Event, WebSocket 등 다양한 실시간 통신 방식을 검토한 결과, 채팅 시나리오에 WebSocket의 실시간성 및 양방향 통신이 잘 어울린다고 판단하여 구현 기술로 WebSocket을 선택했습니다. [ Why : 클러스터링 구성 ] 사용자가 약속 장소에 도착한 상황에서 채팅 기능이 중단된다면 대면 만남에 있어 큰 지장을 줄 수 있습니다.따라서 실시..

1. ECDSA 키 생성ssh-keygen -t ecdsa -b 256 -f config-repo-key 생성 파일'config-repo-key' : 개인키 -> Config 서버에 등록'config-repo-key.pub' : 공개키 -> GitHub Repository에 등록2. Github Repository에 공개키 등록[Repository Settings] > [Deploy keys] -> [Add deploy key] 선택공개키 파일 (config-server-key.pub) 내용 붙여넣기"Allow write access" 체크 해제 (읽기 전용)3. Spring Cloud Config Server 설정[build.gradle]tasks.named("bootJar") { enabled ..

실시간 통신에 활용될 수 있는 각각의 통신 방식 및 기술들이 실제로 어떻게 활용되는지 함께 살펴보도록 하겠습니다.PollingPolling은 가장 기본적인 실시간 통신 방식으로, 클라이언트가 주기적으로 서버에 새로운 데이터가 있는지 확인하는 방식입니다. 매우 단순한 방식이지만, 실제로 새로운 데이터가 없더라도 계속해서 요청을 보내야 하므로 서버와 네트워크에 불필요한 부하를 주는 단점이 있습니다. 또한 실시간성을 높이기 위해 폴링 주기를 높일 경우 요청이 많이 발생하여 서버의 부하가 증가할 수 있습니다. 반대로 폴링의 주기를 늘릴 경우 실시간성이 떨어지게 됩니다. 활용 사례 : 데이터 업데이트가 빈번하지 않은 경우, 실시간성이 크게 중요하지 않은 경우스포츠 경기의 문자 중계 (경기 상황이 1-2분 간격으로..

JPA를 이용한 리포지터리 구현리포지터리 인터페이스는 애그리거트와 같이 도메인 영역에 속한다리포지터리 구현체는 인프라스트럭처 영역에 속한다스프링 데이터 JPA를 이용한 리포지터리 구현스프링 데이터 JPA는 org.springframework.data.repository.Repository 인터페이스를 상속한 인터페이스를 찾아 구현체를 자동으로 등록해준다.스프링 데이터 JPA 규칙엔티티 저장 - Order save(Order entity) / void save(Order entity)엔티티 조회 - Order findById(OrderNo id), Optional findById(OrderNo id)프로퍼티 기반 엔티티 조회 - List findByOrderer(Orderer orderer)중첩 프로퍼티 ..