2달 전 · 익명 님의 새로운 댓글
채팅 애플리케이션에서 Redis 메시지 저장과 RabbitMQ 전송을 안전하게 처리하려면 어떻게 해야하나요?
안녕하세요. 현재 백엔드 개발자를 지망하는 대학생입니다.. 예전에 Springboot를 활용해서 개발한 채팅 애플리케이션 프로젝트를 리팩토링하는 과정에서 문제가 발생하여 질문 드립니다. 아래와 같은 아키텍처 애플리케이션을 구현했습니다. - MySQL: 채팅방 정보(채팅방 이름, 참여 인원수 등등), 사용방 정보 데이터 저장. - Redis: 채팅 메시지 데이터 저장 - RabbitMQ: 채팅 메시지를 전송하기 위한 메시지 브로커 STOMP over WebSocket을 활용해서 클라이언트에서 메시지를 pub해서 메시지 브로커인 RabbitMQ를 거쳐서 구독한 클라이언트에게 메시지(채팅)을 전송하도록 구현했습니다. 그런데 문제가 발생하는 로직이 있습니다. [채팅방 가입 로직] 1. @Transactional 내부에서 MySQL에 채팅방 데이터 저장. (해당 유저가 채팅방에 가입한 것을 저장) 2. Redis에 "User가 채팅방에 들어왔습니다."라는 메세지를 저장. 3. 해당 메시지를 RabbitMQ로 전송. (`rabbitTemplate.convertAndSend(...)`) 이런 상황에서 Redis나 RabbitMQ에서 문제가 발생해서 하나라도 정상적으로 완료되지 않으면 문제가 발생합니다. Redis 서버에 문제가 생겨서 채팅 메시지를 정상적으로 저장하지 않더라도 RabbitMQ를 통해 메시지가 전송되고, RabbitMQ 서버에 문제가 생겨서 정상적으로 전송되지 않더라도 Redis에 채팅 메시지가 저장이 됩니다. 이러한 문제를 해결하기 위해서 2PC, SAGA 패턴, Outbox 패턴 등등을 알아봤고, 그 중 가장 괜찮다고 생각했던 패턴이 Outbox 패턴이었습니다. 근데 또 어려움이 생겼는데, Outbox 패턴을 사용하기 위해 Pulling 기법을 사용 하자니 Redis에 무리가 생길 것 같고, 트랜잭션 로그 테일링 패턴을 사용 하기에는 Redis가 이를 제대로 지원하지 않아 구현이 굉장히 어려워진다는 문제가 생겼습니다. 그래서 MySQL을 Outbox 저장소로 사용할까 고민도 해보았는데, MySQL을 사용하면 속도 면에 불리해지지 않을까라는 생각이 또 들었습니다. 이러한 문제를 어떻게 해결하면 좋을까요...? 제가 궁금한점은 다음과 같습니다. 1. Redis를 활용하는 프로젝트에서 MySQL을 Outbox 저장소로 사용하는 것은 좋지 않은 방법일까요? 2. Outbox 패턴이 최선일까요? 현업에서는 이러한 문제를 어떤 식으로 해결하는지 궁금합니다.
개발자
#spring
#rabbitmq
#redis
#mysql
#transaction
답변 1
댓글 1
조회 127
9달 전 · 고지완 님의 새로운 댓글
권한 관리 AOP와 영속성 컨텍스트 문제
프로젝트를 진행하던 중, 해당 펫이 api를 요청하는 유저가 소유하고 있는 펫이 정말 맞는지 확인하는 권한 검사 로직 등이 중복으로 발생해서 이를 비즈니스 로직에서 분리하고자 스프링 AOP 기술을 활용해보려고 했습니다. 동작은 잘 되지만.. Pet을 조회하는 쿼리가 중복해서 2번이 발생하더군요. 저는 OSIV가 꺼져있더라도, 비즈니스 레이어에서 같은 트랜잭션 내에서 동작하기에 AOP에서 조회한 엔터티도 같은 영속성 컨텍스트에서 관리될 거라고 생각하고 위처럼 작성했는데 어디가 문제인지 모르겠어서 도움을 부탁드립니다.. ㅠㅠ 혹시 가능하시다면 현업에서는 중복되는 권한 체크 로직을 어떻게 관리하시는지도 알려주시면 큰 배움이 될 것 같습니다!
개발자
#aop
#spring-boot
#jpa
#spring
#java
답변 1
댓글 1
조회 27
9달 전 · 익명 님의 새로운 댓글
백엔드 공부중인 학부생인데 실무 관련해서 단순한 궁금증이 있습니다!
안녕하세요 현재 백엔드 개발 공부중인 학부생입니다. 공부중 현업에 관련해서 간단한 궁금증이 있는데 알고있는 현업자분이 없어서 여기에다가 질문 남깁니다. 제가 트랜잭션에 대해 공부하다가 spring의 open-in-view 속성에 대해 알게 되었는데 이 설정을 현업에서는 false로 하는지 궁금합니다. False로 할 경우 lazy load하는 부분에서 문제가 생긴다고 하는데 제 추측으론 현업에선 연관 데이터가 많을것 같고 그럼 lazy load를 사용해야 해서 문제가 있을것 같고 또 키자니 트래픽이 많을때 요청이 종료될때까지 영속성 컨텍스트가 유지되면서 커넥션 풀에 커넥션이 고갈하는 현상이 발생할 것 같은 이런 상황을 현업에선 어떻게 대처하는지 궁금합니다!
개발자
#spring-boot
#jpa
#영속성
#트랜잭션
#데이터베이스
답변 1
댓글 1
조회 77
9달 전 · 익명 님의 질문
동시성+데드락 제어를 위한 비관적 락 잠금 질문
안녕하세요 글쓰기 커뮤니티 프로젝트를 개발하는 중입니다 회원이 소설을 찜하는 기능(좋아요)을 구현 중에 있는데요 찜 객체는 아래 첨부한 코드와 같이 memberId와 novelId를 외래키로 갖습니다 동시성 이슈를 다뤄보고자 500명의 사용자가 동시에 novelId가 1인 소설을 찜하는 요청을 보낸다는 가정 하에 jmeter로 테스트를 돌려보니 동시성 이슈가 아니라 데드락 문제가 발생해서요 favoriteJDBCRepository.save(memberId, novelId); 시 novelId가 외래키라 외래키 정합성 검사 때문에 db 내부적으로 novelId가 1인 레코드에 read lock이 걸리는 것 같습니다 favorite 객체 save 시 트랜잭션 A가 novelId가 1인 레코드에 대해 read lock을 얻고, novelId가 3인 novel의 favoriteCount(찜 개수)를 +1하고자 write lock 요청 -> favorite 객체 save 시 다른 트랜잭션 B도 novelId가 1인 레코드에 대해 readlock을 얻고, novelId가 1인 novel의 favoriteCount(찜 개수)를 +1하고자 write lock 요청 -> write lock은 read lock이 전부 해제되어야 얻을 수 있음. 트랜잭션 A는 B가 read lock을 release하기를 대기하고 B도 A가 read lock을 release하기를 대기하면서 데드락 발생 일단 novelId로 novel을 비관적 락을 사용해 조회해서 favorite 객체를 생성한 뒤에 저장하는 방식으로 데드락+동시성 이슈 둘 다 해결이 되는데요(chooseFavoriteV2) 이 방법 말고도 더 좋은 대안은 없을까요??
개발자
#비관적락
#데드락
#동시성
#데이터베이스
#백엔드
답변 0
댓글 0
추천해요 1
조회 49
일 년 전 · 세혁 님의 새로운 댓글
클라이언트, 서버 두 DB의 데이터를 동시에 수정할 때 무결성 보장
안녕하세요 어플리케이션을 만드는 도중 문제가 생겼습니다. indexedDB( 클라이언트 ), postgreSql( 서버 ) 2곳의 데이터를 동일하게 수정해야할 때 ( 추가, 삭제, 수정 등 ) 한 곳의 api 가 실패하는 순간 이미 수정이 된 곳의 트랜잭션을 롤백 ( abort ) 하여 연동된 두 곳의 데이터가 동일 하도록 무결성을 보장하고자 합니다. 그런데 2가지 문제를 발견하였습니다. 1. indexedDB 의 트랜잭션 도중 다른 api 의 await를 쓰는 순간 indexedDB 는 트랜잭션을 즉시 종료시켜 서버 데이터 수정이 실패해도 abort() 가 불가능하다. 2. postgreSql 의 트랜잭션은 next.js 의 서버사이드 api에서 쿼리를 날리기에 중간에 클라이언트 사이드의 indexedDB 수정 api 사용이 불가능하다. indexedDB는 idb, postgreSql 은 pg 라이브러리를 사용중입니다. 수정 되기 전 상태를 임의로 기록 > 2번째 api 실패? > 기록된 상태로 수정하는 api 요청 이라는 단순한 방법도 생각해봤지만 결국 마지막 상태로 수정하는 것도 별도의 api 요청이기에 이 것또한 실패할 시 무결성 보장이 되지않기에 포기하였습니다... 선배님들은 서버와 클라이언트 데이터를 연동할때 무결성 보장을 어떻게 하시나요? next.js 14 환경입니다.
개발자
#next.js
#indexeddb
#postgresql
#무결성
#데이터베이스
답변 1
댓글 1
조회 148
일 년 전 · 코딩하는기린 님의 답변 업데이트
DB에 있는 데이터를 "조회"할 때도 트랜잭션이 필요한가요?
find 혹은 findOne 함수를 통해 DB에 있는 데이터를 조회할 때도 트랜잭션을 적용하는 것이 좋을지 개발자 분들께 질문드립니다..
개발자
#node.js
#백엔드
#트랜잭션
답변 1
댓글 0
조회 125
일 년 전 · 익명 님의 질문 업데이트
트랜잭션을 붙여야하는 로직인지 궁금합니다..
안녕하세요. 자바 스프링을 개발하고 있는 개발자입니다. 현재 거래처자동등록 로직을 구현하고있습니다. 거래처자동등록버튼을 누르면 a,b,c 테이블의 거래처코드 칼럼을 모두 Update 해줘야합니다. 이때 3개의 update 를 수행하는 서비스단에 transactional 을 붙여줘야할지 판단이 안섭니다. 데이터 정합성이 크게 중요한 부분이 아니라고 판단되서 오류발생시 롤백처리를 해야할 필요가 없을것같아 transactional 어노테이션을 붙이지 않았습니다. fm 대로 하려면 붙여야하겠지만 트랜잭션이 아무래도 테이블 락을 초래하는 단점도 있어서 이런 경우에 어떻게 해야할지 조언을 구하고 싶습니다. 감사합니다.
개발자
#transaction
답변 1
댓글 0
조회 350
2년 전 · 조용구 님의 답변 업데이트
2년차 사이드 플젝으로 이직 가능할까요?
이제 만 2년 서버 개발자로 일하고 있습니다. 다만 해왔던 일들이 좀 강점이 없는 애매한 일들이었습니다 카프카를 쓰지 않는 msa, 데브옵스를 다루지 않고 비즈니스 로직만 작성했던 업무들이었습니다 이런 상황에서 이직을 위해서 사이드 프로젝트를 해서 좋은 it 회사로 이직하고자 합니다 2년차 개발자가 사이드 플잭을 주력으로 해서 취업을 할수있을까 많이 걱정이 됩니다 사실 사이드 플젝으로라도 노력을 해서 내 가치를 올려야 한다는 답은 정해져있지만 다른분들의 의견이 궁금하네요 사이드 플젝을 한다면 아키텍처 설계와 데이터 비동기 통신에서의 트랜잭션 같은 부분을 깊게 공부할 생각입니다. 많은 조언 부탁드리겠습니다 🙇
개발자
#spring
#kotlin
#server
답변 1
댓글 0
추천해요 2
조회 286
2년 전 · 이형래 님의 새로운 답변
임시저장 기능 구현
설문조사나 자기소개서 등에서 임시저장 또는 실시간 저장을 구현하고자 한다면 저장할때마다 트랜잭션을 발생시키시나요? 혹은 로컬스토리지나 세션에 저장후 한꺼번에 디비에 저장하는게 적절할까요? 설문조사 작성중에 나간후 다시 작성할때 데이터가 남아있고 작성도중 이전다음페이지로 왔다갔다해도 데이터들이 남아있기해야한다면요 저장할때마다 디비에하면 서버부하가 심하나요? 그걸 해결할방법이있나요?
개발자
#트랜잭션
#서버부하
#임시저장
답변 1
댓글 0
추천해요 1
조회 521