[Project] java-http-server - 1차 스프린트 후기
·
프로젝트
도서를 보다가 갑자기 나도 HTTP 서버를 구현하고 싶어졌다. 얼마전 스프링 mvc 구조, 톰캣 등 사용자 요청을 Spring이 어떻게 처리하는지 나름 공부했던게 계기가 되었다. 이 구조를 직접 구현해보면 완벽히 내 지식이 될 것 같은 생각이 들었다. 클라이언트의 HTTP 요청을 받아 적절한 처리 후 응답을 보내는 톰캣, 스프링과 유사한 구조의 서버를 만들기로하고 구현 계획을 작성해 10시간 스프린트를 진행했다.구현 결과목표는 Dispatcher Servlet을 사용하는 구조까지 만들어 보는 것이었지만, 서블릿 형태를 구현하는 단계까지만 완료했다.간단히 정리한 구현 내용소켓의 바이트 스트림을 HttpRequest, HttpResponse 객체로 변환HTTP 요청/응답을 처리하는 레이어와 비즈니스 로직을 ..
[Project] 멀티모듈로 분리하기
·
프로젝트
단기 집중개발로 개인 프로젝트를 마무리 후 미흡했던 부분을 보완하거나 개선하는 작업을 진행하고 있다. 테스트 코드 작성이나 프론트엔드 구현 등 작업들이 남아있지만, 가장 하고싶었던건 프로젝트를 레이어 별 멀티모듈로 분리하는 작업이었다. 최근 강의와 유튜브 영상에서 멀티 모듈로 나눈 코드로 시연하는걸 보고 나도 한 번 해보고 싶은게 컸다. 마침 프로젝트 개선 사항에도 부합했기 때문에 진행하기로 결정했고 분리했던 과정을 간략히 기록했다.1. 배경 및 동기현재 프로젝트는 단일 모듈로 구성해 기능과 역할별 패키지를 분리했다. 각 레이어간 역할 및 구조를 명확히 분리하기 위해 레이어 별 멀티 모듈 형태로 구조를 변경했다.// 기존 구조arcademarket(proejct root)├─ docs(문서 모음)├─ ...
[Project] 나혼자 해커톤 후기 - 2
·
프로젝트
지난번 진행했던 개인 프로젝트를 이어서 완성했다(지난 작업 후기). 이번에도 주말동안 약 12시간동안 작업하며 미흡했던 부분을 보완하고 새로운 기능을 개발했다.작업이번에는 타이머를 12시간으로 맞추고 1시간이 남을 때 까지 작업했다. 핵심 기능을 어느정도 완료하고나니 집중력이 떨어져서 후반에 남아있던 프론트엔드 작업은 완성하지 못하고 마무리했다. 작업을 하면서 노트에 완료한 시간을 기록하긴 했는데 정확하진 않다.통계총 작업시간 : 약 11시간커밋 수: 94(+57)Java 파일: 128개(+77)Vue 파일: 13개(+4)Typescript 파일: 47개(지난번 카운트를 잘못했는지 수가 줄었다.)지난번에 완료한 기능회원 : 회원 가입, 회원 기본정보 조회, 로그인 및 인증아이템 마스터 : 정보 등록 및 ..
[Project] 나혼자 해커톤 후기 - 1
·
프로젝트
개요연휴동안 충분히 쉬기도 했고, 그동안 진행하던 개인프로젝트가 지지부진한 것 같아 리프레시할 겸 새로운 단기 프로젝트가 하고 싶었다. 주말동안 시간을 정하고(10시간) 완성해보자는 생각으로 Arcade Market이란 프로젝트를 시작했다. 너무 참신한 아이디어를 내기는 어려울 것 같아 포인트로 아이템을 거래하는 플랫폼을 주제로 진행했다.토요일 오전부터 바로 개발에 들어갈 수 있게 PRD, 유저플로우 문서를 작성했다. AI의 도움을 받아가며 초안을 작성할 수 있었다. 개발할 때 필요할 것 같은 기능상세정의 문서는 대략 템플릿 정도만 만들어두고 개발하면서 바로 AI 생성이 가능하게끔 준비했다. 목요일 퇴근 후, 금요일 출근 전에 약 1~2시간 정도 소요된 것 같다.계획은 백엔드, 프론트엔드 모두 개발할 생..
[Spring] 낙관적 락 / 비관적 락 비교하기
·
Spring Framework/Spring
한정된 수량의 쿠폰을 회원에게 발급하는 시스템에서는 동시 다발적인 요청으로 인해 동시성 문제가 발생할 수 있다. 선착순 쿠폰 발급 시나리오에서 낙관적 락과 비관적 락의 성능을 정량적으로 비교하고, 동시 접속자 수 변화에 따른 각 방식의 특성을 분석했다.실험 환경기술 스택Backend : Spring Boot, Spring Data JPA, PostgreSQL부하 테스트 : K6실행 환경 : 로컬 개발 환경 (단일 서버)시스템 설정별다른 튜닝은 적용하지 않았다.HikariCP max-pool-size: 20Tomcat max-threads: 100락 구현 방식비관적 락 (SELECT FOR UPDATE)낙관적 락 + 재시도 3회 + Exponential Backoff낙관적 락 + 재시도 10회 + Expo..
[JPA] 엔티티의 equals()와 hashCode()
·
Spring Framework/JPA
개요이전 포스팅에서 자바의 동등성(Equality)과 동일성(Identity), 그리고 equals()와 hashCode() 메서드에 대해 정리했다. 일반 자바 객체에서는 객체의 논리적 동등성을 판단하는 데 필요한 핵심 필드들을 선택하여 이 두 메서드를 오버라이딩한다.하지만 JPA 엔티티는 일반 객체와 다른 특성을 가지고 있어 주의가 필요하다:영속성 컨텍스트 관리: 같은 엔티티라도 다른 시점에 조회하면 다른 인스턴스일 수 있다프록시 객체: 지연 로딩 시 실제 엔티티가 프록시로 감싸진다ID 할당 시점: @GeneratedValue 사용 시 엔티티 생성 시점에는 ID가 null이고, persist 호출 후에야 ID가 할당된다이러한 특성으로 인해 JPA 엔티티에서는 equals()와 hashCode() 구현에..
[JPA] N+1 문제
·
Spring Framework/JPA
N+1 문제란 ORM 사용 시 발생하는 대표적인 성능 이슈부모 엔티티를 조회하는 1번의 쿼리 후, 각 부모마다 연관된 자식 엔티티를 조회하는 N번의 추가 쿼리가 실행되는 현상예시: 100개의 게시물과 댓글 있을 때게시글 전체 조회: 1번 + 각 게시글의 댓글 조회: 100번 ⇒ 총 101번의 쿼리가 실행모든 정보를 한 번의 쿼리로 가져오지 못하고 추가 쿼리로 인해 성능 이슈가 발생한다.문제 상황게시물(Post), 댓글(Comment) 엔티티가 있다.(이외의 테이블은 없다고 가정)게시물 목록 조회 시 각 게시물의 댓글 갯수를 함께 조회하고 싶다.@Entity@Table(name = "post")@NoArgsConstructor(access = AccessLevel.PROTECTED)@Getterpublic..
[Spring] tomcat 설정의 동작 원리(max-connections, accept-count, threads.max)
·
Spring Framework/Spring
Spring Boot로 웹 애플리케이션을 개발하면서 application.yml에 있는 Tomcat 설정들을 본적은 있지만 별 생각 없이 무심하게 지나쳤다. 하지만 이 설정들이 정확히 무엇을 의미하고, 어떤 역할을 하는지 궁금해 졌다.server: tomcat: max-connections: 8192 accept-count: 100 threads: max: 200본 포스팅에서는 Tomcat의 세 가지 핵심 설정인 accept-count, max-connections, threads.max가 클라이언트 요청을 처리하는 과정에서 각각 어떤 역할을 하는지 정리했다.설정들의 역할그 전에 알아야 할 것HTTP는 TCP를 기반으로 동작한다클라이언트와 서버간 연결을 위해 3-hand-sha..