服务端 - 代码优化思路

目录

目录

引言

一 :查DB相关的优化

1 代码优化之循环查DB

2 代码优化之循环调Dubbo(或者其他的远程调用)

3 代码优化之重复查询

二 内存、缓存

3 代码优化之内存

4 代码优化之缓存

4.1 实际开发中使用

4.2 余量查询接口优化

5 代码优化之前置缓存

5.1 开发中实际应用

三 并行、串行

6 代码优化之串行接口



引言

以前只注重“功能的实现”,而不注重代码的质量!这是低级的,经过这么久的摸爬滚打,初窥好代码的门径!

一 :查DB相关的优化

1 代码优化之循环查DB

为什么在for中查DB需要被优化?

简单说如果你的这个for很确定,也很稳定,任何情况下只会循环几次,而且不是大查询,这也无可厚非。

但是,如果一个for会循环几十次呢?那么这个接口调几十次DB,这还是一次接口请求,如果是多次呢,如果是高并发的时候呢?mysql服务器会直接被干挂了吧!所以这些代码要被优化掉,以避免和减少db服务器压力。

解决:

把for循环单独查询的数据改为批量查询-转为map-在for循环中根据key拿到当前循环需要的数据

2 代码优化之循环调Dubbo(或者其他的远程调用)

为什么要被优化?

原因和上面差不多,但是这个更严重一些,我们知道RPC远程调用框架有很多,但是无论哪一种,调用远程接口都是比较耗时的,耗时只会比上面更多,同时也会干挂服务器。

解决:

同上

3 代码优化之重复查询

这个比较简单。

场景:

一段业务逻辑中

//查询id=1的图书

//逻辑处理了一会儿

//又查询id=2的图书

//又过会

//又查询id=3的图书

这不是无谓的IO消耗嘛,干嘛不一次查完

解决:

理清逻辑,接下来会遇使用到哪些需要重复查的数据,比如这里,直接批量查询id in (1,2,3)的图书,后面的直接取数据就好了。一次DB不比3次爽

二 内存、缓存

3 代码优化之内存

看我的这个

​​​​​​项目启动时就加载数据到内存_nurture_的博客-CSDN博客_项目启动就加载

4 代码优化之缓存

以前总以为这个很高大尚,很牛逼,怕不会用!可能刚接触的的同学都是这样吧!

开发中使用的场景:

低频修改,高频访问的数据可以考虑缓存。

缓存的经典使用:先查高速介质,高速介质命中则返回,不存在则查低速介质,返回数据后同时把数据放入高速介质

作用:

减轻DB服务器的压力,提高接口响应速度,进而提升用户体验;高并发。

逻辑处理:

一次请求过来====》拿着约定的key去查redis服务器====》查到了就直接用 

                                                                                   ====》查不到就查DB,同时存redis

注意:

这里如果是存储的对象会涉及到序列化和反序列话的问题,没啥,很多工具fastJson啥的都可以做到,不多说。

4.1 实际开发中使用

在选课链路中发生DB 请求时 ,原因是未将一些基础信息进行缓存 , 在请求接口时导致每次请求到 DB 上,增加时间耗时,qbs降低 , 而在这次的选课链路中增加了大量的缓存 redis的使用 , 减少了 DB 的次数与耗时 , 很大的减少了请求耗时。

4.2 余量查询接口优化

背景 :

余量接口的请求与刷新是高频的 ,每个学生进入页面会请求每个课程对应班级的余量信息(80+的选修课,每个选修课在 1-2 个班级)  

在未做缓存优化时服务器的 rt平均在 3 ,缓存处理之后平均在 1

优化方案 : 余量接口合并请求 + redis 缓存

余量请求接口原逻辑是每一条课程的课时数据就请求一次余量接口 , 导致大量的余量接口请求 , 这次将余量接口合并请求 , 并且余量信息存放缓存 redis 中;

 

5 代码优化之前置缓存

研究中!...大佬教教我

5.1 开发中实际应用

前置缓存:

前置缓存的优化主要在调用dubbo接口的一些链路上,把调用接口后走缓存的逻辑前置到调用接口之前来减少dubbo的调用。

假设这里UserContextFilter中的doFilter方法为例,doFilter方法中调用了getAndAnalyseUserContext接口,而由于doFilter是一个访问非常高频的一个方法,每一个url进行过滤都要走这里以获取用户的身份信息等,所以会频繁的调用dubbo走到login的服务端。

我们可以看到服务端的逻辑是从redis中获取userContext。

既然userContext缓存到了redis中,而服务端的逻辑也是从redis中获取,那么我们可以在调用dubbo之前就先去查redis,把调用接口后查redis的逻辑拿到接口调用前,这样直接从缓存中获取到之后就不需要调用dubbo,从而减少dubbo和login服务端的压力。

改造之后

我们可以看到原本直接调用dubbo的逻辑变成了先调用getLoginUserContextFromRedis方法,这个方法中的逻辑是先从redis中获取userContext,获取到则直接返回,否则再走dubbo调用接口。前置缓存改造完成。

那么我们可能会产生这样一个疑问,进行前置缓存改造之后,肯定是从缓存中获取不到才会调用接口走dubbo,而调用接口之后在服务端又进行了一次查缓存的操作,这次操作是否是多余的呢?答案当然是否定的,考虑这样一个场景,我们的业务流量非常大,在缓存失效后同时有很多请求走这个链路,它们从缓存中获取不到数据所以都走到了服务端,那么这个时候由于每个请求调用dubbo的耗时长短不一,导致某些耗时短的请求从缓存中获取不到数据而继续执行到了put操作,put操作之后缓存中已经存在数据了,所以那些耗时长一些的请求又可以直接从缓存中获取到数据,而不用再走DB。因此,即使我们进行前置缓存的改造后,服务端也是要再查一次缓存,拦截掉一些到DB的流量。

记录没有截图,简单的文字记录只为了提醒自己。以后会回来完善文章。

三 并行、串行

6 代码优化之串行接口

场景:

多个没有相互依赖关系的接口在逻辑代码中是以串行的方式执行的

解释:

假设一段逻辑是:

//查寻所有用户信息             假设接口耗时100ms

//查寻所有的图书信息          假设接口耗时100ms

//查询所有的阅读记录信息   假设接口耗时100ms

这段逻辑代码走完就是300ms,这是按照逻辑顺序走的,走的是串行。

如果修改为并行,三个接口的耗时就会远远 < 300ms

如何串行改为并行,涉及到JUC的一个包。这里直记录思路。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值