728x90
원하는 시나리오1. Producer 서버에서 채팅 메시지를 kafka로 전송할 것이다2. Listner를 통해서 kafka에 저장된 메시지를 이중화된 Consumer 서버 중 하나가 받을 것이다3. 이때, 각각의 Consumer 서버는 순서대로 메시지를 처리할 수 있어야 한다 (중복처리, 중복 메시지 발송이 일어나지 않도록) 채팅 메시지가 읽히는 순서를 보장하기 위해서 SpringBoot 서버, kafka 서버 각각을 어떻게 설정해야하는가? Kafka 설정하기파티션(Partition) 설정파티션은 kafka에서 메시지가 병렬 처리될 수 있는 단위이다. 그러나, 메시지 순서를 보장하려면 특정 토픽에 대해서 단일 파티션을 사용해야한다. Kafka가 파티션 내에서만 메시지 순서를 보장하기 때문이다. 따라서,..
채팅에도 여러 종류와 여러 요건이 따른다채팅 요구사항에 대한 체크리스트로 다음과 같은 것들이 있다.채팅의 규모1:1채팅인가(ex. 페이스북)? 그룹채팅인가(ex.디스코드)?그룹채팅이라면 인원의 제한이 따르는가?예상 트래픽, 처리 기준이 얼마나 되는가? (ft.DAU)플랫폼의 종류모바일앱인가 웹앱인가?하나의 계정이 여러 단말기로 접속할 수 있는가?채팅 메시지의 제한텍스트 이외의 파일, 링크 첨부 가능성이 있는가?메시지 개당 길이의 제한이 있는가?암호화의 필요성이 있는가?부가기능읽음 표시가 필요한가?접속 상태를 관리해야하는가? 요구사항을 정립했다면 이 요구사항을 충족시킬 시스템의 아키텍처를 그려보고 싶은데, 그 전에 사전적인 지식을 다시 상기시켜볼 필요가 있다. 채팅은 송신과 수신의 통신 시나리오가 다르..
WebSocket-STOMP 테스트하기SpringBoot의 테스트도구인 JUnit에서 WebSocket - STOMP 프로토콜을 테스트해보자더불어서, Connect시의 accessToken 검증을 거치는 별도로 제작된 interceptor 통과를 위한 설정도 함께 한다. 1. SocketClient 생성socketJS가 활성화된 서버임을 가정하며, 다음과 같이 session 객체를 얻어온다this.SOCKET_URL = "http://localhost:" + port + "/ws";this.session = setSession();...private StompSession setUserSession() throws ExecutionException, InterruptedException { // ..
그런 생각을 했다.이중화된 서버에 Socket 통신을 하면 요청 전달의 오류가 있진 않을까? 예를 들어, Socket.connect()로 HTTP 요청이 일어났다. 그리고 LoadBalancer가 Tomcat1로 전달한다.이후, Socket.publish()로 메시지를 발행했다. 그리고 LoadBalancer가 Tomcat2로 전달한다이러한 발상에 로드밸런서 측에 stickySession을 적용해야하는 게 아닌가 싶었으나, 조금 더 파해친 결과 해당 생각의 오류가 있었다. 1. Socket.connect() 호출 시- socket.connect()가 호출되면, WebSocket 연결이 설정된다. 이 시점에는 HTTP 통신이 이루져 Gateway에서 로드밸런싱이 일어날 것이다. - 초기 'connect()..
SpringBoot의 WithSocketJS 설정SpringBoot 서버 구축 시, withSocketJS() 라는 함수 활성화 선택지가 있다. 그 영향력은 아래와 같다..withSocketJS()가 아닐 때 Client의 접근 (ft. React)// in Spring@Overridepublic void registerStompEndpoints( org.springframework.web.socket.config.annotation.StompEndpointRegistry registry) { registry.addEndpoint("/ws") .setAllowedOriginPatterns("*"); // .withSockJS(); }import {..
1. Get 테스트하기특성 속성(Key)의 데이터(value) 존재, 타입 확인 @DisplayName("모든 정보를 조회한다") @FindWithMockUser @Test public void testFindAllInfo() throws Exception { mockMvc.perform(get(PREFIX) .headers(headers)) // Token 등 필요한 header 첨부 .andDo(print()) .andExpect(status().isOk()) // 기대 상태값 .andExpect(jsonPath("$.data[0].a").exist..