资讯专栏INFORMATION COLUMN

极验高并发验证服务背后的技术实现

DevWiki / 1807人阅读

摘要:像极验这样高并发量同时需要高扩展性的验证服务企业来说,使用协程处理是降低并发开销最合适的方法。其次极验利用过滤非法请求,以及限制不同账户并发。能够比较便捷地搭建处理超高并发高扩展性的动态服务。极验通过以上三个技术手段,来解决高并发问题。

极验目前的用户超过7万家网站,日均验证量1亿次,作为一家专注于验证安全服务的公司,极验所要面临的并发压力主要表现在以下几点:

日益增加的用户并发量。

验证请求是全动态过程,不能够进行缓存。

每一次请求都会造成数据库的读写。

处理请求需要耗费CPU大量的时间进行模型的计算。

作为抗击黑产的第一线,可能遭到黑产的攻击。

那么极验是如何做到,既保证用户的验证需求量,又尽量快速响应用户的验证请求,还能够扛得住黑产的攻击呢?极验主要从三个方面来解决高并发问题。

降低并发的开销

利用协程处理并发,我们熟知的协程相较于线程来说具有的优点是,能够跨平台跨体系架构,不需要线程上下文切换和原子操作锁定及同步的开销。这样就避免了操作系统调度线程造成的资源浪费。同时协程方便切换控制流,能够简化编程模型,避免异步回调代码的逻辑分割,使得程序的可读性好,有利于后台的维护。像极验这样高并发量同时需要高扩展性的验证服务企业来说,使用协程处理是降低并发开销最合适的方法。

from tornado import gen
    @gen.coroutine
    def fetch_coroutine(ur1):
        http_client=AsyncHTTPCient()
        response=yield http_client.fetch(url)
        # In Python versions prior to 3.3, returning a value from
        # a generator is not allowed and you must use
        #   raise gen.return(response.body)
        # instead
        return response.body

其次极验利用OpenResty过滤非法请求,以及限制不同账户并发。OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了比较精良的 Lua 库、第三方模块以及大多数的依赖项。能够比较便捷地搭建处理超高并发、高扩展性的动态 Web 服务。

提升数据库性能

极验主要通过两个手段来提升数据库的性能:验证的临时数据采用基于分布式Redis和构建嵌入式数据库缓存,实现数据库零查询。

Proxy的Redis存储可能是目前比较常规的存储方法,通过代理将读写压力进行合理分配。codis-proxy基于GO和C语言,并发处理能力比较强。后端基于slot概念支持灵活,还具有对用户透明的扩容和缩容操作,简单便捷,集群管理工具丰富等优势。

但是对于极验来说这样的方式并不是那么合适,存在着以下几点极验必须要考虑的问题。

使用代理使得整个结构多了一层不安全因素,一旦代理层出现问题,那么后面的都无法正常运转。

代理本身并不具备良好的扩展性,无法自动的进行分配,在运维上有一定的难度。

加入代理层也会使得整个结构的响应速度相应减慢。

考虑到这些问题,我们选择采用自己的基于客户端的分布式解决方案,结构如下。

客户端通过一致性hash,写入当前机器与hash环上的下一台机器,实现数据冗余。读取时从当前机器读取,失败则从hash环上下一台机器读取。得益于相对简单的结构,扩容、故障恢复速度会快得多,同时运维成本更低。

在高并发量的情况下,数据库往往成为瓶颈,加上大量挂起等待的协程也会使得数据库的性能大大降低。像极验这样每天有大量的验证数据需要读取,提升数据库性能就显得十分重要。我们的解决方案是进行嵌入式缓存,所有查询完全遵循缓存中的数据,缓存定期与数据库同步。同时缓存直接嵌入服务进程内,实现几乎零开销查询。由于Python的GIL存在,我们利用mmap实现进程间共享内存。

我们在实现这个嵌入式缓存的过程中,完全按照我们业务中遇到的实际问题进行设计,所以可能对于其他业务不是很适用。具体来说,极验的数据库查询主要有三种特性:

数据几乎只读不写,并且对于数据一致性要求不高。

数据库查询开销相对计算逻辑比重较大。

接口并发数长期保持在较高水平,用传统缓存方式的话一旦缓存被穿透(例如恶意伪造不存在的数据)系统将崩溃。

基于上面三点特性,我们专门定制了最适合我们自己的缓存,并使得数据库完全不再是系统的瓶颈。

提高计算性能

提高计算性能极验主要采用以下两种方式:

1. 主要性能消耗在数据处理逻辑以及神经网络参数计算

利用Cython将计算密集代码编译成扩展模块供Python调用

def primes(int kmax):
    cdef int n,k,i
    cdef int p[1000]
    result=[]
    if kmax>1000:
       kmax=1000
    k=0
    n=2
    while k

2. 控制神经网络规模,同时优化计算效率

通过不断调整神经网络的参数和加大训练的迭代次数来保证足够精度下网络规模最小。在预测时加入DropOut,让部分神经元不参与计算,减少计算量的同时一定程度避免过拟合。

利用小网络学习大网络所提取到的特征加上现代Cpu的SIMD指令集加速计算——使用优化过的Blas库例如OpenBlas等。这样一来,能够很好的控制神经网络的规模。

极验通过以上三个技术手段,来解决高并发问题。目前我们使用不到二十台阿里云服务器的情况下可以做到5w的并发,并且整个架构可以完全快速横向扩展。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/36186.html

相关文章

  • 极验验证:浅析深度学习模型与应用

    摘要:一时之间,深度学习备受追捧。百度等等公司纷纷开始大量的投入深度学习的应用研究。极验验证就是将深度学习应用于网络安全防御,通过深度学习建模学习人类与机器的行为特征,来区别人与机器,防止恶意程序对网站进行垃圾注册,撞库登录等。 2006年Geoffery  Hinton提出了深度学习(多层神经网络),并在2012年的ImageNet竞赛中有非凡的表现,以15.3%的Top-5错误率夺魁,比利用传...

    王岩威 评论0 收藏0
  • 验证码识别

    摘要:下面我们便来讲种验证码的识别方式和一些思路。哈哈库其实,验证码识别归根到底还是对各种各样图片的识别和操作,中有很对图像处理的库,其中就是其中之一。所以在处理验证码识别之前,必须先了解库和。第五步,按照规定轨迹进行拖动,完成验证。 写在前面 现在,很多网站采取各种各样的措施来反爬虫,其中之一就是使用验证码。当我们访问网页时,必须先通过验证码才能够访问页面。下面我们便来讲2种验证码的识别方...

    keke 评论0 收藏0
  • 验证码识别

    摘要:下面我们便来讲种验证码的识别方式和一些思路。哈哈库其实,验证码识别归根到底还是对各种各样图片的识别和操作,中有很对图像处理的库,其中就是其中之一。所以在处理验证码识别之前,必须先了解库和。第五步,按照规定轨迹进行拖动,完成验证。 写在前面 现在,很多网站采取各种各样的措施来反爬虫,其中之一就是使用验证码。当我们访问网页时,必须先通过验证码才能够访问页面。下面我们便来讲2种验证码的识别方...

    willin 评论0 收藏0
  • 验证码识别

    摘要:下面我们便来讲种验证码的识别方式和一些思路。哈哈库其实,验证码识别归根到底还是对各种各样图片的识别和操作,中有很对图像处理的库,其中就是其中之一。所以在处理验证码识别之前,必须先了解库和。第五步,按照规定轨迹进行拖动,完成验证。 写在前面 现在,很多网站采取各种各样的措施来反爬虫,其中之一就是使用验证码。当我们访问网页时,必须先通过验证码才能够访问页面。下面我们便来讲2种验证码的识别方...

    k00baa 评论0 收藏0
  • 国家企业信用公示系统爬取

    摘要:国家企业信用公示系统的爬取网站分析获取首页通过直接请求网站首页,返回错误提示码,返回结果是代码。验证码识别开发者文档代码结果查询企业在首页的源代码中,有一句注释伪造极验变量百度成功获取到结果链接国家企业信用公示系统爬取 国家企业信用公示系统的爬取 1. 网站分析 1.1 获取首页 通过 requests.get 直接请求网站首页,返回 521 错误提示码,返回结果是js代码。这是采用...

    cloud 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<