본문 바로가기
반응형

전체 글426

[개발자일기] 대 ai 시대 결국 중견기업으로 이직한 4년차 비전공자 개발자 이야기 지금도 인기글이 기계공학 분야인 내 블로그에 지지않고 개발자일기를 쓰고있는 나...ㅎㅎ \\ 나는 또다시 이직을 했다.b2b에서 b2c솔루션회사에서 sm 회사로중소기업에서 중견기업으로 나는 총 2번의 이직을 했었고, 이번이 3번째이다. (중간에 이상한거 껴있는거 빼면은 3번...)4년의 경력에 비해서는 많은 수의 이직이긴 하다. (근데 내가 이번에 느낀건데, 이직안하는 개발자들은 오히려 실력이 부족한것같다. 걍내생각...) 기계공학과를 졸업해서 공기업까지 찍먹했던 나는결국 기계공학의 현실을 받아들이고 it 업계로 도망갔다. https://gallery-k.tistory.com/480 백앤드 프레임워크를 개발하는 b2b 솔루션 회사... 여기서 많은것들을 배웠다.인터넷 강의에서는 알려주지 않는 것들. .. 2026. 8. 30.
고객사 서버는 왜 멈췄을까 (2) | 메모리 문제인 줄 알았는데 범인은 좀비 스레드... 지난 글에서 내가 내린 결론지난 글( https://gallery-k.tistory.com/494 )에서 고객사 서버 먹통(Hang)을 응급조치하고 왔다. 그때 내린 결론은 이거였다. - 스레드 덤프를 보니 261개가 다 WAITING(parking), 거의 다 놀고 있다.- 데드락도 없다(BLOCKED 0) - 그러니 먹통의 원인은 "스레드 밖", 즉 JVM 메모리(Metaspace 99% / Old 94%)다 - 일단 힙·메타스페이스 차등 배분으로 틀어막고 옴 서버실 사용 시간이 끝나서 급하게 마무리했는데 집에 와서 계속 신경쓰이는게 두 개 있었다. 1. Metaspace가 99%까지 찼다는데 — 그럼 그 클래스들 대체 누가 다 만들었지? 2. parking 261개 — 진짜 "노는" 스레드가 맞나?.. 2026. 6. 25.
같은 트랜잭션 안에서 REQUIRES_NEW가 자기 자신과 데드락 거는 법 부모1 트랜잭션이 아직 커밋 안 한 채로 어떤 행에 락을 쥐고 있는데, 그 상태에서 REQUIRES_NEW 자식을 호출하고 자식이 같은 행을 건드리면 멀티유저가 아니어도 단일 요청 내부에서 교착이 난다. 1. 이슈 (증상) 코드 품질 검사를 도는 오케스트레이터에 "통과 기록 보정"을 위한 사전 정리(pre-clear) DELETE를 한 줄 추가했더니, 그 직후부터 H2 락 타임아웃이 터지기 시작했다. 에러: H2 "50200" / LOCK_TIMEOUT / "... locked by tx 1 ... can not be updated by tx 2"발생지점: 검사 도구(PMD 등)의 결과 처리 DELETE 단계타이밍: 약 2000ms(H2 기본 LOCK_TIMEOUT) 대기 후 타임아웃대상행: 직전.. 2026. 6. 24.
백앤드 공부 목록 | 네트워크 / 인프라 / Spring / Java / CS 기초 / DB / 인증 / 보안 백앤드 공부 목록 네트워크 / 인프라https://gallery-k.tistory.com/500 - 로드밸런서 L4와 L7, Spring Boot 서버 앞에서는 무엇이 다를까 https://gallery-k.tistory.com/499 - 서버 이중화는 OS 두 대로 끝나지 않는다 | 운영 환경에서 서버 이중화 https://gallery-k.tistory.com/497 - OSI 7계층 (사실 4계층) 으로 요청 흐름 알아보기 https://gallery-k.tistory.com/481 - [네트워크] 세션 클러스터링 | 이중화 시 서버들이 사용자를 기억하는 방법 https://gallery-k.tistory.com/479 - [네트워크] 이중화(HA) 및 세션 관리, 로드밸런서 이중화 | 끊기지 않.. 2026. 6. 23.
로드밸런서 L4와 L7, Spring Boot 서버 앞에서는 무엇이 다를까 /home/aml/sampleserver 이 프로젝트는 온프레미스 환경에서 도는 Spring Boot 프로젝트이다. (라고 예시를 들어보자)이 서버는 SERVER_PORT=15740으로 스프링부트 서버를 띄우고있다. 이 프로젝트 기준으로 보면 서버는 이렇게 뜬다. export SERVER_PORT=15740export SERVER_PORT_STR="server.port=$SERVER_PORT"export MMB_SERVER_URL_STR="MMB.SERVER_URL=http://localhost:$SERVER_PORT/SamplePrj"즉 스프링부트 서버가 15740 포트에서 뜨고, 서비스 URL은 http://서버IP:15740/SamplePrj 형태이다. L4/L7은 보통 “로드밸런서가 요.. 2026. 6. 23.
서버 이중화는 OS 두 대로 끝나지 않는다 | 운영 환경에서 서버 이중화 서버이중화실무에서 가장 흔한 의미는 OS/VM/물리 장비도 2대 이상 둔다는 뜻이다. 특정 스프링부트 프로젝트에서 자바 프로세스를 띄울 때 이렇게띄운다고 치자. "$JAVA_HOME/bin/java" -Xms512m -Xmx1024m \ -Djavax.ws.rs.ext.RuntimeDelegate=cohttp://m.sun.ws.rs.ext.RuntimeDelegateImpl \ -Xlog:gc*,gc+heap=debug:file="$GC_LOG":time,uptime,level,tags:filecount=10,filesize=20M \ -XX:+HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath="$LOG_DIR" \ -Dfile.encoding=UTF-8 \ .. 2026. 6. 22.
DB 커넥션 풀(Connection Pool) 관리 | 적정 풀 사이즈, 각종 타임아웃, 커넥션 누수 이번에 이런 일이 있었는데 하필 서버시간이 부족해서 DB 커넥션 풀을 확인하지 못했다.https://gallery-k.tistory.com/494 그래서 이번주에 한번 더 찾아가서 볼 예정인데, 그전에 DB 커넥션을 좀 공부해보려고 한다. 커넥션 풀애초에 커넥션 풀이 왜 필요할까? (L4와 TCP의 한계) TCP 통신은 꼼꼼해서 매번 '3-Way Handshake(인사 3번)'를 한다. - '나 데이터 보낸다? 준비됐어?'- '어 받을 준비됐어! 너도 보낼 준비됐지?'- '응 준비끝! 이제진짜 보낸다!' 백엔드 서버가 DB에 쿼리를 날릴 때도 똑같다. 유저가 로그인 버튼을 누를 때마다 서버가 DB랑 3-Way Handshake(인사 3번)' 을 한다. 그런데 매번 데이터를 받아올 때마다"안녕? 연.. 2026. 6. 14.
OSI 7계층 (사실 4계층) 으로 요청 흐름 알아보기 만약 이 페이지로 접속을 했다고 치면...192.168.100.186:15738/index.html밑에와 같은 여러 요청을 보내게 된다. 192.168.100.186:15738/getData192.168.100.186:15738/getImage192.168.100.186:15738/getExcel 요청흐름L7. 응용 계층 (Application)/getData (URL 경로), HTTP 메서드(GET/POST), 쿠키/웹 세션 정보아, /getData 경로로 GET 요청을 보내는구나. 쿠키에 내 로그인 정보도 담아서 HTTP 규격에 맞게 편지를 쓰자. L6. 표현 계층 (Presentation)데이터의 형식 (JSON, XML 등)과 암호화편지 내용이 한국어(UTF-8)네? 컴퓨터가 읽게 인코딩하고,.. 2026. 6. 14.
[Java] 동적 로딩, 동적으로 객체 만들기 | 일반 방식으로 객체를 만들 때와 차이점 동적 로딩은클래스 이름을 코드에 직접 쓰지 않고, 문자열로 받아서 실행 중에 객체를 만드는 방식이다. 일반 방식으로 객체를 만들 때는 이렇게 한다. new DefaultAdapter(info); 방식은 DefaultAdapter 클래스명이 코드에 박혀 있다. 그래서 다른 객체를 생성하려면 Java 코드를 수정하고 다시 빌드해야 한다. 동적 로딩 후 객체 생성은 이렇게 하면 된다. className = "com.inswave.xxx.CustomAdapter";Class adapterClass = ElBeanUtils.getClass(className);Constructor constructor = adapterClass.getConstructor(Map.class);Object obj = const.. 2026. 6. 13.
[Java] 동적으로 객체를 만들 때 고려해야 할 것 | 리플렉션, 캐시 사내 소스코드를 보다가 공부할 내용이 있는 것 같아서 정리해보려고 한다. 사내에 adapter 패턴으로 고객사의 구현체를 동적으로 확장할 수 있는 기능이 있다.(객체 동적으로 만들기 https://gallery-k.tistory.com/496)그런데 동적으로 만들다보니 객체를 만들 때 new 로 만드는게 아니라 문자열로 만든다. (리플렉션)Class adapterClass = ElBeanUtils.getClass(className);Constructor constructor = adapterClass.getConstructor(Map.class);Object obj = constructor.newInstance(adapterInfoMap);리플렉션으로 어댑터를 만드는 건 비싸니까 한 번 만든 어댑터는 .. 2026. 6. 13.
[JVM] 트러블슈팅 | 실제로 일어난 메모리(힙, 메타스페이스) 부족으로 인한 서버 무응답(Hang) 현상 고객사에 설치한 프로그램이 너무 느리다고 해결좀 해달라고 그래서 방문함. - 운영체제 (OS) Oracle Linux Server 9.5 (커널 5.14.0)- CPU 스펙 Intel(R) Xeon(R) Gold 6442Y / 16 Core- 디스크 및 저장 공간 루트(/) 파티션: 총 300GB 중 164GB 사용 (약 55% 사용, 137GB 여유) 백업(/appbackup) 파티션: 총 3.9TB의 대용량 스토리지 연결됨. 2.3TB 사용 중이며 1.6TB 여유 기타 파티션: /application, /logs, /installpgm 등 주요 디렉토리들이 독립된 볼륨으로 분리- CPU 상태 매우 쾌적함 Load Average (0.38, 0.31, 0.33): 시스.. 2026. 6. 10.
[Spring] 스프링 컨테이너의 ConcurrentHashMap '스프링 컨테이너' 를 뜯어보면결국 가장 깊숙한 곳에 있는 것은 단 하나의 Map 객체이다. 스프링의 실제 핵심 클래스인 DefaultSingletonBeanRegistry (빈을 등록하고 관리하는 클래스)의 코드를 열어보면 다음과 같은 변수가 선언되어있다고 한다.// 실제 스프링 프레임워크 내부 코드 (개념적 요약)public class DefaultSingletonBeanRegistry { // 1급 비밀 금고: 완성된 싱글톤 빈들이 저장되는 곳 private final Map singletonObjects = new ConcurrentHashMap(256); // ...} Key (String): 빈의 이름 (예: userServiceImpl)Value (Object): H.. 2026. 6. 7.
[Spring] Spring 빈과 가비지 컬렉션 | 사실 대표적인 싱글톤 패턴 Spring 빈Spring 빈의 진짜 정체: 특별한 건 없다. Spring 빈(Bean)이라고 하면 왠지 Spring만의 특별한 메모리 공간에 저장될 것 같지만결론부터 말하자면 "Spring 빈 전용 메모리 영역" 같은 것은 존재하지 않는다. 모든 Spring 빈은 자바의 일반 객체와 똑같이 Heap 영역에 생성된다. 일반 객체와 Spring 빈의 유일한 차이점은 '누가 그 객체를 쥐고 있느냐' 일반 객체는 지역 변수가 가리키는 동안만 살아있다가 변수가 사라지면 가비지 컬렉터(GC)에 의해 청소된다. Spring 빈은 Spring 컨테이너가 계속해서 가리키고 있기 때문에 서버가 종료될 때까지 죽지 않고 살아있다. 결국 우리가 흔히 말하는 '싱글톤(Singleton)'이라는 단어도 특별한 공간에 저장된.. 2026. 6. 7.
[Java] 싱글톤(Singleton) 패턴 싱글톤싱글톤(Singleton) 패턴을 가장 쉽게 이해하는 방법은 "대한민국(=JVM)에는 단 한 명의 대통령(=싱글톤)만 존재한다"고 생각하는 것이다. 대통령은 1명만 존재한다.모든 국민이 "대통령"을 찾으면 모두가 같은 사람을 가리킨다.누구도 임의로 2번째 대통령을 만들어낼 수 없다. 자바도 마찬가지이다. 3명의 호출자가 `특정ServiceImpl`을 부르더라도, 결국 모두가 가리키는 것은 하나뿐인 '대통령' 인스턴스이다. 이렇게 단 하나만 만드는 이유는 1. 메모리 절약똑같은 일을 하는 객체를 호출할 때마다 100개, 1000개씩 만들면 메모리가 낭비되기 때문이다. 2. 상태 공유모두가 같은 객체를 바라봐야 캐시나 설정값의 일관성이 유지되기 때문이다. 3. 리소스 보호DB 커넥션 풀이나 동시성.. 2026. 6. 6.
[Spring] AOP 프록시와 Aspect 알아보기 DemoControllerInterceptor 가 MethodInterceptor 인터페이스를 implements 한 Aspect 인데,이 Interceptor 가 모든 Controller 호출을 invoke 메서드로 감싼다.DefaultPointcutAdvisor 로 order=0 으로 등록해서 가장 먼저 끼어들도록 해뒀다. (AOP 인터셉터를 Controller 실행 전에 가장 먼저 동작하도록 등록했다는 뜻이다.)MethodInterceptor를 구현했다 -> Controller 메서드 호출을 감싸는 공통 로직이 있다 DefaultPointcutAdvisor로 등록했다 -> 이 인터셉터를 어떤 메서드들에 적용할지 지정했다 order=0으로 등록했다 -> 여러 AOP가 있을 때 가장 먼저 실행되도록 우.. 2026. 6. 6.
반응형