Nresource服务之接口缓存化
1、 背景
Nresource服务日均4.5亿流量,考虑到未来流量急增场景,我们打算对大流量接口进行缓存化处理;根据服务管理平台数据统计显示getUsableResoureCount接口调用量很大,接近40%,故对此接口进行缓存化处理。

2、 方案调研
getUsableResoureCount接口用途:获取用户的可用资源数,契约为:Map<String, Integer> getUsableResoureCount(long userId, int resourceType, ResourceCountTypeEnum typeEnum, List<Integer> cities, List<Integer> caties) throws Exception;支持传入资源数类型(全国/本地)多城市和多类目按照包含的策略进行资源过滤;
由于资源库存表设计字段:城市和类目写入格式为:1,2,3,即以逗号组合的字符串,所以如果缓存用户对应城市和类目的所有余量,实现难度大且意义不大。
通过对接口返回值的观察,我们发现getUsableResoureCount接口返回值很多都是查询用户所有资源余量,不区分城市和类目,且查询结果都为0,所以我们切换思路:是不是可以把这些无余量的数据缓存起来?
通过2021-07-27 10:00:00数据统计我们发现,单节点一分钟getUsableResoureCount接口调用量为395,其中查询所有资源余量的微287,返回值为0的为183,接近46%的请求是无数据的,所以缓存用户无余量的数据是有意义的,能挡住接近50%的无用请求。
缓存用户无余量的数据,我们需要在所有涉及余量增减的操作,同时维护redis中余量变化,如何维护db与缓存中数据的一致性,也是面临的问题,所以我们想:可不可以不缓存余量,只缓存一个余量标识,这样既能挡住无用请求,又不需要维护db与缓存的数据一致性呢?参考布隆过滤器,我们决定对此接口进行缓存余量标识,只记录有还是没有,即1和0。
3、 方案实施
getUsableResoureCount接口先查询缓存,如果返回值为0,则放入缓存,所有增加余量的操作均需要更新redis标识为1。基本目标就是:保证更新标识为有的操作一定成功。考虑到服务并发,写操作(更新redis标识为1)可能会被读操作(更新redis标识为0)覆盖,所以更新redis标识为0的时候,先增加时间校验即晚一分钟更新,因为redis标识更新为0或null,不会影响最终查询,而是会查询db,晚一分钟又可以避免读写覆盖的问题。最终采用lua脚本实现读操作,而写操作采用同步set异步重试保证最终成功;
lua脚本如下:

4、最终效果
接口响应耗时:
2021.9.2 VS 2021.9.9

2021.9.8 VS 2021.9.9

性能提升(ms):1.4 -> 0.9 提升超过30%
整体服务响应耗时:
2021.9.8 VS 2021.9.9

性能提升(ms):1.8 -> 1.6 提升超过10%
缓存命中率统计:
服务节点:10.***.60.***

命中率接近80%
5、未来考量
1)缓存的扩展性,未来新的写接口需要更新redis标识为1;
2)缓存的接口适配性,考虑更多查询接口应用缓存;
ps: 整体思路,由于业务原因,没有采用传统缓存用redis存有效数据的思路,我们是反其道行之,用redis来挡住无效流量
Nresource服务之接口缓存化的更多相关文章
- java接口入参模板化,适用于企业化服务远程调度模板化的场景,接口入参实现高度可配置化
需求:远程服务接口模板化配置提供接入服务 模板接口分为三个模块:功能路由.参数校验.模板入库 路由:这里的实现方式很简单,就是根据业务标识找到对应的处理方法 参数校验: 参数校验这步涉及模板和校验类两 ...
- 唯品会RPC服务框架与容器化演进--转
原文地址:http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=405781868&idx=1&sn=cbb10d37e25 ...
- vue服务端渲染缓存应用
vue缓存分为页面缓存.组建缓存.接口缓存,这里我主要说到了页面缓存和组建缓存 页面缓存: 在server.js中设置 const LRU = require('lru-cache') const m ...
- 在 WPF 客户端实现 AOP 和接口缓存
随着业务越来越复杂,最近决定把一些频繁查询但是数据不会怎么变更的接口做一下缓存,这种功能一般用 AOP 就能实现了,找了一下客户端又没现成的直接可以用,嗐,就只能自己开发了. 代理模式和AOP 理解代 ...
- .NET实现微博粉丝服务平台接口
[文章摘要]Senparc.Weixin.MP虽然是微信公众号的SDK,但由于易信公众号和新浪微博粉丝服务平台也提供了微信兼容接口,所以也可以使用其快速实现相应的服务,当然微博由于与微信存在差异,如果 ...
- 戏说WSGI(Python Web服务网关接口)--[转载]
戏说WSGI(Python Web服务网关接口) 当你在Python的世界中冒险,突然遭遇一只Web怪兽,你会选择什么武器对付它?在兵器谱上,下列兵器可谓名列前茅: Zope,厚重的长枪.较早出现的武 ...
- Axis2创建WebService服务端接口+SoupUI以及Client端demo测试调用
第一步:引入axis2相关jar包,如果是pom项目,直接在pom文件中引入依赖就好 <dependency> <groupId>org.apache.axis2</gr ...
- Spring Cloud开发实践 - 02 - Eureka服务和接口定义
服务注册 EurekaServer Eureka服务模块只有三个文件, 分别是pom.xml, application.yml 和 EurekaServerApplication.java, 内容如下 ...
- 接口缓存--把接口放在redis数据库中,减少访问量
针对访问量大,且数据较固定的接口,建议建立接口缓存,建立了缓存之后,不会再直接去访问接口了. 比如下面的轮播图接口,每刷新一下首页都会访问一下轮播图接口,所以我们用接口缓存来处理,减少访问量. 视图模 ...
随机推荐
- 【阿菜Writeup】Security Innovation Smart Contract CTF
赛题地址:https://blockchain-ctf.securityinnovation.com/#/dashboard Donation 源码解析 我们只需要用外部账户调用 withdrawDo ...
- 【开发工具】idea常用配置
1. 设置鼠标滚轮修改字体大小 我们可以勾选此设置后,增加Ctrl + 鼠标滚轮 快捷键来控制代码字体大小显示. 2. 设置鼠标悬浮提示 3. 设置自动导包功能 Add unambiguous im ...
- 【java se】java注解
目录: 1.注解概述 2.常见的 Annotation 示例 3.自定义 Annotation 4.JDK 中的元注解 5.利用 反射获取注解信息(在反射部分 涉及) 6.JDK 8 中注解的新特性 ...
- linux系统下深度学习环境搭建和使用
作为一个AI工程师,对Linux的一些技能的掌握也能从一定层面反应工程师的资深水平. 要求1:基于SSH的远程访问(本篇文章) 能用一台笔记本电脑,远程登陆一台linux服务器 能随时使用笔记本电脑启 ...
- MySQL-SQL基础1
p.p1 { margin: 0; font: 11px Menlo; background-color: rgba(128, 128, 128, 0.5); min-height: 13px } p ...
- Linux从头学10:三级跳过程详解-从 bootloader 到 操作系统,再到应用程序
作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...
- Java网络编程之TCP
Java网络编程之TCP TCP主要需要两个类:Socket和ServerSocket,Socket是客户端连接服务器时创建,参数需要指定服务器的ip和端口,ServerSocket是服务器端创建 ...
- dotnet C# 给结构体字段赋值非线程安全
在 dotnet 运行时中,给引用对象进行赋值替换的时候,是线程安全的.给结构体对象赋值,如果此结构体是某个类的成员字段,那么此赋值不一定是线程安全的.是否线程安全,取决于结构体的大小,取决于此结构体 ...
- Docker容器管理——Docker容器常用命令
1.查看所有的容器 docker ps 2.查看运行的容器 docker ps -a 3.启动.停止.重启docker容器 docker start ... docker stop ... docke ...
- Python中 sys.argv[]
sys.argv[]是一个从程序外部获取参数的桥梁,从外部取得的参数可以是多个,所以获得的是一个列表(list),用[]提取其中的元素.其第一个元素是程序本身,随后才依次是外部给予的参数. 实例 im ...