전체 글 164

[R2DBC] R2DBC란 무엇인가?

R2DBC가 무엇인지에 대해 정리해보겠습니다. 그리고 이후 포스팅에서는 Spring에서 R2DBC를 활용하여 서비스를 구축하는 방법에 대해 학습해보고자 합니다. R2DBC (Reactive Relational Database Connectivity) 는 관계형 DB에서 효율적으로 코드가 동작할 수 있도록 reactive programming API를 가능하게 해줍니다. 즉 관계형 DB에 논블로킹 접근이 가능하게 해줍니다. 기존 관계형 DB 접근 API (ex JDBC 등 )는 블로킹 API이기때문에, 완전한 논블로킹 서비스를 구축할 수 없었습니다. 그렇기 때문에 이를 해결하고, 보다 적은 스레드와 하드웨어로 더 많은 동시 처리를 하기 위해 R2DBC가 탄생했다고 합니다. 이제는 Spring Data 에..

Spring 2022.07.22

동기와 비동기 그리고 블로킹과 논블로킹

동기와 블로킹, 비동기와 논블로킹에 대해 헷갈리는 경우가 있습니다. 하지만 자세히 보면 두 개념은 기준이 다른 개념입니다. 간단한 설명과 함께 각 개념을 정리해보겠습니다. 먼저 설명에 앞서 아래와 같이 함수명을 정의하고 시작하겠습니다. - 요청한 함수 : Func A - 요청된 함수 : Func B 먼저 동기와 비동기에 대한 설명입니다. 동기 (Sync) - Func A가 Func B를 요청하고 작업이 완료되었는지 계속 확인 - 결과가 주어질 때까지 대기해야 한다 비동기 (Async) - Func A는 요청 후 신경 쓰지 않고 다른 작업을 계속 처리 할 수 있음 - Func B가 작업을 마치면 Call back 으로 알려줌 동기와 비동기의 가장 큰 차이점은 완료여부를 확인하는 주체의 차이로 볼 수 있습니..

ETC 2022.06.13

[Postgresql] Transaction Isolation Level

트랜잭션 격리 수준 (Transaction Isolation Level) - 여러 트랜잭션이 동시에 처리될 때 하나의 트랜잭션이 다른 트랜잭션과의 격리 수준을 어떻게 할지 결정하는 레벨. PostgreSQL에서는 4가지의 표준 Transaction Isolation Level이 있습니다. 먼저 PostgreSQL에서 트랜잭션을 설정하는 방법은 아래 공식 문서를 참고하시면 됩니다. https://www.postgresql.org/docs/current/sql-set-transaction.html 격리 수준은 READ UNCOMMITTED -> SERIALIZABLE 순서로 높아지며, 기본 값은 READ COMMITTED입니다. 1) READ UNCOMMITTED 설정에는 정의되어 있지만, 사실상 지원하지 ..

Database 2022.05.20

[RabbitMQ] Exchange Type

RabbitMQ에서 모든 메시지는 Exchange에서 먼저 받고 그 Type과 Binding 에 따라 각 Queue로 전달됩니다. 전체적인 구조는 아래와 같습니다. RabbitMQ에서는 4가지 Exchange Type이 존재합니다. 1. Direct - routing key를 기반으로 메시지를 전달 2. Fanout - 브로드캐스트 방식 - 모든 큐에 메시지를 전달 3. Topic - routing key 패턴 기반으로 메시지를 전달 4. Headers - routing key 대신 메시지 헤더에 다양한 속성을 추가하여 메시지를 전달

RabbitMQ 2022.05.18

[RabbitMQ] 기초 개념 - 5 (Topic)

이전 Routing을 통해 특정 Queue로 메시지를 전송할 수 있었습니다. 이때 type은 direct로 설정을 했는데요. 하지만 이렇게 direct를 사용하면 하나의 기준으로만 Routing을 할 수 있습니다. 이번에는 여러 기준으로 Routing을 할 수 있는 Topic에 대해 정리하겠습니다. Topic은 .(dot)으로 구분된 단어로 설정 할 수 있습니다. 예시) "stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit". Topic Exchange는 Direct Exchange와 유사합니다. 특정 키로 보낸 메시지는 일치하는 바인딩 키로 바인딩된 모든 큐에 전달됩니다. 바인딩 키에는 두 가지 규칙이 있습니다. 1) * 는 정확히 한 단어를 대체. 2) # 는 0..

RabbitMQ 2022.05.16

[RabbitMQ] 기초 개념 - 4 (Routing)

이번 포스트 정리 개념은 Routing 입니다. Routing의 기본 개념은 출발지에서 목적지로 데이터가 전달될 수 있도록 경로를 선택하는 것을 말합니다. RabbitMQ에서의 Routing 역시 비슷한 개념으로 볼 수 있습니다. 아래 그림과 같이 내가 보내고 싶은 Queue의 경로에만 메시지를 전송합니다. 위와 같이 하려면 Exchange type을 direct로 선언해야 합니다. 이전까지 사용했던 fanout 방식이 모든 Queue에 전송했다면, direct 방식은 경로에 따라 특정 Queue에만 메시지를 전송합니다. 로그 관리 시스템이라면 다음과 같이 특정 Queue는 Error 레벨만 수신하고, 나머지 레벨은 또 다른 Queue에서 처리하는 방식으로 나누어 보다 효율적인 데이터 관리가 가능합니다.

RabbitMQ 2022.05.16

[RabbitMQ] 기초 개념 - 3 (Pub/Sub)

이번 포스트에서는 Publish/Subscribe 패턴에 대해 정리하겠습니다. 이 패턴은 하나의 메시지를 여러 Consumer에게 전송하는 패턴입니다. 이전 포스트에서는 Producer가 Queue에 직접 메시지를 전송하고, 그 Queue가 여러개의 Consumer에게 메시지를 전송했습니다. Exchange 기존 있었던 요소 중 Producer, Queue, Consumer를 기억하실거에요. RabbitMQ의 핵심 메시징 모델은 Producer가 직접 Queue에 메시지를 전달하지 않는다는 것인데, 여기에서 Exchange라는 요소가 추가됩니다. 중간에 보이는 파란색 X가 Exchange 입니다. Producer는 Exchange에만 메시지를 보낼 수 있습니다. Exchange의 역할은 간단한데, Pro..

RabbitMQ 2022.04.12

[RabbitMQ] 기초 개념 - 2 (Work queues)

첫 번째 포스팅에서는 하나의 Producer가 하나의 Consumer에게 메시지를 전달하는 형태에 대해 정리했습니다. 이번에는 하나의 Producer가 여러개의 Consumer에게 메시지를 전달하는 형태에 대해 정리 하겠습니다. Round-robin dispatching Queue는 병렬화 할 수 있다는 장점이 있습니다. 즉, 같은 Queue의 Consumer에게 메시지를 균등 분배 할 수 있습니다. 또한 Consumer 갯수를 계속 추가하면서 쉽게 수평 확장이 가능합니다. 이 방식에서 모든 Consumer는 평균적으로 동일한 수의 메시지를 처리합니다. Message acknowledgment 특정 처리를 하다가 Consumer가 하나 죽으면, 해당 Consumer가 처리하던 메시지를 잃게됩니다.. 이를..

RabbitMQ 2022.04.08

[RabbitMQ] 기초 개념 - 1

RabbitMQ는 메시지 브로커입니다. AMQP 프로토콜을 구현하여씅며, 시스템 간 메시지를 전달해줍니다. 주로 사용하는 몇 가지 용어가 있는데, 해당 용어부터 정리해보겠습니다. - Producer : 메시지를 전송 - Consumer : 메시지를 수신해서 처리 - Queue : RabbitMQ안에 있는 큐. 메시지들은 큐 안에 저장 이해가 쉽게 이미지와 함께 보면 아래와 같습니다. 위 이미지에서는 단순하게 전송, 수신 2가지 기능이 있습니다. - 전송(Sending) Producer에서 큐로 메시지를 보냅니다. 과정은 간단히 다음과 같이 처리 됩니다. 1. Producer에서 RabbitMQ 연결 2. Producer에서 RabbitMQ로 메시지 전송 3. 전송 완료 후 연결 종료 - 수신(Receiv..

RabbitMQ 2022.04.01

[subList] Java.Util.ArrayList$SubList Deserialization 이슈 해결

Dto에서 선언한 List를 Service로직이나 Dao단에서 subList를 이용할 경우가 있습니다. 해당 subList를 통해 특정 길이로 잘라서 아래와 같이 사용하는 경우가 있었습니다. List dataList = new ArrayList(); dataList = dataList.subList(0,5); subList는 fromIndex, toIndex를 받아 해당하는 크기만큼 리스트를 반환합니다. 해당 값을 Redis로 캐싱할 때 아래와 같은 이슈가 발생했습니다. Redis deserialization error could not read JSON: cannot construct instance of ` Java util. ArrayList$SubList` subList로 자르면서 캐싱된 데이터 ..

Java 2022.03.30