πŸ”§ k6 λΆ€ν•˜ν…ŒμŠ€νŠΈ

HyojinΒ·2024λ…„ 11μ›” 28일
1

1. λΆ€ν•˜ ν…ŒμŠ€νŠΈ λŒ€μƒ μ„ μ • 및 λͺ©μ 

  • ν…ŒμŠ€νŠΈ λŒ€μƒ:

    • λŒ€κΈ°μ—΄ μ„œλΉ„μŠ€μ˜ 쑰회 APIλ₯Ό λŒ€μƒμœΌλ‘œ μ§„ν–‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
    • 토큰 생성, λŒ€κΈ°μ—΄ 정보 쑰회, μ½˜μ„œνŠΈ 일정 및 μ’Œμ„ 쑰회, μ’Œμ„ μ˜ˆμ•½ APIκ°€ λŒ€μƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€.
  • ν…ŒμŠ€νŠΈ λͺ©μ :

    • μ„œλΉ„μŠ€μ˜ μ„±λŠ₯ μΈ‘μ •: λ™μ‹œ μ‚¬μš©μž μˆ˜κ°€ 급증할 λ•Œ μ‹œμŠ€ν…œμ˜ λ°˜μ‘ μ‹œκ°„ 및 μ•ˆμ •μ„±μ„ ν™•μΈν•˜κ³ , μ„œλ²„μ˜ 처리 λŠ₯λ ₯을 ν‰κ°€ν•©λ‹ˆλ‹€.
    • μ„œλΉ„μŠ€μ˜ 처리 λŠ₯λ ₯ νŒŒμ•…: μ‹œμŠ€ν…œμ΄ 100λͺ…μ˜ 가상 μ‚¬μš©μž(VUs)둜 λΆ€ν•˜λ₯Ό μ²˜λ¦¬ν•  수 μžˆλŠ”μ§€ ν™•μΈν•˜κ³ , μš”μ²­ 처리 μ‹œκ°„, 였λ₯˜μœ¨ 등을 λΆ„μ„ν•©λ‹ˆλ‹€.
    • μ΅œμ ν™” ν•„μš”μ„± 뢄석: 응닡 μ‹œκ°„μ΄ κΈΈμ–΄μ§€κ±°λ‚˜ 였λ₯˜κ°€ λ°œμƒν•  경우, μ„œλ²„μ˜ λ¦¬μ†ŒμŠ€ ν™•μž₯μ΄λ‚˜ μ΅œμ ν™”κ°€ ν•„μš”ν•œμ§€ νŒŒμ•…ν•©λ‹ˆλ‹€.

2. λΆ€ν•˜ ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€

  • ν…ŒμŠ€νŠΈ λŒ€μƒ: λŒ€κΈ°μ—΄ μ„œλΉ„μŠ€ (μ΅œλŒ€ 100λͺ… λ™μ‹œ 접속, ν™œμ„±ν™”λœ λŒ€κΈ°μ—΄ 토큰 10λͺ…)
  • μ‹œλ‚˜λ¦¬μ˜€ κΈ°κ°„: 20초 λ™μ•ˆ 가상 μ‚¬μš©μžκ°€ 루프 λ°©μ‹μœΌλ‘œ μš”μ²­μ„ λ°˜λ³΅ν•˜λ©° μ‹€ν–‰λ©λ‹ˆλ‹€.
  • μ»¨ν…Œμ΄λ„ˆ λ¦¬μ†ŒμŠ€ μ œν•œ:
    • ν…ŒμŠ€νŠΈ 쀑인 Spring μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ Docker μ»¨ν…Œμ΄λ„ˆλŠ” 2 CPU와 4GB λ©”λͺ¨λ¦¬λ‘œ λ¦¬μ†ŒμŠ€κ°€ μ œν•œλ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
    • 이λ₯Ό 톡해 ν…ŒμŠ€νŠΈ κΈ°κ°„ λ™μ•ˆ μ„œλ²„μ˜ λ¦¬μ†ŒμŠ€λ₯Ό κ΄€λ¦¬ν•˜κ³ , κ³Όλ„ν•œ λ¦¬μ†ŒμŠ€ μ†ŒλΉ„λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ λ¦¬μ†ŒμŠ€λ₯Ό 일정 λ²”μœ„ λ‚΄λ‘œ μœ μ§€ν•˜λ„λ‘ μ„€μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ‹œλ‚˜λ¦¬μ˜€ μ„ΈλΆ€ λ™μž‘:
1. 토큰 생성 API 호좜 - μ‚¬μš©μžκ°€ μ½˜μ„œνŠΈ μ˜ˆμ•½μ„ μ‹œμž‘ν•˜κΈ° 전에 토큰을 μƒμ„±ν•©λ‹ˆλ‹€.
2. λŒ€κΈ°μ—΄ 정보 API 호좜 - λŒ€κΈ°μ—΄μ— λŒ€ν•œ 정보λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
3. μ½˜μ„œνŠΈ 일정 쑰회 API 호좜 - μ‚¬μš©μžκ°€ μ›ν•˜λŠ” μ½˜μ„œνŠΈμ˜ 일정을 ν™•μΈν•©λ‹ˆλ‹€.
4. μ½˜μ„œνŠΈ μ’Œμ„ 쑰회 API 호좜 - μ‚¬μš©μžκ°€ μ›ν•˜λŠ” μ½˜μ„œνŠΈμ˜ μ’Œμ„ 정보λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
5. μ½˜μ„œνŠΈ μ’Œμ„ μ˜ˆμ•½ API 호좜 - μ‚¬μš©μžκ°€ μ›ν•˜λŠ” μ½˜μ„œνŠΈμ˜ μ’Œμ„μ„ μ˜ˆμ•½ν•©λ‹ˆλ‹€.

슀크립트

import http from 'k6/http';
import { check, sleep } from 'k6';

export let options = {
    vus: 100, // λ™μ‹œ μš”μ²­ 수
    duration: '20s', // ν…ŒμŠ€νŠΈ 지속 μ‹œκ°„
};

export default function () {
    const userId = Math.floor(Math.random() * 100000) + 1;
    const tokenUrl = `http://localhost:8082/api/queue/tokens/users/${userId}`;

    // 1. λŒ€κΈ°μ—΄ 토큰 생성 μš”μ²­
    const tokenHeaders = {
        'Content-Type': 'application/json',
    };

    const tokenResponse = http.post(tokenUrl, JSON.stringify({}), { headers: tokenHeaders });

    check(tokenResponse, {
        'Token creation is status 200': (r) => r.status === 200,
    });

    if (tokenResponse.status !== 200) {
        console.error(`Failed to create token for userId: ${userId}, Status: ${tokenResponse.status}`);
        sleep(1);
        return;
    }

    const tokenData = tokenResponse.json();
    const queueToken = tokenData.queueToken; // μƒμ„±λœ λŒ€κΈ°μ—΄ 토큰

    // 2. λŒ€κΈ°μ—΄ 정보 폴링 쑰회
    const queueInfoUrl = 'http://localhost:8082/api/queue/tokens/users';
    const queueInfoHeaders = {
        'Content-Type': 'application/json',
        'QUEUE-TOKEN': queueToken, // λŒ€κΈ°μ—΄ 토큰 μ„€μ •
    };

    let queuePosition = -1;
    let queueInfoResponse;

    // λŒ€κΈ°μ—΄ μƒνƒœκ°€ -1이 아닐 경우 계속 ν΄λ§ν•˜μ—¬ μƒνƒœ 확인
    while (queuePosition !== -1) {
        queueInfoResponse = http.get(queueInfoUrl, { headers: queueInfoHeaders });

        check(queueInfoResponse, {
            'Queue info is status 200': (r) => r.status === 200,
        });

        if (queueInfoResponse.status !== 200) {
            console.error(`Failed to fetch queue info with token: ${queueToken}, Status: ${queueInfoResponse.status}`);
            sleep(1);
            return;
        }

        const queueInfo = queueInfoResponse.json();
        queuePosition = queueInfo.queuePosition;

        if (queuePosition !== -1) {
            console.log(`Waiting for position to be -1, current position: ${queuePosition}`);
            sleep(3); // 일정 μ‹œκ°„ ν›„ λ‹€μ‹œ λŒ€κΈ°μ—΄ μƒνƒœλ₯Ό 확인
        }
    }

    // 3. μ½˜μ„œνŠΈ μŠ€μΌ€μ€„ 쑰회
    const concertScheduleUrl = 'http://localhost:8082/api/concerts/1/schedules';
    const concertScheduleHeaders = {
        'Content-Type': 'application/json',
        'QUEUE-TOKEN': queueToken, // λŒ€κΈ°μ—΄ 토큰 μ„€μ •
    };

    const concertScheduleResponse = http.get(concertScheduleUrl, { headers: concertScheduleHeaders });

    check(concertScheduleResponse, {
        'Concert schedule is status 200': (r) => r.status === 200,
    });

    if (concertScheduleResponse.status !== 200) {
        console.error(`Failed to fetch concert schedule with token: ${queueToken}, Status: ${concertScheduleResponse.status}`);
        sleep(1);
        return;
    }

    // 4. μ½˜μ„œνŠΈ μ’Œμ„ 정보 쑰회
    const concertSeatsUrl = 'http://localhost:8082/api/concerts/1/schedules/1/seats';
    const concertSeatsHeaders = {
        'Content-Type': 'application/json',
        'QUEUE-TOKEN': queueToken, // λŒ€κΈ°μ—΄ 토큰 μ„€μ •
    };

    const concertSeatsResponse = http.get(concertSeatsUrl, { headers: concertSeatsHeaders });

    check(concertSeatsResponse, {
        'Concert seats is status 200': (r) => r.status === 200,
    });

    if (concertSeatsResponse.status !== 200) {
        console.error(`Failed to fetch concert seats with token: ${queueToken}, Status: ${concertSeatsResponse.status}`);
        sleep(1);
        return;
    }

    // 5. μ’Œμ„ μ˜ˆμ•½ μš”μ²­
    const reservationUrl = 'http://localhost:8082/api/reservations';
    const reservationHeaders = {
        'Content-Type': 'application/json',
        'QUEUE-TOKEN': queueToken,
    };

    const seatNumber = Math.floor(Math.random() * (172 - 120 + 1)) + 120;
    const seatIdsArr = [seatNumber];

    const reservationPayload = JSON.stringify({
        concertId: 1,
        scheduleId: 1,
        seatIdsArr: seatIdsArr, // λ°°μ—΄λ‘œ μ„€μ •
        userId: userId
    });

    const reservationResponse = http.post(reservationUrl, reservationPayload, { headers: reservationHeaders });

    check(reservationResponse, {
        'Reservation is status 200': (r) => r.status === 200,
    });

    if (reservationResponse.status === 200) {
        console.log(`Reservation succeeded for userId: ${userId}, Seats: ${seatIdsArr}`);
    } else {
        console.error(`Reservation failed for userId: ${userId}, Status: ${reservationResponse.status}`);
        console.error(`Reservation failed. Response: ${reservationResponse.body}`);
    }

    sleep(1); // μš”μ²­ κ°„ 간격
}

3.λΆ€ν•˜ ν…ŒμŠ€νŠΈ κ²°κ³Ό

μ§€ν‘œκ°’
성곡적인 μš”μ²­ λΉ„μœ¨50.94% (1028/2018)
성곡적인 μš”μ²­ (200 OK)90% (9/10)
HTTP μš”μ²­ μ‹€νŒ¨ λΉ„μœ¨49.05% (990/2018)
평균 응닡 μ‹œκ°„518.26ms
μ΅œλŒ€ 응닡 μ‹œκ°„6.3s
μš”μ²­ 수 (전체)2018
μš”μ²­ 성곡 λΉ„μœ¨50.94%
λ™μ‹œ μ‚¬μš©μž (VUs)평균 31λͺ…, μ΅œλŒ€ 100λͺ…
ν…ŒμŠ€νŠΈ 진행 μ‹œκ°„ν‰κ·  2.06초

4. μ„±λŠ₯ μ§€ν‘œ 뢄석

4.1. 성곡적인 μš”μ²­ λΉ„μœ¨

  • ν…ŒμŠ€νŠΈμ—μ„œ 50.94%의 성곡 μš”μ²­ λΉ„μœ¨μ€ λŒ€κΈ°μ—΄μ—μ„œ λ™μ‹œ μ²˜λ¦¬ν•  수 μžˆλŠ” ν™œμ„± μ‚¬μš©μž 수의 μ œν•œμœΌλ‘œ 인해 일뢀 μš”μ²­μ—μ„œ μ‹€νŒ¨κ°€ λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€.
  • μ½˜μ„œνŠΈ 일정 쑰회 APIμ—μ„œ ν™œμ„±ν™”λœ λŒ€κΈ°μ—΄ 토큰 10λͺ…이기에 10개만 μ„±κ³΅ν•˜λŠ” 것은 정상 μ‘λ‹΅μž…λ‹ˆλ‹€.
  • μ˜ˆμ•½ APIμ—μ„œ 10개 쀑 9κ°œλŠ” 정상 μ²˜λ¦¬λ˜μ—ˆκ³ , λ‚˜λ¨Έμ§€ 1κ°œλŠ” λ™μΌν•œ μ’Œμ„μ— λŒ€ν•΄ λ™μ‹œμ— μ˜ˆμ•½ μš”μ²­μ΄ 듀어와 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” λ™μ‹œμ„± 문제둜 인해 λ°œμƒν•œ 정상적인 처리둜, 2개 쀑 ν•˜λ‚˜λ§Œ μ˜ˆμ•½μ΄ μ„±κ³΅ν•œ μƒν™©μž…λ‹ˆλ‹€.

4.2. 응닡 μ‹œκ°„

  • 평균 응닡 μ‹œκ°„μ€ 518.26msμ˜€κ³ , μ΅œλŒ€ 응닡 μ‹œκ°„μ€ 6.3초둜 μƒλ‹Ήνžˆ 큰 차이λ₯Ό λ³΄μ˜€μŠ΅λ‹ˆλ‹€.
  • 일뢀 μš”μ²­μ΄ κ³Όλ„ν•˜κ²Œ κΈ΄ μ‹œκ°„μ„ μ†Œμš”ν•˜λŠ” κ²½μš°κ°€ μžˆμŒμ„ μ•Œ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

4.3. HTTP μš”μ²­ μ‹€νŒ¨

  • μš”μ²­ μ‹€νŒ¨ λΉ„μœ¨μ΄ 49.05%둜, 전체 ν…ŒμŠ€νŠΈμ—μ„œ μƒλ‹Ήνžˆ 높은 μ‹€νŒ¨μœ¨μ„ λ³΄μ˜€μŠ΅λ‹ˆλ‹€.
  • μš”μ²­ μ‹€νŒ¨μ˜ μ£Όμš” μ›μΈμœΌλ‘œλŠ” λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²°μ΄λ‚˜ λŒ€κΈ°μ—΄ 처리 λ‘œμ§μ—μ„œμ˜ λ™μ‹œμ„± 문제, λ¦¬μ†ŒμŠ€ λΆ€μ‘± 등이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

3.4. λ™μ‹œ μ‚¬μš©μž 수

  • ν…ŒμŠ€νŠΈμ—μ„œλŠ” μ΅œλŒ€ 100λͺ…μ˜ μ‚¬μš©μžκ°€ λ™μ‹œ μ ‘μ†ν•˜μ˜€μœΌλ©°, ν‰κ· μ μœΌλ‘œ 31λͺ…이 λ™μ‹œμ— μš”μ²­μ„ λ³΄λƒˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ„±λŠ₯에 직접적인 영ν–₯을 λ―ΈμΉ˜λŠ” μ§€ν‘œλ‘œ, μ‹œμŠ€ν…œμ˜ λΆ€ν•˜λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • λ™μ‹œ μ‚¬μš©μž μˆ˜κ°€ λŠ˜μ–΄λ‚ μˆ˜λ‘ μ‹œμŠ€ν…œμ— κ³ΌλΆ€ν•˜κ°€ 걸릴 수 μžˆμŒμ„ 확인할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

5. μ‹œμŠ€ν…œ 병λͺ© 탐색

5.1. 응닡 μ‹œκ°„ 뢄석

  • 응닡 μ‹œκ°„μ΄ 길어진 μš”μ²­μ„ 뢄석해보면, λŒ€κΈ°μ—΄ 처리 λ‘œμ§μ—μ„œ λ¬Έμ œκ°€ λ°œμƒν•œ κ²½μš°κ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
  • μ—¬λŸ¬ μš”μ²­μ΄ λ™μ‹œμ— λŒ€κΈ°μ—΄μ— μ ‘κ·Όν•˜λ €κ³  μ‹œλ„ν•˜λ©΄μ„œ λ°œμƒν•˜λŠ” λ™μ‹œμ„± 문제둜 인해 일뢀 μš”μ²­μ΄ λŒ€κΈ° μƒνƒœμ—μ„œ κΈΈμ–΄μ‘Œμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²°μ΄λ‚˜ λŒ€κΈ°μ—΄ μ²˜λ¦¬μ—μ„œμ˜ Lock λ¬Έμ œλ„ 병λͺ©μ˜ 원인일 수 μžˆμŠ΅λ‹ˆλ‹€.

5.2. λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° λΆ€μ‘±

  • JDBC μ—°κ²° ν’€μ—μ„œ μžμ› 고갈 λ¬Έμ œκ°€ λ°œμƒν–ˆμ—ˆμŠ΅λ‹ˆλ‹€. HikariPool-1 - Connection is not available 였λ₯˜κ°€ λ°œμƒν•œ μ΄μœ λŠ” λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° ν’€ 크기가 λ„ˆλ¬΄ μž‘κ±°λ‚˜, λ™μ‹œ 접속 μ‚¬μš©μžκ°€ λ§Žμ•„μ§€λ©΄μ„œ 컀λ„₯μ…˜ 풀이 κ³ κ°ˆλ˜μ—ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
  • 컀λ„₯μ…˜ ν’€ 섀정을 μ΅œλŒ€ 크기 증가 및 νƒ€μž„μ•„μ›ƒμ„ μ‘°μ •ν•˜μ—¬ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° 문제λ₯Ό ν•΄κ²°ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

6. μ„±λŠ₯ κ°œμ„  λ°©μ•ˆ

6.1. λ™μ‹œμ„± 처리 κ°œμ„ 

  • λŒ€κΈ°μ—΄ μƒνƒœ 관리 둜직 κ°œμ„ : λŒ€κΈ°μ—΄μ„ 효율적으둜 κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ λ™μ‹œμ„± μ œμ–΄ 및 μŠ€μΌ€μ€„λ§ μ•Œκ³ λ¦¬μ¦˜μ„ κ°œμ„ ν•˜μ—¬ μš”μ²­μ„ λΉ λ₯΄κ²Œ μ²˜λ¦¬ν•  수 μžˆλ„λ‘ κ°œμ„ ν•©λ‹ˆλ‹€.

6.2. λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° ν’€ μ‘°μ •

  • 컀λ„₯μ…˜ ν’€ 크기 증가: ν˜„μž¬ 컀λ„₯μ…˜ ν’€ 섀정이 λΆ€μ‘±ν•˜μ—¬ JDBCConnectionException이 λ°œμƒν•˜μ˜€μœΌλ―€λ‘œ, 컀λ„₯μ…˜ ν’€ 크기λ₯Ό 늘리고 νƒ€μž„μ•„μ›ƒ 섀정을 μ‘°μ •ν•©λ‹ˆλ‹€.
  • HikariCP 섀정을 톡해 컀λ„₯μ…˜ ν’€μ˜ 크기λ₯Ό 늘리고, maxLifetime, idleTimeout 등을 μ‘°μ •ν•©λ‹ˆλ‹€.

6.3. 응닡 μ‹œκ°„ κ°œμ„ 

  • 비동기 처리: λŒ€κΈ°μ—΄ μ²˜λ¦¬λ‚˜ λ°μ΄ν„°λ² μ΄μŠ€ 쑰회 λ“±μ˜ μ‹œκ°„μ΄ 많이 μ†Œμš”λ˜λŠ” μž‘μ—…μ„ 비동기 μ²˜λ¦¬ν•˜μ—¬ μ‚¬μš©μž κ²½ν—˜μ„ ν–₯μƒμ‹œν‚€λŠ” λ°©μ•ˆμ„ κ³ λ €ν•©λ‹ˆλ‹€.

7. 가상 μž₯μ•  λŒ€μ‘ κ³„νš

7.1. λ°μ΄ν„°λ² μ΄μŠ€ μž₯μ•  λŒ€μ‘

  • μž¬μ‹œλ„ 둜직: λ°μ΄ν„°λ² μ΄μŠ€ 연결이 μ‹€νŒ¨ν•  경우, 일정 μ‹œκ°„ λ™μ•ˆ μž¬μ‹œλ„ν•˜λ„λ‘ μ„€μ •ν•˜μ—¬ μΌμ‹œμ μΈ μž₯μ• λ₯Ό μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

7.2. μ„œλ²„ μž₯μ•  λŒ€μ‘

  • λ‘œλ“œ λ°ΈλŸ°μ‹±: μ—¬λŸ¬ μ„œλ²„λ‘œ λΆ€ν•˜λ₯Ό λΆ„μ‚°μ‹œν‚€κΈ° μœ„ν•΄ λ‘œλ“œ λ°ΈλŸ°μ„œλ₯Ό μ„€μ •ν•˜κ³ , μ„œλ²„ μž₯μ•  μ‹œ λ‹€λ₯Έ μ„œλ²„λ‘œ μžλ™μœΌλ‘œ μš”μ²­μ΄ μ „μ†‘λ˜λ„λ‘ μ„€μ •ν•©λ‹ˆλ‹€.
  • μ„œλ²„ λͺ¨λ‹ˆν„°λ§: μ„œλ²„μ˜ λ¦¬μ†ŒμŠ€λ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ λͺ¨λ‹ˆν„°λ§ν•˜κ³ , 이상 징후가 λ°œμƒν•˜λ©΄ μžλ™ μŠ€μΌ€μΌλ§μ„ 톡해 μžμ›μ„ ν™•μž₯ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

7.3. 큐 μ‹œμŠ€ν…œ μž₯μ•  λŒ€μ‘

  • 큐 μ‹œμŠ€ν…œ λͺ¨λ‹ˆν„°λ§: 큐 μƒνƒœλ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ λͺ¨λ‹ˆν„°λ§ν•˜μ—¬ 큐에 μŒ“μΈ μš”μ²­ μˆ˜κ°€ μž„κ³„μΉ˜λ₯Ό λ„˜μœΌλ©΄ μ•Œλ¦Ό μ‹œμŠ€ν…œμ„ 톡해 κ΄€λ¦¬μžμ—κ²Œ κ²½κ³ ν•©λ‹ˆλ‹€.
  • 큐에 λŒ€ν•œ λͺ¨λ‹ˆν„°λ§ κ°•ν™”: 큐에 λŒ€ν•œ λͺ¨λ‹ˆν„°λ§ μ§€ν‘œλ₯Ό μΆ”κ°€ν•˜κ³ , 큐 처리 지연 μ‹œ μžλ™ν™”λœ μ•Œλ¦Όμ„ 톡해 μž₯μ• λ₯Ό 쑰기에 감지할 수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

8. κ²°λ‘ 

  • λΆ€ν•˜ ν…ŒμŠ€νŠΈλ₯Ό ν†΅ν•΄μ„œ λ™μ‹œμ„± 처리 및 λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° λΆ€μ‘± λ˜λŠ” API μ„±λŠ₯ λ“±μ˜ λ¬Έμ œμ μ„ λ°œκ²¬ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ„±λŠ₯ νŠœλ‹ 및 λŒ€κΈ°μ—΄ 처리 둜직 κ°œμ„ μ΄ ν•„μš”ν•˜λ‹€λŠ” κ±Έ μ•Œκ²Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.
  • API 응닡 μ‹œκ°„ 뢄포λ₯Ό 기반으둜 병λͺ© 지점을 λΆ„μ„ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.
  • 가상 μž₯μ•  λŒ€μ‘ κ³„νšμ„ μˆ˜λ¦½ν•˜μ—¬ μ‹œμŠ€ν…œ μž₯μ•  λ°œμƒ μ‹œ 즉각 λŒ€μ‘ν•  수 μžˆλ„λ‘ μ‹œμŠ€ν…œμ„ κ°•ν™”ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.
  • 응닡 μ‹œκ°„μ΄ 맀우 κΈ΄ μš”μ²­μ΄ μžˆμ„ 경우, μ‹œμŠ€ν…œμ—μ„œ κ³Όλ„ν•œ μžμ›μ„ μ†ŒλΉ„ν•˜κ±°λ‚˜, νŠΉμ • μ„œλ²„λ‚˜ λ„€νŠΈμ›Œν¬ 병λͺ©μ΄ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
profile
μ–΄μ œμ˜ λ‚˜λ³΄λ‹€ μ„±μž₯ν•œ μ‚¬λžŒμ΄ 될 수 μžˆλ„λ‘ λ…Έλ ₯ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보