성능 테스트 느낀 점

로컬에서 진행되어 실제 테스트 환경과 매우 다를 수 있음을 인지 부탁드립니다.

## 데이터 정합성 분석 (Data Integrity Analysis)

  • 테스트 목표: 10,000개 메시지 전송

  • 성공적으로 전송된 메시지: 9,996개 (stompmessages_sentcount)

  • 유실된 메시지: 4개

유실 원인 분석: checks 항목을 보면, 로그인 실패가 1번, 웹소켓 핸드셰이크 실패가 3번 발생했습니다.

✗ 로그인 성공: ✓ 9999 / ✗ 1 ✗ 웹소켓 핸드셰이크 성공 (101): ✓ 9996 / ✗ 3

정확히 4번의 연결 실패가 있었고, 이로 인해 4개의 메시지가 전송되지 못했습니다. 이는 매우 중요한 사실로, 메시지가 전송 중에 사라진 것이 아니라 애초에 연결 단계에서 실패하여 보내지 못한 것임을 의미합니다. 따라서 메시징 시스템 자체의 데이터 정합성은 신뢰할 수 있습니다.


## 🚨 성능 병목 및 불안정성

테스트 중 몇 가지 심각한 성능 저하 지점이 발견되었습니다.

1. 간헐적인 연결 실패 앞서 언급했듯이, 총 4번의 연결 실패가 발생했습니다. 이는 현재의 부하 시나리오(짧은 시간 동안 수많은 연결과 해제를 반복)에서 서버가 모든 요청을 안정적으로 받아주지 못하고 있음을 나타냅니다.

2. 심각한 응답 지연 (가장 큰 문제) max 값을 보면 일부 요청에서 극심한 지연이 발생했습니다.

  • http_req_duration (max): 3.79초

    일부 로그인 요청은 응답에 거의 4초가 걸렸습니다. 이는 사용자 경험에 치명적일 수 있습니다.

  • ws_connecting (max): 30초

    더 심각한 것은, 일부 웹소켓 연결 시도는 30초라는 타임아웃에 가까운 시간이 걸렸다는 점입니다. 이는 서버가 새로운 웹소켓 연결 요청에 거의 응답하지 못하는 상태에 빠졌었음을 의미합니다.

3. 테스트 시나리오의 특성 이 테스트는 매우 짧은 시간 동안 수많은 연결/해제(Connection Churn)를 반복하는 시나리오입니다. 10명의 사용자가 각각 1,000번씩 '로그인 -> 웹소켓 연결 -> 메시지 1개 전송 -> 연결 해제'를 반복합니다. 이런 종류의 부하는 서버의 연결 수립 및 자원 해제 능력에 큰 부담을 줍니다.


## 💡 총평 및 다음 단계

총평:

  • 메시징 시스템의 데이터 정합성은 높습니다 (연결만 되면 메시지는 잘 보냄).

  • 하지만 높은 연결/해제 부하(High Connection Churn) 상황에서 서버는 불안정한 모습을 보이며, 심각한 성능 병목 현상(최대 30초 지연)을 드러냈습니다.

{
    "root_group": {
        "name": "",
        "path": "",
        "id": "d41d8cd98f00b204e9800998ecf8427e",
        "groups": {},
        "checks": {
                "로그인 성공": {
                    "name": "로그인 성공",
                    "path": "::로그인 성공",
                    "id": "18fdb27d845d7c75f4ecb28a4922d978",
                    "passes": 9999,
                    "fails": 1
                },
                "웹소켓 핸드셰이크 성공 (101)": {
                    "name": "웹소켓 핸드셰이크 성공 (101)",
                    "path": "::웹소켓 핸드셰이크 성공 (101)",
                    "id": "3530370aad37ba89b72f6aa5443982d5",
                    "passes": 9996,
                    "fails": 3
                }
            }
    },
    "metrics": {
        "ws_session_duration": {
            "p(95)": 13.007302800000009,
            "avg": 26.235615984498438,
            "min": 3.233652,
            "med": 7.836388,
            "max": 30001.799051,
            "p(90)": 10.938089400000004
        },
        "ws_msgs_sent": {
            "count": 29988,
            "rate": 113.41476754660277
        },
        "http_req_duration": {
            "avg": 205.84052241459986,
            "min": 0,
            "med": 202.48603400000002,
            "max": 3790.220869,
            "p(90)": 255.4106678,
            "p(95)": 276.77879794999996
        },
        "ws_sessions": {
            "rate": 37.816268530694984,
            "count": 9999
        },
        "vus": {
            "value": 1,
            "min": 1,
            "max": 10
        },
        "http_req_receiving": {
            "p(90)": 0.5600535,
            "p(95)": 0.72793895,
            "avg": 0.2796097115999997,
            "min": 0,
            "med": 0.19042,
            "max": 13.990607
        },
        "http_reqs": {
            "count": 10000,
            "rate": 37.82005053574856
        },
        "http_req_connecting": {
            "p(90)": 0,
            "p(95)": 0,
            "avg": 0.04802938039999998,
            "min": 0,
            "med": 0,
            "max": 13.016015
        },
        "stompmessages_sent": {
            "count": 9996,
            "rate": 37.80492251553426
        },
        "http_req_blocked": {
            "avg": 0.06539765109999982,
            "min": 0,
            "med": 0.007999,
            "max": 13.172904,
            "p(90)": 0.0105962,
            "p(95)": 0.012672299999999996
        },
        "http_req_sending": {
            "avg": 0.05247582260000015,
            "min": 0,
            "med": 0.0400875,
            "max": 4.874325,
            "p(90)": 0.08483,
            "p(95)": 0.09436814999999998
        },
        "http_req_failed": {
            "passes": 1,
            "fails": 9999,
            "value": 0.0001
        },
        "iterations": {
            "rate": 37.82005053574856,
            "count": 10000
        },
        "http_req_waiting": {
            "avg": 205.50843688040027,
            "min": 0,
            "med": 202.1864205,
            "max": 3790.115918,
            "p(90)": 254.94746460000002,
            "p(95)": 276.1499719999998
        },
        "ws_connecting": {
            "p(95)": 12.2209955,
            "avg": 25.557775146714565,
            "min": 2.966713,
            "med": 7.152249,
            "max": 30001.166563,
            "p(90)": 10.247525800000002
        },
        "http_req_duration{expected_response:true}": {
            "max": 3790.220869,
            "p(90)": 255.41175660000002,
            "p(95)": 276.7817659,
            "avg": 205.8611085254524,
            "min": 76.816994,
            "med": 202.493007
        },
        "http_req_tls_handshaking": {
            "p(95)": 0,
            "avg": 0,
            "min": 0,
            "med": 0,
            "max": 0,
            "p(90)": 0
        },
        "checks": {
            "passes": 19995,
            "fails": 4,
            "value": 0.9997999899994999
        },
        "iteration_duration": {
            "max": 30235.852213,
            "p(90)": 266.11490810000004,
            "p(95)": 288.6529071499999,
            "avg": 235.52983322630004,
            "min": 80.59275,
            "med": 211.21114899999998
        },
        "data_received": {
            "rate": 38749.05847510363,
            "count": 10245639
        },
        "vus_max": {
            "value": 10,
            "min": 10,
            "max": 10
        },
        "data_sent": {
            "count": 11441827,
            "rate": 43273.04753612923
        }
    }
}

위 경우는 매번 연결을 끊고 다시 맺고 메시지를 반복한 거여서 그다지 좋은 테스트는 아니였던 거 같다.

다른 테스트를 진행하였는데 10명의 유저가 0.1초당 1개씩 , 총 1000개를 각각 보내게 테스트 하였습니다.

k6-1  |

k6-1  |   █ TOTAL RESULTS

k6-1  |

k6-1  |     checks_total.......: 20      0.196767/s

k6-1  |     checks_succeeded...: 100.00% 20 out of 20

k6-1  |     checks_failed......: 0.00%   0 out of 20

k6-1  |

k6-1  |     ✓ 로그인 성공

k6-1  |     ✓ 웹소켓 핸드셰이크 성공 (101)

k6-1  |

k6-1  |     CUSTOM

k6-1  |     stompmessages_received.........: 46042  452.976795/s

k6-1  |     stompmessages_sent.............: 10000  98.383388/s

k6-1  |

k6-1  |     HTTP

k6-1  |     http_req_duration..............: avg=262.07ms min=260.32ms med=262.3ms max=264.12ms p(90)=262.7ms p(95)=263.41ms

k6-1  |       { expected_response:true }...: avg=262.07ms min=260.32ms med=262.3ms max=264.12ms p(90)=262.7ms p(95)=263.41ms

k6-1  |     http_req_failed................: 0.00%  0 out of 10

k6-1  |     http_reqs......................: 10     0.098383/s

k6-1  |

k6-1  |     EXECUTION

k6-1  |     iteration_duration.............: avg=1m41s    min=1m41s    med=1m41s   max=1m41s    p(90)=1m41s   p(95)=1m41s

k6-1  |     iterations.....................: 10     0.098383/s

k6-1  |     vus............................: 10     min=10       max=10

k6-1  |     vus_max........................: 10     min=10       max=10

k6-1  |

k6-1  |     NETWORK

k6-1  |     data_received..................: 11 MB  110 kB/s

k6-1  |     data_sent......................: 1.8 MB 17 kB/s

k6-1  |

k6-1  |     WEBSOCKET

k6-1  |     ws_connecting..................: avg=17.39ms  min=16.03ms  med=17.47ms max=18.71ms  p(90)=18.7ms  p(95)=18.7ms

k6-1  |     ws_msgs_received...............: 46042  452.976795/s

k6-1  |     ws_msgs_sent...................: 10020  98.580155/s

k6-1  |     ws_session_duration............: avg=1m41s    min=1m41s    med=1m41s   max=1m41s    p(90)=1m41s   p(95)=1m41s

k6-1  |     ws_sessions....................: 10     0.098383/s

k6-1  |

k6-1  |

k6-1  |

k6-1  |

k6-1  | running (01m41.6s), 00/10 VUs, 10 complete and 0 interrupted iterations

k6-1  | send_and_wait_all ✓ [ 100% ] 10 VUs  01m41.6s/10m0s  10/10 iters, 1 per VU

결과를 보면 서버에 메시지는 10000개가 정상적으로 보내진 것을 확인할 수 있다.

메시지 유실은 되지는 않았지만 계속해서 부하를 올려가며 테스트를 진행하다 보니 메시지를 보낸시점이 36분 0초에 시작 되고 25초에 마무리가 되지만 DB상 저장되는 것이 37분 04초로 서버 입장에서 매우 지연되는 것을 볼 수 있었다.

사실 테스트를 하면서 느낀 것은 채팅 메시지 유실될 걸 걱정하면서 메시징 큐 시스템을 물론 발전 시킬 수 있다. 근데 그러한 경우는 내 생각에 MSA 처럼 많은 서비스가 붙은 상황에서

Last updated