일기 · 199

  1. 2026
  2. 9월
  3. 09.20 듀오링고리타분위기린
  4. 09.19 반값 설빙
  5. 09.18 우주 전쟁
  6. 4월
  7. 04.19 REBEL HEART
  8. 1월
  9. 01.20 e ∈ F
  10. 01.20 기술개발 진행상황 공유 1
  11. 01.20 기술개발 진행상황 공유 2
  12. 01.20 기술개발 진행상황 공유 3
  13. 01.15 항저우
  14. 2025
  15. 10월
  16. 10.24 어제까지의 이야기
  17. 10.09 돈 벌기
  18. 9월
  19. 09.02 PERFECT BLUE
  20. 8월
  21. 08.31 코코아분말 0.9%
  22. 08.30 WHAT THE
  23. 08.29 문을 닫고 들어오세요
  24. 08.28 하우스도르프 공간
  25. 08.27 All Time Low
  26. 08.26 세상의 끝을 겨눈대도
  27. 08.25 앉은 자리가 꽃자리
  28. 08.24 6과 7 사이 자연수
  29. 08.23 아직 아무 문제도 발견되지 않았습니다
  30. 08.22 Adventure
  31. 08.21 Adobe Creek
  32. 08.20 나의 무가지보(無價之寶)
  33. 08.19 T. Rex
  34. 08.18 누구를 위하여 종은 울리나
  35. 08.17 Sunday Morning
  36. 08.16 일상의 안녕
  37. 08.15 친애하는 우리의 결함에게
  38. 08.14 이것이 있으므로 저것이 있다
  39. 08.13 나는 나의 길을 간다
  40. 08.12 Vanilla Latte
  41. 08.11 그것은 하나의 가까움
  42. 08.10 정복 불허의 공간에
  43. 08.09 쉼 없이 수선하기
  44. 08.08 나는 전설이다
  45. 08.07 철판치즈버거
  46. 08.06 난 포기에 소질 있음
  47. 08.05 스피또런
  48. 08.04 하룻밤 만에
  49. 08.03 세상에 딱 하나뿐인
  50. 08.02 게으름뱅이를 위한 변명
  51. 08.01 북극 백화점
  52. 7월
  53. 07.31 사람은 무엇으로 사는가?
  54. 07.30 KRAFTON Yeoksam Office
  55. 07.29 Slowly flowing day
  56. 07.28 What's this?
  57. 07.28 Architectural Improvements 4
  58. 07.27 Lime Light
  59. 07.26 우리가 기다린 미래
  60. 07.25 Final approach
  61. 07.25 Poster Design Note : Form and Flow
  62. 07.25 Poster Design Note : How We Made It
  63. 07.24 폭풍의 눈
  64. 07.23 IYKYK
  65. 07.22 순살치킨 -> 치킨너겟
  66. 07.21 TRAIN - TRAIN
  67. 07.21 Architectural Improvements 3
  68. 07.21 Logo Design Note : The Logic of Flow
  69. 07.20 어떤 통찰도 지름길로는 얻을 수 없다
  70. 07.20 DeepDive : Many Over Mighty
  71. 07.19 시간이 느리게 가는 건
  72. 07.19 Architectural Improvements 2
  73. 07.19 DeepDive : GC-Triggered Stop-the-World
  74. 07.18 EVEREST
  75. 07.18 Architectural Improvements 1
  76. 07.18 PhantomFlow : High-performance HTTP request simulator
  77. 07.18 Introduction to Project KlickLab
  78. 07.18 What is Clickstream data?
  79. 07.17 깊은 사고는 더 이상 니즈가 없다
  80. 07.16 이기적인 토대 위
  81. 07.15 무엇이든, 언제가는
  82. 07.14 경험을 압축하는 알고리즘은 존재하지 않는다
  83. 07.13 무한한 가능성을 가질 것
  84. 07.12 화려한 거짓을 향해
  85. 07.11 Kentucky Fried Chicken
  86. 07.10 Tropical Blue
  87. 07.09 처음처럼 내 딛는
  88. 07.08 어제와 다른 하늘의 색
  89. 07.07 누군가의 달이었기를
  90. 07.06 아직 뜯지 않은 마음
  91. 07.05 황금의 오솔길
  92. 07.04 우리는 오가는 바람
  93. 07.03 Nic dwa razy
  94. 07.02 Never basic
  95. 07.01 입꼬리올림근
  96. 6월
  97. 06.30 그럼에도 불구하고
  98. 06.29 과잉포장된 자존심
  99. 06.28 E3i3
  100. 06.27 118
  101. 06.26 무한 우주에 순간의 빛일지라도
  102. 06.25 RUSH
  103. 06.24 그래, 우리는
  104. 06.23 The wind blowing low
  105. 06.22 피어나는 마음의 꽃
  106. 06.21 하나는 죽고, 하나는 살았다
  107. 06.20 초속일초
  108. 06.19 씨앗이 가장 고귀한 이유는
  109. 06.18 Evening Primrose
  110. 06.17 마음이 휑뎅그렁할 때
  111. 06.16 하나
  112. 06.15 강철무지개
  113. 06.14 유람
  114. 06.13 13일의 금요일
  115. 06.12 백만 스물하나, 백만 스물둘
  116. 06.11 경안천
  117. 06.10 달이 아름답네요
  118. 06.09 Tampermonkey
  119. 06.08 미르
  120. 06.07 나 평생 꿈만을
  121. 06.06 아르기닌
  122. 06.05 변속주
  123. 06.04 Global Running Day
  124. 06.03 가장 밝은 별
  125. 06.02 천천히
  126. 06.01 circular metal ring
  127. 5월
  128. 05.31 담장과 쪽문
  129. 05.30 투표런
  130. 05.29 출발선
  131. 05.28 Post Traumatic Growth
  132. 05.27 SET
  133. 05.26 READY
  134. 05.25 청복
  135. 05.24 열복
  136. 05.23 강제 푸시 반성합니다
  137. 05.22 유로파
  138. 05.21 떠오름과 저묾
  139. 05.20 Family Friend Fools
  140. 05.19 Time machine
  141. 05.18 맑은 일요일
  142. 05.17 흐린 토요일
  143. 05.16 PTG
  144. 05.15 셋이 만드는 하나
  145. 05.14 Lotte+Cafeteria
  146. 05.13 오십삼
  147. 05.12 일장춘몽
  148. 05.11 𝑬𝒗𝒆𝒓𝒍𝒂𝒏𝒅, 𝑬𝒗𝒆𝒓 𝑴𝒊𝒏𝒅
  149. 05.10 五月雨よ
  150. 05.09 Your Journey Starts Here
  151. 05.08 「권의 속도」
  152. 05.07 Quiet Air
  153. 05.06 놀자판 하루
  154. 05.05 뭔데이
  155. 05.04 After School
  156. 05.03 나침반이 가리킨 곳
  157. 05.02 짧은 하루
  158. 05.01 예고된 악재는 악재가 아니다
  159. 4월
  160. 04.30 Can More
  161. 04.29 초급반
  162. 04.28 감사합니다. 죄송합니다.
  163. 04.27 맥도날드 원정
  164. 04.26 무용(無用)의 쓸모
  165. 04.25 Sunny Day
  166. 04.24 벚나무 아래에서
  167. 04.23 언제나 이타카를 마음에 두라
  168. 04.22 D-100
  169. 04.21 수상한 미용실
  170. 04.20 손으로 컴퓨터를 마주하다
  171. 04.19 비가 오면 빨래를 하자
  172. 04.18 반차
  173. 04.17 발표, 청소, 러닝
  174. 04.16 반티 발주
  175. 04.15 첫 달리기
  176. 04.14 선택과 해석
  177. 04.13 Home Sweet Home
  178. 04.12 人生
  179. 04.11 반티 디자인 공모 & 제출
  180. 04.10 알고리즘의 끝, C언어의 시작
  181. 04.09 하와이안 스테이크
  182. 04.08 Long Chat
  183. 04.07 Es irrt der Mensch, solang' er strebt.
  184. 04.06 마무리
  185. 04.05 움직이는 물체의 시간은 느리게 간다
  186. 04.04 하나의 칼날
  187. 04.03 3x7=21
  188. 04.02 퀴즈 다음날, 시험 전날
  189. 04.01 April Fools' Day
  190. 3월
  191. 03.31 1년의 90번째 날
  192. 03.30 日曜日은 칠요일 중 첫째 날 이다
  193. 03.29 토요일은 주말이 아니다
  194. 03.28 그래프와 치킨버거
  195. 03.27 3주차의 시작
  196. 03.26 기초 다지기
  197. 03.25 기초 다지기 & 정리해야 할 CS 개념들
  198. 03.24 0.44%
  199. 03.23 본가 다녀온 날
  200. 03.22 문제 풀이에 집중한 하루
  201. 03.21 동료학습
  202. 03.20 첫번째 시험
  203. 03.19 먹다가 끝난 하루
  204. 03.18 눈이 쌓이면 버그도 쌓인다
  205. 03.17 깃허브, 팀별 면담, 키워드 공부
  206. 03.16 외출과 배달
  207. 03.15 첫 주말
  208. 03.14 컴퓨팅 사고로의 전환
  209. 03.13 cookie4u.store + 1주차 발제 + 회식
  210. 03.12 디지털 포춘쿠키
  211. 03.11 정글 입성
  212. 03.10 입소 당일

PhantomFlow : High-performance HTTP request simulator

KlickLab의 데이터 파이프라인은 고객의 모든 상호작용을 분석하는 것을 목표로 한다.
이는 대규모 트래픽을 지연 없이 처리해야 한다는 것을 의미했다.

시스템이 과연 피크 타임의 부하를 견딜 수 있는지,
병목 지점은 어디인지에 대한 답을 찾기 위해
실제와 같은 트래픽을 시뮬레이션할 강력한 도구가 필요했다.

그래서 우리는 자체적인 트래픽 생성 도구.
팬텀 플로우를 만들었다.


Version 1: simulate_launcher_cluster.js

초기 버전은 익숙하고 생산성이 높은 Node.js의 cluster 모듈을 활용해 멀티코어 기반의 트래픽 생성기로 만들어졌다. 간단한 테스트에는 충분했으나, 목표 성능을 향해 나아가면서 몇 가지 명확한 한계에 부딪혔다.

  • 높은 동시성에서의 RPS 불안정: 워커 수를 늘릴수록 성능이 선형적으로 증가하지 않고,
    특정 지점부터는 오히려 불안정해지는 현상이 발생했다.
  • 이벤트 루프 병목: CPU 집약적인 작업이 이벤트 루프에 부담을 주어 전체 처리량을 저하시켰다.
  • 제한적인 제어: 수천 개의 동시 연결에 대한 세밀한 제어가 어려웠다.
  • 성능 분석의 어려움: 내장된 프로파일링 기능이 부족했다.

운영체제(Windows) 자체의 한계

개발 및 초기 테스트는 주로 Windows 환경에서 이루어졌으며,
이로 인해 다음과 같은 운영체제 수준의 제약도 성능에 영향을 주었다.

  • 소켓 핸들 수 제한: Windows는 리눅스에 비해 동시에 열 수 있는 소켓(파일 디스크립터)의 수에 제한이 크고,
    커널 튜닝 여지도 적어 고부하 상황에 대응하기 어렵다.
  • 타이머 정밀도 문제: 고해상도 타이머가 필요한 경우에도 Windows는 정밀한 이벤트 스케줄링이 어렵고, 이는 고속 요청 분산에 영향을 줬다.
  • 네트워크 스택의 부하 내성 부족: Linux의 epoll에 비해 Windows의 IOCP 모델은 고성능 네트워크 처리를 위해 더 많은 설정과 관리가 필요했고, 예상보다 일찍 병목이 발생했다.
  • 프로세스 간 통신(IPC) 비용: Node.js의 cluster 모델에서 워커 간 메시지 전달 성능이 Windows에서는 Linux 대비 더 낮게 나타났다.

이러한 제약은 도구의 실제 성능과 확장성을 측정하는 데 장애 요소로 작용했으며, 이후 Linux 환경으로의 전환을 결정하게 된 또 하나의 계기가 되었다.


전환점 1: Go 언어

시스템의 한계를 돌파하기 위해 언어와 아키텍처를 재검토했고,
Go는 모든 요구사항에 대한 명쾌한 해답을 제시했다.

  • 고루틴 기반의 압도적인 동시성
  • 정교한 HTTP 클라이언트 제어
  • 내장 프로파일링 도구 pprof

전환점 2: Windows -> Linux

초기 개발은 Windows에서 이루어졌으나,
고부하 테스트를 진행하며 운영체제 수준의 명확한 한계에 직면했다.

  • 네트워크 성능: Linux의 epoll 모델은 Windows의 IOCP에 비해
    고성능 네트워크 처리에 더 최적화되어 있으며, 적은 커널 튜닝으로도 높은 성능을 보장한다.

  • 자원 관리 한계: Windows는 동시에 열 수 있는 소켓 핸들 수에 대한 제약이 더 크다.
    수만 개의 동시 연결을 시뮬레이션해야 하는 상황에서 이는 명백한 병목점으로 작용했다.


Version 2: PhantomFlow.Go

PhantomFlow는 Go로 재작성된 CLI 기반의 고성능 트래픽 시뮬레이터이다.

주요 목적

  • 실제 클릭스트림과 유사한, 고유하고 동적인 이벤트 데이터를 실시간으로 생성
  • 수천~수만 RPS 수준의 고속 트래픽을 안정적으로 발사
  • 성공/실패 요청 수 및 RPS를 1초 단위로 출력
  • pprof로 성능 병목 분석 가능

주요 최적화 포인트

  • sync.Pool: 문자열 생성 시 GC 압력 최소화
  • 고유 시드: 데이터 중복 방지
  • 커스텀 http.Transport: 연결 수 조정 및 안정성 강화
  • KST 타임스탬프: 로그 시간 비교 용이

실행 예시

빌드

go build phantomflow.go

실행

# 시간 기반 모드 (5분 동안 512 워커로 실행)
./phantomflow -d 300 -c 512 http://YOUR-NLB-ENDPOINT/api/analytics/collect

# 요청 수 기반 모드 (100만 개 요청, 256 워커로 실행)
./phantomflow -n 1000000 -c 256 http://YOUR-NLB-ENDPOINT/api/analytics/collect

출력 예시

2025-07-18 21:30:01 [진행] 성공: 153024, 실패: 18, RPS: 5098.12
2025-07-18 21:30:02 [진행] 성공: 158210, 실패: 18, RPS: 5186.00

pprof를 활용한 실시간 성능 분석

코드에 포함된 pprof 서버 덕분에 부하 테스트 중에도 PhantomFlow의 내부를 들여다볼 수 있다.

// 단 한 줄로 활성화되는 강력한 프로파일링 서버
go func() {
  _ = http.ListenAndServe("localhost:6060", nil)
}()

SSH 터널링 예시 (EC2 환경)

ssh -L 6060:localhost:6060 -i your-key.pem ubuntu@your-ec2-ip

이후 브라우저에서 아래 주소로 접속

http://localhost:6060/debug/pprof/

결론

Node.js로 시작하여 Go로 전환하고, AWS 환경에 맞춰 최적화하는 과정을 통해
PhantomFlow는 KlickLab의 데이터 수집 파이프라인을 검증하는 핵심 도구가 되었다.

이 도구는 인프라의 한계를 사전에 파악하고,
병목 지점을 개선하며, 사용자에게 항상 안정적인 서비스를 제공할 수 있게 해준다.

GitHub 저장소: https://github.com/Eatventory/PhantomFlow

댓글