Skip to content
isdnetworks
Go back

어디서 정해지는지 몰라 못 바꿨다

결제 연동에 쓰는 상점 계정 mid 를 바꿔 달라는 요청이 왔다. config 의 설정 파일에서 바꿨는데 안 바뀐다.

Table of contents

Open Table of contents

정해지는 자리가 여럿이었다

값이 어디서 오는지 따라갔다.

// 1. 결제 요청
$mid = $this->payment->getMid();

// 2. Payment 라이브러리
public function getMid() {
    return $this->client->mid;
}

// 3. 클라이언트 객체 생성
$this->client = PaymentClientFactory::create($channel);

// 4. 팩토리
public static function create($channel) {
    $row = $this->db->where('channel', $channel)->get('payment_client')->row();
    return new PaymentClient($row->mid, $row->key);
}

설정 파일이 아니라 payment_client 테이블에서 온다. 설정 파일에도 같은 이름의 값이 있었는데 그것은 예전에 쓰던 것이고 지금은 아무도 안 읽는다.

값이 정해질 수 있는 자리가 configpayment_client 와 코드 기본값으로 여럿이고 앞의 것이 없으면 다음으로 넘어간다. 어느 계층에서 정해지는지를 모르면 고칠 자리 자체를 못 찾는다.

체인을 그려 봤다

값이 정해지는 경로를 그려 봤다.

결제 요청
  → Payment 라이브러리
    → PaymentClientFactory
      → payment_client 테이블 (channel 로 조회)

바꿀 자리는 payment_client 다. 이 그림이 없으면 config 부터 뒤진다.

왜 테이블로 갔는지도 확인했다. channel 이 여럿이고 각각 다른 mid 를 쓰며 운영 중에 바뀌는데 설정 파일이면 채널이 늘 때마다 배포가 필요하다.

이유를 알고 나니 config 의 옛 값을 지워도 되는지가 정해져서 지웠다. 안 읽히는 값이 남아 있으면 다음 사람이 나와 똑같이 그것을 고치고 안 바뀐다고 할 것이다.

어느 채널인지도 봐야 했다

테이블에 행이 여럿이다.

SELECT channel, mid, use_yn FROM payment_client;
channel  mid        use_yn
card     M1234567   Y
mobile   M1234568   Y
card     M9999999   N

card 가 두 행이고 하나는 안 쓰는 것이다. createuse_yn 조건을 안 걸고 있었다.

$row = $this->db->where('channel', $channel)->get('payment_client')->row();

row() 가 어느 행을 가져올지는 정렬에 달렸는데 정렬이 없으면 예측이 안 된다. 매뉴얼도 정렬 컬럼의 값이 같으면 서버가 어느 순서로든 돌려줄 수 있고 실행 계획에 따라 달라진다고 적고 있다.

조건과 정렬을 넣었다.

$row = $this->db->where('channel', $channel)
                ->where('use_yn', 'Y')
                ->order_by('client_no', 'desc')
                ->get('payment_client')->row();

조건 없는 단건 조회는 어느 행이 올지 모른다. 정렬만 붙여서도 부족한데 같은 채널의 행이 둘이면 정렬 값이 같아져 다시 미정으로 돌아가므로 기본키를 정렬에 하나 더 얹어야 확정된다.

안 쓰는 행과 바꾸는 순서

use_yn='N' 행을 지울지 남길지 봤다. 남기기로 했는데 옛 결제 건의 mid 를 조회할 일이 있고 지우면 그 이력을 못 읽는다.

대신 조회할 때 조건을 반드시 걸게 하고 조회를 한 곳으로 모았다.

class PaymentClientRepository {
    public function getActive($channel) { ... }   // use_yn='Y'
    public function getById($no) { ... }          // 이력 조회용
}

getActivegetById 로 이름에서 용도가 갈린다.

계정을 바꾸는 일이 또 있을 것이라 절차도 적었다.

1. 새 행을 추가한다 (use_yn='N' 으로)
2. 시험 환경에서 그 행을 활성으로 바꿔 시험한다
3. 정상이면 운영에서 옛 행을 'N', 새 행을 'Y' 로
4. 결제 한 건을 실제로 해 본다
5. 문제가 있으면 3번을 되돌린다

행을 지우고 새로 만드는 대신 추가하고 전환한다. 되돌리기가 한 줄이다.

검증 — 체인에 낀 캐시

바꾸고 나서도 옛 mid 가 나왔다. getActive 의 조회 결과를 캐시하고 있었다.

$row = $this->cache->get("payment_client:{$channel}");
if (!$row) {
    $row = $this->repo->getActive($channel);
    $this->cache->save("payment_client:{$channel}", $row, 3600);
}

3600 이라 한 시간이고 바꾸면 최대 한 시간 뒤에 반영된다.

$this->cache->delete("payment_client:{$channel}");

바꾸는 화면에서 캐시를 지우게 했다. 값이 정해지는 체인에 캐시가 끼어 있으면 그것도 체인의 일부다.

정리


Share this post on:

Previous Post
처음 관리형 인프라를 썼을 때
Next Post
게임 서버가 몇 시간마다 멎었다 — 원인은 락 순서였다