Hulk 图床是支持 360 公司绝大部分业务的图片服务,支持多种图片处理功能,如:裁剪、压缩、滤镜、pHash 计算、人脸识别、格式转换、gif 首帧提取……等等,支持的业务线包括:搜索、图搜、新闻、信息流、广告……等等,每天 CDN 回源图床后端 150+ 亿 PV。
图床业务逻辑相对简单,抽象看就是:上传和下载,这里简单分享图床这两个模块的架构以及图片的上传和下载时所经历的服务。
1. 上传模块(Davinci)
【Davinci 架构图】
业务上传图片到图床逻辑大致如下:
SDK 上传
通过 SDK (或者业务自己构造 HTTP 请求)将图片 POST 到 Davinci 上传接口 ,接口域名解析的 VIP 均衡到后端 Nginx (80 端口)。Nginx:80 转发
Nginx 80 通过 upstream,将请求通过负载均衡,均衡给后端处理的服务(Nginx 8360) 。排队等待上传处理
后端服务将上传任务进行排队,等待 Gearman 异步服务进行队列消费和任务调度,同时给该上传请求返回任务 ID,用于查询处理结果。图片初始处理和存储
Gearman worker 异步对图片进行处理,比如压缩、初始裁剪、人脸识别等,并将图片以及图片处理后的元信息落地存到 Cassandra。将任务 ID 对应的处理结果,存在 Redis,用于提供用户查询。获取上传结果
通过 <iii> 中获取的任务 ID,获取图片上传和处理结果。
PS: 图床同时也支持同步上传、回调通知的方式,将图片上传结果反馈给业务方。
2. 下载模块(Picasso)
【Picasso 架构图】
用户通过 URL 请求图床的一张图片,大致流程如下:
图片 URL 请求
图片 URL 根据图床域名 CNAME 配置,请求到 CDN 节点。如果所请求的 CDN 节点已缓存过该图片,则直接返回数据。CDN 回源
如果 中没命中 CDN 缓存,将会回源到图床后端(Nginx 80 端口)。图床后端缓存(Varnish)
为了减少图床后端的计算压力,图片请求回源到图床后端时,并不是直接到存储集群读图片、处理图片,而是先通过 varnish 前端缓存服务,如果 varnish 缓存命中,则直接响应图片数据。Varnish 缓存没命中
如果 varnish 缓存没命中,则转发给 Nginx 8360 端口,进而转发给 PHP fast-cgi 进行图片读取和响应。图片处理
在 <iii> 中读取了图片数据,会在 Nginx (8360)这层的 filter 模块进行处理,处理规则是在图片 URL 的参数中指定。比如:指定裁剪宽高、滤镜、黑白、人脸裁剪、gif 首帧提取等等,这个 filter 模块主要是使用了开源的 GraphicsMagick 进行图片处理,静态编译到 Nginx。响应处理后的数据
通过 Nginx (8360)这层模块的处理,得到符合 URL 指定规则的图片,最后响应并缓存到 CDN 节点。
以上就是图床上传和下载模块的处理逻辑。