- 本文章主要未探索koa与nextjs的性能情况以及解决方案,想直接了解决方案的同学,可以直接翻到最底部。
- 文章有很多是跑的性能指标图片,如有不合理之处,欢迎留言交流😊;
环境准备
- 机器配置
MacBook Pro (16-inch, 2019)
2.6 GHz 六核Intel Core i7
32G内存
- 系统环境配置
node v14.17.2
npm v6.14.13
pm2 v5.2.0
// 性能测试工具版本
autocannon v7.9.0
clinic v12.0.0
- 代码项目包版本
"koa": "^2.13.4",
"koa-router": "^12.0.0",
"nodemon": "^2.0.19",
"next": "12.3.0",
创建一个简单的koa进程
创建一个简单的koa进程,访问http://localhost:52013/test时,返回一个hello world的字符串;
const Koa = require('koa');
const router = require('koa-router')();
const app = new Koa();
const post = 52013;
router.get('/test', async (ctx, next) => {
ctx.body = "hello world";
})
app.on('error', err => {
console.error('catch server error', err)
});
app.use(router.routes()); //作用:启动路由
app.use(router.allowedMethods());
app.listen(post, () => {
console.log(`启动${post}端口`);
});
使用autocannon进行性能测试
用koa返回hello world字符串,单核性能测试
10秒100个连接数autocannon -c100 -d10 localhost:52013/test
10秒100个连接数
10秒1000个连接数autocannon -c1000 -d10 localhost:52013/test
10秒1000个连接数
10秒10000个连接数autocannon -c10000 -d10 localhost:52013/test
10秒10000个连接数
koa用pm2启用集群模式(2个)
image.pngautocannon -c100 -d10 localhost:52013/test
10秒100个连接数
image.pngautocannon -c1000 -d10 localhost:52013/test
10秒1000个连接数
image.pngautocannon -c10000 -d10 localhost:52013/test
10秒10000个连接数
从结果来看,使用pm2集群部署能承受更高的并发请求
koa返回与nextjs请求两个接口时,相同的html字符串数据
image.pngautocannon -c1000 -d10 localhost:52013/test
10秒1000个连接数
nextjs返回Hello world
image.pngautocannon -c1000 -d10 localhost:3000
10秒1000个连接数
nextjs使用getStaticProps与getStaticPaths,不请求接口
image.pngautocannon -c1000 -d10 localhost:3000/channel/25950
10秒1000个连接数
从结果来看
,损失损失27%
nextjs使用getStaticProps与getStaticPaths,请求两个接口
image.pngautocannon -c1000 -d10 localhost:3000/channel/25950
10秒1000个连接数
从结果来看
,两个接口大约会损失60%
多的并发数,并且接口超时,会导致返回error数据
nextjs使用getServerSideProps,不请求接口
image.pngautocannon -c1000 -d10 localhost:3000/channel/25950
10秒1000个连接数
从结果来看
,getServerSideProps大约会损失82%
多的并发数,并且超时请求,非常多
nextjs使用getServerSideProps,请求两个接口
image.pngautocannon -c1000 -d10 localhost:3000/channel/25950
10秒1000个连接数
从结果来看
,在getServerSideProps中请求两个接口大约会损失96%
多的并发数,并且存在超时请求
nextjs使用getServerSideProps,请求两个接口,增加最新middleware.js
image.pngautocannon -c1000 -d10 localhost:3000/channel/25950
10秒1000个连接数
从结果来看
,损失率没增加middleware大致相同,但是超时链接明显增加了
nextjs静态页面,增加最新middleware.js
image.pngautocannon -c1000 -d10 localhost:3000
10秒1000个连接数
从结果来看
,会损失80%
多的并发数,并且超时请求也非常多
在nextjs中使用getStaticProps、getStaticPaths、getServerSideProps、middleware方法后的性能损耗
在nextjs中使用getStaticProps、getStaticPaths、getServerSideProps、middleware方法后的性能损耗.png各方法在请求接口后的性能损耗后
各方法在请求接口后的性能损耗后.png基于上面测试数据,我们可以得出以下几点:
- 请求数据越多,并发数越低,所以需要尽量缩减生成的html数据大小;
- 使用middleware对整个nextjs影响较大,不管是静态页面还是SSG、ISR、SSR,如能不使用,最好不要用(影响范围:
全局
); - getServerSideProps对性能同样影响很大,不过渲染的数据能实时传输;
- getStaticProps与getStaticPaths对性能影响较小,不过数据实时性很差,使用pm2多集群部署时,会产生严重的数据延迟,因为服务端的生成的ISR页面,只有在下一次请求成功时,才会更新,但是下一次请求获取到的数据却依然是老的数据,再次请求,才是上一次的数据(
导致部署pm2多集群时,可能会出现严重的数据延迟
);
针对以上几点,可以尝试以下几个优化方向:
1.对传输数据进行压缩;
2.自定义服务端,搭建一个node服务端:
- 将node与nextjs集成,node层将nextjs使用getServerSideProps函数返回的html进行缓存处理;
- 将node与nextjs集成,node层对nextjs使用getStaticProps与getStaticPaths的数据进行更新,并进行获取;
3.部署docker集群;
主要针对第二点的第一个方案;
需要考虑的点:
保证部署多集群时,缓存数据是对集群服务器是同步的
如果不是同步的,将数据存储在单个进程的内存中,那么可能造成缓存一份数据,每台机器都需要缓存一下,并且返回数据时,(对于实时性高的应用)返回的数据可能都不同,生成html和缓存html都需要花费时间
如何保证nextjs返回的数据是正常准确的
网友评论