从数据层面 -----Webapi的性能调优建议 使用缓存.压缩银弹

前提

前后端分离项目中的三个角色:

客户端    后端服务  数据库

具体拆分为: 客户端  webapi项目  efcore  数据库

需求:如何将一个2s的调用链 缩短至500ms甚至更低

我们访问api时发现耗时 2.71s

 

 

 

老样子 我们打开Vs2019性能探测器 分析 2.71s 由什么原因产生 调试CPU使用率 测试接口被调用时的CPU耗时情况 注意使用打开项目的第一次请求 

 

 

接口耗时 1.9 剩余800ms 可能由于网络IO

我们接着调用方/被调用方继续调试 

 

 

 1948ms 有1947来自该函数  该外部代码来着 Efcore Efcore 又来着 Mysql数据库

到此位置 我们可以确定瓶颈来自 efcore+mysql 根据经验断定Mysql为性能瓶颈

当前我再次使用本地缓存 进行调优 Mysql调优将会在后期文章中说明

在ASP.NET CORE中使用 本地缓存 

导入包

 

 

 

添加IOC容器中

 

 

 通过构造函数使用

 

 

 将数据查询的数据存到本地缓存

 

 

 

 

 使用缓存作用 瞬间 由1700ms =》21ms

 

 

 问题随之而来 当查询的数据不一样 加入有100w查询 那就有100w个缓存 内存还有吗?GC是想回收 也回收不了

解决办法:

   设置缓存过期时间 让内存自动释放 因为他不能自动回收 他的内部使用的是静态变量

 

 

 如果遇见大并发量时就算你 用1小时自动清理 也不能保证缓存不爆炸 

解决办法 :设置缓存的存储大小 

 

 

 缺陷

    假如 :某个用户的某一条数据就是你设置的限制大于100M 就会导致所有的数据 存不进去 如何防止这种大对象的存入

ps( 假设 我们内存只有4GB 规定3分钟自动清理一次缓存 并且每个用户 能使用的最大内存为100M 当1W并发量进入时 其中5000个用户每个用户进行查询的其中一个数据不论是 图片 视频还是 其他的 直接达到了100M 那会 使我们的内存占用率直接拉满 所以我们如何应对这种大对象的存储 ) 需要限制单个数据的缓存大小

 

 

 

以上我们解决了 内存长大的一系列问题 我们忽略了 并发问题线程问题

在C#里面 凡是API 以Try开头的 都是为了并发

所以我们改造我们的代码为

 

 

 缓存总在第二次进行使用 我们如何进行缓存预热

 解决办法 我们当我们项目启动时自动对缓存进行预热 只需要继承IHostedService

 

 

 

为了达到高并发 我们需要为服务进行集群 每个实例在启动时都会更新缓存 可能数据会导致重复 还要保证数据的同步 重复的共作 不仅麻烦还慢  所以 我们将本地缓存进行拆分  --------》分布式缓存 Redis

如果你想使用本地缓存采取 同时更新的方式 你会发现 延时性非常 高 最好的办法其实还是 分布式缓存 !

本地缓存的性能始终高于分布式缓存 

 数据库数据问题,只要数据导致了性能瓶颈 那么我们就用缓存解决

如果是 程序导致了性能瓶颈 我们需要通过代码优化  就是尽量在代码中使用Async +Await

优化思路:

串行代码 执行时间不断累加 如何缩短时间? 将串行代码改成并行 

服务通过webapi 到客户端 通过网络IO 这个IO也会消耗时间 我们还可以同客户端缓存 减少网络IO 直接通过客户端响应数据 ======HTTP缓存 把webapi的数据存到客户端

一:HTTP协商缓存:查询较多

使用的工具:

 

 

 添加服务到IOC容器

 

 

 

 

 二:HTTP强制缓存

不变化的数据作强制缓存 :字典数据 页面数据 图片等 ,JS CSS等

数据压缩:

 

 

 

 

 

 原理就是:

 

 

 默认支持压缩的格式 

 

 

 我们来扩展一个对图片进行压缩的扩展

 

 

 还可以自定义压缩格式 实现IComperssionProvider接口

 

 添加到配置中:

 

 

 

 

posted @ 2021-10-30 17:05  三五八团楚云飞  阅读(416)  评论(0)    收藏  举报