웹 서비스 전체 구조와 운영체제

(URI) Uniform Resource Identifier자원을 식별하는 가장 큰 개념. (URL) Uniform Resource Locator리소스가 어디에 있는지 위치를 나타내는 것.URL은 URI에 포함되는 관계이다. HTTP 메시지는 ASCII 문자열로 되어있다. HTTP/1.1까지는 텍스트 기반이라 직관적이지만 무거웠다. 그래서 HTTP/2.0부터는 바이너리(이진) 프레이밍 계층으로 나누어 전송 HTTP 메시지 구조Start Line (시작 줄): HTTP/1.1 200 OK (201, 400, 401, 404, 500 등 응답 코드)Header (헤더): 메타 데이터 (Content-Type, 쿠키 등)Empty Line (공백 라인): 헤더와 바디를 구분Message Body (본문): ..

2026.03.30
CS

비대해진 Drive 서비스 리팩토링 및 권한 상속 모델을 적용한 드라이브 자원 공유

기존 구조와 문제초기에는 DriveController에서 단일 DriveService를 주입받아 모든 비즈니스 로직을 처리하는 구조였다.DriveController └── DriveService └── DriveEmbeddingService DriveEmbeddingScheduler └── DriveEmbeddingService 이 구조에서 DriveService는 다음과 같은 다양한 역할을 홀로 비대하게 수행하고 있었다.폴더의 생명주기 관리 (생성, 이동, 삭제, 수정 등)파일의 생명주기 관리 (생성, 이동, 삭제, 수정 등)드라이브 자체의 관리 및 유저 식별AI 연동 질의 시 참조될 파일 및 폴더 관리기능이 추가될수록 단일 클래스가 비대해졌고, 코드의 가독성과 확장성이 떨어졌다. 각 도메인..

2026.03.29

[인프런 김영한] 실전 데이터베이스 설계 1

자연 키 vs 대리 키비즈니스 로직에서 자연스럽게 생성되는 의미가 있는 값인 자연 키는 변경 가능성이 있다.PK가 변경된다는 것은, 이와 연관관계를 맺고 있는 모든 테이블의 FK가 변경되어야 함을 의미한다.이는 FK 제약 조건 위반, 데이터 역사성 왜곡, 외부 시스템 연동 문제 등의 심각한 문제를 야기한다.즉, PK는 절대 변하지 않는 값인 대리 키 (Auto Increment, UUID 등)로 설정해주어야 한다.따라서 비즈니스 로직과 무관한 대리 키를 PK로 설정함으로써 느슨한 결합을 해주는 것이다.대리 키는 PK로 자연 키는 UNIQUE로 복합 키복합 키를 구성할 때 자연 키들로 구성한다면 비즈니스 변화에 취약해진다.복합 키를 구성하고 있는 모든 키를 FK로 가지고 있어야 하므로 쓰기/조회 성능 ..

2026.03.29

OAuth 2.0과 JWT를 활용한 Spring Security 로그인 개념 정리

※ 이 글은 최주호님의 인프런 강의 '스프링부트 시큐리티 & JWT 강의'을 기반으로 학습한 내용을 정리한 것입니다. 세션 기반 로그인Web Server는 무상태이기 때문에 로그인한 사용자를 기억하지 못한다.그래서 WAS는 메모리 공간에 HttpSession 객체(세션)를 생성하고, 로그인한 유저에 대한 정보를 해당 객체 내부에 저장한다. 이것이 사용자 정보를 세션에 저장한다 라는 의미이다.그리고 해당 세션 정보 전체를 주지 않고, 해당 유저를 찾을 수 있는 세션 ID만 생성해서 발급해서 HTTP 응답 헤더(Set-Cookie)에 담아서 브라우저에 전달해준다.이렇게 발급된 세션 ID를 브라우저는 쿠키에 저장해두고, 요청마다 요청 헤더에 자동으로 쿠키(세션 ID)를 서버에 전달해서 최초 로그인 후에는 로그..

2026.02.23

재고 차감으로 알아보는 동시성 제어 - DB, Redis 락

※ 이 글은 최상용님의 인프런 강의 '재고시스템으로 알아보는 동시성이슈 해결방법'을 기반으로 학습한 내용을 정리한 것입니다. 자바 synchronized@Service@RequiredArgsConstructorpublic class StockService { private final StockRepository stockRepository;// @Transactional public synchronized void decrease(Long id, Long quantity) { Stock stock = stockRepository.findById(id).orElseThrow(); stock.decrease(quantity); stockRepository..

2026.02.21
[인프런 김영한] 스프링 트랜잭션 AOP, 커밋/롤백, 전파 썸네일

[인프런 김영한] 스프링 트랜잭션 AOP, 커밋/롤백, 전파

트랜잭션 AOP 이해 @Transactional이 적용된 특정 메서드나 클래스가 하나라도 있다면, 트랜잭션 AOP는 프록시를 만들어서 스프링 컨테이너에 등록한다.그리고 프록시가 내부에서 실제 basicService를 참조하게 된다. 만약 호출되는 함수가 트랜잭션 적용 대상이라면, 트랜잭션을 먼저 시작하고 basicService.tx()를 호출한다.트랜잭션 적용 대상이 아니라면, 그냥 바로 basicSerivec.nonTx()를 호출한다. 트랜잭션 AOP 초기화 시점 주의사항@SpringBootTestpublic class InitTxTest { @Autowired Hello hello; @Test void go() { } @TestConfiguration stat..

2026.02.18
AI 연동형 사내 드라이브 시스템 썸네일

AI 연동형 사내 드라이브 시스템

드라이브 시스템 사용자는 개인 드라이브에 폴더를 만들거나 파일을 업로드할 수 있다. 드라이브에 파일을 업로드하면, 벡터 임베딩 스케줄러에 의해 벡터 임베딩을 시켜 벡터 DB에 저장되도록 하며 임베딩이 완료되기 전까지는 해당 파일을 통해 질의를 할 수 없다. 또한 폴더 하위에 임베딩이 완료되지 않은 파일이 있다면 해당 폴더를 선택해서 질의할 수 없다. 폴더 하위라는 것은, 그 어떤 모든 자손 폴더 및 파일을 말한다. 드라이브에서 파일과 폴더를 선택해서 질의하면, 해당 폴더에 들어있는 모든 하위 파일들 및 선택한 파일에 대해 답변을 해준다.사용자가 선택한 폴더 하위(하위의 하위 등 모든 자손)에 있는 모든 파일들과 폴더가 아닌 직접 선택한 파일들에 대해 id를 추출해서 RAG가 참조할 수 있도록 ..

2026.02.08
[인프런 김영한] 자바 예외 썸네일

[인프런 김영한] 자바 예외

예외 계층 최상위 예외 객체인 Throwable을 상속받는 Exception과 Error 중에, 잡아야 하는 예외는 Exception 이다. Error는 잡으려고 하면 안되기 때문이다.Exception은 체크 예외 (컴파일 시점에서 체크하는), RuntimeException은 언체크 예외 (컴파일 시점에 체크하지 않는) 체크 예외public class CheckedAppTest { @Test void checked() { Controller controller = new Controller(); Assertions.assertThatThrownBy(controller::request) .isInstanceOf(Exception.class);..

2026.02.08
[인프런 김영한] 스프링과 트랜잭션 썸네일

[인프런 김영한] 스프링과 트랜잭션

순수한 서비스 계층서비스 계층은 특정 기술에 종속적이지 않게 개발해야 한다. 즉, 기술에 종속적인 부분은 프레젠테이션 계층(UI), 데이터 접근 게층에서 가지고 간다.이렇게 해야, 나중에 기술이 변경되더라도 비즈니스 로직을 담당하는 서비스 계층은 수정하지 않을 수 있다. 트랜잭션 동기화 매니저 스프링은 트랜잭션 동기화 매니저를 제공해서, 한 트랜잭션 내에서 동일한 커넥션을 사용하도록 한다.트랜잭션 매너지가 데이터소스를 통해 커넥션을 만들면 트랜잭션 동기화 매니저에 보관하고, 레포지토리가 이 트랜잭션 동기화 매니저에 저장된 해당 커넥션을 가져다 쓰는 방식으로 동일한 커넥션을 유지하는 것.덕분에 파라미터로 커넥션을 넘기지 않아도 된다.트랜잭션 동기화 매너지가 관리하는 커넥션이 없으면, 새로운 커넥션을 ..

2026.02.05