当前位置: 首页 > news >正文

公司CEO和我说:在系统优化的时候,不要轻易用多线程

(一)前言

最近一段时间整个公司有不少应用上线,上线后慢慢开始暴露一些问题,除去bug之外,一个很值得关注的点就是系统的优化。毕竟优化系统不仅可以使得程序更加稳定,还能节省一些资源的浪费。作为一个技术氛围很不错的公司,很多人会把自己的优化方案发出来和大家一起讨论,只不过没想到这一讨论把公司CEO以及几位P8、P9大佬都给炸出来了。

本文将会介绍系统优化的常用方式,以及优化的一些误区。

(二)程序优化

2.1 慢sql

应用上线后,我们可以通过各种云产品监控慢Sql,以阿里云的产品为例,通过应用实时监控服务ARMS就能将一段时间内的慢Sql统计出来。慢Sql出现的最大可能就是Sql走了全表扫描,没有经过索引。检查Sql语句可以通过explain命令查看执行过程,如果没有建立索引就建索引,如果已经有索引就优化索引。另外要注意避免索引失效,比如一下六点就会导致索引失效:

  • 1、复合索引不要跨列或无序使用(最佳左前缀):索引的顺序和sql语句查询时的顺序一致
  • 2、复合索引尽量使用全索引匹配
  • 3、不要在索引上进行任何操作(计算、函数、类型转换)
  • 4、like尽量以“常量”开头,不要以%开头,否则索引失效
  • 5、尽量不要使用类型转换(显示、隐式),否则索引失效,如:
name的属性是varchar,这里变成了int
select * from teacher where name=123
  • 6、 尽量不要使用or,否则索引失效

2.2 在循环中调用查询外部服务的语句

在系统优化时,我们还看到了在for循环中去调用查询外部服务或者数据库的情况,比如像下面这样:

for (String user:userList) {
    User resultUser = UserMapper.selectByName(user);
    result.add(resultUser);
}

在一个循环中,多次调用数据库查询语句,要知道每次调用sql命令都是有网络开销的。遇到这种情况,建议将单次查询改成批量一次或几次查询,节省网络开销的时间。

2.3 接口只返回必要信息

这个要求主要针对那些调用量很大的接口,有些接口会返回大量的数据,有很多都是非必要的,导致网络传输开销大。

优化方案也很简单,调整返回对象,只返回需要的信息。

2.4 异步线程一定要用线程池

如果代码中涉及到异步线程的逻辑,一定要用线程池。有一个业务就出现了自己开线程,结果程序运行过程开了N多线程,直接把应用搞崩了。

(三)产品优化

3.1 查询增加时间约束

以我们现在所做的大数据应用为例,数据动不动就上亿,这个时候做好查询时时间范围的限制能给系统带来极大的性能提升。比如我们现在搜索用的ElasticSearch,就在产品测让用户每次进入时只看到最近三个月的信息。

如果用户想查看更多就让他们自己去选时间范围。根据正常的使用情况,每一百次查询,可能只会有一次用户自定义查询时间范围的动作,极大提高效率。

3.2 不让用户进行深分页

目前常用的前端分页主要有两种,第一种是展示给用户开头几页和最后几页,比如下面这种:

这种分页仅适合于数据量少的应用,另外一种分页方式是只展示当前页的前后几页,而不会给用户直接跳转到最后一页的机会,比如百度的分页:

我们要知道不管是哪种数据库的分页,页数越深,效率就越低。尽可能在产品测就不让深分页出现。

3.3 批量操作业务进行约束

很多产品喜欢设计一些很牛逼的功能,比如全选下载不设置任何限制。这在技术上是很不合理的设计,这一点上最好和产品沟通,批量操作设置勾选上限。

(四)系统优化误区

4.1 使用多线程提高效率

在大部分人的认知里,把单线程改成多线程总能提高效率,但就是这个问题的讨论直接把公司CEO以及好几位P8、P9大佬都炸出来了。这几位在阿里干了超过十年的大佬给出的一致意见就是,在系统优化的时候,不要轻易用多线程,你以为你提高了效率,其实可能已经埋下了很多坑

他们的结论来源于这么多年的经验,无论是http调用,springboot内嵌的tomcat;还是rpc的dubbo调用,他们本身都维护了线程池。所以除非业务调用时的RT时间无法忍受,否则真的不建议在服务方法里起多线程。除了带来代码维护的不确定性外,从机器整体cpu能支撑的qps来看其实并没有多大提升

有位P8表示他以前在一个部门待过,那里尽喜欢在代码里加多线程,结果就是写完代码之后,先找了一波人专门监控代码运行情况,然后再找一波人来优化代码。费时费力不讨好。

(五)总结

系统的优化不是什么高大上的技术,其实就是很多基本的知识。但是他又很重要,保证了系统的稳定和资源的节省。另外系统优化的目的是为了让应用运行更加稳定,如果系统优化导致应用变得不确定了,那就得不偿失了。

最后祝所有同行1024程序员节快乐,我是鱼仔,我们下期再见。

相关文章:

  • phalapi-进阶篇6(解决大量数据存储数据库分表分库拓展)
  • 快速理解工厂方法模式,及其在源码中的应用
  • 线上报了内存溢出异常,又不完全是内存溢出
  • 用代码告诉你“问世间情为何物,直教人生死相许”
  • 互联网公司的完整开发流程是怎样的?
  • 如何在SpringBoot启动时执行初始化操作,两个简单接口就可以实现
  • BZOJ4584 : [Apio2016]赛艇
  • 查准考证网站卡了整整一个小时进不去,被抢票支配的恐惧又来了
  • 【C#公共帮助类】 ToolsHelper帮助类
  • 这次终于把Spring的监听器讲明白了
  • jquery ajax分页 js对象
  • 详解单例模式及其在Sping中的最优实践
  • Magento Shell
  • 深入了解ElasticSearch的Nested数据类型
  • Python3发送post请求,自动记住cookie
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • 11111111
  • CentOS 7 防火墙操作
  • Java知识点总结(JavaIO-打印流)
  • JS实现简单的MVC模式开发小游戏
  • MQ框架的比较
  • Python_OOP
  • python大佬养成计划----difflib模块
  • Spring Boot快速入门(一):Hello Spring Boot
  • TypeScript实现数据结构(一)栈,队列,链表
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 读懂package.json -- 依赖管理
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 为视图添加丝滑的水波纹
  • 一起参Ember.js讨论、问答社区。
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​Spring Boot 分片上传文件
  • (39)STM32——FLASH闪存
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (分布式缓存)Redis分片集群
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (接口封装)
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (转) Face-Resources
  • (转)项目管理杂谈-我所期望的新人
  • **PHP二维数组遍历时同时赋值
  • .aanva
  • .mysql secret在哪_MYSQL基本操作(上)
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET delegate 委托 、 Event 事件
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET简谈设计模式之(单件模式)
  • .NET实现之(自动更新)
  • .net网站发布-允许更新此预编译站点