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数据库中,减少访问量
针对访问量大,且数据较固定的接口,建议建立接口缓存,建立了缓存之后,不会再直接去访问接口了. 比如下面的轮播图接口,每刷新一下首页都会访问一下轮播图接口,所以我们用接口缓存来处理,减少访问量. 视图模 ...
随机推荐
- mysql 常用见的错误处理
一, 创建用户: 命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指 ...
- 2018秋招C/C++面试题总结
一.C和C++的区别是什么? C是面向过程的语言,C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛.C中函数不能进行重载,C++函数可以重载C++在C的基础上增添类,C是一个结构化语言,它 ...
- uwp 之吐司 toast
Toast -------------------------------------------------------------- var t = Windows.UI.Notification ...
- 服务端负载监控-参考srs服务器源码
#include <map> #include <stdio.h> using namespace std; struct SrsMemoryObject { void* pt ...
- 09.SpringMVC之类型转换
一. 类型转换器 前端传入的值,从表单中传入的值,都是字符串或者是字符串数组的形式传入的,在后端需要进行手动的转换类型,然后才能正确的使用. 框架一般对常见的数据类型的转换进行了封装提供,如字符串转换 ...
- AAC简介
AAC共有9种规格,以适应不同的场合的需要: MPEG-2 AAC LC 低复杂度规格(Low Complexity)--比较简单,没有增益控制,但提高了编码效率,在中等码率的编码效率以及音质方面,都 ...
- 高德渲染网关Go语言重构实践
1.导读 高德启动Go业务建设已经有段时间了,主要包含Go应用落地,Go中间件建设,云原生三个部分.经过持续的发力,在这些方面取得了不错的进展.高德Go业务落地过程是如何实现的,遇到过哪些问题,如何 ...
- Java同步之线程池详解
带着问题阅读 1.什么是池化,池化能带来什么好处 2.如何设计一个资源池 3.Java的线程池如何使用,Java提供了哪些内置线程池 4.线程池使用有哪些注意事项 池化技术 池化思想介绍 池化思想是将 ...
- AbpVnext使用分布式IDistributedCache Redis缓存(自定义扩展方法)
AbpVnext使用分布式IDistributedCache缓存from Redis(带自定义扩展方法) 我的依赖包的主要版本以及Redis依赖如下 1:添加依赖 <PackageReferen ...
- 矩阵BFS
leetcode 1091矩阵BFS 在一个 N × N 的方形网格中,每个单元格有两种状态:空(0)或者阻塞(1). 一条从左上角到右下角.长度为 k 的畅通路径,由满足下述条件的单元格 C_1, ...