시작하며

안녕하세요 배라개발팀 박민철 입니다.
배민7주년 행사 중 QR코드를 활용한 보물찾기 이벤트를 진행했던 경험을 이야기를 해보려 합니다.

보물찾기란?

지난 6월 배민7주년 행사가 있었습니다.
배민7주년 행사 컨셉은 미래와 경쟁하자 였고, 미래기술에 대한 브레인스토밍 중 QR코드를 활용하자는 의견을 토대로 보물찾기 이벤트를 제작하게 되었습니다. 행사장소 곳곳에 붙여진 QR코드를 촬영하면 (상품 || ) 이미지가 나오는데, 상품이미지를 저(노예)에게 보여주면 해당 상품을 받을 수 있는 방식으로 진행하였습니다.
OnePiece

QR코드란?

QR코드는 Quick Response의 약어로, 1994년 일본의 덴소웨이브란 회사에서 처음으로 개발하였습니다.

  1. 기존 코드(바코드)보다 대용량의 정보 저장 가능.
  2. 오염 또는 손상에도 데이터 복원 가능.
  3. 위치찾기심볼을 기준으로 어느 방향에서나 인식 가능.

QR코드를 제작하는 서비스를 해본 경험이 있어서, 어렵지 않게 구현 할 수 있었습니다.

$('#element').qrcode({
    text: "http://www.woowahan.com",
    width: 240,
    height: 240,
    render: "table" // "canvas", "table"
});

(JQuery 플러그인을 사용하면 쉽게 QR코드를 만들 수 있어요!)

걱정거리들

"상품이미지URL을 추측하거나, 직접 입력하면 어떡하지?"

사용자 화면에 이미지URL이 어떤 방식으로든 노출이 가능하기 때문에 사실 가장 많이 걱정을 했습니다.
이부분은 상품번호를 md5로 암호화하여 모바일에서 직접입력하기 어렵게 했습니다.
(실제로 URL의 코드 일부를 수정해서 호출하거나, 직접 md5코드를 제작하여 호출하신분도 있었어요!)

“암호화 때문에 URL이 길어져서, QR코드의 복잡도가 높아 인식률이 떨어지면 어떡하지?”

상품이 많지 않아, 인식률이 떨어지길 기대했지만,
goo.gl 서비스를 이용하여 단축URL을 생성하고, 보다 간단한 QR코드가 만들어지도록 했습니다.

goo.gl

“정말 많은 사람들이 참여하면 어떡하지?”

이부분은 오픈전날(D-1) 갑자기 불현듯 스쳐 지나가며 생각이 났습니다.
AWS Micro EC2 딱 하나 띄어놓고 있었는데, 점점 불안해지며 잠이 달아나기 시작했습니다.
jmeter라는 성능테스트도구를 사용하여 500명 동시접속의 시나리오를 작성하여 그 결과를 볼 수 있었습니다.
원활하게 처리됨을 확인 하고 그제서야 맘편히 잠들 수 있었습니다.

jmeter [500명 x 2회 = 1000번 수행]

서비스 구현

요구사항

보물찾기의 요구사항(제가 해석한)은 다음과 같습니다.

  • 보물은 10종류이며, 꽝포함 11장의 QR코드가 생성 되어야 한다.
  • 보물종류별 개별수량이 모두 다르다.
  • 사용자는 같은 보물을 중복해서 수령할 수 없다.

개발스펙

  • AWS EC2 (Micro)
  • PHP 5.6
  • MySql 5.5
  • JQuery.qrcode.js

개발구현

...
if ($code == "꽝") {
    return "꽝이미지";
}
if (hasHistory($session_id, $code)) {
    return "상품이미지"; // 아쉬움1.
}
if (getRemainCount($code) > 0) {
    updateCount($code);
    writeHistory($session_id, $code);
    return "상품이미지";
}
return "꽝이미지"; // 아쉬움2.
...

아쉬움1.

이미 같은 상품을 발견한 사용자에게 을 보여주려고 했으나, 혹시 모를 상황에 대비해 상품이미지를 노출했습니다.

  1. 당첨이 되고, 새로고침을 할 경우.
  2. 당첨이 되고, 뒤로가기를 눌렀을 경우.

하지만, 현장에서는 사용자에게 같은 상품에 다시 당첨이 되었다고 오해를 일으켰습니다.
차라리 위의 경우 이미 발견한 상품이라는 안내가 더 좋았을 것 같습니다.

아쉬움2.

상품의 수량이 없어지면서 계속 이 노출이 되었습니다.
마치 누군가는 모든게 인것 처럼 보이게 되었고, 불친절한 경험을 제공할 수 있다는 생각을 하게 되었습니다.
상품이미지와 함께 아쉽게 놓쳤다는 안내라도 보여줬으면 하는 아쉬움이 남았습니다.

실전

real [사진을 찾다보니 꽝인 경우밖에 없었어요]

13:00부터 모든 데이터를 초기화하고 서비스를 오픈하여 15:00까지 큰 이슈 없이 이벤트가 자연스럽게 종료가 되었습니다.
보물찾기 이벤트를 진행 하면서 크게 2번의 위기가 있었는데요.

첫번째는 100여장 정도의 QR코드 프린트물을 행사장소 곳곳에 붙이는 일이었습니다. 다른 노예분들께서 도와주셨지만 정말 힘들었어요.
(상품들이 생각보다 너무 빨리 발견되어서 좀 더 변태같이 어렵게 숨기지 못한 아쉬움이 있었습니다.)

두번째는 상품수령에 대한 구글스프레드시트 작성과 상품지급을 동시에 처리하는 일이 쉽지가 않았습니다.
보물찾기 이벤트에 적극적으로 참여해주셔서 그런지 금방 보물이 바닥을 보였는데요, 수령자를 기록하는 일과 상품을 지급하는 일을 혼자서 맡아서 진행하다보니 정신이 없었습니다. 중간에 같은 상품을 중복해서 수령한 경우가 있었는데, 구글스프레드시트 덕분에 정상적으로 회수하고 정합성을 유지할 수 있었습니다.
(Google Apps Script를 활용하면 자동화를 할 수 있는데, 마저 구현하지 못해서 아쉬움이 있었습니다. 이렇게 바쁠줄 몰랐어요.)

그 뒷이야기

13:00부터 15:00까지 데이터를 정리하여 보았습니다.

  • 상품: 10종류 50개
  • 접속기록: 2940
  • 접속한 세션 수: 616
  • 한 세션의 최다 접속 시도: 73 (대박)
  • 한 세션의 최다 당첨 수: 3
  • 보물 발견 세션 수: 38
  • 최고 효율(당첨/시도): 1/1 (100%)
  • 1/1을 제외한 최고효율(당첨/시도): 3/4 (75%)
  • 당첨 중 최저효율(당첨/시도): 1/54 (1.85%)
  • URL 조작: 9건
  • 촬영 비율 (상품/꽝/조작): 1949/982/9
  • 최다 촬영 상품: 비치볼 (564건)
  • 최저 촬영 상품: 라인스피커 (16건) 제일 힘들게 숨긴 보람이 있네요
  • 가장 빨리 발견된 상품: 비치볼 (13:23:10)
  • 가장 늦게 발견된 상품: 라인스피커 (13:46:29)

마치며

보물찾기 프로젝트를 진행하면서, 서비스 구현 보다는 크고 작은 문제를 어떻게 해결하면 좋을지를 많이 고민 했던 것 같습니다. 그런 부분에서 더 흥미와 재미를 느낄 수 있었고, 고민을 하면 할 수록 더 나은 대안이 도출 되었지만 불안정한 내용들을 완벽히 채우지 못해 정말 아쉬움이 많이 남습니다. 다음에 기회가 된다면 더 나은 서비스로 찾아뵙도록 하겠습니다. :-)
읽어주셔서 감사합니다.