天天看点

OpenResty在腾讯游戏营销技术中的应用和实践

很高兴今天能有这个机会来到网易大厦来分享腾讯游戏营销技术和 OpenResty 一些应用案例。

先做一个简单的自我介绍。我在加入到腾讯之前一直在通讯行业里面从事通信软件的研发工作,包括在华为,还有UT斯达康。

2012年10月份我加入到腾讯,现在在腾讯互动娱乐事业群负责部分的营销技术相关的工作。我接触的技术工作比较多、也比较杂,所以我自称是全“沾”工程师,不敢自称是全栈工程师。从底层的单片机到嵌入式、协议栈开发,再到上层应用开发,也做过游戏的后台,现在在做营销相关的一些技术,所以各种技术都沾过,不一定很深入,但是都接触过一些。

我今天要分享的内容主要包括两大块:

  • 第一块就是 OpenResty 在腾讯游戏营销 类API 网关中的应用
  • 第二块是 OpenResty 在腾讯游戏广告投放系统中的应用

我的分享会偏重 OpenResty 的应用,不会涉及到太多 OpenResty 具体的技术细节方面,主要是想通过一些应用的案例来把一些优化的思想跟大家做一个分享,来抛砖引玉。

OpenResty 在腾讯游戏营销 API 网关中的一个应用

进入到第一个分享案例, OpenResty 在腾讯游戏营销 API 网关中的一个应用,下面有一个一个帽子,可能大家会比较奇怪,如果大家看过《海贼王》的同学可能就会比较熟悉,这个就是《海贼王》里面路飞的帽子,也是我们内部 API 网关的 logo,我们团队把所有做的公共性的组件、平台性的东西都以《海贼王》里面的名字进行命名,当然还有很多。

接下来就看一看我们为什么也要做 API 网关,做 API 网关的业务背景是怎么样的,因为我们是业务开发团队,一个新游戏上线之前,它是需要做大量的营销推广类活动,包括各种签到、运营、抽奖等活动。形态也各有不同,比如小游戏、小程序这种推广类的、H5l引导类的等等。

除此之外,每个游戏它都有一个自己的微社区,在每个游戏的 APP 的入口可以进到里面去,提供一些资讯、攻略、个人数据,还有一些积分,排名等等的功能,也包括赛事直播的一些内容在里面。

每个游戏都有这样大量的活动,并且这个游戏的数量还是非常大的。然后它访问的后台的流量也是非常大的,会远远超过这里面提到的数字。

面对这样一个比较复杂的业务,我们一开始的时候是怎么样做的呢?在功能的层面,我们就把它划分了很多这样相似的功能模块,大概有二三十个这样的功能模块,模块化之后是不是就没有问题呢?但其实问题依然存在,主要包括两个方面:

  • 第一个方面:在开发阶段还是有大量重复性的、非功能性的模块的开发,比如:身份验证、登陆校验、流量控制、频次控制、安全等等这样的事情要做。
  • 第二个方面:就是线上运行的时候也存在大量的防刷,异常用户行为,需要进行行为控制和分析,包括防刷、秒杀、抽奖类活动的一些流量控制等干预。

这样的问题都让我们去思考,怎么样去做到功能性的开发和非功能性保障的独立,以及怎么样去做统一的流量控制,那这个其实就是 API 网关要做的事情了,所以接下来我们对业界 API 网关的方案做了大量的考察和分析,大概会分为2大类:

OpenResty在腾讯游戏营销技术中的应用和实践

第一类就是开源的方案,开源方案里面有我们比较熟悉的基于 OpenResty 的orange、KONG,还有其他语言的,比如 go 语言、Java 语言都有自己的 API 网关的方案。

第二个就是云的方案,各个主流的云厂商都有自己的 API 网关的解决方案,这些方案都有各自的优缺点,但是都有一个共同的问题,就是都不能满足我们业务个性化的需求,包括很多定制化的需求。另外还有一个问题,它不能和我们现有的,特别是大公司里面,现有的组件、平台要去做对接,要去做一个融合,这个很难做得到,因为它不是开源的。

所以我们基于此选择一个最简单的、最简化版的开源方案,就是 orange 的方案去做一个完全的定制化。

在定制化之前,我们看一下 orange 这个方案会有哪些问题或者不能满足需求的方面,我们从五个方面去看,这五个方面也是我们做任何技术方案选型或者考察评估的时候,可以去分析的点:

OpenResty在腾讯游戏营销技术中的应用和实践

我们具体来看一下,orange 在这五个方面的不足吧

  1. 易用性:orange 还是没有面向我们业务同学比较熟悉的基于应用、服务、API的配置和管理的操作界面
  2. 可用性:orange 把网关本身的可用性和配置节点的可用性都交给我们自己来保证。
  3. 性能:随着规则数增加,性能下降是非常明显的。
  4. 安全性:仅有一些黑白名单和一些通用的认证规则、认证的插件,用不太上。
  5. 可维护性:也是有一些缺失,在错误日志和染色日志,还有调用跟踪定位等等方面还是有缺失的。

接下来我们就从五个方面来说一下,我们是怎么样做优化和思考的:

易用性方面优化

第一个是在易用性方面优化,这里面有两张图,左边这张图是 orange管理端的截图,我们看得出来里有提供了很丰富的技术型的插件,有URL的重定向、重写,还有各种认证,还有限速,还有安全等等。那么它存的问题是什么呢?举个简单例子,就是我们要添加一个新的 API,那我要到所有的插件里面配置这个API 的 URL,插件下面还有选择器,以及规则都要去操作一遍,非常的重复和麻烦。

第二个问题就是对业务开发人员来说,他的思维和操作习惯,会更加关注业务,比如更加关注我的某个个应用,某个应用下面的某个服务,某个服务于下面的某个API的使用情况(认证、校验、安全、流控、统计等等方面的运行情况或者执行情况)。

所以这里有一句话就是在做易用方面的设计的时候要更加多的去考虑面向业务,而不是面向技术,我看好像KONG的配置界面也有做service的概念,越是有这个方面的考虑。

可用性方面的优化

第二个就是可用性方面的优化,可用性这个事情,大公司里面会相对比较容易一点,因为大公司有自己更加可靠的设备或者是组件来保证底层、下面节点的可用性。而腾讯内部有这样一个接入层网关的组件叫做 TWG/STGW,它们一开始是为了把不同的运营商的流量汇集到腾讯自己的机房里面来,同时也来做负载均衡、容错等等一些可用性的保障。所以网关本身节点的可用性这个事情就很简单,直接把这个 API 网关节点挂到这个 TGW/STGW 上面来就可以了,最后三台网关机器跨机房部署,在容灾层面做了进一步的可用性的保证。

第二个方面就是配置节点的可用性的优化,配置节点存放配置信息,配置信息虽然很小的,但也可以做一些简单的优化,最简单就是独立部署 MySQL 或者是 Redis,把配置信息放到这些地方去,然后自己去保证mysql/redis的可用性。

第三个还可以用 MySQL 或者更轻量级的 sqlite 去存放这个配置的信息,由管理端自己去保证它的可用性,管理端每次添加新的 API 的时候,同时去写入到这三个配置节点里面去,然后同时写入到 API 网关的共享内存里面去,这样输入粗暴,但是简单省事,对我们快速上线的东西来说还是可以用的。

最后一个方法就是用ETCD ,把配置信息存放到ETCD里面,利用ETCD去中心化的协议去做保证它的可用性,以及一致性。这个方案相对会比较完美一点,但是它有一个问题就是我们要去 API 网关里面编写新的代码监听 ETCD等操作,我们也在逐步地向这个方案过渡。

性能优化

第三个就是性能优化,一开始我们队orange 的性能做了一个初步的测试,发现Orange性能随着它的规则数量增加,QPS 下降还是比较明显的,然后我们就去做火焰图的分析,分析之后发现 60% 的操作都会消耗在 json 操作和正则表达式的匹配操作中去,并且 json 操作占了大头。

对我们来说第一反应就是 json 操作花了这么多时间,我们是不是可以去用一个更加高性能的 json 的处理库去替换 orange 里面的 Cjson呢,对于腾讯的同学来说,都比较熟悉的是RapidJSON,因为这是腾讯第一个开源的项目,很快就把 RapidJSON 替换掉 orange 里面的cJSON,发现效果还非常明显,一下子就提升了 10%+ 的性能。

接下来是不是这样就 OK 了呢?我们继续问一下为什么要做这件事情,简单阅读了下代码,原因是还是非常简单,就是orange 自己每一次 http 请求的时候,每一个 worker 收到请求的时候都会到共享内存里面去拉取配置信息,然后去做一个json反系列化操作,变成每个 worker 的数据结构,不管这个配置信息有没有更新,都去做这件事情,作者可能是为了自己的考虑,有配置更新的时候,这样实时能知道。

我们接下来再去问自己第二个问题,就是能否不做这件事情,对我们来说,牺牲一点实时性,一个配置更新过半分钟或者隔几秒钟得到这个配置最新信息,我们是可以接受的。所以我们很简单就可以去掉上面频繁的系列化操作,就是直接起一个 Timer 去过一段时间 check 一下这个共享内存里面有没有配置信息的更新标志即可,非常简单的这样一个优化就直接把这部分的 JSON 操作直接去掉了。

所以这里有一个体会是最大的优化是不做或者是柔性的平衡,这种柔性平衡可能会包括很多方面,牺牲一些其他的资源来得到性能,牺牲内存得到性能,或者牺牲一些实时性得到性能,还包括牺牲一些产品的体验得到性能,这些都是柔性的平衡,可能需要我们花更多时间去思考。

接下来我们就去做进一步的优化,因此我们做一个完整的性能测试,一个完整的性能测试主要会包括这么七个环节,前面的三个环节都是为了第四个环节的压力测试做准备的,包括环境准备、配置调优、静态检查等等。

这里面环节当然也有自己要去注意的事情,环境准备虽然很简单,但也要考虑一些问题,就是测试机的性能和压测工具的性能往往也会有问题里面。还有测试机和被测试机的时延等等,都需要考虑,否则会影响我们测试出来的真实性。

其他的话配置调优和静态检查这两块参考一些通用总结的经验就可以去做了。

下面就开始做压力测试,压力测试需要注意的是要尽量去模拟现网的真实环境和现网的处理流程去做,如果我们只是简单做一个echo测试的话,虽然这个性能数据很高,但不一定很真实,有参考价值。所以我们在腾讯内部的一个C1的机型上面,模拟真实现网流量和配置,大概测试出来的数据在18000 QPS。这个数据比之前采用了 PHP 的同步阻塞的传统的 CGI 的方式肯定是要高一个数量级的,但不一定就没有优化的空间了。

所以接下来我们继续去做瓶颈分析、性能分析。性能分析就用到了我们性能分析神器:火焰图,OpenResty社区的同学都非常熟悉火焰图

OpenResty在腾讯游戏营销技术中的应用和实践

我们把 CPU 消耗前10的操作做一个归纳,归纳出来有这么几类操作,第一个是 JSON 的操作占了9.18%。第二是 L5 的操作占了4.74%(L5是腾讯内部的一个负载均衡服务的组件),另外一个就是正则表达式匹配占了 10.36%。其他的就是nginx的操作以及系统调用等。

接下来我们就对这三个方面的操作,看看是不是有优化的空间。首先我们看一下 L5 的这个操作有没有优化的空间,刚刚说 L5 是腾讯内部的一个负载均衡的组件,我们就把它也集成到 API 网关里面来了,他们的工作原理会跟本机的 L5agent 进行通讯,所以我们在做压力测试的时候要去看一下,在压力测试这么大流量的情况下,L5agent 是不是有 CPU 消耗,或者它有没有出错,接下来再看一下它的日志和出错情况是否正常的,然后再把这个用 FFI 的方式替换我们之前的Lua C/API的方式,看看有没有性能的提升。我们又再进一步去分析 L5 这个操作,发现它是用了阻塞的 UDP 的调用,所以这里是有风险的,它会影响到其他的协程的执行的,所以我们需要尽量地把它的超时时间设得更短一点,也尝试看看能否用 cosocket 的方式去实现 L5 的API,但发现协议没有开源等等,经过这一些列的尝试,最后放弃了这部分的优化。

接下来就是 JSON 操作的优化,有前面的经验之后,我们做性能优化的时候就会问自己两个问题。第一个问题为什么要做这件事情,分析发现,是因为我们后端的服务把所有响应的数据都做了一个JSON encode,然后API网关会进行JSON decode然后去去提取里面的一个返回码,根据后端返回的返回码的不同,向前端返回是200OK还是其他的HTTP的不同的响应码,仅仅做这样一件事情。那继续问第二个问题能否不做,很显然是可以的,就是我们可以直接让后端返回数据的时候把返回码字段独立出来, API 网关的直接拿到返回码做一个判断即可,然后把数据字段直接转发给前端就 OK 了。非常简单的一个优化,直接就可以省掉了这部分的 JSON 操作。

另外 JSON 操作确实会消耗我们很多 CPU 的性能,我们一些同学也经常在 debug 里面去打印,想把这个 debug 日志里面去打印很多数据结构里面的内容(用json.encode来打印),然后放到生成环境上去,虽然这个 debug 操作是不会执行,但是这个函数,JSON encode操作是会执行的,这样的话会导致生产环境极大的性能损耗,等等这样类似的情况还是非常多的,所以我们在实际过程当中还是要去留意这样一些不好的编码的习惯。

正则表达式匹配的优化

第三个就是正则表达式匹配的优化。大家知道正则表达式匹配都是由正则表达式引擎来做的,常用的正则表达式引擎就是PCRE,于是我们就去考虑有没有更加高性能的正则表达式匹配的引擎呢?我们也去做了一些调研,正则表达式应用最多的领域其实是在安全领域里面,安全领域里面有这样的的IPS、IDS 这样的一些安全检测和防御性的产品里面会大量地使用正则表达式匹配的操作,它之前也是用 PCRE 来做正则表达式的匹配。后来就是在这两年的时候,都统一切换到了英特尔开源的 Hyperscan 这样的正则表达式引擎来了。

OpenResty在腾讯游戏营销技术中的应用和实践

为什么它会去做这样的改变呢?Hyperscan 正则表达式引擎比这个PCRE有哪些优势呢?分析后发现它有这么几个方面的不一样或者说优点。

  • 第一个就是它不仅仅是支持块模式,还支持流模式。所谓的流模式就是跨不同的网络包去做一个匹配,这个对安全产品是非常有用的。
  • 第二个就是它一次可以编译多个规则,大家知道正则表达式最后都会编译成状态机到内部去做匹配的操作。
  • 第三个就是一个输入多个规则只匹配1次,它可以并行匹配多个规则,这个是很厉害的。它的性能可能会很高,所以我们接下来我们就去做了这样一个验证,就是把30万条http get 请求(包括 URL),写到一个文本里面去。然后每个参数都做一个正则表达式的匹配,用 PCRE 的代码和 Hyperscan 的代码去读这个文件,一条条读,然后匹配每一个规则。发现 Hyperscan 匹配正则表达式所以花费的时间确实比PCRE所花的时间低很多,大概只有后者的30%左右的样子。所以接下来我们就非常果断地把它引入到我们的 API 网关里面来,用火焰图继续验证, CPU 的消耗,从之前的10%+降低到7%只有了。

所以接下来是不是还有可以优化的空间?当然有,就是开启它的并性匹配度规则的操作,这个 Hyperscan 里面也是提供了回调,然后我们只需要把每个规则设置一个标志位,然后去匹配完之后检查这个标志位以后就OK了,就可以做得到了。

另外还有一件事情是什么呢?就是正则表达式规则编写难度的问题,我们不能要求业务开发同学每次都要去编写正则表达式,这个对他们来说也不一定编写得正确,也有一些学习的成本在里面。所以我们就去看了一下大部分的参数还是比较类似的,所以就把这些参数的正则表达式做一些归纳,然后用一些文字性的描述,做了一个模板,业务人员就可以直接去选择这些模板就OK了,也很好的解决了这个问题。

安全性方面的优化

第四个方面的优化就是安全性方面的优化。安全性方面的优化要做的一件事情就是,它需要把我们这个 API 网关的安全策略去和公司现有的一些安全的产品做结合。腾讯内部有这样的自己的安全产品,叫门神,所以我们在 http 请求进来post read阶段就去和安全产品做一个交互,让它去过滤流量。它过滤的流量没有问题之后,再进入到我们的安全策略里面。当然这个安全策略也相对会比较简单,包括有 API 白名单,配置到 API 的流量才可以进到里面来。然后还有基于用户过滤的黑白名单,还有登录校验,支持腾讯的手Q、微信等的多种校验方式,也都把它集成进来了。

另外去做参数校验,参数校验则用前面提到的正则表达式做非常严格的必选参数的校验。另外就是如果做了非常严格的正则表达式匹配的话,SQL 防注入等等这样的问题也不会有。这个就是安全性方面的优化。

可维护性方面的优化

最后就是可维护性方面的优化,我们也做了两点:

  • 第一是添加了一些日志和统计的功能。例如,把 4xx/5xx 等一些错误日志独立出来,另外就是添加基于某个用户id后者请求id的染色日志跟踪打印。
  • 第二个方面的优化不一定属于今天讲的内容里面的,就是我们也做了调用链跟踪系统。API 网关在这个调用链跟踪系统里面是作为起点,它会去生成Trace id,以及创建调用链的上下文,以及结束调用链,另外就是还可以控制调用链跟踪的采集的频率等。

那到这里就快速简单介绍了一下第一个应用案例,在易用性、可用性、性能,还有安全性以及可维护性这五点,我们的一些思考和优化的过程。

OpenResty 在腾讯游戏、广告投放系统中的应用案例

接下来进入到第二部分,就是 OpenResty 在腾讯游戏、广告投放系统中的应用案例。还是和之前的内容一样,我不会涉及到很多具体的 OpenResty 的技术的细节,主要是想跟大家分享一下案例,以及在这个案例里面一些优化的思想。

这个案例相对会比较大胆一点,因为大概腾讯游戏有好几个亿的营销费用都会通过这个系统投放出去。广告投放的形式有很多种,有包段广告位的、包段时间段的、包段流量的,还有普通竞价的,还有实时竞价的。今天我想跟大家分享的就是实时竞价的广告投放形式和我们 OpenResty 的一个结合,以及 OpenResty 在里面的优化。

OpenResty在腾讯游戏营销技术中的应用和实践

什么是实时竞价广告?以及实时竞价广告的流程是怎么样的?这里面有一个图。我们从最右边往左看,最右边就是我们的用户打开手机看内容,比如看头条里面的内容或者刷新闻。过程中会看到有广告位的,当刷到有广告的那个页面的时候,这个时候 APP 就会向 ADX (广告交易平台)服务器发一个广告请求。广告交易平台服务器收到这个广告请求之后,它会去把这个广告请求分发给下面的广告主的 DSP 服务器,当然DSP 服务器可能会有很多家,一般来说只有大型的广告主才会有自己的 DSP 服务器。

腾讯游戏作为一个比较大型的广告主,它也有自己的 DSP 服务器。它收到的广告请求之后会怎么做呢?它会把这个广告请求里面的流量到它的DMP(数据管理平台)数据库里面去做一个判断,怎么判断?就是这个用户是不是我需要的,如果是我需要的话,我应该给他评估一个怎样的价钱,就是说我愿意出多少钱给来获得这个用户的这个广告曝光机会。

这里面会涉及到一些机器学习的算法去评估这个出价,最终确定了出价之后,他会把这个出价原路返回给 ADX 服务器。ADX 服务器收到这个出价之后,它会等待其他广告主的 DSP服务器的出价,放在一起比较来最终选择最高出价的广告主的广告,然后把这次广告曝光的机会给到这个广告主,展示这个广告主的广告素材,这个就是一个比较简化的实时竞价广告的流程。

里面需要做的一个事情就是,在这个 ADX 和 DSP 服务器之间的交互是通过 OpenRTB 协议来做的,这里面有两个问题需要解决:

  • 第一个是流量非常大,ADX所有的广告请求都会发给 DSP 服务器,有些大的媒体可能有好几万个QPS,如果好几家的话加起来很轻松会超过十万QPS。
  • 还有一个问题就是 ADX要求所有的DSP 必须在 100 毫秒返回出价响应,这个100ms包括网络上的时间,如果 100 毫秒之内我没有收到你响应的话,我就视为你放弃了这个出价。

当然实时竞价广告技术方面有很多挑战,主要有这么几块的挑战。

  • 第一个就是在数据方面,包括标签挖掘、人群扩散、画像分析,还有一些实时分析、透视分析来辅助刷选投放目标人群,这个是在数据方面的技术挑战。
  • 第二个就是算法,算法会包括两个比较核心的算法。第一个就是 pCTR,第二个就是pCVR,pCTR 就是点击率预估算法,pCVR是转化率预估算法,这个转化可能会包括多个,有下载、注册、付费、活跃等等都属于转化。这两个算法会用到现在比较热的一些机器学习的算法在里面。
  • 第三个方面的挑战就是在系统层面的挑战,刚才提到了 ADX 和 DSP 服务器,它之间会有比较高的QPS,另外就是时延有要求,100毫秒的要求。今天我分享的内容主要是偏重于在第三块,就是在系统层面怎么和 OpenResty 进行结合。

这个是实时竞价广告系统在系统侧的一个架构简图,最上面是流量层,各ADX的广告请求流量会发到下面的接入层。接入层又包括两部分,一个是静态的 CDN,一个是动态的 RTB 网关,CDN 存放广告的素材,RTB 网关会做一件事情,就是进行 OpenRTB 协议的编解码,此外还会做一些安全和流量控制等操作。

在逻辑层包括竞价引擎,最下面的就是数据层包括 DMP 数据管理平台。这两个部分做的事情就是我们刚刚说的,一起来确定这个广告请求是不是我们需要的用户,如果是我们需要的用户的话,我们怎么样给它估算一个价钱。

OpenResty在腾讯游戏营销技术中的应用和实践

这里面标了橙黄色字体的,就是我们用 OpenResty 进行过重构或者说优化过的地方,包括接入层的 RTB 网关,还有逻辑层竞价引擎,以及 DMP 的数据管理平台的一部分。

我们就一个个来看一下我们怎么样做重构和优化的

  • 首先在接入层,我们直接用 OpenResty 定制了 RTB 网关,为什么用 OpenResty 定制 RTB 网关呢?刚刚提到了,它的流量非常大,这个可以充分发挥 OpenResty 的nginx+lua协程高性能的特性。
  • 另外还有一个问题就是不同的媒体有不同的 OpenRTB协议,虽然有标准规定,但是它们还是会有一些差别的,对接起来还是非常地麻烦,所以对每家媒体都利用插件化方式做了差别化的处理,来提高开发联调时候的效率。
  • 接下来就是在安全方面的一个优化,这里的安全策略跟前面讲的安全策略可能不太一样。这里面主要是基于 OpenRTB协议本身的安全策略,包括Request id的各个阶段校验,还有参数的非对称加密做防盗链,泄露用户信息等,另外就是一些防作弊,我们把这些安全性方面的优化都放到这个 RTB 网关里面来做。
  • 另外,RTB 网关还做了一个比较大的优化,就是把目标流量筛选也直接放到了 RTB 网关里面来了。之前传统的做法都是怎么做的呢?都是让流量进入到 DMP 数据平台里面来,经过竞价引擎、广告检索、标签查询服务来到 DMP 数据管理平台里面去确定这个用户是不是我们需要的。因为DMP数据管理平台里面存放了所有用户的加密ID信息以及一些标签属性、偏好等等,之前都是这样来判断的。

其实我们可以简化一点,直接把这部分加密数据放到 RTB 网关里面来,当然也会遇到一个问题就是用户的加密标识信息非常大,大概会有十几亿条,另外一个设备标识加密后至少是32个字符串,如果全部存放到内存里面的话大概要十几个G,当然这还不包括查找索引额外的开销。

那我们就去寻找一个哈希算法,可以把一个固定长度的字符串直接转化为一个整型,然后我们把这个整型直接通过Bitmap直接映射到 512 兆的内存中的一个bit中去。这样就可以直接通过 512 兆的内存存放40亿的加密设备号,当然也会有不同的加密设备号映射到相同的比特位里面去了,但这个没有关系,我们还是继续走之前原来的路径,让它在最后面 DMP 里面再做一次判断。

经过这么一个简单的优化之后,我们在第一时间里面可以过滤掉大概80%以上的流量,所以对整个系统的性能也是有非常大的提升。

OpenResty在腾讯游戏营销技术中的应用和实践

接下来就在逻辑层的优化,逻辑层主要是竞价引擎,竞价引擎会涉及到大量的内部服务的访问,比如标签查询、广告检索,还有点击率预估查询、频次控制查询、计费检查等等这样一些内部服务访问,同时会涉及到大量的调DB、调缓存、调redis等操作,我们很多的业务其实都是这样的,大量的I/O操作,非常典型的 IO 密集型的服务,所以我们也是非常果断地用 OpenResty 把它完全重构了,之前都是采用比较传统、非常老旧的C++的多线程同步框架。当然现在内部也有很多C++协程的方案,我们还是选择用 OpenResty 直接把它重构了。

另外一个方面就是利用 OpenResty 新建一些新的协程,去把之前一些串行化的操作做并行处理,来降低时延,可能一两个并行化操作就可以降低竞价出价的时延10%左右,也是非常可观的收获。

最后就是在数据层这一块,我们看看 OpenResty 是否有它的用武之地呢?

OpenResty在腾讯游戏营销技术中的应用和实践

数据层DMP 有三个功能,第一个是数据的采集,第二个是数据的计算,第三个就是数据的应用。在最原始数据采集这一块,因为我们后面也会把 DMP 做得更大,为我们营销体系做服务的,所以这里面涉及到大量的数据采集的工作,包括广告曝光、社区行为、公众号行为、各种营销活动行为等等,当然和之前一样,经过加密处理后进行收集。

那在数据应用这一块,我们有大量的标签查询、账号转化,还有内部数据合作、实时查询等等操作,这些操作其实都是非常,也可以直接用这个 OpenResty来做,所以我们用了非常少的服务器,很轻松的就可以处理数十亿这样的一些数据收集和查询操作。

那到这里,我的2个应用案例就分享完了,最后用四个数字来总结一下我讲的内容,以及想表达的优化思想,3527(不是9527):

  • “3”是什么意思?就是刚才提到的我们系统架构里面的三层,接入层、逻辑层和数据层,这里面三层都可以考虑用 OpenResty 去做优化,大家都比较熟悉在OpenResty主要是在接入层 CDN 和 API用的最多,其实在逻辑层也可以考虑用 OpenResty 去尝试做一些工作,特别是I/O密集型的逻辑层。并且我们OpenResty 升级了支持TCP/UDP服务器的stream-module,如果能更加稳定的话,我们也会去尝试用这个 module直接做我们逻辑层的服务,最后就是在数据层也可以去看看有没有这样非常简单的数据收集和查询操作,如果有的话,量也比较大的话也可以考虑用 OpenResty 来轻松实现。
  • “5”是什么意思呢?我们刚刚说做任何方案选型、考察、评估、深入的时候都可以从这五个方面去做。第一个是易用性,第二个是可用性,第三个是性能,第四个是安全性,第五个是可维护性。我们技术同学往往考虑得比较多是性能,可用性、安全性这三块,但其实在第一点和第五点,易用性和可维护性这一块需要我们花更多的时间考虑。特别是对于我们做业务开发的同学来说,80%以上的时间可能都是这两个方面,如果我们易用性和可维护性做得好的话会帮我们节省大量的时间。
  • 第三个数字就是“2”,“2”就是说我们在做性能优化的时候都要去问自己两个问题。第一个问题就是为什么要做这件事情。第二个问题就是能否可以不做,能否可以牺牲掉一些其他的资源,比如说内存资源来提高性能。能否就是牺牲一些实时性来提高性能,或者说我们牺牲产品的体验来提高性能等等,我们需要做性能优化的时候,可以更多地去往上层做一些这样的考虑和权衡。
  • “7”是我们在测试性能优化的时候有7个环节。里面每个环节都需要有自己注意的事情,并且可以去做一些归纳和总结。