问题回顾

今天,同事小赵接到客户导入新闻数据要求,由客户提供新闻数据。于是小赵通过 SQL 脚本把新闻数据入库后,发现前台展示新闻特别慢。幸好当时是晚上凌晨1点,用户比较少,处理问题来得及,最终经过近半小时的排查问题,原来问题出在这里。

问题定位

在小赵导完数据后,测试小赵发现内容管理列表页访问特别慢,加载完数据需要 16 秒左右。

于是我用 F12 打开 chrome 调试工具,发现获取新闻内容列表数据的 API 接口:“getManageArticleList" 接收的数据有 7.1 M,接口响应时间长达 16 秒多,太不正常了。

但是同一个接口换一个查询条件,接收的数据只有 367 KB,响应时间 4.5 秒。

由此,这说明两个问题:

第一、API 接口的请求与响应是没问题的

第二、换查询条件后,接口响应时间差距近 12 秒之多,说明接收数据有问题

既然是数据问题,于是在和小赵对比入库前和入库后的新闻数据后,发现问题出在图片 base64 加密存储。

原来,客户提供的文章数据中包含图片,但由于客户原图不在了,只能从别的地方收集新闻时,把包含图片的新闻采用了 base64 加密串给了小赵。而这些 base64 加密的图片每张基本上在 1 M 左右,前端一次性分页加载 10 条共 7M 的数据,变慢就不足为怪了。

另外,为什么新闻列表页需要加载图片呢?

通过代码走查,发现图片是放在 contentText 字段里面,但是 新闻内容列表 select 分页语句却包含了 contentText 字段,明显 select 语句不合理。

select ..., contenText from article 

解决方案

由于时间比较紧迫,本次发版又不涉及服务升级,只能从修改数据入手了。

第一步,用 like 模糊查询存在包含 base64 串的文章,共 34 条记录,数据比较少

select id,title,contenText from article where contenText like '%data:image%'

第二步, 从新闻详情页下载图片,用 fastdfs 分布式文件服务器上传图片后,得到图片的下载地址,替换 img 标签的 src 属性值。

图片地址格式如下:

group1/M00/00/00/rBIK6VcaP0aARXDSNFHrUgHEviQ663.jpg

10 个人 34 条新闻,花了近 20 分钟,完成 base64 图片地址替换后,问题解决。

问题总结

什么是 base64 编码?

base64 编码简单来说就是把一张图片数据加密成一串字符,使用该字符串代替图像地址。

用 base64 把图片加密成一串字符的好处是:“可以不需要单独用文件服务器存储文件,节省一个 http 图片请求。”

但是,如果不合理利用 base64 带来的问题是:“CSS 文件的体积变大,CSS 文件的体积直接影响渲染,导致用户会长时间注视空白屏幕。”

#index {  background: url(data:image/png;base64,xxxxx) no-repeat center;}

所以,使用 base64 编码的前提是图片足够小,以一个 3kb 的 logo 图片为例:

一张 3.27 KB logo 图片,已经很小了,但是如果将其制作转化成 base64 编码,生成的 base64 字符串编码足足有 4406 个,也就是说,图片被编码之后,生成的字符串编码大小一般而言都会比原文件稍大一些。即便 base64 编码能够被 gzip 压缩,压缩率能达到 50% 以上,想象一下,一个元素的 css 样式编写居然超过了 2000个 字符,那对 css 整体的可读性将会造成十分大的影响,代码的冗余使得在此使用 base64 编码将得不偿失。

看似微不足道的问题,如果追踪溯源,还是能学习到一些技术有趣的一面,只是看你有心了。

延伸

CssSprites 与 base64 比较?

小心 base64 编码数据拖慢你的后台服务相关推荐

  1. 大恶人吉日嘎拉之走火入魔闭门造车之.NET疯狂架构经验分享系列之(二)后台服务代码部分

    程序写太长了,大家看着也累,我也写着也很辛苦,接下来,还是写得简短一些,尽量多一些截图,少一些文字吧. 同样是,欢迎指点批评的同学,我虚心学习提高,改改以往的高姿态. 架设软件系统就像大家看饭店厨师炒 ...

  2. 大恶人吉日嘎拉之走火入魔闭门造车之.NET疯狂架构经验分享系列之(二)后台服务代码部分...

    程序写太长了,大家看着也累,我也写着也很辛苦,接下来,还是写得简短一些,尽量多一些截图,少一些文字吧. 同样是,欢迎指点批评的同学,我虚心学习提高,改改以往的高姿态. 架设软件系统就像大家看饭店厨师炒 ...

  3. 【Android】Android中判断后台服务是否正在运行

    判断服务是否在运行 在应用中涉及到后台运行服务,而使用解锁事件来重启服务保证服务是一直运行的.但是这种不加判断直接开启服务的方式优点在于快速(不必花费时间判断服务是否运行),缺点是控制的太粗糙:比较合 ...

  4. Web后台服务开发——数据库查询之引入TypeORM

    文章转自 极客论坛 前置条件 首先按照  Web后台服务开发--安装MySQL 和 Web后台服务开发--安装HeidiSQL 安装MySQL: 然后创建一个数据库,假定名称为test,你也可以选择其 ...

  5. 在CentOS7上部署.net core 控制台应用程序部署为后台服务

    在CentOS7上部署.net core 控制台app为后台服务 转载于:https://www.cnblogs.com/wangwust/p/9821547.html

  6. android 发送前台广播,使用IntentService与BroadcastReceiver实现后台服务(Android7.0可用)...

    IntentService的优点 IntentService会创建单独的线程处理所有的Intent请求, 会处理onHandleIntent方法实现的代码, 隐藏开发者无须处理多线程问题, 当所有请求 ...

  7. xunsearch: 开启后台服务,索引……随笔记录

    重启后台服务: cd $prefix ; bin/xs-ctl.sh restart 索引: # 导入 MySQL 数据库的 dbname.tbl_post 表到 demo 项目中,并且平滑重建 ut ...

  8. 若依微服务版后台服务通过jar包部署到Windows服务器

    场景 若依微服务版手把手教你本地搭建环境并运行前后端项目: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/109363303 在前 ...

  9. 【JavaService】部署Java jar为Windows后台服务

    将Java jar文件部署为Windows后台服务有多种方法:Service Installer.Java service Wrapper.JavaService.exe等等.这里介绍下使用JavaS ...

最新文章

  1. python编程爱心-使用Python画出小人发射爱心的代码
  2. Linux is执行程序命令,linux命令执行过程详解
  3. ThreadLocal源码剖析
  4. 众唱点歌机会显示无法连接服务器,目前众多厂商唱多的服务器附加存储缺点分析...
  5. springboot mysql时区设置_java/springboot/mysql时区问题解决方案
  6. leetcode50:Pow(x, n)详解——pygo
  7. 《C++之那些年踩过的坑(附录一)》
  8. 力扣171.Excel表列序号
  9. SNMP原理及常用配置命令
  10. 恶魔的指纹---49幅由算法生成的七芒星图像
  11. FlasCC例子研究之bitmapdata
  12. html小游戏社区,h5小游戏源码(h5养成社区源码)
  13. Linux入门的基础知识点
  14. 开发请打开Debug模式--Dcat-Admin框架实战(三)
  15. 张家港、张家口、张家界、张家川
  16. 【Python实例学习】用Python的xlsxwriter模块操作Excel表格,包括写入数据、样式设置、插入图片等
  17. 生物统计学教材中的统计推断方法
  18. 小数化分数c++(附做法数学证明)
  19. 领导驾驶舱在企业中逐渐占领地位
  20. 【BZOJ】1455 罗马游戏 左偏树

热门文章

  1. latex 根据 excel, csv 的数据生成表格
  2. tkinter动态表格 - 实时更新数据(TkinterTable)
  3. 学校作业《C语言课程设计》
  4. Linux文件系统功能和作用详解
  5. 如何在Windows中调整ClearType以提高屏幕可读性
  6. MobaXterm官网下载地址
  7. WinMount开发者刘涛涛
  8. 【解决方案】如何搭建一套完整的工厂安防智能监控系统——EasyCVR实现设备接入与维护
  9. 集成学习(Ensemble Learning),Bagging、Boosting、Stacking
  10. 2020 年天津理工大学研究生招生考试 数据结构部分