전체 글59 2025년 회고록 (feat. 우테코 7기 회고) 2025년은 정말 빠르게 지나갔다. 빠르게 지나갔지만 기술적으로도, 소프트스킬적으로도 많은 성장을 한 것 같다.우아한테크코스 7기2025년 한 해를 정리해 보자면, 우테코라고 표현할 수 있을 것 같다. 10개월이라는 기간 동안 우테코를 진행하면서 정말 배운 점이 많았다. 기술적 성장 Level1- 객체지향객체지향을 공부하고 나름 많이 생각해봤는데 그렇게 중요한 부분인가...?라는 생각이 많이 들었던 것 같다. 과도한 추상화는 프로젝트의 복잡도를 높이고, 코드를 이해하는데 꽤 오랜 시간이 걸린다. 물론 기능 요구사항이 모호하거나, 변경될 가능성이 높은 부분에 추상화를 적용하는 건 좋지만, 변경 가능성이 매우 적은 부분에도 추상화를 적용하는 건 과하다는 생각이 드는 것 같다. 주변에 객체지향을 정말 좋아하.. 2025. 12. 31. MySQL의 기본 트랜잭션 격리수준은 왜 Repeatable Read일까? 트랜잭션 격리 수준을 공부하다가 문득 궁금증이 생겼습니다.Oracle, PostgreSQL의 경우에는 기본 격리 수준이 Read Committed인데, 왜 MySQL은 Repeatable Read가 기본 격리 수준일까요?과거 MySQL의 복제 작업과거 MySQL은 Master -> Replica 복제 작업 시 Statement-Based Replication(SBR) 방식을 사용했습니다. SBR 방식이 무엇일까요? 그림을 보면서 이해해봅시다.SBR 방식은 쿼리문을 그대로 복제 후 실행하는 방식을 의미합니다. 동작방식에 대해 조금 더 구체적으로 알아볼까요? 1) Insert, Update 등 쿼리문이 날아오면, 해당 쿼리 실행 후 MasterDB의 Binary Log에 실행 쿼리가 기록됩니다2) Binar.. 2025. 12. 26. Spring AI와 RAG을 활용한 AI Agent 만들기 이번에 피드줍줍 매니저라는 AI Agent를 개발했습니다. 간단하게 설명하자면, LLM을 통해 개발 DB에 데이터를 조회/삽입하거나, 팀 개발 문서를 검색해 주는 Agent입니다. 왜 만들었는가?피드줍줍 팀 내 Discord 채널에 다음과 같은 알람이 왔습니다. 해당 팀원은 프론트 개발자인데요, 백엔드 개발자는 간편하게 DB에 접근해 insert 쿼리문 작성하면 되는 것이지만 프론트 팀원들은 애초에 DB 접속이 불가했기에 벌어진 상황이었습니다. DB에 데이터를 넣는 것 자체는 간단하지만 백엔드 팀원들이 부재중일 경우, 데이터를 넣어줄 때까지 기다림으로써 개발이 늦어지거나, 수동으로 400개 데이터를 넣어야 하는 상황이 발생할 수도 있죠. 최근 당근에서 출시한 AI 관련 서적을 읽고 AI를 활용해 팀원들의.. 2025. 12. 13. Claude가 최신 공식문서 읽게 하기 이번에 피드줍줍 매니저를 만들면서 AI를 많이 활용했는데요, 정보가 불확실하다는 걸 많이 느꼈습니다. 특히 SpringAI의 경우에는 나온 지 얼마 되지 않은 기술이라, AI가 잘 모르는 부분이 있더라고요. 그래서 공식문서를 열심히 읽었던 기억이 납니다. 이번에 RAG 환경을 구축해보면서 파인튜닝을 통한 AI 학습은 오래 걸리고 비용이 많이 들지만, 실시간으로 공식문서를 스크랩해 어딘가 저장해 놓고, AI가 문서를 읽게 하는 건 비용이 얼마 들지 않을 것 같다고 생각했습니다. 지원해 주는 툴이 있나 찾아본 결과 역시나 있었습니다! 바로 MCP 서버를 이용하는건데요, Context7이라는 오픈소스가 있고, 이걸 MCP 서버에 등록을 하면 됩니다. Context7은 다양한 라이브러리, 프레임워크 API의 .. 2025. 12. 12. Spring SSE의 내부 동작 탐색(AsyncRequestNotUsableException) SSE 연결 중, Client가 연결을 종료했을 때 AsyncRequestNotUsableException이 발생했습니다. 왜 이런 에러 로그가 찍히는 거고, 비동기 처리를 한 적이 없는데 왜 에러에 Async가 붙은 건지 궁금해 글을 작성하게 되었습니다. 이를 이해하기 위해서는 우선 Spring에서의 SSE 연결 흐름에 대해 알아야 합니다.SSE 요청 흐름SSE의 초기 요청 흐름입니다. 여기서 중요한 점은, 연결을 유지하는 동안 스레드를 계속 점유하고 있지 않는다는 점입니다. 하나의 스레드가 하나의 연결을 담당하는 대신에, NIO Selector에게 연결 정보를 넘겨준 후 스레드 풀에 반환이 됩니다. NIO Selector 내부에서는 하나의 스레드로 여러 개의 연결을 관리할 수 있는데요, 상당히 흥미로.. 2025. 12. 8. SSE 연결 끊김 트러블슈팅: HttpLoggingFilter와 Content-Length 충돌 초기 SSE 연결은 확인할 수 있었는데 이후 하트비트 혹은 이벤트 값이 전송이 안 되는 문제가 발생했습니다. 결론부터 말하자면, Filter에서 로그를 남기고 있었고, Filter가 SSE 연결을 강제로 끊어버리고 있었습니다. 위와 같이 개발자 도구를 통해서 SSE 연결이 잘 된 것을 확인할 수 있었는데요, 추가적인 하트비트 응답이 오지 않는 상황이었습니다. 세부적인 로깅을 통해 하트비트를 수행하는 스케줄러는 잘 동작하는걸 확인할 수 있었는데요, 이상하게 응답이 오지 않았습니다. 원인은 Filter를 통해 모든 Request, Response에 대해 로깅을 남기고 있어서였습니다.@Overrideprotected void doFilterInternal( final HttpServletRequ.. 2025. 12. 7. 이전 1 2 3 4 ··· 10 다음