Skip to content

Payment Load Test

SilberBullet edited this page Aug 23, 2026 · 8 revisions

๐Ÿ”ฅ Payment ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ

Mock PG๋กœ ๊ฒฐ์ œ confirm๊นŒ์ง€ ๋ถ€ํ•˜ํ…Œ์ŠคํŠธํ•˜๋‹ค๊ฐ€ ์ฐพ์€ HikariCP ์ปค๋„ฅ์…˜ ํ’€ ์ž๊ธฐ์ž ์‹ ๋ฐ๋“œ๋ฝ ๊ธฐ๋ก


๋ชฉ์ฐจ

  1. ๋ฐฐ๊ฒฝ
  2. Mock PG
  3. 1์ฐจ โ€” 30 threads, HikariCP ํ’€ ๋ถ€์กฑ ํ™•์ธ
  4. 2์ฐจ โ€” ํ’€์„ 20์œผ๋กœ ๋Š˜๋ ธ๋”๋‹ˆ ์˜คํžˆ๋ ค ์•…ํ™” โ†’ ์ง„์งœ ์›์ธ
  5. ๊ถŒ์žฅ ํ•ด๊ฒฐ ๋ฐฉํ–ฅ
  6. ์žฌํ˜„ ๋ฐฉ๋ฒ•

๋ฐฐ๊ฒฝ

POST /payment/payments/confirm์€ ์™ธ๋ถ€ PG(Toss)๋ฅผ ์‹ค์ œ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋™์•ˆ ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์—์„œ ์ œ์™ธ๋˜์–ด ์žˆ์—ˆ๋‹ค. ์ด๋ฒˆ์— Mock PG๋ฅผ ๋งŒ๋“ค์–ด confirm๊นŒ์ง€ ํฌํ•จํ•œ ์ „์ฒด ํ๋ฆ„์„ ๋ถ€ํ•˜ํ…Œ์ŠคํŠธํ–ˆ๊ณ , ๊ทธ ๊ณผ์ •์—์„œ ํ’€ ํฌ๊ธฐ๋กœ๋Š” ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” ์‹ค์ œ ๋™์‹œ์„ฑ ๊ฒฐํ•จ์„ ์ฐพ์•˜๋‹ค. ๋„๋ฉ”์ธ ๊ตฌ์กฐ์™€ API ์ „์ฒด๋Š” Payment ์ฐธ๊ณ .


Mock PG

PaymentTossClientAdapter๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” baseUrl์€ ์„ค์ •์œผ๋กœ ์™„์ „ํžˆ ์™ธ๋ถ€ ์ฃผ์ž…๋˜๋ฏ€๋กœ, ์•ฑ ์ฝ”๋“œ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ์ด ๊ฐ’๋งŒ ๋กœ์ปฌ ์„œ๋ฒ„๋กœ ๋Œ๋ฆฌ๋ฉด confirm ์ „์ฒด(๋ฝ ํ•ด์ œ ์‹œ์ , ํŠธ๋žœ์žญ์…˜ ๋ถ„๋ฆฌ, ์ง€๊ฐ‘ ์ถฉ์ „๊นŒ์ง€)๋ฅผ ๋ถ€ํ•˜ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณ„๋„ ์˜์กด์„ฑ ์—†์ด JDK ๋‚ด์žฅ HttpServer๋งŒ์œผ๋กœ MockTossServer.java๋ฅผ ์ž‘์„ฑํ–ˆ๊ณ , ๊ธฐ์กด ๋‹จ์œ„ํ…Œ์ŠคํŠธ(TossPaymentAdapterTest.kt)๊ฐ€ WireMock์œผ๋กœ ์ด๋ฏธ ๊ฒ€์ฆํ•ด ๋‘” ์‹ค์ œ ์š”์ฒญ/์‘๋‹ต ํฌ๋งท์„ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ž๋‹ค.

JMeter ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ๋งค ๋ฐ˜๋ณต prepare๋กœ ์ƒˆ ๊ฒฐ์ œ๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ ์‘๋‹ต์„ ๊ทธ๋Œ€๋กœ confirm์— ํ˜๋ ค๋ณด๋‚ด๋Š” ์ฒด์ด๋‹ ๊ตฌ์กฐ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค (confirm์€ READY ์ƒํƒœ์— ๋Œ€ํ•ด ๋‹จ ํ•œ ๋ฒˆ๋งŒ ์„ฑ๊ณตํ•˜๋ฏ€๋กœ).


1์ฐจ โ€” 30 threads, HikariCP ํ’€ ๋ถ€์กฑ ํ™•์ธ

30 threads๋กœ ๋ถ€ํ•˜๋ฅผ ๊ฑธ์ž confirm ์„ฑ๊ณต๋ฅ ์ด 58%(80/138)๋กœ ๋–จ์–ด์กŒ๋‹ค. Prometheus๋กœ ํ™•์ธํ•œ 5๋ถ„ ๊ตฌ๊ฐ„ ์ง€ํ‘œ:

์ง€ํ‘œ ๊ฐ’
hikaricp_connections_active ์ตœ๋Œ€ 10 (๊ธฐ๋ณธ ํ’€ ํฌ๊ธฐ)
hikaricp_connections_pending ์ตœ๋Œ€ 30
confirm ํ‰๊ท  ์‘๋‹ต์‹œ๊ฐ„ (์ผ๋ถ€ ๊ตฌ๊ฐ„) 30~60์ดˆ

confirm 1๊ฑด์ด prepare 1ํšŒ + confirm ๋‚ด๋ถ€ ํŠธ๋žœ์žญ์…˜ 2ํšŒ, ์ด DB ์™•๋ณต 3๋ฒˆ์„ ํ•„์š”๋กœ ํ•˜๋Š”๋ฐ 30๋ช…์ด think-time ์—†์ด ๋ชฐ์•„์น˜์ž ๊ธฐ๋ณธ ํ’€(10)์ด ๊ทธ๋Œ€๋กœ ๋ฐ”๋‹ฅ๋‚ฌ๋‹ค โ€” ์—ฌ๊ธฐ๊นŒ์ง€๋Š” ํ•ฉ๋ฆฌ์ ์ธ "์šฉ๋Ÿ‰ ๋ถ€์กฑ" ๊ฒฐ๋ก ์ด์—ˆ๋‹ค.


2์ฐจ โ€” ํ’€์„ 20์œผ๋กœ ๋Š˜๋ ธ๋”๋‹ˆ ์˜คํžˆ๋ ค ์•…ํ™” โ†’ ์ง„์งœ ์›์ธ

maximum-pool-size: 20์œผ๋กœ ๋Š˜๋ฆฌ๊ณ  ์žฌ๊ฒ€์ฆํ•˜๋‹ˆ ์˜ˆ์ƒ๊ณผ ๋ฐ˜๋Œ€๋กœ confirm ์„ฑ๊ณต๋ฅ ์ด 1.5%(1/66)๋กœ ๋” ๋‚˜๋น ์กŒ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ DB์—” ์‹ ๊ทœ APPROVED๊ฐ€ 9๊ฑด์ธ๋ฐ confirm 200 ์‘๋‹ต์€ 1๊ฑด๋ฟ์ด์—ˆ๋‹ค โ€” 8๊ฑด์€ ์„œ๋ฒ„์—์„œ ์‹ค์ œ๋กœ ์ฒ˜๋ฆฌ(์ง€๊ฐ‘ ์ถฉ์ „๊นŒ์ง€)๋์ง€๋งŒ ํด๋ผ์ด์–ธํŠธ๊ฐ€ 60์ดˆ ๋„˜๊ฒŒ ๊ธฐ๋‹ค๋ฆฌ๋‹ค ๋จผ์ € ํƒ€์ž„์•„์›ƒ์œผ๋กœ ํฌ๊ธฐํ•œ ๋’ค ์‘๋‹ต์ด ๋„์ฐฉํ•œ ๊ฒƒ์ด๋‹ค.

๋ถ€ํ•˜ ๊ตฌ๊ฐ„์˜ HikariCP ์ถ”์ด:

active:  0, 17, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, ...   โ† ์ตœ๋Œ“๊ฐ’์— ๊ณ ์ •, ์ „ํ˜€ ์•ˆ ํ’€๋ฆผ
pending: 0,  0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, ...   โ† ๋Œ€๊ธฐ์—ด๋„ ๊ณ ์ •, ์ „ํ˜€ ์•ˆ ์ค„์–ด๋“ฆ

ํ’€์ด ๋ถ€์กฑํ•ด์„œ ์ค„์„ ์„œ๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ์™„๋ฃŒ๋˜๋Š” ์š”์ฒญ์ด ์ƒ๊ธธ ๋•Œ๋งˆ๋‹ค ๊ฐ’์ด ์˜ค๋ฅด๋‚ด๋ ค์•ผ ํ•œ๋‹ค. 100์ดˆ ๊ฐ€๊นŒ์ด ์™„์ „ํžˆ ํ‰ํ‰ํ–ˆ๋‹ค๋Š” ๊ฑด ๊ทธ ์‹œ๊ฐ„ ๋™์•ˆ ๋‹จ ํ•˜๋‚˜๋„ ๋๋‚˜์ง€ ๋ชปํ–ˆ๋‹ค๋Š” ๋œป์ด๋‹ค (๋ถ€ํ•˜๊ฐ€ ๋๋‚˜๋ฉด ๊ณง๋ฐ”๋กœ active=0, idle=20์œผ๋กœ ํšŒ๋ณต๋˜๋ฏ€๋กœ ๋ˆ„์ˆ˜๋Š” ์•„๋‹ˆ์—ˆ๋‹ค).

30 threads, pool=10 โ€” ๋Œ€๊ธฐ(pending)๊ฐ€ 30๊นŒ์ง€ ํŠ€๋Š” ๊ตฌ๊ฐ„

๊ทธ๋ฆผ 1 โ€” pool=10์ผ ๋•Œ ๋Œ€๊ธฐ๊ฐ€ 30๊นŒ์ง€ ํŠ€๋Š” ์ฒซ ๋ฒˆ์งธ ๋ถ€ํ•˜ ๊ตฌ๊ฐ„ image

Note

์œ„ ์Šคํฌ๋ฆฐ์ƒท โ€” active๊ฐ€ ํ’€ ์ตœ๋Œ“๊ฐ’(20)์—, pending์ด 30์— ๋ชป ๋ฐ•ํžŒ ์ฑ„ ๋ถ€ํ•˜๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๋‹จ ํ•œ ์นธ๋„ ์›€์ง์ด์ง€ ์•Š๋Š”๋‹ค. ์ •์ƒ์ ์ธ "ํ’€ ๋ถ€์กฑ"์ด๋ผ๋ฉด ์™„๋ฃŒ๋˜๋Š” ์š”์ฒญ์ด ์ƒ๊ธธ ๋•Œ๋งˆ๋‹ค ๋‘ ๊ฐ’์ด ์˜ค๋ฅด๋‚ด๋ ค์•ผ ํ•˜๋ฏ€๋กœ, ์ด ์™„์ „ํ•œ ์ˆ˜ํ‰์„  ์ž์ฒด๊ฐ€ ๋ฐ๋“œ๋ฝ์˜ ์ฆ๊ฑฐ๋‹ค.

๊ทผ๋ณธ ์›์ธ โ€” ์ปค๋„ฅ์…˜ ํ’€ ์ž๊ธฐ์ž ์‹ ๋ฐ๋“œ๋ฝ: confirm์˜ ๋‘ ๋ฒˆ์งธ ํŠธ๋žœ์žญ์…˜์€ DB ํŠธ๋žœ์žญ์…˜์„ ์—ฐ ์ฑ„๋กœ ๊ทธ ์•ˆ์—์„œ ์ง€๊ฐ‘ ์„œ๋น„์Šค๋ฅผ gRPC๋กœ ๋ธ”๋กœํ‚น ํ˜ธ์ถœํ•œ๋‹ค. ์ด ์•ฑ์€ ๋ชจ๋†€๋ฆฌ์Šค๋ผ ์ง€๊ฐ‘ gRPC ์„œ๋ฒ„๊ฐ€ ๊ฐ™์€ JVM, ๊ฐ™์€ HikariCP ํ’€์„ ์“ฐ๋Š”๋ฐ, ๊ทธ ํ•ธ๋“ค๋Ÿฌ๋„ ์ž๊ธฐ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๊ฐ™์€ ํ’€์—์„œ ์ปค๋„ฅ์…˜์„ ํ•˜๋‚˜ ๋” ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

sequenceDiagram
    participant C as confirm ์Šค๋ ˆ๋“œ (x N)
    participant Pool as HikariCP ํ’€ (size=20)
    participant W as Wallet gRPC ํ•ธ๋“ค๋Ÿฌ

    C->>Pool: โ‘  ์ปค๋„ฅ์…˜ ํš๋“ (Payment Tx2 ์˜คํ”ˆ)
    Note over C,Pool: ํ’€์˜ ์ปค๋„ฅ์…˜์ด ์ „๋ถ€ โ‘ ์—์„œ ์†Œ์ง„๋  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
    C->>W: โ‘ก getWallet/chargePoints (๋ธ”๋กœํ‚น, ์ปค๋„ฅ์…˜ ์ฅ” ์ฑ„๋กœ ๋Œ€๊ธฐ)
    W->>Pool: โ‘ข ์ž๊ธฐ ์ฟผ๋ฆฌ์šฉ ์ปค๋„ฅ์…˜ ์š”์ฒญ
    Pool--xW: ํ’€ ์ „๋ถ€๊ฐ€ ์ด๋ฏธ โ‘ ์— ์ ์œ ๋ผ ์žˆ์–ด ๋ฐฐ๋ถ„ ๋ถˆ๊ฐ€
    Note over C,W: ์•„๋ฌด๋„ ๋๋‚˜์ง€ ๋ชปํ•จ โ€” ์ˆœํ™˜ ๋Œ€๊ธฐ
Loading

๋™์‹œ confirm ์ˆ˜๊ฐ€ ํ’€ ํฌ๊ธฐ์— ๊ทผ์ ‘ํ•˜๋ฉด ๋ชจ๋“  ์ปค๋„ฅ์…˜์ด "โ‘ ์—์„œ ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ"์—๊ฒŒ ์ ์œ ๋œ ์ฑ„ โ‘ข์— ํ•„์š”ํ•œ ์ปค๋„ฅ์…˜์ด ํ•˜๋‚˜๋„ ๋‚จ์ง€ ์•Š๋Š”๋‹ค โ€” ๊ณ ์ „์ ์ธ ์ค‘์ฒฉ ์ž์› ํš๋“ ๋ฐ๋“œ๋ฝ์ด๋‹ค.

Important

ํ’€์„ 20์œผ๋กœ ๋Š˜๋ ธ์„ ๋•Œ ๋” ๋‚˜๋น ์ง„ ๊ฒƒ๋„ ์ด๊ฑธ๋กœ ์„ค๋ช…๋œ๋‹ค: ํ’€์ด ํด์ˆ˜๋ก ๋” ๋งŽ์€ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— โ‘ ๊นŒ์ง€ ๋„๋‹ฌํ•ด ๊ฐ™์€ ํ•จ์ •์ด ๋” ์™„์ „ํ•˜๊ฒŒ ๋ฐœ๋™ํ•œ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ํ’€ ํฌ๊ธฐ๋กœ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š”๋‹ค.

ํฅ๋ฏธ๋กœ์šด ์ ์€, ๋ฐ”๋กœ ์œ„ Toss PG ํ˜ธ์ถœ์€ ์ •ํ™•ํžˆ ๋ฐ˜๋Œ€๋กœ ์งœ์—ฌ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค โ€” ์ฝ”๋“œ ์ฃผ์„์—๋„ "ํŠธ๋žœ์žญ์…˜ ์ข…๋ฃŒ ์‹œ ๋ฝ์ด ํ•ด์ œ๋˜๋ฏ€๋กœ ์™ธ๋ถ€ PG ํ˜ธ์ถœ ์ค‘ DB ๋ฝ์ด ์œ ์ง€๋˜์ง€ ์•Š๋Š”๋‹ค"๊ณ  ๋ช…์‹œ๋ผ ์žˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์™ธ๋ถ€ ํ˜ธ์ถœ์„ ํŠธ๋žœ์žญ์…˜ ๋ฐ–์—์„œ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์›์น™์„ ์ด๋ฏธ ์•Œ๊ณ  Toss ํ˜ธ์ถœ์—” ์ ์šฉํ–ˆ์ง€๋งŒ, ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์˜ ์ง€๊ฐ‘ gRPC ํ˜ธ์ถœ์—๋Š” ์ ์šฉํ•˜์ง€ ๋ชปํ•œ ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.


๊ถŒ์žฅ ํ•ด๊ฒฐ ๋ฐฉํ–ฅ

Tip

์ง€๊ฐ‘ gRPC ํ˜ธ์ถœ์„ Tx2 ๋ฐ–์œผ๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค: (a) ๊ฒฐ์ œ ์ƒํƒœ๋ฅผ APPROVED๋กœ ๋จผ์ € ์ปค๋ฐ‹ โ†’ (b) ํŠธ๋žœ์žญ์…˜ ๋ฐ–์—์„œ ์ง€๊ฐ‘ gRPC ํ˜ธ์ถœ. Toss ํ˜ธ์ถœ๊ณผ ๋™์ผํ•œ ํŒจํ„ด์ด๋‹ค.


์žฌํ˜„ ๋ฐฉ๋ฒ•

cd payment/mock-pg && ./start-mock-pg.sh          # Mock PG ๊ธฐ๋™
# ์•ฑ์„ local,loadtest ํ”„๋กœํŒŒ์ผ๋กœ ๊ธฐ๋™ (application-loadtest.yml)
cd payment && ./confirm.sh 30 10 60               # 30๋ช… / ramp 10์ดˆ / ์œ ์ง€ 60์ดˆ

Grafana RAIO Main - Application Metrics ๋Œ€์‹œ๋ณด๋“œ์˜ "DB ์ปค๋„ฅ์…˜ ํ’€ (HikariCP)" ํŒจ๋„๋กœ active/pending ์ถ”์ด๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿš€ RAIO Backend

Home


๐Ÿ“– Getting Started

๐Ÿ›๏ธ Architecture

๐Ÿงฑ Core Modules

๐Ÿ’ณ Domains

๐Ÿ“š Guides

Clone this wiki locally