自从 Vue2 出正式版后, 就开始了 SSR 之旅, 不过之前用的都是虚拟主机, 部署不了 SSR, 所以也只是在本地写着玩, 双 11 的时候, 买了个某云主机, 正式开始了 SSR 之旅, 然后过程并不顺利, 部署, 运行都没问题, 但是发现内存泄漏严重, 1核1G内存的主机根本负担不了, 没什么访问量的情况下, 几个小时的时间, 1G 内存就用光, 明显有很严重的内存泄漏, 在本地环境压测, rps(每秒请求数) 无限接近于 1, 在云服务器更是压测都完成不了, 于是开始了优化之旅
1. 内存泄漏
经过查资料和测试, 发现 axios 和 vue-meta 都有内存泄漏之嫌
vue-meta
之前有写过一篇 Vue2 SSR渲染, 如何根据不同页面修改 meta?, 既然这个有内存泄漏的嫌疑, 只好先把代码恢复回去
axios
axios 的拦截器在 node 端也会导致内存泄漏, 因为之前版本是 SPA 版的, axios 配置也是针对 SPA 的配置, 里面有用到拦截器, 并且有大量的逻辑处理在里面, 包括加载进度, 错误处理等等, 这些逻辑在 node 端是没有任何意义的, 那么我们就需要对 node 端写个专门的 axios 配置文件
api/index-server.js (server端)
https://github.com/lincenying...api/index-client.js (client端)
https://github.com/lincenying...
2. 缓存
缓存主要包括两个部分:
服务端的 api 数据缓存
组件的缓存
服务端的 api 数据缓存
昨天已经写了一篇文章: Vue2 SSR 缓存 Api 数据, 这里不再多说, 上面 axios 服务端配置文件中, 也有相关代码
组件的缓存
首先先安装lru-cache
然后在server.js
里createBundleRenderer
的时候带上缓存的配置
require('vue-server-renderer').createBundleRenderer(bundle, {
cache: require('lru-cache')({
max: 1000, // 缓存最大数量
maxAge: 1000 * 60 * 15, // 缓存时间 15分钟
})
})
在组件里申明 key
serverCacheKey: () => {
return `aside::account`
}
组件缓存的相关用法, 请参考官方文档:
https://github.com/vuejs/vue/...
注意: 一般情况下, 我们不要给容器型组件, 只给展示型组件加缓存, 如一个组件是静态组件, 如组件的数据是通过 props 传进去的
3. 配置 nginx
一般情况我们都需要用 nginx 或者 apache 做端口转发,
server {
listen 80;
server_name mmxiaowu.com www.mmxiaowu.com ssr.mmxiaowu.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Connection "";
proxy_pass http://127.0.0.1:8080;
}
}
我们可以修改下配置文件, 让静态文件直接走 nginx, 不再经过 nodejs
server {
listen 80;
server_name mmxiaowu.com www.mmxiaowu.com ssr.mmxiaowu.com;
location ~ ^/(static|upload)/ {
root /your/webroot/mmf-blog-vue2-ssr/dist;
expires 30d;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Connection "";
proxy_pass http://127.0.0.1:8080;
}
}
经过以上一些优化后, 再进行一次压测:
E:\web\webpack\mmf-blog-vue2-ssr>loadtest -n 2000 http://localhost:8080/
[Sat Dec 31 2016 14:12:17] INFO Requests: 0 (0%), requests per second: 0, mean latency: 0 ms
[Sat Dec 31 2016 14:12:22] INFO Requests: 246 (12%), requests per second: 49, mean latency: 20.3 ms
[Sat Dec 31 2016 14:12:27] INFO Requests: 508 (25%), requests per second: 52, mean latency: 19 ms
[Sat Dec 31 2016 14:12:32] INFO Requests: 773 (39%), requests per second: 53, mean latency: 18.8 ms
[Sat Dec 31 2016 14:12:37] INFO Requests: 1036 (52%), requests per second: 53, mean latency: 19 ms
[Sat Dec 31 2016 14:12:42] INFO Requests: 1296 (65%), requests per second: 52, mean latency: 19.2 ms
[Sat Dec 31 2016 14:12:47] INFO Requests: 1548 (77%), requests per second: 50, mean latency: 19.9 ms
[Sat Dec 31 2016 14:12:52] INFO Requests: 1776 (89%), requests per second: 46, mean latency: 21.8 ms
[Sat Dec 31 2016 14:12:57] INFO
[Sat Dec 31 2016 14:12:57] INFO Target URL: http://localhost:8080/
[Sat Dec 31 2016 14:12:57] INFO Max requests: 2000
[Sat Dec 31 2016 14:12:57] INFO Concurrency level: 1
[Sat Dec 31 2016 14:12:57] INFO Agent: none
[Sat Dec 31 2016 14:12:57] INFO
[Sat Dec 31 2016 14:12:57] INFO Completed requests: 2000
[Sat Dec 31 2016 14:12:57] INFO Total errors: 0
[Sat Dec 31 2016 14:12:57] INFO Total time: 39.933183222 s
[Sat Dec 31 2016 14:12:57] INFO Requests per second: 50
[Sat Dec 31 2016 14:12:57] INFO Mean latency: 19.9 ms
[Sat Dec 31 2016 14:12:57] INFO
[Sat Dec 31 2016 14:12:57] INFO Percentage of the requests served within a certain time
[Sat Dec 31 2016 14:12:57] INFO 50% 16 ms
[Sat Dec 31 2016 14:12:57] INFO 90% 27 ms
[Sat Dec 31 2016 14:12:57] INFO 95% 43 ms
[Sat Dec 31 2016 14:12:57] INFO 99% 57 ms
[Sat Dec 31 2016 14:12:57] INFO 100% 133 ms (longest request)
效果非常不错, rps 已经能达到 50 了, 内存使用也大弧度下降了, 不过在云服务器上依然不够理想, 因为可能是云服务器上数据比本地的多, 另外云服务器的配置太烂...但是随着运行时间的增加, 内存肯定也会上升, 毕竟缓存也是需要占用内存的, 不过这个是属于合理开支...
过了差不多一天的时间, 内存只涨了 7M 左右...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。