API 응답 속도를 빠르게 만드는 방법
·
Backend
서비스를 운영하다 보면 가장 자주 듣는 말 중 하나가 바로 “API 속도 좀 개선해 주세요.” 다. 사용자가 느린 응답을 경험하면 서비스 만족도는 즉시 떨어지고, 심하면 이탈까지 이어진다. 그렇다면 서버 개발자는 API 응답 속도를 어떻게 개선할 수 있을까?방법은 다양하지만 많은 프로젝트에서 가장 효과가 높고 적용 난도가 적당한 것이 바로 캐싱(Caching) 과 페이징(Pagination) 처리다.이 글에서는 실제로 제가 여러 프로젝트를 진행하면서 경험한 내용을 중심으로 왜 이 두 가지가 중요한지, 어떻게 적용하는지, 각각의 장단점은 무엇인지 정리해본다.API 성능은 왜 느려질까?API가 느려지는 원인은 크게 세 가지다.1) DB 조회 부하복잡한 조인대량 데이터 Full Scan인덱스 미사용명령어 자체..
@Transactional 동작 원리
·
Backend
“Spring의 트랜잭션은 어떻게 DB 트랜잭션과 연결될까?”Spring을 사용하다 보면 거의 반사적으로 @Transactional을 붙인다.서비스 코드 상단에 조용히 선언해두면 여러 SQL 실행이 하나의 묶음처럼 처리(commit)되고 오류가 나면 자동으로 되돌아간다.(rollback)하지만 막상 “Spring이 이걸 어떻게 수행하지? 진짜 DB의 트랜잭션과는 어떻게 연결되는 걸까?” 라고 물으면 설명이 흐려지는 경우가 많다.이번 글에서는@Transactional이 실제로 무엇을 하고 어떤 흐름으로 DB 트랜잭션과 묶이는지 그리고 프로젝트를 하면서 고민해봤던 부분과 문제 해결 경험을 가볍게 곁들여 정리해본다.Spring의 @Transactional은 “프록시 기반 AOP”로 시작된다핵심은 이거다.@Tr..
폐쇄망 환경에서 서로 다른 두 DB를 다뤄야 할 때
·
Backend
현재 진행 중인 프로젝트는 공공기관 시스템으로, 온프레미스 환경에서 전자정부프레임워크(eGovFrame) 기반으로 개발 중이다.그런데 예상치 못한 구조적 문제가 하나 있었다.서비스 로직상 서로 다른 두 개의 데이터베이스(DB A, DB B) 를 동시에 조회하고, 심지어 일부 기능에서는 두 DB의 테이블을 조인해야 하는 상황이 발생했다. 예를 들어보면 아래와 같은 케이스다.DB_A.user 와 DB_B.approval 테이블을 조인해야 하는 업무 로직이 있음두 DB 모두 user 테이블을 가지고 있어, 데이터 싱크를 맞춰야 하는 이슈도 존재함처음에는 단순히 DataSource를 두 개 선언해서 해결될 줄 알았지만 막상 실제 조인이 필요한 부분에서 iBatis나 MyBatis 수준에서는 처리 불가한 제약이 ..
온프레미스 환경에서 무중단 배포(Zero Downtime Deployment) 구축 방안 탐구기
·
Backend
최근 회사에서 진행 중인 공공기관 시스템 구축 프로젝트를 맡게 되었다.공공기관 특성상 보안 정책이 매우 엄격해서, 클라우드 인프라를 활용할 수 없고 완전한 온프레미스(On-Premise) 환경 위에서 서비스를 운영해야 했다.그런데 배포 절차를 살펴보다가 이런 부분이 눈에 띄었다.“배포 중에는 서비스가 중단될 수 있습니다.공지 후 재배포를 진행하세요.”즉, 배포 과정에서 서비스 중단이 전제된 구조였다.하지만 요즘 사용자는 1~2분의 중단에도 민감하게 반응한다.그래서 “이 온프레미스 환경에서도 무중단 배포가 가능할까?”라는 궁금증이 생겼고,그걸 직접 조사하고 정리해본 내용을 기술 블로그 형태로 남겨보려 한다.무중단 배포란 무엇인가?무중단 배포(Zero Downtime Deployment)는 말 그대로 서비스..
REST API
·
Backend
REST API란 무엇이고, 좋은 API 디자인 규칙은?서버 개발을 하다 보면 가장 자주 듣는 단어 중 하나가 바로 API입니다.그중에서도 특히 REST API는 거의 모든 웹 서비스에서 기본처럼 사용되고 있죠.이번 글에서는 REST API란 무엇인지, 그리고 좋은 API 디자인 규칙은 무엇인지 정리해보겠습니다.1. API란 무엇인가?API (Application Programming Interface)뜻: "어플리케이션끼리 데이터를 주고받을 수 있는 인터페이스"👉 쉽게 말해, 서버와 클라이언트가 대화하는 창구입니다.예를 들어:클라이언트: “아이디 1번 유저 정보 좀 줘!”서버: “여기 있어요. 이름은 홍길동이고, 나이는 25살입니다.”이때 요청과 응답의 규칙을 정해놓은 것이 바로 API입니다.2. R..
JPA(Java Persistence API)
·
Backend
JPAJPA를 쓰다 보면 이론만 알았을 때는 상상하지 못한 문제들이 터집니다.저도 개인 프로젝트에서 여러 번 부딪혔고, 그때마다 구글링 + 디버깅으로 해결책을 찾아야 했습니다.이번 글에서는 제가 실제로 겪었던 문제들을 정리하면서, 여러 해결 방법과 각각의 장단점까지 비교해보겠습니다.1. N+1 문제문제 상황게시판 프로젝트에서 Post와 Comment를 1:N 관계로 매핑했습니다.게시글 목록을 조회하면서 댓글 수도 함께 보여주고 싶었는데, 단순히 postRepository.findAll()을 호출하니 쿼리가 엄청나게 많이 나가더군요.@Entitypublic class Post { @Id @GeneratedValue private Long id; private String title; ..
쿠키 vs 세션 vs JWT
·
Backend
쿠키 vs 세션 vs JWT웹 개발을 하다 보면 항상 부딪히는 주제가 있습니다. 바로 사용자 인증(로그인)이에요.“사용자가 로그인했는지, 로그인했다면 누구인지”를 서버가 어떻게 기억할까요?여기서 쿠키(Cookie), 세션(Session), JWT(Json Web Token)이 등장합니다.1. 쿠키(Cookie)정의: 브라우저에 저장되는 작은 데이터 조각저장 위치: 클라이언트(브라우저)용도: 로그인 상태 유지, 사용자 설정(언어, 테마 등) 저장특징:서버가 응답할 때 Set-Cookie 헤더를 내려주면, 브라우저가 저장이후 같은 도메인에 요청할 때 자동으로 쿠키를 함께 보냄👉 예시내가 로그인 후 페이지를 새로고침했는데 계속 로그인 상태로 남아있는 것 = 쿠키 덕분2. 세션(Session)정의: 서버가 사..
캐시(Cache)
·
Backend
캐시(Cache)란? 서버 개발자가 꼭 알아야 할 개념웹 서비스를 만들다 보면 "속도"와 "부하" 문제를 필할 수 없습니다.이때 자주 언급되는 해결책이 바로 캐시(Cache) 입니다.1. 캐시(Cache)란?자주 쓰이는 데이터를 임시로 저장해두는 공간다시 같은 데이터를 요청할 때, 원본 데이터베이스(DB)나 외부 API까지 가지 않고, 캐시에 저장된 값을 빠르게 반환👉쉽게 말하면 "자주 쓰는 물건을 방 안에 두고 쓰는 것"과 비슷합니다.냉장고(캐시)에 음료를 두면, 마트(DB)까지 갈 필요가 없는 거죠.2. 캐시가 중요한 이유속도 향상DB를 직접 조회하지 않고 빠르게 응답 가능서버 부하 감소동일한 요청을 여러 번 처리할 때 효율적비용 절감외부 API 호출을 줄여 비용이나 트래픽 절약3. 캐시의 종류(1..
멀티 스레드
·
Backend
멀티 스레드 멀티 스레드 개념 운영체제는 실행 중인 프로그램을 프로세스로 관리한다. 두 가지 이상의 작업을 처리해야 할 때는 멀티 프로세스를 생성해서 처리하기도 한다. 하지만 멀티 태스킹이 꼭 멀티 프로세스를 뜻하지는 않는다. 하나의 프로세스 내에서 멀티 태스킹을 할 수 있도록 만들어진 프로그램들도 있다. 예를 들어 메신저는 채팅 작업을 하면서 동시에 파일 전송 작업을 수행하기도 한다. 하나의 프로세스가 두 가지 이상의 작업을 처리할 수 있는 이유는 멀티 스레드가 있기 때문이다. 스레드는 코드의 실행 흐름을 말하는데, 프로세스 내에 스레드가 두 개라면 두 개의 코드 실행 흐름이 생긴다는 의미이다. 멀티 프로세스가 프로그램 단위의 멀티 태스킹이라면 멀티 스레드는 프로그램 내부에서의 멀티 태스킹이라고 볼 수..
싱글톤 패턴
·
Backend
싱글톤 패턴 애플리케이션 전체에서 단 한 개의 객체만 생성해서 사용하고 싶다면 싱글톤(Singleton) 패턴을 적용할 수 잇다. 싱글톤 패턴의 핵심은 생성자를 private 접근 제한해서 외부에서 new 연산자로 생성자를 호출할 수 없도록 막는 것이다. 생성자를 호출할 수 없으니 외부에서 마음대로 객체를 생성하는 것이 불가능해진다. 대신 싱글톤 패턴이 제공하는 정적 메소드를 통해 간접적으로 객체를 얻을 수 있다. 다음은 싱글톤 패턴의 전체 코드이다. public class Singleton { //private 접근 권한을 갖는 정적 필드 선언과 초기화 private static Singleton singleton = new Singleton(); //private 접근 제한을 갖는 생성자 선언 pri..
Getter와 Setter
·
Backend
Getter와 Setter 객체의 필드(데이터)를 외부에서 마음대로 읽고 변경할 경우 객체의 무결성(결점이 없는 성질)이 깨질 수 있다. 예를 들어 자동차의 속력은 음수가 될 수 없는데, 외부에서 음수로 변경하면 객체의 무결성이 깨진다. Setter 이러한 문제점 때문에 객체 지향 프로그래밍에서는 직접적인 외부에서의 필드 접근을 막고 대신 메소드를 통해 필드에 접근하는 것을 선호한다. 그 이유는 메소드는 데이터를 검증해서 유효한 값만 필드에 저장할 수 있기 때문이다. 이러한 역할을 하는 메소드가 Setter이다. public class GetterAndSetterPractice { private double speed; public void setSpeed(double speed) { if(speed <..
접근 제한자
·
Backend
접근 제한자 경우에 따라서는 객체의 필드를 외부에서 변경하거나 메소드를 호출할 수 없도록 막아야 할 필요가 있다. 중요한 필드와 메소드가 외부로 노출되지 않도록 해 객체의 무결성(결점이 없는 성질)을 유지하기 위해서이다. 자바는 이러한 기능을 구현하기 위해 접근 제한자(Acces Modifier)를 사용한다. 접근 제한자는 public, protected, private의 세 가지 종류가 있다. 접근 제한자 제한 대상 제한 범위 접근 제한자 생성자 설명 public 클래스, 필드, 생성자, 메소드 없음 protected 필드, 생성자, 메소드 같은 패키지이거나, 자식 객체만 사용 가능 (default) 클래스, 필드, 생성자, 메소드 같은 패키지 private 필드, 생성자, 메소드 객체 내부 클래스의 ..