목록전체 글 (242)
FireDrago
--------------------------------------------------접속하고 싶은 채널 id를 입력해주세요ex) https://chzzk.naver.com/live/{채널 id}> b044e3a3b9259246bc92e863e7d3f3b8--------------------------------------------------[INFO] i.g.h.c.c.c.w.ChzzkWebsocketClient : >>> Websocket 연결 성공! 인증 패킷 전송 시작...[INFO] i.g.h.c.c.c.w.ChzzkMessageHandler : >>> 치지직 웹소켓 서버 접속 승인 완료# 1차 배치 분석 결과[INFO] i.g.h.chatpipeline.buffer.ChatBuf..
(이 포스팅의 설계는 변경되었습니다. 변경된 설계 참고해주세요)웹소켓을 기반으로 한 실시간 시스템은 필연적으로 비대칭적 처리 속도를 해결해야 한다.수집단에서 쏟아지는 데이터를 분석단이 제때 소화하지 못할 때 발생하는 데이터 유실을 막고,시스템의 전체적인 처리량(Throughput)을 위한 아키텍처 설계 과정을 정리했다.이전 포스팅 웹소켓 클라이언트와 스레드 참고하자1단계 : 수집데이터 수집의 핵심은 도메인 보호와 책임의 분리다.외부 플랫폼(치지직)의 데이터 구조에 시스템이 종속되지 않게 설계했다. 1. 매퍼 클래스와 표준 도메인의 도입외부에서 유입되는 JSON 데이터는 변경 가능성이 높고 비즈니스 로직에 부적합하다.이를 위해 전용 매퍼를 두어시스템 내부에서 사용하는 표준 도메인 객체(ChatMessage..
스프링환경에서 동적 객체 생성이 필요할때스프링 프레임워크는 IoC 컨테이너가 객체의 생명주기와 의존성을 대신 관리해 준다.빈을 통해 객체의 의존성을 프레임워크가 관리하고,개발자는 비지니스 로직에 집중할 수 있게 된다. 하지만 모든 객체를 싱글턴 빈으로 미리 만들어둘 수는 없다.프로그램 실행 중에 결정되는 상태값을 필수로 가져야 하는 객체는 실행시점에 빈으로 미리 등록할 수 없다.아래의 웹소켓 연결 클래스 코드를 보자public class ChzzkWebsocketClient extends WebSocketClient { // 사용자가 보고싶은 채널입력에 따라 달라지는 '채널id' private final String chatChannelId; // 매번 연결때마다 달라지는 '엑세스..
왜 웹소켓 클라이언트에서는 스레드를 직접 관리해야 할까?본격적인 채팅 분석 시스템의 설계에 앞서, 반드시 짚고 넘어가야 할 핵심 개념이 있다.바로 웹소켓 클라이언트와 스레드의 관계다. Spring으로 간단한 웹 서버를 개발할 때,스레드를 어떻게 생성하고 관리할지 고민하지 않는다.Spring Boot 내장 톰캣이 1 요청 1스레드 (Thread-per-Request) 모델을 통해멀티 스레딩을 알아서 처리해주기 때문이다. 하지만 웹소켓 클라이언트는 다르다.연결은 오래 유지되고, 메시지는 언제 어떤 스레드에서 도착할지 보장되지 않는다.이 순간부터 스레드 관리는 프레임워크가 아니라, 개발자의 책임이 된다. 이번 글에서는 톰캣이 숨겨준 스레드 처리방식을 알아보고,이를 통해 채팅 봇 과 분석 서비스에서 구현해야 할..
본 포스팅은 개인적인 학습 목적으로 작성되었으며, 분석된 내용은 서비스 업데이트에 따라 언제든 변경될 수 있습니다1. `Java Websocket` vs `Spring Websocket`Java 기본 웹소켓 라이브러리직접 구현해야 할 점이 많고 스프링 통합 기능 지원되지 않음로우레벨에서 ‘웹소켓’ 자체를 학습하는데 유리하기 때문에 선택함2. `onOpen` 이벤트 처리2.1 WebSocket 핸드셰이크 (HTTP -> WS 전환)HTTP 형식으로 Websocket 연결요청 전송 특정 헤더를 포함한다.Websocket 전환이 승인되면, 서버는 다음과 같은 응답을 반환한다.2.2 onOpen 콜백 호출 및 프로토콜 전환 완료클라이언트(java-websocket)는 서버로부터 상태 코드 `101 Switch..
본 포스팅은 개인적인 학습 목적으로 작성되었으며, 분석된 내용은 서비스 업데이트에 따라 언제든 변경될 수 있습니다1. 채팅창 연결 치지직 방송에 입장하면 채팅 연결을 위한 웹소켓 연결 통신이 이루어진다.GET wss://kr-ss3.chat.naver.com/chat HTTP/1.1Host: kr-ss3.chat.naver.comConnection: UpgradePragma: no-cacheCache-Control: no-cacheUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36Upgrade: websocketOrigin: ..
11월 28일, 10개월간의 우아한테크코스 과정이 끝났다.수료는 했지만, 아직 ‘끝났다’는 실감은 들지 않는다. 우테코만 가면 모든 것이 해결될 것 같았던 1년 전의 나는지금과 어떻게 달라졌을까?그리고 왜 아직도 끝난 느낌이 들지 않는 걸까? 이 질문들을 정리하지 않으면10개월 동안의 경험과 변화가 금방 흐릿하게 사라질 것만 같았다.앞으로의 방향을 제대로 잡기 위해,우테코에서 배운 것들을 정리해보기로 했다. '우테코만 가면 해결될 줄 알았다'는 착각1년 전의 나는 우테코 최종 코딩테스트를 준비하며 전전긍긍하고 있었다.그리고 불과 2주일 전까지는 딜리버리히어로 면접 결과를 기다리며 또다시 전전긍긍하고 있었다. 우테코에 합격만하면 개발자로서 좋은 회사를 들어갈 수 있을거라 믿었고,딜리버리히어로만 합격하면 행..
AI 시대에 프로그래밍 공부하기 지난 10년에서 15년 동안, 이런 무대에 앉는 거의 모든 사람들은 여러분의 자녀가 컴퓨터 과학을 배우는 것이지극히 중요하다고 말했을 겁니다. 모두가 프로그래밍하는 법을 배워야 한다고요.사실, 이제는 거의 정반대입니다. 아무도 프로그래밍을 할 필요가 없도록,그리고 '인간의 언어'가 바로 프로그래밍 언어가 되도록 컴퓨팅 기술을 만드는 것이 바로 우리의 일입니다.이제 세상의 모든 사람이 프로그래머입니다. 이것이 바로 인공지능의 기적입니다.- 젠슨 황 (nvidia CEO)- 오늘날 어떤 사람들은 AI가 프로그래밍을 자동화할 것이라는 이유를 들며다른 사람들에게 프로그래밍을 배우지 말라고 만류합니다.이 조언은 역사상 최악의 커리어 조언 중 하나로 평가받게 될 것입니다.미래의..
왜? 쿼리 성능을 측정 해야할까?서비스는 성장하고 데이터는 계속 쌓인다. 지금의 쿼리 구조가 미래의 대용량 데이터 환경에서도 최적의 성능을 보장할 수 있는지 검증할 필요가 있었다. 문제가 발생한 뒤에 대응하는 것은 늦다.이 글은 프로젝트에서 정확한 쿼리 실행 시간을 측정하고, 쿼리 지연 문제를 해결하는 과정을 기록했다. 쿼리 속도 측정하기1. AOPAOP 를 사용하여 Repository 실행시간을 측정하면 쿼리실행 속도를 완전히 측정할 수 있을까?1. 측정 범위가 너무 넓다: AOP는 메서드 호출 시작부터 끝까지를 측정하기 때문에, 순수 쿼리 실행 시간 외에 커넥션 획득/반납, 네트워크 지연, 결과 변환(매핑) 등의 부가적인 시간이 모두 포함된다.2. 개별 쿼리 분석이 불가능하다: 하나의 메서드에..
문제 상황개발 단계에서 로깅은 단순히 디버깅을 위해 콘솔에 출력하는 수준이면 충분했다. 하지만 운영 중에는 장애 원인 분석, 요청 흐름 추적, 성능 모니터링 등 로그가 단순한 출력 이상의 역할을 해야 했다. 도커 환경에서 애플리케이션을 실행하면 로그가 컨테이너 내부에만 남는다. 컨테이너가 재시작되거나 교체되면 로그는 그대로 사라져버리기 때문에 원인 분석이 불가능했다. 또한 로그를 특정 서버 안에서만 확인할 수 있다 보니, 서버에 일일이 접속해야 하는 불편함이 있었다. 무엇보다 로그가 단순 문자열로 쌓이는 형태라면 운영 중 발생하는 문제를 빠르게 분석하기가 쉽지 않다.특정 요청이 어떤 흐름을 거쳤는지, 쿼리가 얼마만큼의 시간이 걸렸는지 등을 체계적으로 확인할 방법이 없었다.이런 상황에서는 장애 대응 속도가..
