问题描述
在实际使用中发现, 等待时间经常有超过10秒以上的情况,接口响应慢,取决于服务器的硬件和软件配置、网络带宽、缓存机制、请求处理逻辑等
- 缓存机制需要正确配置,不同版本内缓存nginx配置受影响
- 前端公共资源,特别是lib库,应该按需加载(目前每个页面都加载,登陆页/首页/ITSM各加载3次)属于bug
- 平台侧的加载速度需要提升,渲染子应用时间应该提升
- 部分无关接口需要延后触发时间或者合并 Portal通用资源收集
排查发现并不是只有4个接口慢,而是当有大量请求或者高并发的请求时,服务器所有请求响应都变慢了, 正常情况下,静态资源的响应时间很快,不会占用服务器的资源,当在服务器CPU 占用过高, 或者网络带宽不足的时候,就会造成接口的响应缓慢。
如果是 Node.js 单线程、单核运行的情况下,一旦阻塞,就会造成宕机。由于使用的是是HTTP1.1 ,在 chrome 下并发请求 6个。排查发现由于使用了 require JS, 使用后会进行自动拆包,会将 js 大于1M 都会拆包
如何解决这种现象?
- 增加服务器成本,采用负载均衡等技术
- 使用 CDN 技术:将静态资源文件缓存在全球各地的 CDN 服务器上,可以提高访问速度,降低服务器负载。(由于内部系统,往往是单机部署,未实现)
- 压缩静态资源文件:对于 JavaScript、CSS 等文件,可以使用压缩工具进行压缩,减小文件体积,提高下载速度。(已经使用 webpack 最小压缩)
- 使用缓存:可以在服务器端或浏览器端设置缓存策略,让客户端在一定时间内缓存静态资源文件,减少对服务器的请求次数。(已经对于静态资源进行缓存,还有优化空间)可以在 NGINX 中加入下面配置,静态资源强缓存 7 天
location /itsm/static { add_header Cache-Control "max-age=2592000, s-maxage=3600"; }
- 并发请求限制:可以通过限制并发请求的数量,避免服务器负载过高,导致响应时间变慢。
(大部分接口没限制,若有人对接口进行压力测试,就会造成响应缓慢) - 升级 HTTP2(这一点不太容易,HTTP2 IE 不支持,必须要 HTTPs)
- 减少HTTP请求,合并重复请求
- 减少资源大小
具体方案
优化requirejs和splitChunks
因为requirejs和splitChunks会造成很多的js请求,而chrome在http1.1只能并发6个请求,因此对于产品,我们可以不用 requirejs 和 splitChunks。去除 requirejs 插件, 因此在打包产品包的时候可以不使用插件。
如果没有办法移除, 我们可以使用 system js 来代替 requirejs 来加载。SystemJS 诞生于 2015 年,那个时候 ES Module 还未成为标准,在浏览器端只能通过 requirejs、seajs 等方案实现模块加载,随着 npm 在前端界的流行,一个项目中可能存在多种模块规范。SystemJS 是现阶段下(浏览器尚未完全正式支持importMap)原生 ES Module 的替代品,ES Module 被编译成 System.register 格式之后能够跑在旧版本的浏览器当中。
使用https和cdn加速
- 首先你需要获取一个SSL证书, 然后安装证书, 在Nginx的安装目录下创建cert目录,将下载的.crt和.key文件拷贝到cert目录中。打开 Nginx 安装目录下 conf 目录中的 nginx.conf 文件,找到“HTTPS server”部分。重启Nginx
server { listen 443; server_name 你网站的域名; ssl on; root html; index index.html index.htm; ssl_certificate cert/你的证书文件名.pem; ssl_certificate_key cert/你的证书文件名.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { root html; index index.html index.htm; } }
- 然后在原来的http配置那里做个301到https。
# 建议复制多一份原配置,出错可以恢复
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
# 监听80端口,http重定向
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
# 监听443端口,https重定向
listen 443 ssl;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 default_server ssl;
server_name www.example.com;
# 下面代码省略...
}
使用CDN缓存加速
- 把一些较大的包和一些公司通用的包,静态资源放在nginx服务器上, 通过公共网络资源方式引入(jQuery等)
- 同时可以使用CDN和模块联邦热更新, 实现实时动态更新而无需打包业务线项目