Skip to content
isdnetworks
Go back

배경 작업이 한도를 다 쓰고 있었다

주문 완료 문자가 간헐적으로 안 나갔다. 로그를 보니 한도 초과 응답이었다. 그런데 주문 쪽 하루 발송량은 한도의 절반도 안 됐다.

Table of contents

Open Table of contents

원인 — 다른 곳이 쓰고 있었다

같은 발송 업체를 쓰는 곳을 찾았다.

$ grep -rn "sms_client\|SmsClient" --include=*.php application/

네 군데였다.

주문 완료 문자
배송 시작 문자
재고 알림(관리자용)
가격 비교 사이트 순위 알림

마지막 것이 cron 으로 5분마다 돌면서 순위가 바뀌면 문자를 보내고 있었다. 순위가 자주 바뀌는 날에는 하루 수백 통이었다.

한도는 SmsClient 가 쓰는 계정 단위고 쓰는 곳은 넷이다. 한 곳이 많이 쓰면 나머지가 못 쓴다. 주문 쪽 발송량만 보고 있어서 이유를 못 찾고 있었다.

무엇이 우선인지 정했다

넷의 성격이 달랐다.

용도못 나가면
주문 완료고객이 확인을 못 받음
배송 시작고객이 확인을 못 받음
재고 알림관리자가 화면에서 볼 수 있음
순위 알림다음 알림에서 알 수 있음

ordership 은 대체 수단이 없고 stockranking 은 있다.

못 나갔을 때 대체 수단이 있는지가 기준이었다. 우선순위를 정하지 않으면 먼저 부른 쪽이 다 쓰는 구조가 그대로 남는다.

몫을 나눴다

용도별로 하루 한도를 정했다.

$quota = [
    'order'   => 2000,
    'ship'    => 2000,
    'stock'   => 200,
    'ranking' => 300,
];

발송 전에 그날 몫을 썼는지 본다.

$used = $this->db->where('send_type', $type)
                 ->where('DATE(send_date)', date('Y-m-d'))
                 ->count_all_results('sms_log');

if ($used >= $quota[$type]) {
    log_message('warning', "일일 한도 도달: {$type} ({$used}/{$quota[$type]})");
    return false;
}

sms_log 를 세어 ranking 이 300통을 쓰면 거기서 멈추고 order 몫은 안 건드린다.

한도에 걸리면 조용히 안 나가므로 그것도 알게 했다. log_message 와 별개로 하루 한 번 사용량을 남겼다.

[문자 사용량 2014-11-30]
  order    412 / 2000
  ship     389 / 2000
  stock     12 /  200
  ranking  300 /  300  ← 한도 도달

전에는 문자가 안 나간 것을 며칠 뒤에 문의를 받고서야 알았다.

근본은 덜 보내는 것

ranking 이 매일 한도에 닿았다. 매일 닿으면 그건 몫이 부족한 것이 아니라 발송 조건이 잘못된 것이다.

실제로 그랬다. 순위가 1등 바뀌어도 문자가 나가고 있었다.

// 이전: 순위가 바뀌면
if ($newRank != $oldRank) { send(); }

// 이후: 순위 구간이 바뀌거나 5위 안에 들어오거나 나갈 때만
if (rankBand($newRank) != rankBand($oldRank)) { send(); }

rankBand 로 구간을 비교하니 하루 300통이 8통이 됐다.

몫을 나누는 것보다 애초에 덜 보내는 쪽이 나았다. 몫은 문제가 퍼지는 것을 막는 장치이고 근본은 발송 조건이었다.

업체가 주는 한도가 실제로 얼마인지도 확인했다. 문서에는 있는데 계약에 따라 다를 수 있어서 물어봤고 SmsClient 응답도 같이 봤다.

{"code":"200","remain":3218}

응답에서도 남은 양을 주고 있었다. remain 을 로그에 남기니 남은 양이 어떻게 줄어드는지 보였고 우리 계산과 업체 계산이 다른 것도 이걸로 발견했다.

실패한 발송도 한도를 먹고 있었다. 번호가 틀려서 실패한 것도 세진다.

정리


Share this post on:

Previous Post
있으면 안 되는 파일을 찾았다
Next Post
로그인 방식이 배포 형태를 정했다