240 likes | 688 Views
SOHU 精准广告投放系统. @DJ_ 戴军. 系统逻辑结构. Adserver. Adserver. 标签库. CTIndex. NetWork. 广告请求参数接收 & 获取. 获得 UA 与 PA. ADIndex. 根据请求参数从相应广告来源获得广告. AdExchange. CTR 模块. Ranking. Layout. AdServer 实现. 开发环境: Linux 开发语言: C++ 服务架构: nginx + fastcgi 模块间通信: thrift 本地缓存: redis 日志记录: log4cxx
E N D
SOHU精准广告投放系统 @DJ_戴军
Adserver 标签库 CTIndex NetWork 广告请求参数接收&获取 获得UA与PA ADIndex 根据请求参数从相应广告来源获得广告 AdExchange CTR模块 Ranking Layout
AdServer实现 开发环境:Linux 开发语言:C++ 服务架构:nginx + fastcgi 模块间通信:thrift 本地缓存:redis 日志记录:log4cxx 服务运行方式:多进程多线程
AdServer前端http请求接收 AdServer的http请求接收层采用nginx搭建,nginx接收到http请求后会将请求转发给后端的fastcgi服务。 通过GET方式接收的参数: 广告位ID 广告位尺寸 轮播数 通过http请求头接收的参数: 用户IP UserAgent 通过查表获得的参数: 用户当前所在地域ID(可通过nginx配置实现) 注意:nginx安装时要--with-http_realip_module
AdServer核心 AdServer核心部分为使用C++开发的多线程fastcgi进程。 FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)。它还支持分布式的运算, 即 FastCGI程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。 fastcgi fastcgi User Nginx fastcgi fastcgi
AdServer核心 AdServer的fastcgi进程利用C++开发,采用固定线程数的多线程模型。 全局连接池(index & ctr module) 线程0 接收http请求 Popconn 查询index Pushconn Popconn 查询CTR Pushconn 排序 输出 线程1 接收http请求 Popconn 查询index Pushconn Popconn 查询CTR Pushconn 排序 输出 线程n 接收http请求 Popconn 查询index Pushconn Popconn 查询CTR Pushconn 排序 输出 辅助线程 Popconn, 关闭损坏连接, 创建新的连接, Pushconn 待维修连接池
AdServer与其他模块间通信 AdServer与AdIndex、CTR模块间通信采用thrift。 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml这些编程语言间无缝结合的、高效的服务。 thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。 thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
structCtrRet { 1: optional map<string,ret_info> eCPM_map, 2: optional string adpid } structCtrQuery_list { 1: optional list<CtrQuery> query_list, 2: optional string regionid, 3: optional string browser, 4: optional string os, } structCtrRet_list { 1: optional list<CtrRet> ret_list, 2: optional string extdata } service CtrServ { CtrRet_list request(1: CtrQuery_listreq_info) } structquery_info { 1: optional string adid, 2: optional string score, 3: optional i64 bid, } structret_info { 1: optional string adid, 2: optional double ecpm, 3: optional string bucket, 4: optional double ctr } structCtrQuery { 1: optional list<query_info> item, 2: optional string adpid, 3: optional string turn }
thrift --gen cppctrserver.thrift Thrift官方网站: http://thrift.apache.org/ Thrift服务端代码
本地缓存 本地缓存采用reids,主要用于广告频次控制以及同一用户同一页面不同广告位之间广告去重逻辑的实现。 频次控制: 1、monitor server记录用户看过的广告 2、AdServer投放时读取用户当天看过的广告记录,去除达到频次控制数的广告 去重控制: 1、AdServer以MD5(用户ID+URL)为Key,记录5秒内Key上投放的广告 2、AdServer以MD5(用户ID+URL)为Key,查询5秒内Key上记录的广告,去除重复的广告 注意:本次作业不需要实现该功能
日志记录 日志记录采用log4cxx库结合logrotate实现. 需要注意的问题: 1、多进程写同一个日志文件 2、为什么用logrotate进行日志文件切割,而不用log4cxx进行日志切割? 注意:本次作业可选择实现该功能,若不实现该功能则运行方式改为单进程多线程
统计服务器工作流程 用户浏览器 监测请求 统计服务器 广告投放数据库 监测日志 Storm
Cookie Mapping Server工作方式 SOHU为cookie mapping发起方 对方为cookie mapping发起方
SOHU为cookie mapping发起方 Sohu.com页面 第三方广告公司或广告主Server(thirdparty.com) Sohu用户ID 对方用户ID与用户标签 Sohu Cookie Mapping Server(sohu.com) 标签转换 记录日志(Sohu用户ID,对方用户ID,对方用户标签)
对方为cookie mapping发起方 对方投放广告页面 (thirdparty.com) Sohu Cookie Mapping Server (sohu.com) 对方用户ID与标签 302跳转,so hu用户ID 标签转换 第三方广告公司或广告主Cookie mapping Server (thirdparty.com) 记录日志(Sohu用户ID,对方用户ID,对方用户标签)