1. 请求接收与初步处理
- 用户发送请求:https://www.icon2u.com/avatar/[标识符](标识符可能是哈希值或邮箱)
- 服务器接收请求,提取标识符部分
- 忽略所有查询参数(如s=56、d=monsterid、r=g等),这些参数不会影响处理逻辑
2. 白名单验证(使用内存缓存)
- 从请求头中提取Referer信息
- 解析Referer获取域名
- 检查域名是否存在于内存中的白名单集合中
- 如果域名不在白名单中:
- 返回403错误或预设的默认头像
- 请求处理结束
- 如果域名在白名单中:
- 继续后续处理
3. 标识符处理与内存缓存检查
- 检查标识符是哈希值还是邮箱
- 如果是邮箱:
- 转换为SHA256哈希值
- 使用哈希值作为键检查内存缓存
- 如果内存缓存命中:
- 立即返回缓存的128px头像
- 触发异步统计记录
- 请求处理结束
- 如果内存缓存未命中:
- 继续后续处理
4. 文件系统缓存检查
- 使用哈希值构建文件路径:[缓存目录]/[哈希值].png
- 检查文件是否存在
- 如果文件存在:
- 读取文件内容
- 将头像添加到内存缓存(供后续请求使用)
- 返回头像图像
- 触发异步统计记录
- 请求处理结束
- 如果文件不存在:
- 继续后续处理
5. 从Gravatar获取头像
- 构建Gravatar请求URL:https://secure.gravatar.com/avatar/[哈希值]?d=404
- 设置较短的超时时间(如3秒)
- 发送请求到Gravatar
- 如果Gravatar返回成功(200状态码):
- 立即将Gravatar返回的图像返回给用户
- 触发异步任务:
- 保存图像到文件系统
- 添加到内存缓存
- 记录统计信息
- 请求处理结束
- 如果Gravatar返回失败或超时:
- 继续后续处理
6. 返回默认头像并触发异步生成
- 从预设的0-10个默认静态头像中随机选择一个
- 返回该静态头像给用户
- 触发异步任务:
- 使用DiceBear API生成个性化头像
- 生成的头像保存到文件系统(设置1个月有效期)
- 添加到内存缓存
- 记录统计信息
- 请求处理结束
典型请求场景示例
场景1:热门头像(内存缓存命中)
- 接收请求,提取哈希值
- 验证域名在白名单中
- 内存缓存命中
- 立即返回缓存的头像
- 异步记录统计信息
场景2:已缓存头像(文件缓存命中)
- 接收请求,提取哈希值
- 验证域名在白名单中
- 内存缓存未命中
- 文件缓存命中
- 返回头像并添加到内存缓存
- 异步记录统计信息
场景3:Gravatar有头像
- 接收请求,提取哈希值
- 验证域名在白名单中
- 内存缓存未命中
- 文件缓存未命中
- Gravatar请求成功
- 立即返回Gravatar头像
- 异步保存头像和记录统计
场景4:无头像用户(首次访问)
- 接收请求,提取哈希值
- 验证域名在白名单中
- 内存缓存未命中
- 文件缓存未命中
- Gravatar请求失败
- 返回随机静态默认头像
- 异步生成个性化头像并记录统计
场景5:邮箱请求转换
- 接收请求,提取邮箱
- 验证域名在白名单中
- 转换邮箱为哈希值
- 继续场景1-4中的相应流程
异步处理详情
- 统计记录:
- 记录域名、哈希、时间戳、缓存命中情况
- 批量写入数据库(如每分钟一次)
- 缓存保存:
- 将Gravatar或DiceBear头像保存到文件系统
- 更新内存缓存
- 默认头像生成:
- 调用DiceBear API生成个性化头像
- 保存生成的头像到缓存
- 缓存维护:
- 定期清理过期缓存
- 预热热门头像缓存
- 更新内存中的白名单
核心简化与优化点
1. 全面内存缓存策略
- 头像缓存:将常用头像缓存到内存,减少文件系统访问
- 白名单缓存:将白名单域名加载到内存,加速验证过程
- 定期刷新:设置合理的缓存刷新机制,保持数据新鲜度
2. 参数处理简化(重点优化)
- 统一尺寸:忽略所有尺寸参数(如s=56或s=112),始终返回128px标准尺寸
- 忽略Gravatar特定参数:忽略d=monsterid、r=g等所有额外参数
- 简化缓存键:仅使用哈希值作为缓存键,不考虑参数变化
3. 处理流程优化
第一阶段:快速响应路径
- 接收请求
- 获取请求的标识符(哈希值或邮箱)
- 从内存获取缓存的白名单列表
- 域名白名单验证
- 从Referer中提取域名
- 快速检查域名是否在内存中的白名单列表中
- 如不在白名单,返回403错误或默认头像
- 内存缓存检查
- 如为邮箱,转换为哈希值
- 使用哈希值检查内存缓存
- 如内存中有缓存,立即返回标准128px头像
第二阶段:文件缓存路径
- 本地文件缓存检查
- 检查文件系统中是否有对应哈希值的头像缓存
- 如缓存存在,将其加入内存缓存并返回
第三阶段:外部获取路径
- Gravatar获取
- 设置较短超时时间(如3秒)
- 尝试从Gravatar获取头像
- 如获取成功,立即返回给用户,无需等待本地保存
- 如获取失败,立即返回预设的随机默认头像(0-10中随机选择一个)
第四阶段:异步处理(不影响响应速度)
- 异步后台任务
- 异步记录访问统计
- 异步保存从Gravatar获取的头像到本地文件系统
- 对无头像用户,异步调用DiceBear生成头像并设置1个月缓存期
- 定期更新内存中的白名单和热门头像缓存
- 按计划执行缓存维护任务
白名单缓存实现细节
初始化阶段
- 服务启动时从文件加载白名单域名到内存
- 使用高效的数据结构(如HashSet)存储,实现O(1)查找复杂度
- 预分配足够空间避免动态扩容开销
刷新机制
- 设置白名单文件监视器,检测文件变化自动刷新缓存
- 或设置定时刷新(如每10分钟),保持内存数据与文件同步
- 提供手动刷新API,用于紧急更新
容错机制
- 如白名单加载失败,使用上一次成功加载的数据
- 如没有历史数据,可设置"安全模式"(如只允许已知域名)
- 记录错误但不中断服务
优化效果对比
白名单验证
- 原来:每次请求都从文件读取白名单并执行验证
- 优化后:从内存中快速验证,接近零延迟
参数处理
- 原来:处理多种尺寸和参数组合,为每种组合维护缓存
- 优化后:完全忽略参数变化,只维护单一尺寸(128px)的缓存
请求处理路径
- 原来:所有请求类型使用相似处理逻辑
- 优化后:针对主要场景(哈希值请求)优化,最小化处理步骤
缓存效率
- 原来:主要依赖文件系统缓存
- 优化后:双层缓存(内存+文件系统),大幅减少I/O操作
响应速度
- 原来:完成全部处理(包括保存)后返回
- 优化后:获得有效头像立即返回,后续处理异步进行
实施建议
- 分阶段实施:
- 第一阶段:实现白名单内存缓存和参数简化
- 第二阶段:添加头像内存缓存层
- 第三阶段:实现异步处理机制
- 监控与调优:
- 添加性能监控点,记录各环节处理时间
- 根据实际数据调整内存缓存大小和刷新频率
- 定期分析热门头像,优化缓存策略
- 平滑过渡:
- 在一段时间内同时支持旧参数和新策略
- 逐步将用户引导至优化的请求格式