Google 광고에 대해 알아보자 - Google Ad Manager
ODK Media에 다니는 동안 서비스에서 매출을 일으키는 광고 업무를 1년 반 정도 했었다. 운영되는 스트리밍 서비스가 여러개여서 이미 돌아가고 있는 광고 코드를 수정하는 일과 새로 런칭하는 서비스에 구글 배너 광고와 동영상 광고를 연동하는 일을 했고 헤더비딩 어댑터를 손보는 일도 종종 있었다. 벌써 무슨 말인지 모르겠다고? 사실 나도 잘 모른다..😰 이 글은 봐도봐도 광고를 모르겠는 나를 위해서 남겨두는 것이다. 회사에 Advertisement 101 문서를 남기면서 엔지니어로 혹은 미래에 창업자로 살아가는 동안 광고 도메인을 잊지 않고 있으면 꽤 큰 도움이 될 것 같아서 블로그 글로 한번 더 남겨둔다. 잘못된 설명이 있다면 제보 바랍니다.
웹 페이지에 광고가 어떻게 차는 걸까?
간단한 예를 들어보자. 기저귀를 파는 업체 기저귀세상은 기저귀를 웹 상에서 홍보를 해서 판매량을 올리고 싶어 안달이 나있다. 이때 기저귀세상의 직원은 불현듯 블로그 서비스를 만들고 있는 친구를 떠올린다. 그리고 그 친구에게 연락해 "야 너네 블로그 웹 서비스 가장 하단 영역에 가로 728px, 세로 90px 영역 하나 만들어서 우리 회사 상품 광고 태우고 싶은데 부탁 좀 하자. 1000번 노출을 할때마다 5만원씩 줄게. 그렇게 좀 해주라!" 라고 능청스럽게 이야기 한다. 이 상황에서 블로그 서비스를 만드는 친구는 기저귀세상의 직원으로부터 광고 영역에 넣을 HTML, CSS, JS 파일을 받아 부탁받은 영역에 계약 조건대로 삽입하게 되고, 이 블로그 서비스를 이용하는 사용자들은 어느 순간부터 기저귀 광고를 보게 된다. 여기서 광고 노출을 부탁한 업체 기저귀세상을 광고주라 하며, 광고를 노출해줄 플랫폼을 가진 친구를 게시자(Publisher 또는 Supply 또는 매체)라고 부른다.
광고 네트워크(Ad Network)는 무엇인가?
위의 예시를 다시 생각해보자. 이 세상에는 기저귀세상 뿐만 아니라 별의별 상품과 서비스를 판매하고 홍보하고 싶어하는 회사들이 존재하고, 검색 포털이나 온라인 신문사 등등 광고를 실을 수 있는 매체 또한 매우 다양하고 수 또한 많다. 기저귀세상 입장에서는 어떤 매체에서 기저귀를 광고해야 사람들이 관심을 갖고 볼까라는 고민을 할 것이고, 그렇게 수많은 매체를 둘러보며 선별하는 고통을 겪으며 마침내 그 매체들에게 연락해 광고 지면(웹 상에서 광고를 보여줄 공간)을 구매하기에 이른다. 블로그를 운영하는 친구 입장에서도 일이 복잡해지기는 매한가지다. 점점 블로그 구독자와 방문수가 높아지면서 기저귀세상 뿐만 아니라 다양한 회사들에서 연락이 오기 시작했다. 계약을 성사한 회사가 많아질 수록 이 블로그 운영자 친구는 회사들과 직접 소통하는 일이 많아졌고 나날이 변하는 요구사항을 들어줘야해서 탈모가 찾아와 매달 약국에 찾아가 프로페시아를 사먹는 지경에 이르렀다.
정리하면, 광고주와 게시자 모두 아래와 같은 문제를 겪게 된다.
광고주의 고통
- 선별해야할 매체가 너무 많고 선택하기도 어렵다.
- 각 매체들의 지면에 광고를 게재하기 위해 광고 서버를 모두 연동해야 한다.
- 매체마다 과금 방식과 데이터 형태가 달라서 머리털을 쥐어잡으며 관리해야 한다.
- 최대한 많은 사람에게 그리고 광고가 잘 먹힐 수 있는 사람에게만 효율적으로 광고를 노출시키고 싶은데 그걸 구체화할 로직과 인터페이스를 구축할 기술과 시간이 턱없이 부족하다. 기저귀 만드는 회사에 IT 인력이 있는걸 본 적이 있는가? 있다면 미안합니다. 그만큼 전반적으로는 없을 수 밖에 없다는 의미다.
게시자의 고통
- 여러 광고주들로부터 광고 애셋(HTML, CSS, JS 파일들)을 받은 후 직접 관리해야 한다.
- 한정된 시간과 공간(지면)으로부터 최적의 수익을 고민해야 한다.
- 같은 지면에 대해 복수의 광고주들이 입찰을 할 수 있다. → 중재의 고통
- 광고주들의 인성이 일관되지 않기 때문에 양질의 광고주를 선별해야 하는 수고가 있다.
이를 해결하기 위해 Ad Network 라는 중간자 역할을 하는 서비스를 만드는 회사가 나타났다. 이 Ad Network 는 매체 대신 광고 지면을 특정 형태 및 단가에 따라 카테고리로 정리해(이를 인벤토리라 부른다) 광고주들에게 판매를 하고, 그렇게 받은 광고 애셋을 어느 매체에 보여줄지 결정한다. 따라서 매체는 광고주들과 직접 대면하는 일이 없어지고 자신들의 매체의 어느 공간을 광고 지면으로 삼을지만 정하면 되었다. 광고주들도 여러 매체들에 보낸 자신들의 광고를 일일이 트래킹하여 리포트를 만드는 수고스러움도 Ad Network 가 통합해주는 자료를 통해 덜 수 있게 되었다. 이런 Ad Network 를 갖고있는 대표적인 회사들이 아마존, 구글, 페이스북 등이다.
Google Ad Manager, DFP, Google AdSense, Google Ad Exchange
그럼 Google Ad Manager(이하 GAM)는 무엇이고 DFP는 무엇일까? 근데 GAM을 사용하다보면 Google AdSense, Google Ad Exchange 등의 용어들이 계속 보인다. 너무 헷갈리니까 이 개념들을 한번에 정리하고 넘어가보자.
Google AdSense와 Google Ad Exchange
이 두 서비스는 모두 위에서 알아본 Ad Network 다. 두 서비스의 차이점은 AdSense는 광고수주가 자동으로 이루어지는 반면 Ad Exchange는 게시자가 광고수주 및 계약을 구글을 통해 직접 수동으로 해야한다는 점이다. AdSense는 광고수주가 자동으로 이루어지고 게시자가 가입신청만 하면 바로 수익을 낼 수 있는만큼 사용이 간편하지만 광고위치마다 게시자가 받고싶은 판매 금액을 설정하는 등의 커스터마이징이 불가능하다. 즉, 광고수주와 CPM(Cost Per Mille, 광고를 1,000번 노출시키는 비용)을 정밀하게 세팅해서 수익을 극대화하기 어렵다. 반면 Ad Exchange는 모든 광고수주를 일일이 계약해야 하는 번거로움이 있지만 이런 커스터마이징을 할 수 있기 때문에 선택권이 훨씬 넓으며 수익을 극대화할 수 있다.
DFP(Double Click for Publishers)
DFP는 구글이 제공하는 광고 서버다. 예를 들어보자. 게시자의 사이트에 광고 위치가 4개가 있고, 이 4개에서 광고를 보여주어야 한다. 여기서 게시자의 사이트란 위에서 언급한 우리의 친구가 만드는 블로그 서비스같은 사이트를 말한다. 이때 위에서 설명한 AdSense나 Ad Exchange에 있는 광고들 중 몇가지를 선택해서 노출해야 한다. 그럼 어딘가에선 광고 Pool에서 광고를 선택하는 로직이 작동하고 있어야한다. 이렇게 광고 위치에 적합한 광고를 선택해서 반환하는 역할을 하는 친구가 DFP다. 이 반환된 광고는 하나의 HTML 파일이며 iframe에서 실행되고 이 HTML에서 CSS, JS 파일을 불러온다. 이때 iframe에서 불러온 HTML은 Parent DOM과는 독립된 문서로 취급되는데, 이 iframe 안에서 로드한 JS 파일이 Parent DOM에 여러가지 경로로 접근할 수 있다. 여기에 대해서는 뒤에서 다시 자세히 알아보자.
Google Ad Manager(GAM)
GAM은 Ad Exchange와 광고서버인 DFP를 통합한 managed 서비스이다. GAM을 사용하면 게시자가 직접 광고 계약을 맺지 않아도 GAM이 광고서버를 통해 구글 광고 네트워크에서 광고를 서빙하기 때문에 광고 수주를 쉽게 할 수 있고 이 과정이 무료이다. 그리고 구글 Ad Network 를 Facebook이나 Amazon 같은 제 3의 Ad Network와 경쟁시켜 더 높은 CPM을 가진 광고를 서빙해서 매출을 높일 수 있다. 이렇게 여러 광고 Pool들을 서로 경쟁시켜 가장 수익성이 좋은 광고를 선택하는 과정을 일종의 Header Bidding 이라고 볼 수 있다. HTML의 Head 태그에서 다수의 광고를 요청해 경쟁에서 이긴 광고를 선택하는 방식이 아니어서 엄밀한 관점에서 Header Bidding은 아니지만 광고 경쟁 과정이 구글의 광고서버에서 이루어지기 때문이다. Header Bidding 에 대해선 뒤에서 다시 알아보자. 이외에 배너 광고, 동영상 광고, 광고주문, Ad Rule 등을 하나의 서비스에서 통제 및 관리할 수 있으며 광고 수익 리포팅까지 제공하기 때문에 이런 점을 누려야 한다면 GAM을 사용하는 것이 합리적이다. 광고주문, Ad Rule 등의 개념도 뒤에서 알아보자. 단순히 광고를 받아서 지면에 노출하는 정도만 필요하다면 AdSense 혹은 Ad Exchange를 사용하면 되고, 여러 Ad Network를 사용하면서도 광고주로부터 직접 광고를 받는 등 더 유동적으로 광고 집행을 해야하는 경우라면 이런 GAM을 사용하면 된다.
Google Ad Manager의 필수 개념들
GAM을 활용할때 필수적인 개념들이 있는데 아래와 같다.
- Order
- Ad Unit
- Line Item
- Creative
- Placement
- Key-value
Order(광고주문): Source of ads
이름 그대로 광고주와 게시자간의 계약을 GAM 상에서 주문이 들어온 것으로 간주한다. 공식 문서에서 아래와 같이 정의한다.
상호작용하는 광고 판매자와 구매자 간에 형성된 합의로서 광고 캠페인의 세부정보를 명시합니다. 광고주문은 하나 이상의 광고 항목을 포함합니다.
adpushup에서는 아래와 같이 정의한다.
In Ad Manager, orders are the equivalent of ‘purchase requests’ made by a buyer/advertiser.
GAM이 Ad Network 와 다른 점은 GAM은 Ad Network 를 하나의 광고주문으로 만들어 관리할 수 있고(즉 GAM이 Ad Network 를 포함할 수 있고), 직접 광고주로부터 purchase request(광고지면 구매 요청)를 받아 광고주문으로 만들 수 있다. 즉, 광고주문은 게시자 입장에서는 어떤 광고가 들어올지에 대한 Source가 되는 것이다. 이때 하나의 광고주문은 여러 Line Item(광고항목)을 포함할 수 있고 이 광고항목을 통해 광고주가 원하는 타게팅을 상세하게 지정할 수 있다.
Ad Unit(광고단위): Where to put ads?
광고단위는 광고 태그(ad tag)가 삽입될 자리이다. 광고 태그는 구글 광고서버가 어떤 광고지면에서 광고 요청이 온 것인지 파악하는 데에 사용되는 key다. 서버는 이 태그를 보고 어떤 GAM 사용자인지, 어느 광고지면인지 알 수 있다. 이 광고단위는 어떤 종류와 사이즈의 광고가 들어갈지에 대한 값을 설정한다. 예를 들어, 300x250 사이즈의 일반 배너 광고를 위한 광고단위를 GAM 상에서 만들었다. 그럼 이 광고단위 상세 페이지에서 이 광고단위를 위한 ad tag를 generate 할 수 있다. 이렇게 만든 ad tag를 게시자의 사이트에서 로드한 GPT library가 활용해 광고를 서빙한다.
Line Item(광고항목): When and How to put ads?
광고항목은 하나의 광고주문의 상세한 설정을 담는 Box다. 구체적으로, 광고항목은 광고 애셋(Creative - 광고문안, 실제 광고를 표현하는 HTML 같은 정적 파일)이 어느 위치에서 보여져야 할지(특정 광고단위를 타게팅해서), 얼마나 잦은 빈도로 또 최대 몇번 노출이 될 것인지, 어느 지역의 누가 볼지 등의 설정들을 모아놓은 집합이다. 이때 하나의 광고주문은 최소한 하나의 광고항목을 포함해야 하며 여러개를 포함할 수도 있다. 그래서 하나의 광고주문이 여러 광고항목을 포함하면 그만큼 다양한 조합으로 광고를 노출하겠다는 의미이다. 이렇게 만들어진 하나의 광고항목은 아래에서 설명할 광고문안들을 포함하게 된다.
Creative(광고문안): What to show?
광고문안은 이미지, 텍스트, 동영상 등 사용자가 직접 보게되는 광고이다. Simple!
Placement(게재위치)
게재위치는 단순히 광고단위들을 묶는 논리적인 그룹이며 꼭 만들지 않아도 된다. 즉, 선택사항이다. 관리해야 하는 서비스가 여러개이고, 광고단위도 많다면 게재위치를 만들어서 동일한 성격의 광고단위를 묶어놓고 광고항목에서 이 게재위치를 타게팅함으로써 한번에 여러개의 광고단위를 연결하는 방식으로 활용할 수 있다.
Key-value(키-값)
키-값은 배너 광고와 동영상 광고를 세분화해서 타게팅할 수 있도록 돕는다. GAM 어드민의 Inventory > Key-values 메뉴에서 키-값을 새로 만들거나 수정할 수 있다.
광고 서빙 과정을 그림과 함께 알아보자
여러 웹 사이트들을 보다보면 이렇게 우측에 있는 광고를 본 적이 있을 것이다.
하단에 가보면 이렇게 큰 광고도 있고 position fixed 또는 sticky로 졸졸 따라다니는 광고도 본 적이 있을 것이다.
박스를 그려놓은 5개 영역이 광고단위(Ad Unit)이다. 각 박스는 자신의 위치에 따라 이름을 갖고 있고 사이즈가 제각각이다. 박스 순서대로 YOUR_SITE_RIGHT_1, YOUR_SITE_RIGHT_2, YOUR_SITE_RIGHT_3, YOUR_SITE_BOTTOM, YOUR_SITE_STICKY 라고 가정해보자.
우리가 세운 회사에서 이 사이트를 운영하고 있다고 상상을 해보자. 애플에서 우리 사이트가 너무 애플의 감성과 맞아떨어져서 자신들의 제품을 이 사이트에 광고를 하고싶다고 요청이 들어왔다. 그래서 우리 회사의 광고팀은 GAM 상에서 위 그림과 같이 5개의 광고항목을 가진 광고주문을 등록했다. 이렇게 광고주문을 만들었고, 이 광고주문은 5개의 광고항목들을 포함하고 있다. 이제 각 광고항목에 광고문안들을 포함시켜야 한다.
위와 같이 광고문안은 구체적인 광고 정보(텍스트, 이미지, 영상 → HTML, CSS, JavaScript 애셋)를 담는다.
이렇게 다섯개의 광고항목들은 각각 다른 광고문안을 최소 하나씩 갖고있다. 이렇게 해서 광고주문, 광고단위, 광고항목, 광고문안을 각각 만들어 하나씩 연결했다. 이제 GAM 상에서 다섯개의 광고단위마다 ad tag를 만들고 우리의 웹 사이트에서 다섯개의 div들을 GPT Library를 이용해 연동해주면 각 광고단위의 광고항목 안에 들어있는 광고문안들이 노출될 것이다. 이 광고문안은 한번씩 노출될 때마다 impression이, 클릭될 때마다 click이 구글 광고 서버로 보내지고 쌓이게 되며 원하는 기간 별 리포트로 볼 수 있다. 광고항목은 자신이 포함하는 광고문안들의 모든 impression과 click을 합산해서 정보를 표현한다.
자, 이렇게 애플과 계약해서 광고를 보여주고 있었는데 이번엔 현대자동차에서 계약을 하고싶다고 연락이 왔다. 현대자동차 측에서 YOUR_SITE_RIGHT_1과 YOUR_SITE_STICKY 광고단위 위치에 새로 출시할 자동차 광고를 하고싶다고 칭얼거린다. 이미 이 두 광고단위에는 YOUR_SITE_RIGHT_1_300x250, YOUR_SITE_STICKY_300x250 두 광고항목이 각각 연결되어 서빙되고 있다. 어떻게 해야할까?
이번에도 Apple Order를 만든 것처럼 Hyundai Order 광고주문을 만들고 HYUNDAI_RIGHT_1_300x250, HYUNDAI_STICKY_300x250 라는 두 광고항목을 만든다. 그다음 현대자동차 측에서 만든 광고문안을 받아서 광고항목 안에 포함시킨다. 그리고 YOUR_SITE_RIGHT_1 광고단위에 가서 HYUNDAI_RIGHT_1_300x250을, YOUR_SITE_STICKY 광고단위에 HYUNDAI_STICKY_300x250를 추가로 연결한다.
그러면 결국 우리의 사이트에 있는 YOUR_SITE_RIGHT_1, YOUR_SITE_STICKY는 위 그림과 같이 각각 두개의 광고항목이 연결되고, 이때부터 두 광고항목은 광고를 서빙하기 위해 경쟁하기 시작한다. 물론, 처음에 광고주문을 계약할때 특정 기간 동안 광고단위 몇개를 독점할 수도 있다. 특정 시점에 어느 지역에서, 어떤 시간대에, 어떤 페이지에서, 어떤 에피소드에서, 어떤 정보(key-value)를 가진 유저가 사이트에 접속하는지에 따라 각기 다른 key-value가 세팅된 광고 요청이 나갈 것이고 이런 조건에 부합하는 광고항목이 이제는 두개 이상이기 때문에 어떤 광고가 CPM(Cost Per Mille)이 높은지 등에 따라 경쟁에서 이긴 광고문안 하나가 서빙된다. 이렇게 광고 경쟁을 통해 이긴 광고를 서빙하는 과정을 Header Bidding 이라고 한다.
자연스럽게, Header Bidding
위에서 살펴본 헤더비딩은 GAM 상에서 하나의 광고단위에 여러 광고항목이 연결되어 경쟁하는 형태인데, 이렇게 GAM 내부에서만 경쟁이 일어나게 되면 우리 사이트 입장에서는 헤더비딩을 위해 다른 작업이나 코드를 작성하지 않아도 된다. 구글 광고 서버가 알아서 입찰을 하고 CPM이 높은 광고문안을 선택해줄 것이기 때문이다. 논외로, 이런 편리성 때문에 현재 인터넷 광고 시장은 Google Ads가 가장 큰 파이를 차지하고 있다.
그런데 구글이 거의 독식 하다시피 하는 이런 상황을 못마땅해 하는 광고 플랫폼사들이 존재하는데, 여기에는 Facebook, Amazon 같은 거대한 회사도 있고 소규모 광고 네트워크를 가진 회사들도 있다. 이렇게 구글 이외의 광고 플랫폼까지 우리 사이트에 들여와 구글 광고와 경쟁시키면 더 높은 Ad Revenue를 기대해볼 수 있지 않을까?
그런 기대를 실현시킬 수 있는 대표적인 라이브러리가 Prebid.js이다.
prebid.js를 다운로드 하는 페이지에 가보면 Bidder Adapters를 선택한 뒤 다운로드 하도록 되어있는데, 이 Bidder Adapters 하위에 있는 항목들이 위에서 언급한 소규모 광고 네트워크를 갖고있는 광고 플랫폼이다. 더 높은 광고 수익을 위해 우리의 상상속 회사의 광고팀은 이 플랫폼사들과 개별적으로 서비스마다 계약을 맺는다. 이중 이미지에서 보이는 33Across 라는 곳을 찾아보자.
우측에 있는 Our Story를 보면 아래와 같이 써있다.
33Across is a technology company focused on solving the challenge of consumer attention for automated advertising. Our Attention Platform is the first programmatic solution to unify high-impact creative, quality supply, and true technology-driven scale. Brands can now deliver superior audience engagement while 33Across publishers benefit from the ability to drive more revenue for every ad placement, resulting in greater efficiency and an enhanced consumer experience.
요약하면 33Across는 광고문안들이 더 어그로를 잘 끌 수 있도록 광고 서빙을 자동화하는 기술 회사이다. 다른 Bidder들도 사이트를 들어가면 대부분 비슷한 설명을 하고 있다.
광고팀이 이렇게 계약한 플랫폼사들을 Bidder Adapters에서 선택한 다음 prebid.js를 다운로드 하면 된다. 이 글은 GAM을 전반적으로 살펴보면서 광고 도메인에 대해 얕은 수준으로 알아보는 것에 목적이 있기 때문에 Prebid의 구체적인 코드 예제는 생략한다. 머리 아프다..
1... 2'/your_site_gam_id/YOUR_SITE_RIGHT_1_300x250': { 3 mediaTypes: { 4 banner: { 5 sizes: [[300, 250]] 6 } 7 }, 8 bids: [ 9 { 10 bidder: '33across', 11 params: { 12 siteId: 'your_33across_id', 13 } 14 }, 15 ] 16 }, 17...
라고 해놓고 json 코드를 써버리고 말았는데, prebid.js를 연동한다면 위 코드처럼 각 광고항목의 사이즈와 헤더비딩 어댑터(위에서 말한 광고 플랫폼들)를 정의하게 될 것이다. 다른 어댑터를 추가한다면 해당 플랫폼에 회사와 사이트 정보로 가입을 하고 bids 배열에 해당 어댑터 정보를 추가하면 된다.
이렇게 구글이 아닌 여러 플랫폼사들의 광고 네트워크까지 끌어들여 광고 수익을 높이고자 하지만 세상에 공짜는 없다. 이상하리만치 CPM이 높고 Customer Attention(어그로)을 끄는 광고문안이라면 도박성 게임, 성인 관련 컨텐츠를 포함하고 있을 가능성이 농후하다. 이런 이유로 유튜브나 네이버 같은 큰 회사들이 아닌 소규모 사이트에서 영상을 보면 성인 또는 도박성 게임 광고가 자주 나오는 것이다. 사실 멀리 안가고 연합뉴스, 한국일보 같은 사이트만 가봐도 그렇다 🥲 구글을 통해서만 서빙하면 이런 일을 방지할 수 있지만 아주 높은 CPM을 기대하기는 어려운데, 구글이 광고문안을 적당한 수준으로 필터링을 해서 진입장벽이 존재하기 때문이다. 즉, 우리 사이트에서 광고 수익성과 사용자 경험은 어느 수준 이상으로는 양립하기 어렵다. 광고 수익성을 높이면 사용자 경험이 곤두박질 치고 사용자 경험을 높이면 매출이 떨어진다. 따라서 사용자 경험을 크게 해치지 않는 선에서 최대한 많은 광고 수익을 만들어내는 영역(gray area)을 찾는 것이 광고팀의 숙제가 될 것이다.
다행히 광고팀의 숙제를 도와줄 수 있는 도구가 있다. 바로 아래의 두가지다.
- Key-value(키-값)
- Ad Rule(광고규칙)
키-값은 배너 광고와 동영상 광고 모두에 사용될 수 있고, 광고규칙은 동영상 광고에 사용될 수 있다. 배너 광고에 키-값을 적용해 타게팅하는 내용에 대해서는 이 문서의 초반에서 다루었다. 키-값을 동영상 광고에 적용하려면 광고규칙을 사용해야 하는데, 배너 광고의 광고항목에서 키-값을 세팅하는 것과 똑같다. 키-값은 이미 다루었으니 광고규칙에 대해서 알아보자.
Ad Rule(광고규칙)
동영상 광고는 배너 광고처럼 단순히 키-값을 사용해서 타게팅 하지 않고 광고규칙이라는 것을 만들어서 타게팅 한다. 정확히는, 광고규칙에 키-값을 이용해 타게팅 한다. 하나의 광고규칙을 만들때 preroll, midroll, postroll이 몇초 짜리 광고를 포함할지, 몇개의 광고를 보여줄지, 광고 사이의 텀은 몇초로 할지 등을 정할 수 있다. preroll, midroll, postroll은 각각 동영상의 시작, 중간, 끝에 삽입되어 나오는 동영상 광고를 의미한다. 그 다음, 이 광고규칙이 어디에 적용될지 정해야 하는데 광고규칙을 만들때 타게팅 할 광고단위를 선택할 수 있다.
이때 광고규칙이 여러개가 존재할 수 있는데, 타게팅이 정확히 같은 규칙이 2개가 있다면 최근에 만든 것이 우선적용 되므로 타게팅이 겹치지 않도록 주의해야 한다.
그런데 이 광고규칙을 만들기 전에 먼저 Content sources를 준비해야 한다. 점점 낯선 용어들이 쏟아져 나와서 이제 그만 글을 마쳐야 한다는 느낌이 강력하게 오고있다. 여기서 부터는 실제로 회사에서 GAM 어드민을 열어볼 수 있거나 광고 작업 경험이 있는 독자에게만 쉽게 읽힐 것이므로 이해가 안되는 부분은 그냥 스킵하고 읽어도 좋다.
Content sources 에 대해 살짝 알아보면, 구글 광고 서버가 동영상 광고를 내려주려면 현재 사이트에서 재생 중인 동영상의 재생 위치, 영상 전체 길이, 영상의 메타 정보가 필요한데, 사이트에서 서빙하는 모든 영상마다 이 정보들이 필요하다. 우리 사이트에서 유튜브처럼 영상까지 볼 수 있고 이 영상에 동영상 광고를 서빙하고 싶다면 우리가 서빙하는 모든 영상들의 메타 정보를 반환하는 API를 만들어 구글 광고 서버가 알게 할 수 있다. 그 API의 endpoint를 GAM에 등록할 수 있는데, 구글 광고 서버가 이 API를 주기적으로 호출해서 우리 영상들의 메타 정보를 데이터베이스에 쌓은 것이 Content sources 라고 이해하면 된다. 이것은 미디어 정보에 대한 RSS 이므로 이를 MRSS 라고 한다.
이건 Content sources를 만드는 페이지인데 Name, Type, URL, Sync rule을 정하게 되어있다. Name은 소스의 이름이다. Type은 MRSS, Ooyala, Brightcove 셋중 하나를 선택할 수 있는데 에피소드 영상의 출처가 어딘지를 나타낸다. 즉, Type이 Ooyala, Brightcove라면 에피소드 영상들이 Ooyala와 Brightcove 인프라에 있다는 것이다. 만약 영상을 우리 인프라에서 직접 서빙한다면 Type을 MRSS로 선택한다. MRSS는 위에서 설명한 Media RSS의 약자이다. 미디어 파일용 RSS 라는 의미이다. URL은 각 MRSS의 endpoint를 의미한다. Ooyala, Brightcove 인프라를 사용해서 영상을 서빙하면 Ooyala, Brightcove 어드민에서 MRSS endpoint를 제공하는데 이 endpoint를 URL에 입력하면 된다. 우리 인프라에서 영상을 서빙한다면 Type을 MRSS로 선택하고 모든 영상에 대한 정보를 XML 형태로 반환하는 MRSS API를 만들어 해당 API의 endpoint를 URL에 입력하면 된다. Sync rule은 구글 광고 서버가 주어진 MRSS endpoint를 자동으로 요청할지, GAM 어드민 사용자가 직접 클릭할때 요청할지 결정하는 옵션이다. 자동으로 설정했다면 몇분(2~5분)마다 구글 광고 서버가 긁어갈 것이다.
광고규칙의 효용성은 이를 활용하면 웹 사이트의 재배포 없이 수없이 많은 경우의 광고 서빙 로직의 조합을 테스트해볼 수 있다. 어느 기간 동안 이렇게 테스트를 진행한 광고규칙들 중 시기별로 가장 높은 수익을 낸 광고규칙을 계속 사용하면 꾸준히 높은 광고수익을 기대해볼 수 있다.
배너 광고 리프레시와 메모리 누수
위에서 그림으로 배너 광고를 알아볼때 광고문안은 광고애셋(HTML, CSS, JavaScript)을 담는다고 했다. 그런데 만약 우리 사이트에서 수익을 높이기 위해 배너 광고를 특정 주기(30초, 1분 등)로 리프레시를 하게 되면 메모리 누수가 생길 염려가 생긴다. 이건 당해봐서 아는 것이다..🙃
로드된 배너 광고는 ad tag id를 가진 div 태그 하위에 iframe으로 서빙되는데, iframe은 Parent Document 하위에서 독자적인 DOM을 가지며 이 안에서 로딩된 js 파일은 iframe 속성을 통해 제약을 걸지 않는 이상 상위 DOM으로의 탐색을 할 수 있다. 이렇게 로딩된 js 파일이 상위 DOM에 접근해 여러개의 이벤트 핸들러를 달고, 그 핸들러 안에서 클로저가 생긴다고 가정해보자. 사실 클로저가 생길 가능성이 매우 크다. 이 파일이 자체적으로 자신이 속해있는 문서가 닫힐때(beforeunload) 이벤트 핸들러를 해제하지 않는다면 광고 리프레시가 될때마다 이벤트 핸들러가 계속 누적되고 누적되는 수만큼 그 안에서 생성되는 클로저들도 쌓이게 된다. 이런 식으로 이벤트 핸들러와 클로저의 누적이 지속되면 메모리가 적은 디바이스의 브라우저에서 memory leak로 인한 페이지 리로드가 반복되는 현상을 겪을 수 있다. 나는 영상을 3~40분을 보면 적게는 2GB에서 많게는 6GB까지 메모리가 증가하는 것을 목격한 적이 있다..
광고 갱신으로 인한 메모리 누수 문제를 어떻게 해결할 수 있을까?
배너 광고가 iframe 안에서 렌더링 된다고 했는데, iframe에 대한 MDN 문서를 보면 아래의 attributes를 확인할 수 있다.
allow, allowfullscreen 같은 속성이 보이고 sandbox라는 것이 보인다. sandbox 속성에 들어갈 수 있는 값 목록을 보면 allow-modals, allow-same-origin, allow-scripts, allow-top-navigation 같은 값들이 보인다. allow-scripts 값을 주지 않으면 iframe의 문서에서 스크립트를 실행할 수 없고 allow-top-navigation 값을 주지 않으면 스크립트가 상위 DOM 탐색을 할 수 없다. 이 두 값을 전달하지 않는 방식으로 iframe을 샌드박싱하면 스크립트 동작을 막아서 메모리 누수를 차단할 수 있을 것 같다. 다만 iframe을 만드는 것은 GPT Library의 몫이기 때문에 우리는 코드를 작성하지 않고 아래처럼 광고문안을 작성할때 SafeFrame 옵션을 사용해서 샌드박싱을 할 수 있다.
새 광고문안을 만드는 페이지에서 Serve into a SafeFrame 옵션이 기본으로 체크되어 있다. 이 SafeFrame 기능이 제공되기 시작한 것이 비교적 최근(2019)이기 때문에 최근에 만들어진 광고문안은 샌드박싱이 되지만 오래전에 만들어진 광고문안은 그렇지 않기 때문에 만약 회사에서 운영 중인 광고문안이 SafeFrame 으로 서빙되고 있지 않다면 migration 을 꼭 고민해봐야 한다.
여기까지 Google Ad Manager와 광고 서빙에 필요한 배경지식과 개념들을 전반적으로 훑어보았다. 기회가 여유가 된다면 GPT를 사용해 구글 배너 광고와 동영상 광고를 연동하는 코드에 대한 설명도 글로 다뤄보면 좋을듯 싶다.
참고 문서