푸른영혼의 별 | Tech Blog

Java Backend Engineer의 기술 블로그입니다.
Spring Boot, MSA, JPA, Kafka, Kubernetes 등 실무 경험을 공유합니다.

주요 프로젝트: Settlement MSA · ASAT · GitHub


Posts (총 505편 · 25 / 51 페이지)

  • *아키텍처 *vs *SOLID *vs *의존성 역전 (DIP) *vs *의존성 주입 (DI)* — *4 개 가 *왜 *자꾸 *섞이는가*

    “아키텍처 가 *중요하다”“SOLID 를 *지켜야 한다”“DIP 를 *적용 했다”“Spring 의 *DI 를 *쓴다”같은 *뜻 으로 말하는 사람과 *이 4 개 가 *서로 다른 *층서로 다른 *개념 이라고 말하는 사람은 *PR 리뷰완전히 다르게 *한다.

    4 개 는 *서로 *포함 / 실현 / 근거관계 다. 아키텍처시스템 전체경계와 흐름, SOLID클래스/모듈 수준5 가지 *설계 원칙, DIPSOLID 의 *D추상화 의 *방향대한 원칙, DIDIP 를 *실현 하는 구현 기법 중 하나. 위 → 아래추상도 가 *낮아지고 *구체성 이 *높아진다.

    이 글은 4 개 의 *경계그려 흔한 *오해 (예: “DI = DIP”, “SOLID = 아키텍처”, “Spring 쓰면 *아키텍처 좋아짐”) 를 분해 한다. Java + Spring 기준 예제 로 같은 *코드4 개 *층 에서 각자 *무엇을 *해결 했는지보인다.

  • *객체지향* 의 *핵심 가치* — *역할 · 책임 · 협력* 의 *진짜 의미* 와 *settlement 에서 의 *살아있는 적용***

    “객체지향이 뭐예요?” 라고 물으면 대부분 “클래스, 상속, 다형성, 캡슐화” 라고 답한다.

    그런데 알란 케이 (Alan Kay) — 객체지향이라는 단어를 만든 사람 은 말했다 :

    “I’m sorry that I long ago coined the term ‘objects’ for this topic because it gets many people to focus on the lesser idea. The big idea is messaging.”

    “오래전 ‘objects’ 라는 용어를 만든 것을 후회한다. 사람들이 *더 작은 개념 에 집중하게 만들었다. 진짜 큰 아이디어 는 *메시징”*

  • *객체 지향 개발* 에서 *테스트 를 학습* 한다는 것 의 *의미* — *JUnit 을 외우는 일* 이 아니라 *생각 의 형태 를 바꾸는 일**

    “테스트 를 학습 한다”처음 듣는 신입 에게 이 말JUnit 의 어노테이션외우는 일 처럼 들린다. @Test, assertEquals, Mockito.when().thenReturn()문법 학습.

    그러나 *9 년 을 지나고 보면 이 단어 의 *진짜 의미전혀 다른 영역 에 있다. *테스트 를 배운다 는 것은 내 코드 의 *형태 자체바꾸는 학습. 내 객체 가 *어떻게 *남과 대화 하는지, 어디서 *경계 가 깨지는지, 무엇이 *내 책임 이고 무엇이 *남의 책임 인지 를 눈에 보이는 형태드러내는 학습*.

    즉 *테스트 의 학습객체 지향 의 학습다른 이름.

  • *DB 배치 처리* 의 *성능 향상* *2 축* — *커버링 인덱스* (테이블 안 보기) + *데이터 청킹* (한 번에 다 안 들기)

    settlement-service월 정산 집계 배치. 수억 row 의 *결제 데이터셀러 별합산. 처음 *돌렸을 때 *6 시간 걸림. *튜닝 후 *18 분. 20 배 단축.

    마법 은 없었다. 두 가지 만 *제대로 한 결과. *커버링 인덱스 + 데이터 청킹.

  • 오프셋 과 어셈블리어 의 관계 — 어셈블리어 는 결국 오프셋 의 산술 언어 였다는 깨달음

    gdb 에서 disas main 을 친다. 화면 가득 수십 줄 의 어셈블리. 무엇이 보이는가 :

    mov    -0x10(%rbp), %rax       ; rbp 에서 -16 만큼 떨어진 곳
    call   0x4011a0 <printf@plt>    ; 현재 위치 에서 *상대* 점프
    mov    0x20(%rdi), %rcx         ; rdi 가 가리키는 곳 에서 +32
    lea    0x2e9b(%rip), %rsi       ; 현재 명령어 의 *다음 주소* 에서 *상대*
    jne    0x401234                 ; 조건 분기 — *상대* 오프셋
    

    전부 *오프셋. 예외 없이. 어셈블리어 의 *모든 메모리 접근, 모든 호출, 모든 분기, 모든 변수결국 *기준점 + 거리산술**.

  • *CPU 와 *DB* 의 *관계* — *메모리 와 *SSD* 를 *포함* 해서 *하드웨어 → 기계어 → 어셈블리 → 자바* 4 단 으로 *내려간다*

    “DB 가 *느리다” 라고 말하는 사람과 *“이 SELECT 가 *L3 미스 → DRAM 1 회 + SSD random read 1 회 + JIT 컴파일 안 된 ResultSet 루프 라서 느리다” 라고 말하는 사람은 *프로파일러를 *완전히 다르게 *읽는다.

    DB 한 줄 의 *결과 가 *Java 의 *Long id 에 들어오기까지 — CPU → L1 → L2 → L3 → DRAM → NVMe SSD → 페이지 캐시 → DB 버퍼풀 → JDBC → JIT → JVM Heap최소 8 개 의 *계층통과 한다. 각 계층 의 지연 시간 (latency)수십 배 / 수천 배 / 수십만 배불연속 적 으로 튄다.

    이 글은 그 한 줄어떻게 *흐르는지하드웨어 → 기계어 → 어셈블리 (x86-64) → 자바 (JDBC + JIT)4 단 추상화내려가 *분해 한다. 4 단동시에 *볼 수 있게 되면 *프로파일러의 *flame graph 도, DB 의 *EXPLAIN ANALYZE 도, GC 로그같은 *언어읽힌다.

  • *APM* 과 *응답 시간 분포* — *백엔드 서버 개발자* 의 시각 에서 *왜 평균 이 거짓말 인가*

    “우리 평균 응답 200ms 인데요”. 그런데 사용자 한 명Slack 으로 “왜 *오늘 결제 가 *10 초씩 걸리냐” 한다.

    둘 다 사실. 평균 이 200ms 라는 것99 명 이 *50ms 인데 1 명 이 *15,000ms 라는 극단 적 분포수학적 으로 동일 할 수 있다.

    백엔드 서버 개발자책임평균 을 보는 것아니라 *분포 를 보는 것. 그리고 *그 분포 의 *long tail왜 길어졌는지추적 가능 하게 만드는 것 — 그 도구 가 APM.

  • *Kubernetes 의 로드밸런서* — *L4 (Service) vs L7 (Ingress)* 의 *네트워크 계층* 과 *알고리즘 의 *진실*

    K8s 로드밸런서의 네트워크 계층 — 알고리즘 비교표 L4 (Service) 의 kube-proxy 는 iptables 모드 = *랜덤 선택, IPVS 모드 = round-robin. L7 (Ingress) 의 nginx-ingress = round-robin, Traefik = weighted round-robin. 같은 “로드밸런서” 라도 계층과 도구 에 따라 알고리즘 이 다르다.*

  • *AI 코드 PR* 머지 전, *7 가지 질문* — *vibe coding 의 *마지막 게이트***

    AI 코드 PR 머지하기 전, 7 가지 질문 AI 가 만든 코드의 PR 머지 전 던져야 할 7 가지 질문 — 신뢰할 수 없는 입력 / 동시 요청 / 경계값 / 외부 의존 다운 / 100만 건 데이터 / 도메인 규칙 / 로그·알람. Rule of thumb: “이게 운영에서 죽을 수 있는 5 가지 시나리오는?” — 머지 전 항상.

  • *ELK + Beats* — *Filebeat / Logstash / Elasticsearch / Kibana* 의 *4 단계* 와 *production 로깅 의 *진짜 그림*

    Beats + ELK — 경량 수집기 추가 (운영 표준) 서비스/앱 → Filebeat (경량 수집) → Logstash (파싱·변환) → Elasticsearch (색인·검색) → Kibana (시각화). 이 4 단계 의 *각자 책임 분리 가 production 로깅 의 진짜 그림.*