Redian新闻
>
写代码与洪水滔天

写代码与洪水滔天

科技

你好,我是yes。

之前不是稍微吐槽了下一个项目的代码嘛,有几个同学(1V1问答的同学)就顺着问了我几个平日里一些编码的问题。

不同人写代码其实分了好几种情况:

  • 有些人完全没意识到问题,这个属于个人知识瓶颈,需要多加学习。
  • 有些人就随意写,赶时间,没责任心,当下能跑就行,后面管它洪水滔天。
  • 有些人就贼纠结,写个小功能想七想八,脑子总往着亿级流量上怼,可能项目黄了之前其实都只几个人用。

这几个情况我都经历过,写代码虽被戏称搬砖,但咱毕竟也是类似阿提斯特一样的创作型工作,跟心情有一定的关系。

工期紧心情差,将就将就,闲得很心情好,我缀一口咖啡精雕细琢。

咳咳,扯远了,回到今天的主题。其实平日里想要写好代码,没那么难,这篇我就总结下需要注意的几个要点,不是很全,但是都是比较常见的点。

批处理思想

遥想当年我还是实习生的时候,写个代码风风火火闯九州!就没有我不敢莽的代码。

一个 for 循环闯天下:

for (YesDTO dto : yesDTOList) {
     //do sh
     save(xx);//插入数据库
}

dev 和 qa 库里就几条数据,跑的好好的,一上线几千条数据,直接干蒙 mentor。

我当时都没意识到问题所在,但从他的眼神中我看到了杀气。

影响不大,这锅还得他背,谁让他不 check 我的代码?

现在知道了,一条一条插入太慢了,涉及到网络的开销,数据的解析等等。

所以特别在 for 循环的时候要想到批处理思想

for (YesDTO dto : yesDTOList) {
     //do sh
     xxList.add(xx);//添加列表
}
//批量插入
saveBatch(xxList);

不仅仅是我提到的数据库操作,还有 RPC、HTTP 调用也是一样,需要提供批量处理的接口替换 for 循环的一次次调用。

批处理能显著提高吞吐,如果你看过一些中间件的源码或底层一些实现你肯定能 get 里面很多批处理的思想。

事务

本地操作,如果涉及多个表的修改,不要忘了上事务,不然一旦中间处理出了差错,数据就不一致了,意味着需要补数据,而补数据是一件非常麻烦且敏感的事情。

如果本地操作,涉及多个表的修改,又涉及远程调用(或HTTP调用),需要注意事务的范围。

开始事务
修改A
RPC调用
修改B
结束事务

不推荐在事务中使用远程调用(或HTTP调用)。

因为远程调用(或HTTP调用)可能因为网络等其他原因导致响应很慢,而如果你的事务包裹了这些调用,可能会因为处理慢而长时间持有数据库连接,或阻塞后续其他请求修改对应的值,使得连接池的连接耗尽,然后就都堵着,就都挂了。

所以写代码的时候要想着上事务保证数据的一致性,又得想着事务内部的行为会不会阻塞连接的释放导致后续雪崩问题。

还有要注意一点,有些同学在事务里面包了 RPC 调用(或HTTP)是想着如果 RPC 调用失败本地事务就回滚,通过这样的手段来保证一致性。

这种想法是错的,因为调用可能是超时或其他网络情况,这不能代表对方的业务执行失败,所以如果对方执行成功,你还是回滚了本地事务,其实数据还是不一致的。

如果需要确保一致性,就只能上分布式事务,可以看下我这篇:分布式事务汇总

异步

异步化改造是提升服务性能的一个有力手段!

如果某个模块流量高,异步能减轻压力。

如果某个模块处理流程复杂且缓慢,异步能避免同步调用超时。

在编码中遇到以上这两个问题,就可以考虑异步。(当然还有其他场景,但这两个比较常见)

可以通过 MQ 或者线程池来实现异步。

在平日工作的场景中,我更多使用  MQ 来实现异步,因为线程池的任务毕竟是存储在内存中的,它没有自带的持久化操作,而且任务队列大小也有限,而 MQ 自带持久化且能存储的任务量更大。

你想,假设你线程池堆积了1千个任务,然后服务挂了,那不又得考虑补偿的机制了?而 MQ 就没有这个烦恼。

当然,一些定时批处理任务类的场景还是要利用线程池的,不过这种场景的数据源已经持久化在数据库中了,不会丢失。

重试

就像我前面说的,RPC 调用或 HTTP 调用可能因为网络问题没拿到正确的响应,这时候你必须要有重试的操作。

比如有个业务是异步的,别人调了你之后,你慢慢处理,等你处理完了需要通知别人,这就涉及到回调。

而回调别人接口的时候,脑子里一点要想着会遇到网络问题,比如超时等,你必需要设计一个重试机制来保证通知到对方。

这个重试机制最好是间隔延迟的,比如1s、5s、30s、1min 、5min这种间隔重试,也就是说需要给对方一点时间来恢复服务,避免对方服务出问题的前几分钟把重试都用了,导致后面需要人工介入补偿。

还有需要限制重试次数,因为我们的资源也是有限的,不可能给它无限重试,当达到一定的失败次数后进行记录,后续人工介入处理。

幂等

提到重试,那肯定伴随着幂等。

一切接口,如果可以,就按幂等实现,也是说一个接口同样的入参,调用多次都跟调用一次产生的结果是一样的。

因为现在基本上都是微服务,远程调用非常频繁,基本上 RPC 框架都会自带重试机制,你的接口很有可能在你没准备的情况下被被重复调用,所以幂等就很重要。

并且有时候需要补偿等动作时,幂等的接口可以让你补偿更加方便且没有后顾之忧。

缓存

缓存是提高服务性能的一个重要手段之一。

很多大流量高并发服务基本上业务层的数据源都来自于缓存,对于一些精细化拆分的业务组来说,可能几年都没写过 SQL。

我相信市面上公司基本都会接入  Redis(或类似组件),咱也不是说啥都要上缓存,只是说编码时候考虑下这块是否需要利用缓存来减少服务的压力,比如一些频繁调用且基本上不会更改的固定配置等等。

而缓存不仅仅是分布式缓存,还有本地缓存,也要善于利用本地缓存来实现优化。

总结

我稍微总结下以上内容:

  1. 编码时要有批处理思维,避免 for 循环单条保存数据和远程调用(效率极低)。
  2. 注意事务的范围,避免事务中进行远程调用或分布式锁竞争等可能长时间造成数据库连接不释放的场景,也就是说不要无脑用 @Transactional 包裹整个方法;
  3. 异步改造提高性能,但是要注意异步后如何保证异步的逻辑一定会被执行,且异步逻辑出错如何补偿等问题;
  4. 网络是不稳定的未知的,重试机制必不可少,要注意重试间隔,给对端多点时间恢复,减少需要人工介入的场景;
  5. 尽可能按幂等实现方法,防止被重复调用导致数据错乱;
  6. 缓存,缓存大法YYDS,但是要注意失效时间以及大 key 问题。

虽说咱是打工人,不是给人卖命,但是一些基本职业素养还是要有的,我们还是需要有责任地管一管,避免后面的“洪水滔天”。

好了,今天就暂时分享这么多,后期我看着再整理一下实现的细节点。

还有,我最新一期的个人VIP专属问答已经启动了,已经给很多小伙伴修改了简历和回答面试问题,有几个已经找到工作啦!

问答详情,可以看我的这篇介绍:最后再接 3 个名额凑个整。

我是yes,从一点点到亿点点我们下篇见~

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
2022南美南极行(15)巴西 萨尔瓦多这样写代码,同事乐开花!ChatGPT明知自己写代码有漏洞,但你不问它就不说程序员教 AI 写代码,反被 AI 取代?谷歌工程主管:AIGC 将在 3 年内终结编程不编写代码也可以为开源项目做出贡献 | Linux 中国IDE + ChatGPT,这款编辑器真的做到可以自动写代码了!代码与价值观:思考加密领域中的“无需信任”对领域的认知比会写代码更重要春招大爆料!面试官礼貌微笑背后的人脉密码与人性特征!| 求职必修课GPT-4 Copilot X震撼来袭!AI写代码效率10倍提升,码农遭降维打击一个程序员决定写代码到60岁唯一维护 API 的普通工程师轻松搞垮 Twitter,马斯克:我们重写代码吧GPT-4写代码能力提升21%!MIT新方法让LLM学会反思,网友:和人类的思考方式一样亚马逊已在多种工作职能中使用ChatGPT,包括编写代码等2023年完成业务目标,从战略解码与重点工作规划开始对打GPT-4,文心一言抢先实测!画「林黛玉倒拔垂杨柳」很惊艳,但写代码不大行“大疫”要来?卫生局警告:奥克兰这一急性病病例增加!或与洪灾有关!这些症状要注意!AI编程成本只有人类程序员的万分之一,速度却快了10000倍,再雇人类来写代码就离了大谱?数百程序员专门教AI写代码、40个bug能修复31个,“取代程序员”这次要成真了?GPT-4 Copilot X 震撼来袭!AI 写代码效率 10 倍提升,码农遭降维打击2023元月小惊喜身价近千亿的谷歌联合创始人在隐退多年后回谷歌写代码Nature:把ChatGPT用于科研的读者中,最多的竟是“头脑风暴,写代码、报告文稿、文献综述或研究论文”!ChatGPT 带火“提示工程师”,不用写代码也能年薪数百万?《知识》自古是被当作私有财产同行热议:游戏程序员们写代码这么烂,真的是常态吗?被时代埋没的女建筑师宋慧乔新剧“杀”疯了,开分直冲9.3!奈飞成大赢家?解锁背后的流量密码与现实挑战不写代码、靠“玩”ChatGPT年入百万,提示工程师正变成硅谷新宠全球最大ChatGPT开源平替来了!支持35种语言,写代码、讲笑话全拿捏干货!不做实验不写代码,直接发5.5分SCI!(附复现实操)无需写代码能力,手搓最简单BabyGPT模型:前特斯拉AI总监新作别总写代码,这 130 个网站比涨工资都重要!不写代码,拿百万年薪!ChatGPT提示工程或造就15亿码农大军煮屁话禅茶(二)
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。