性能优化作为一个老生常谈的话题,基本上每一个研发都或多或少的参与过相关的工作;网上相关的资源也非常多,正好技术派因为某些原因,做了几次的服务迁移,从之前杭州到现在的香港,整体服务的性能表现也出现了很大的波动,经过一系列的优化努力,最终的效果勉强符合预期
接下来我们给各位小伙伴分享一下,技术派整个项目中,借助的优化思想以及对应的实现手段
1. 优化方法论
一般来说,有计划有准备的动作,行动之前的都会有相应的指导手册;那么作为一个性能优化的主题,我们可以从哪些方面去努力呢?
1.1 如何做性能调优
性能调优是一个系统性的过程,需要根据具体的业务需求和系统环境来制定。以下是一些基本步骤:
-
确定目标:首先,你需要明确你希望通过性能调优达到什么样的目标。这可能包括提高系统的响应时间、处理能力或资源利用率等。
-
收集数据:在开始优化之前,你需要收集关于系统性能的数据。这可能包括CPU使用率、内存使用情况、磁盘I/O、网络I/O等。
-
分析数据:通过分析收集到的数据,你可以找出系统的性能瓶颈。这可能是硬件问题,也可能是软件问题。
-
制定优化策略:根据分析结果,你可以制定出针对性的优化策略。这可能包括升级硬件、优化代码、调整系统参数等。
-
实施优化:按照你的优化策略,开始进行优化操作。在优化过程中,你需要持续监控系统性能,以确保优化效果。
-
评估优化效果:优化完成后,你需要评估优化的效果。如果达到了预期的目标,那么优化就成功了。如果没有,那么你可能需要重新分析数据,找出新的性能瓶颈,然后再次进行优化。
-
持续改进:性能调优是一个持续的过程,你需要定期对系统进行性能测试和优化,以确保系统始终保持最佳状态。
1.2 性能优化指导方案
基于前后端的特点,对各自的性能优化方案做了一个简单的归纳提炼
对应的文字版本
前端优化
-
资源侧:
- 删除冗余的静态资源依赖
- 多个小图标合成一张图,减少网络开销
- 字体文件过大,按需进行拆分
-
网络传输
- 代码压缩
- 浏览器做缓存
- 使用CDN加速
- 建立长连接,复用请求,减少dns解析、握手开销
-
编码
- 防止重复提交
- 异步响应
- 减少无用请求
- 瀑布流式渲染,不需要等待全部返回再加载
- 接口拆分
后端优化
-
系统架构优化
- 选择合适的硬件设备,如CPU、内存、硬盘等
- 选择合适的操作系统和中间件,如Linux、Apache、Nginx等
- 采用分布式架构,实现负载均衡和高可用性
-
数据库优化
- 选择合适的数据库类型,如关系型数据库(MySQL、PostgreSQL等)和非关系型数据库(MongoDB、Redis等)
- 设计合理的表结构,避免冗余字段和大表
- 使用索引优化查询性能
- 定期进行数据库维护,如数据清理、碎片整理等
-
代码优化
- 优化算法和数据结构,提高程序运行效率
- 减少不必要的计算和IO操作
- 使用缓存技术,如Memcached、Redis等,减轻数据库压力
- 缓存预热
- 使用多线程或异步处理,提高并发能力
- 减少资源竞争,缩小锁粒度
- 池化技术,增加复用
- 数据异构,冗余需要的信息,减少额外交互
- 批处理
-
网络优化
- 选择合适的网络协议,如HTTP/1.1、HTTP/2等
- 使用CDN加速静态资源访问
- 优化网络传输数据大小,减少传输时间
- 使用HTTPS保证数据传输安全
-
监控与调优(注意这一块没有体现再上面的图中)
- 监控系统性能指标,如CPU、内存、磁盘IO、网络IO等
- 分析系统日志,发现潜在问题
- 根据监控数据进行性能调优,如调整系统参数、优化数据库查询等
- 定期进行系统巡检,确保系统稳定运行
2. 优化方案实操
接下来,我们真实的体验以下,技术派项目中用到的哪些优化手段
2.1 静态资源缓存
由于技术派的前台项目并没有做前后端分离,前端的相关资源信息也是由后台服务器返回,因此我们可以给静态资源设置缓存策略,借助浏览器缓存来减少资源重复加载的时间
对于静态化资源配置的方案,可以在SpringBoot项目中进行配置,如
@SpringBootApplication
public class Application implements WebMvcConfigurer {
/**
* 配置返回的静态资源的压缩与缓存方式
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS).cachePrivate())
.resourceChain(true)
.addResolver(new EncodedResourceResolver())
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}
也可以直接在nginx这里进行配置,如技术派之前选择的方案
location ~* ^.+\.(css|js|txt|xml|swf|wav|pptx)$ {
access_log off;
expires 10m; # 缓存有效期 10分钟
proxy_pass http://paicoding_host;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
access_log off;
expires 1d; # 缓存失效时间 1天
proxy_pass http://paicoding_host;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
2.2 静态资源压缩返回
将返回结果进行压缩,从而实现减少网络传输的开销,同样是一个常见的优化思路,同样的我们这里基于nginx的配置来实现压缩返回
gzip on
回复