Producer-Consumer Pattern with RabbitMQ
📘 Backend/Java2024. 6. 25. 15:51Producer-Consumer Pattern with RabbitMQ

📚 Producer Consumer Pattern기존에 RabbitMQ의 Queue에서 대량의 데이터를 받아서 동시성을 처리할 때 사용하던 방법은,ReentrantLock의 tryLock을 이용해 명시적 Lock을 걸고 임계영역을 보호하는 방법을 사용 중 이었습니다.근데 문제는 평소 AI Engine에서 받은 MQTT 데이터의 흐름이 평상시에는 일정한 개수(1초에 200개 정도) 나오다가AI Engine에 특정 조건이 트리거 되어 특정 모드로 바뀔때 수 없이 많은 데이터가 쏟아져 나올 떄가 있으며, 그 메시지들을 그대로 Consume 해버리게 됩니다.Thread들을 충분히 나누었음에도 부하가 심해 Spring Server가 일시적으로 멈춤, 오작동하거나 API 호출이 안 먹는다거나 이슈들이 많았습니다...

DataBufferLimitException - Webflux 버퍼 크기 제한 초과
📘 Backend/Spring2024. 6. 18. 18:41DataBufferLimitException - Webflux 버퍼 크기 제한 초과

DataBufferLimitException - Webflux 버퍼 크기 제한 초과WebClient로 Data를 받는 작업 중, WebClient에서 허용하는 Buffer를 초과한 데이터가 들어왔을떄 발생한 에러 해결 기록입니다.아래 API 요청 코드에서 return되는 데이터 중 1개 필드의 값이 Encoding된 Streaming Frame 데이터를 받도록 되어 있었습니다.public Mono getRtspStreamFrame(final String uri) { return webClient.get().uri(uri).retrieve().bodyToMono(String.class); }서버를 실행 시킨 후, 해당 API 요청을 해보니 아래와 같은 에러가 발생했습니다.DataBufferLim..

비밀번호 찾기 & 재설정 구현(Google SMTP & Redis)
📘 Backend/Spring2024. 6. 3. 22:44비밀번호 찾기 & 재설정 구현(Google SMTP & Redis)

비밀번호 찾기 & 재설정 기능 구현(Google SMTP)사내 비밀번호 찾기/초기화 기능을 위해 Email 인증을 자체 SMTP 서버를 만들어서 하려다가, 귀찮아서 Google SMTP를 이용하기로 했습니다.우선 Google 계정 설정에 들어가서 아래 2개의 작업을 해줍니다.Multi Factor Authentication(2FA) 활성화App Password 생성그리고 Gmail 탭으로 들어가 Mail 설정의 Forwarding and POP/IMAP 탭에 들어가서 아래와 같이 설정합니다.Spring Boot Server 설정build.gradle 파일에 Mail 추가implementation 'org.springframework.boot:spring-boot-starter-mail'applicatio..

📘 Backend/Python2024. 5. 25. 00:24Pandas란? Numpy와의 차이점 & 행렬 히트맵 생성

PandasPandas는 파이썬에서 데이터 조작과 분석을 위한 고성능 라이브러리입니다. 주로 구조화된 데이터, 특히 표 형식의 데이터를 다루는 데 사용됩니다. Pandas는 데이터를 효율적으로 로드, 조작, 분석, 그리고 시각화할 수 있는 다양한 기능을 제공합니다.주요 기능데이터 구조Series: 1차원 배열 형태의 데이터 구조로, 인덱스를 가진다.DataFrame: 2차원 표 형태의 데이터 구조로, 여러 열을 포함하며 각 열은 Series 객체로 구성된다.데이터 입출력CSV, Excel, SQL, JSON 등 다양한 파일 형식에서 데이터를 읽고 쓸 수 있다.데이터 정제 및 조작결측치 처리: fillna(), dropna()데이터 필터링: 조건에 맞는 데이터 선택데이터 정렬: sort_values()데이..

ReentrantReadWriteLock - ReadLock & WriteLock을 사용한 Read Thread 성능 향상
📘 Backend/Concurrency2024. 5. 3. 15:34ReentrantReadWriteLock - ReadLock & WriteLock을 사용한 Read Thread 성능 향상

ReentrantReadWriteLock왜 사용해야 하는지?주로 읽기 작업이 많은 어플리케이션에서 읽기 작업이 느릴때읽기 작업에 드는 비용이 클 때읽기 작업을 수행하는 Reader Thread가 여러개일때 이런 상황이 왜 문제일까?읽기 작업을 수행하는 Thread가 여러개가 있고,한 Thread가 공유 Resource를 읽을때 다른 Thread들은 Blocking 상태가 됩니다. 이때 앱의 읽기 성능애 문제가 생깁니다. (다른 Thread들은 대기상태 이기 때문)위와 같은 상황을 ReentrantReadWriteLock을 사용하여, 읽기 작업을 수행하는 Thread들의 공유 리소스 동시 접근이 가능하게 하기 위한 클래스가 ReentrantReadWriteLock 입니다.사용법Thread 여러개가 있는 앱..

ReentrantLock - Lock 획득을 위해 대기중인 Thread에 Interrupt 호출이 안먹힐 때
📘 Backend/Concurrency2024. 4. 30. 17:53ReentrantLock - Lock 획득을 위해 대기중인 Thread에 Interrupt 호출이 안먹힐 때

ReentrantLock - lockInterruptibly()특정 Thread에서 Lock 획득을 위해lock.lock()을 호출했을 때 다른 스레드에 의해 이미 Lock이 점유되어 있는 상황에서 현재 Thread는 Lock이 해제되는걸 기다리기 위해 무한 대기 상태에 걸려 있습니다. (Blocking 상태)이때 대기 상태를 해제하기 위해 Thread를 Interrupt를 시켰는데 Interrupt 호출이 되지 않아서, 알아보고 해결한 방법을 기록합니다.아래 예시 코드로 설명해보겠습니다.lockInterruptibly()를 사용해야 하는 이유 - 예시 코드@Overridepublic void run() { lock.lock(); // Lock 획득 실패 - 다른 스레드에서 사용 중 // ....

Spring WebSocket (Stomp X)
📘 Backend/Spring2024. 4. 26. 11:25Spring WebSocket (Stomp X)

처음 WebSocket을 사용할떄 WebSocket API를 직접 사용하는것이 아닌, Stomp를 사용했었습니다.Stomp는 WebSocket 위에서 동작하는 Messaging Sub Protocol입니다.Stomp를 사용할때의 장점은,구독(Subscribe) & 발행(publish) 메시징 패턴을 빠르고 쉽게 구현할 수 있고,다양한 플랫폼과의 호환성이 높아 통합이 용이합니다.하지만, Stomp 프로토콜 자체의 오버헤드가 있어 많은 메시지를 처리하는데 있어 속도 저하를 느껴서 바꾸게 되었습니다.이번엔 순수 WebSocket API를 이용하는 걸로 바꾸었고,순수 WebSocket API를 이용하면 직접적인 메시지 포맷팅, 연결 상태 관리 등을 직접 제어해 복잡성이 증가하지만,성능과 낮은 지연 시간이 중요한..

image