///
Search
Duplicate
🌍

최종 프로젝트 질문 리스트

Search
질문
태그
답변
튜터님 답변
공통
프론트 프레임워크에 대해서 잘 알지 못하고 백엔드 서버와 통신하는 과정에서 일어나는 문제를 해결하기 위해 시간을 쏟기 보다는 백엔드 기술에 조금 더 집중하기 위해 보다 경험이 많은 SSR을 선택하였습니다.
현업에서는 react, vue써서 만든다. 그렇게도 해봐라
공통
현재 당근마켓과 번개장터 등등 개인 중고거래 서비스는 많지만 개인 물물교환 사이트는 쉽게 찾아 볼 수 없었습니다. 또한 요즈음 물물교환 거래를 원하는 사람이 많은데 마땅한 서비스가 없어서 카카오톡 오픈톡방, 당근 마켓 게시글을 통하여 물물교환하는 모습을 볼 수 있어서 물물교환 서비스를 기획했습니다. 전국적으로 사용할 서비스를 의도하여 월간 활성 이용자수(MAU)를 1000만명 정도로 예상하고 구현했습니다.
사용자의 수를 예상하고 만들어야 그에 대한 아키텍처도 나온다.
거래
공통
단점 - 저희 서비스에서 다른 도메인 간의 의존성을 분리시켜 서비스와 리포지토리단의 결합도를 낮출 수 있었습니다. 컨트롤러에서는 이전과 같이 메서드 하나만 호출하면 된다는 편리함이 있습니다. 하지만 결국엔 퍼사드 레이어가 여러 의존성을 가지는 것을 피할 수 없고 코드가 추가되는 것이기 때문에 더 많은 유지 보수가 필요할 수 있습니다. 장점 - 더 많은 유지보수가 필요하지만 추후에 멀티 모듈화에 대비해 모듈들을 분리할 때, 만약 이전과 같이 서로 다른 도메인들의 서비스와 리포지토리가 엮어 있다면 모든 서비스와 리포지토리를 확인해야 하지만 퍼사드 패턴을 사용한다면 오염된 퍼사드 부분만 보면 되는 것이기 때문에 추후 상황을 고려해 바꾸는 것이 더 좋다고 생각하여 퍼사드 패턴을 채택하였습니다.
거래
공통
일단은 설계상 순환참조문제가 발생할 수 있는 구조자체를 만들지 않는 것이 좋지만 해결 책으로는 @Lazy 어노테이션을 통해서 임의로 해결 할 수있습니다. 하지만 이러한 방식은 스프링에서 권장하지 않는 방법입니다. 그 이유는 애플리케이션 로딩 시점이 아니라 해당 Bean 이 필요한 시점에 주입을 받기 때문에 특정 HTTP 요청을 받았을 때 Heap 메모리가 증가할 수 있으며 메모리가 충분하지 않을 경우 장애가 발생할 수 있다는 이유 때문입니다. 또 다른 해결 방법은 필드 주입방식 혹은 Setter 를 이용한 주입방식을 이용하는 것입니다. 하지만 2개의 방법 모두 spring에서 지향하는 방식이 아니기에 Facade Pattern를 도입 하는 방식을 선택했습니다. 답변 - 클론 데이터 모델링 학습
연관관계를 끊어라 너무 많은 연관관계는 생산성을 낮추고 순환참조를 발생시킨다. 퍼사드패턴을 이렇게 사용하는 경우는 처음본다.
채팅
물물교환 서비스이므로 물건을 교환하는 사람들끼리 어디서 만날지, 물건의 상태 또는 얼마의 추가금을 내야하는지 등 게시글에 적혀있지 않은 추가적인 사항들을 주고 받을 수 있어야 하는데 이에 채팅 서비스가 적절하다고 생각했습니다. 웹 소켓은 핸드 쉐이킹이 필요하고 http 또는 https 프로토콜과 get메서드 통해 이루어 집니다. Request 요청에는 websokcet으로 변경하기 위해 업그레이드 하기 위해 upgrade 헤더와 connection 헤더가 포함됩니다. 그 후 응답으로 Switching Protocols 이 오면이 클라이언트와 서버 간에 웹 소켓 연결이 설정됩니다. 웹 소켓 연결이 설정되면, 양방향 통신이 가능해집니다. 클라이언트나 서버는 언제든지 메시지를 보낼 수 있고, 상대방은 해당 메시지를 즉시 수신할 수 있습니다. 이러한 양방향 통신은 실시간성이 중요한 애플리케이션에서 매우 유용하게 사용됩니다. 웹 소켓은 일반적으로 TCP 연결 위에 구현되며, 핸드 쉐이킹 이후에는 TCP 연결이 유지됩니다. 이것은 데이터를 실시간으로 전송하고 수신하기 위해 새로운 TCP 연결을 맺지 않아도 된다는 장점을 가지고 있습니다. 대신에, 한 번의 핸드 쉐이킹으로 연결이 설정되고 이후에는 계속해서 데이터를 주고받을 수 있습니다. 웹 소켓은 이벤트 기반으로 동작하며, 클라이언트나 서버가 메시지를 보낼 때마다 이벤트가 발생합니다. 이벤트를 처리하는 핸들러를 등록하여 메시지를 수신하고 처리할 수 있습니다.
게시글
응답 속도에 대해서 쿼리 최적화에 대해서 신경을 많이 썼습니다. 게시글 목록을 불러오는 것에 있어서 한방 ~ 두방 쿼리와 어플리케이션 레벨에서 정렬 로직 등 추가적인 로직 없이 구현하여 응답 속도 개선을 했습니다. 네트워크 적으로는 아마 CSR 방식이 아닌 SSR 방식으로 구현을 하여 로딩 속도가 빠른 걸로 예상됩니다. 추후에 CloudFront 에 대해서 한 번 공부해보겠습니다 감사합니다!
공통
기존에는 Test 할 때 H2를 사용하려고 했으나, 테스트 환경과 배포 환경의 데이터베이스가 다르면 예상과 결과가 달라질 수가 있다는 것을 깨달았습니다. 그래서 현재는 H2 사용을 하지 않고 테스트 컨테이너를 따로 만들어, 테스트 환경의 DB와 배포 환경의 DB를 MySQL로 통일하였습니다.
게시글
커서의 키값 중복에 대해 해결 방안은 알고 있지만 해결하지는 않았습니다. 해결 방안은 CustomCursor를 직접 만들어서 해결하는 방법인데. 예를들어 시간을 기준으로 정렬을 한다면 시간 게시글 고유 아이디를 섞어서 2024010100000001 2024010100000002 이렇게 커스텀 아이디를 지정하면 만약에 시간이 겹치더라도 겹치지 않고 정렬을 할 수 있습니다. 하지만 저희 DB에는 시간을 ms까지 저장하고 있다는 점을 봤을 때, 이 ms까지 겹칠 일은 극히 희박합니다. 따라서 아직 중복에 대한 문제는 문제를 해결해서 얻는 리소스 대비 다른 기능 개발했을 때 얻는 리소스가 더 커서 해결은 해두지 않은 상태입니다.
클라이언트에서 커서ID를 클라이언트단에서 확인 할 수 있는가? 커서를 보내줄 때 시간을 보내고 있음 게시글 ID를 DB 시퀀스 사용하는 것으로 보임 → 그럼 문제 없어 보임 Dto에 Id를 그대로 내보내면 보안 복합키로 해서 데이터를 식별해서 할 수 있는 것들을 복합키로 사용
알림
채팅의 경우 메시지가 저장될 때, 즉 상대방에게 보내질 때 알림이 전송되도록 구현하였고, 거래의 경우 거래가 만들어질 때 즉, 사용자가 상대방에게 거래를 요청한 경우 알림이 전송되도록 구현하였습니다. 사용자가 로그인한 상태에서만 알림을 받고 또, 해당 사용자가 받은 알림들을 나타내줘야 했기 때문에 사용자가 로그인했는지 안했는지 프론트에서 확인을 해야 했었는데 확인 할 방법을 고민하다가 JavaScript Cookie 라이브러리를 사용하여 해당 사용자의 'Authorization’이름의 Cookie를 불러와서 Cookie가 있으면 알림들을 받을 수 있고 볼 수 있도록 구현하였습니다.
채팅
채팅을 구현 할 때 실시간성을 중요하게 생각했는데 폴링 방식은 일정한 간격으로 서버에 요청을 보내고 응답을 받아야 하기 때문에 실시간 통신에 제한이 있습니다. 반면 웹소켓은 서버와 클라이언트 간의 양방향 연결을 제공하여 실시간으로 데이터를 교환할 수 있습니다. 또한 폴링 방식은 일정한 간격으로 서버에 요청을 보내기 때문에 불필요한 네트워크 트래픽이 발생해 서버에 부하를 줄 수 있습니다. 하지만 웹소켓은 연결을 유지하고 있기 때문에 필요할 때만 데이터를 주고받아 효율적으로 네트워크를 사용할 수 있습니다. 물론 웹 소켓도 자원이 소비되지만 폴링 방식보다 자원을 더 효율적으로 사용한다고 생각해 웹 소켓 방식을 사용했습니다. 스케일 아웃을 고려해 외부 메시지 브로커를 사용할 예정입니다.
채팅
채팅방 입장 시 ChatRoom.html 파일이 로드될 때 Websocket 연결을 위한 스크립트가 실행됩니다. 연결 후 해당 소켓을 stomp 클라이언트로 래핑 후, 연결에 성공 시 해당 채팅방의 id 값을 구독합니다. 메시지를 발행할 때는 클라이언트가아니라 서버로 보내도록 했고 서버에서 메시지를 저장하고 채팅방의 최근 메시지, 최근 메시지 시간을 업데이트 한 후에 해당 메시지를 구독자에게 전달합니다.
거래
처음 erd설계 때 Deal테이블 연관관계를 DealWallet이라는 테이블에만 설정 했었는데 교환을 신청하는 유저와 교환 신청을 받는 유저에 대한 필드를 따로 두어 받다보니 코드에 복잡도가 증가했었습니다. 이를 해결하기위해 Bill라는 테이블을 만들어 Deal테이블과 연관관계를 맺고 Bill_post이라는 테이블을만들어 Post테이블과 Bill테이블 두 테이블과 연관관계를 맺어 포스트를 받는 테이블을 만들었고 거래테이블에는 명세서 id 2개를 넣어 놓고 필요할 때는 요청하는 사람의 명세서인지 요청 받는 사람의 명세서인지 Id값으로 거래명세서 테이블에서 정보를 가져와 이용하기만 하면 되기 때문에 코드의 복잡도가 줄어들게 되었습니다.
알림
SSE 자체적으로 서비스 다운타임을 유발하지는 않겠지만, 사용자가 몰렸을 때 서버의 용량이나 네트워크의 용량에 따라서 일어날 수도 있을 것 같습니다. 이런 상황을 대비하고자 한다면 로드 밸런싱을 통해 단일 서버의 과부하를 방지할 수 있겠습니다.
쿠폰
정확히는 Redis의 Increment 메서드를 이용하여 동시성 문제를 해결하였습니다. Increment 메서드는 조회와 쓰기를 원자단위로 가져가기 떄문에 조회나 쓰기 중간에 다른 쓰레드와의 동시성 문제가 발생하지 않고 레디스는 싱글 쓰레드이기 때문에 동시성 문제를 충분히 해결할 수 있다고 생각했습니다.
알림
해당 부분에 대해 API를 연결해서 카카오톡 메시지로 전달하려는 계획이 있었지만, 해당 기능을 구현하려면 KakaoTalk Bizmessage 를 가입해야합니다. 즉 카카오톡 비즈니스 채널을 개설해야하는데. 사업자 등록증 필요하여 구현하지 않았습니다.
공통
감사합니다