인기 글

여행 동행 참여에 대해 동시성 문제 해결하고 성능 비교 해보기
·
Spring
개요현재 여행 동행 모집 프로젝트를 진행하는 중에, 동행 참여에 대한 동시성 이슈가 발생했다. 1. 동시성 문제 발생 원인여행 동행 모임 참여 로직은 다음과 같다.멤버가 우동(동행 모임)에 대해 참여 요청을 보낸다.참여할 수 있는지 유효성 검증을 한다. (인원 체크, 기존 참여 여부 확인 등)우동에 대기자로 등록한다.관리자가 승인하면 동행에 최종 참여된다.한 우동에 대해 대기자는 최대 5명만 가능하기 때문에, 처음에는 대기자 객체를 생성할 때 대기자 수를 체크했다.public class WaitingMember { public static WaitingMember of(Udong udong, Long memberId, int currentWaitingMembersCount) { ..
스프링MVC는 왜 스레드를 최대 200개까지 사용할까?
·
Spring
스프링 MVC는 웹 애플리케이션 개발에서 널리 사용되는 프레임워크이다.많은 사람들이 스프링을 왜 쓰냐 하면 거의 다 "스레드가 많아서", "대규모 트래픽 처리할 수 있어서"라고 한다.사실 스레드 개수 문제가 아니다 🙅‍♀️node.js는 적은 스레드로 논블로킹을 사용해서 충분히 트래픽을 처리한다. 스프링 MVC 기준 스레드 풀의 max값은 200이다.server: tomcat: threads: max: 200 # 생성할 수 있는 thread의 총 개수 min-spare: 10 # 항상 활성화 되어있는(idle) thread의 개수 max-connections: 8192 # 수립가능한 connection의 총 개수 a..
그래서 커넥션 풀 사이즈는 어떻게 설정하라구요?
·
Operating System
커넥션 풀이란?커넥션 풀은 데이터베이스 연결을 미리 생성하여 저장하고, 클라이언트 요청 시 이를 재사용하는 방식이다. 웹 애플리케이션 서버(WAS)가 실행되면 데이터베이스와의 연결 객체를 생성해 풀(pool)에 저장하고, 클라이언트 요청이 오면 이를 빌려주며 작업이 끝나면 반납받아 다시 저장한다. 커넥션 풀이 왜 필요할까?커넥션 생성에는 높은 비용이 발생한다고 한다. 아래는 한 행을 insert 하는 데 드는 시간을 나타낸다.(괄호 안의 숫자는 비율을 나타낸다)// MySQL 8.0 Documentation // https://dev.mysql.com/doc/refman/8.0/en/insert-optimization.htmlConnecting: (3)Sending query to server: (2) ..
JVM Warm-up, feat. 스프링 첫 요청이 오래 걸리는 이유
·
Java & OOP
원인웹 애플리케이션을 실행한 후 초기 요청이 지연되는 현상을 이해하려면, 자바 프로그램이 실행되는 방식을 깊이 살펴볼 필요가 있다.C, C++과 같은 컴파일 언어는 소스 코드를 기계어로 직접 변환하여 최적화된 성능을 제공하나 빌드 환경에 종속적이라는 단점이 있다.즉, 플랫폼이 바뀌면 재컴파일이 필요하다. 자바는 이러한 플랫폼 종속적인 문제를 해결하고자 JVM을 도입하였다.자바는 자바 코드는 컴파일 시 바이트 코드로 변환되고, 실행 시 JVM이 이를 기계어로 변환하여 실행한다.이러한 구조 덕분에 Java는 플랫폼에 종속되지 않게 되었지만, 이 과정에서 변환 작업이 추가되므로 성능에 영향을 미칠 수 있다. 1. 클래스 로더JVM에서 클래스 로더(Class Loader)는 바이트 코드를 메모리에 로드하는 역할..
JVM 구조와 동작 과정
·
Java & OOP
자바를 공부하다 보면 Write once, run anywhere (한 번 작성하면, 어디서나 실행된다.) 라는 말을 볼 수 있다. 컴퓨터가 어떤 프로그램을 실행하려면, 컴퓨터가 읽을 수 있는 언어(기계어)로 작성되어야 한다.자바 프로그램에서는 JVM(Java Virtual Machine)이라는 가상머신이 우리가 작성한 java코드를 기계어로 변환해 주고, 어떤 운영체제에서도 이 코드가 실행될 수 있도록 도와주는 역할을 한다.즉, JVM 덕분에 OS에 독립적인 특징을 가지고 있는 것이다. JVM 작동 원리우리가 작성한 코드가 JVM에 전달되어 실행되기까지 과정은 아래와 같다. 개발자가 자바 소스코드(.java)를 작성한다.자바 컴파일러(javac)가 자바 소스코드를 자바 바이트코드(.class)로 컴파일..
로또 코드 예제로 이해해 보는 객체 지향 설계 5원칙(SOLID)
·
Java & OOP
스프링 입문을 위한 자바 객체 지향의 원리와 이해를 보고 5장은 꼭 정리해야겠다 싶어서 예시와 함께 이해해 보려고 노력했다! 이 원칙들은 주기적으로 봐야 할 것 같아서 포스팅한다...! 개요SOLID는 객체 지향 프로그래밍의 설계 원칙으로, 로버트 C. 마틴(Robert C. Martin)이 제시한 다섯 가지 원칙이다. 마이클 페더스(Michael Feathers)가 이를 두문자어로 정리하여 널리 알려졌다. SOLID의 5대 원칙SRP(Single Responsibility Principle): 단일 책임 원칙OCP(Open Closed Principle): 개방 폐쇄 원칙LSP(Liskov Substitution Principle): 리스코프 치환 원칙ISP(lnterface Segregation Pr..
싱글톤 패턴은 thread safe하지 않다?(개선 방식 4가지)
·
Java & OOP
싱글톤 패턴은 클래스의 인스턴스를 하나만 생성하고, 어디서든 이를 접근할 수 있도록 하는 디자인 패턴이다.나도 기본적인 싱글톤 구현 방식으로만 알고 있었는데, 이 방식이 멀티 스레드 환경에서 안전하지 않다는 얘기를 듣고 알아보게 되었다!  기본 싱글톤 구현 (Lazy Initialization)class Singleton { // 싱글톤 클래스 객체를 담을 인스턴스 변수 private static Singleton instance = null; // 생성자를 private로 선언 (외부에서 new 사용 X) private Singleton() {} // 외부에서 정적 메서드를 호출하면 그제서야 초기화 진행 (lazy) public static Singleton getIns..
스레드 로컬(Thread Local)이란?
·
Java & OOP
스레드 로컬이란?ThreadLocal은 멀티스레드 환경에서 각 스레드가 독립적인 데이터를 저장하고 관리할 수 있도록 지원하는 메커니즘이다. 여러 스레드가 동시에 실행되는 애플리케이션에서는 공유 데이터로 인해 경쟁 상태(race condition)가 발생할 수 있다.이러한 문제를 방지하기 위해 데이터를 스레드 간에 독립적으로 관리해야 할 때 ThreadLocal을 사용할 수 있다.  스레드 로컬이 필요한 이유1. 스레드 간 데이터 충돌 방지멀티스레드 환경에서 동일한 데이터를 여러 스레드가 동시에 접근하면, 의도치 않은 결과가 발생할 수 있다.(ex. race condition) ThreadLocal은 각 스레드가 독립적인 데이터를 유지할 수 있도록 하여 이런 충돌을 방지한다. 2. 세션 및 사용자 정보 관..
프로세스와 스레드
·
Operating System
프로세스와 스레드란?프로그램프로그램은 윈도우의 .exe 파일이나 Mac의 .dmg 파일과 같은 컴퓨터에서 실행할 수 있는 파일을 통칭한다.,단 아직 실행되지 않은 상태의 코드 덩어리를 의미한다. 프로세스프로세스는 실행 중인 프로그램을 말한다, 모든 프로그램은주소 공간, 파일, 메모리 등 자원이 필요한데 운영체제로부터 이 자원을 할당받은 프로그램을 의미한다. 스레드스레드는 프로세스 내에서 동시에 진행되는 흐름의 단위이다. 과거에는 프로그램을 실행할 때 하나의 프로세스만 사용했다.예를 들어, 파일을 다운로드하면 다운로드가 끝날 때까지 다른 작업을 수행할 수 없었다.기술이 발전하며 프로그램이 점점 더 복잡해지면서 단일 프로세스로는 한계가 있었고, 여러 프로세스를 사용하면 메모리를 낭비하고 CPU 자원을 중복..

최신 글

1장. 사용자 수에 따른 규모 확장성 - (3) 샤딩, 메시지 큐, 자동화
·
📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초
가상 면접 사례로 배우는 대규모 시스템 설계 기초를 읽고 정리한 글입니다. 무상태(stateless) 웹 계층이제 웹 계층을 수평적으로 확장하는 방법을 고민해 볼 순서다. 먼저 상태 정보(예: 사용자 세션 데이터)를 웹 서버 안에서 제거해야 한다.왜냐하면 서버마다 상태를 따로 가지고 있으면, 로드밸런서가 클라이언트 요청을 특정 서버로만 보낼 수밖에 없기 때문이다. 바람직한 전략은 이 상태 정보를 관계형 데이터베이스나 NoSQL 같은 지속성 저장소에 보관하고, 필요할 때 가져오는 방식이다. 1. 상태 정보 의존적인 아키텍처상태 정보를 보관하는 서버는 클라이언트 정보, 즉 상태를 유지하여 요청들 사이에 공유되도록 한다.사용자 A의 세션 정보나 프로파일 이미지 같은 상태 정보는 서버 1에 저장된다.사용자 A를..
1장. 사용자 수에 따른 규모 확장성 - (2) 캐시, CDN
·
📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초
가상 면접 사례로 배우는 대규모 시스템 설계 기초를 읽고 정리한 글입니다. 캐시웹 계층과 데이터 계층을 넘어, 시스템의 응답 시간(latency)을 개선하려면 캐시를 도입하는 것이 중요하다.응답 시간은 캐시(cache)를 붙이고 정적 컨텐츠를 콘텐츠 전송 네트워크(CDN)로 옮기면 개선할 수 있다. 캐시는 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 보관해, 뒤이은 요청을 더 빠르게 처리할 수 있도록 돕는 저장소이다.위 설계에서는, 사용자가 웹 페이지를 새로고침할 때마다 데이터를 가져오기 위해 데이터베이스를 계속 호출한다.애플리케이션의 성능은 데이터베이스를 얼마나 자주 호출하느냐에 크게 좌우되는데, 캐시는 그런 문제를 완화할 수 있다. 캐시 계층(cache tier)캐시 계층은 데이터가 잠시 보..
1장. 사용자 수에 따른 규모 확장성 - (1) 규모 확장성의 기초
·
📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초
가상 면접 사례로 배우는 대규모 시스템 설계 기초를 읽고 정리한 글입니다. 단일 서버처음에는 단 한 대의 서버에서 실행되는 간단한 시스템부터 설계해 본다.웹, 앱, 데이터베이스, 캐시 등이 전부 서버 한 대에서 실행되는 구조이다.이 구조에서 사용자 요청 처리 흐름을 살펴보자사용자는 api.mysite.com 같은 도메인 이름으로 접속한다.접속을 위해 도메인 이름 서비스(DNS)를 통해 IP 주소로 변환해야 한다. DNS는 보통 제3 사업자(third party)가 제공하는 유료 서비스를 이용하며, 시스템 내부 요소는 아니다.DNS 조회 결과로 웹 서버의 IP 주소가 반환된다.해당 IP 주소로 HTTP 요청이 전달된다.웹 서버는 요청을 처리하여 HTML 페이지나 JSON 응답을 반환한다. 데이터베이스 분..
99클럽 코테 스터디를 수료하며
·
항해99 코테 스터디
시작 계기 개발자 오픈채팅방에서 정보를 얻어 시작하게 된 코테 스터디를 드디어 수료하게 되어 후기를 남긴다.이직 준비로 인해 코딩 테스트를 계속 준비해야 했기에, 스스로에게 강제성을 부여하고자 시작하게 되었다. 조금 더 심화된 알고리즘 공부를 하고 싶어 자바/미들러 반을 선택했다.조금 어렵긴 했지만, 결과적으로 좋은 선택이었다고 생각한다. 확실히 뒤로 갈수록 난이도가 높아져 힘들기도 했지만 😵‍💫 그래도 만족스럽다. 강제성 부여 굿 매일 코테를 풀었는지, TIL을 작성했는지 카톡 알림이 오기 때문에 누워 있다가도 "아 맞다!" 하고 일어나서 하게 된다.최근에 면접 최탈하면서 살짝 번아웃이 와서 공부를 좀 놨는데, 이거라도 있어서 그나마 다시 책상에 앉을 수 있었다.중간에 제주도 여행을 다녀왔는데 이거..
99클럽 코테 스터디 13일차 TIL + JadenCase 문자열 만들기
·
항해99 코테 스터디
- 오늘의 학습 키워드JadenCase 문자열 만들기- 풀이class Solution { public String solution(String s) { StringBuilder sb = new StringBuilder(); boolean isStart = true; for (char c : s.toCharArray()) { if (c == ' ') { sb.append(c); isStart = true; } else { if (isStart) { sb.append(Character.toUpperCase(c));..
99클럽 코테 스터디 12일차 TIL + 포도주 시식
·
항해99 코테 스터디
- 오늘의 학습 키워드포도주 시식- 풀이import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] wine = new int[n + 1]; // 1-based index for (int i = 1; i = 1) dp[1] = wine[1]; if (n >= 2) dp[2] = wine[1] + wine[2]; for (int i = 3; i - 오늘의 회고dp[i]는 i번째 포도주까지 고려했을 때, 최대로 마실 수 ..