返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Koa服务限流的示例分析
  • 621
分享到

Koa服务限流的示例分析

2024-04-02 19:04:59 621人浏览 泡泡鱼
摘要

小编给大家分享一下Koa服务限流的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!koa 中间件不调用 next最初的想法

小编给大家分享一下Koa服务限流的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

koa 中间件不调用 next

最初的想法是在 koa 中间件中进行计数,超过6个时将next函数缓存下来。等正在进行中的任务结束时,调用next继续其他请求。

之后发现 koa 中间件中,不执行next函数请求并不会停下,而是不再调用之后的中间件,直接返回内容。

const Koa = require('koa');
const app = new Koa();
app.use((ctx, next) => {
 console.log('middleware 1');
 setTimeout(() => {
  next();
 }, 3000);
 ctx.body = 'hello';
});
app.use((ctx, next) => {
 console.log('middleware 2');
});
app.listen(8989);

以上代码首先在控制台打出 ‘middleware 1' => 浏览器收到 ‘hello' => 控制台打出 ‘middleware 2'。

这里还有一个要注意的地方,就是一个请求已经结束(finish)后,他的next方法还是可以继续调用,之后的middleware还是继续运行的(但是对ctx的修改不会生效,因为请求已经返回了)。同样,关闭的请求(close)也是同样的表现。

使用 await 让请求进行等待

延迟next函数执行不能达到目的。接下来自然想到的就是使用await让当前请求等待。await的函数返回一个Promise,我们将这个Promise中的resolve函数存储到队列中,延迟调用。

const Koa = require('koa');
const app = new Koa();
const queue = [];
app.use(async (ctx, next) => {
 setTimeout(() => {
  queue.shift()();
 }, 3000);
 await delay();
 ctx.body = 'hello';
});
function delay() {
 return new Promise((resolve, reject) => {
  queue.push(resolve);
 });
}
app.listen(8989);

上面这段代码,在delay函数中返回一个Promise,Promise的resolve函数存入队列中。设置定时3s后执行队列中的resolve函数,使请求继续执行。

针对路由进行限流,还是针对请求进行限流?

限流的基本原理实现后,下面一个问题就是限流代码该写在哪里?基本上,有两个位置:

针对接口进行限流

由于我们的需求中,限流是因为要请求接口的性能有限。所以我们可以单独针对这个请求进行限流:

async function requestSomeapi() {
 // 如果已经超过了最大并发
 if (counter > maxAllowedRequest) {
  await delay();
 }
 counter++;
 const result = await request('Http://some.api');
 counter--;
 queue.shift()();
 return result;
}

下面还有一个方便复用的版本。

async function limitWrapper(func, maxAllowedRequest) {
 const queue = [];
 const counter = 0;
 return async function () {
  if (counter > maxAllowedRequest) {
   await new Promise((resolve, reject) => {
    queue.push(resolve);
   });
  }
  counter++;
  const result = await func();
  counter--;
  queue.shift()();
  return result;
 }
}

针对路由进行限流

这种方式是写一个koa中间件,在中间件中进行限流:

async function limiter(ctx, next) => {
 // 如果超过了最大并发数目
 if (counter >= maxAllowedRequest) {
  // 如果当前队列中已经过长
  await new Promise((resolve, reject) => {
   queue.push(resolve);
  });
 }
 store.counter++;
 await next();
 store.counter--;
 queue.shift()();
};

之后针对不同路由在router中使用这个中间件就好了:

router.use('/api', rateLimiter);

比较

实现了针对接口进行限流,觉得逻辑有些乱,于是改用了针对路由进行限流,一切运行的很完美。

直到我又接了个需求,是要请求三次这个接口返回三次请求的结果数组。现在问题来了,我们不能直接调用接口,因为要限流。也不能直接调用请求接口的函数因为我们的限流是以路由为单位的。那怎么办呢?我们只有请求这个路由了,自己请求自己。。。

需要注意的地方

监听close事件,将请求从队列中移出
已经存储在队列中的请求,有可能遇到用户取消的情况。前面说过koa中即使请求取消,之后的中间件还是会运行,也就是还会执行需要限流的接口,造成浪费。

可以监听close事件来达到这个目的,每个请求我们需要用hash值来标记:

ctx.res.on('close', () => {
 const index = queue.findIndex(item => item.hash === hash);
 if (index > -1) {
  queue.splice(index, 1);
 }
});

设置超时时间

为了防止用户等待过长时间,需要设置超时时间,这在koa中很容易实现:

const server = app.listen(config.port);
server.timeout = DEFAULT_TIMEOUT;

当前队列已经过长

如果当前队列已经过长了,即使加入队列中也会超时。因此我们还需要处理队列过长的情况:

if (queue.length > maxAllowedRequest) {
 ctx.body = 'error message';
 return;
}

以上是“Koa服务限流的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网JavaScript频道!

--结束END--

本文标题: Koa服务限流的示例分析

本文链接: https://lsjlt.com/news/78865.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Koa服务限流的示例分析
    小编给大家分享一下Koa服务限流的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!koa 中间件不调用 next最初的想法...
    99+
    2024-04-02
  • koa之中间件流程控制的示例分析
    这篇文章主要为大家展示了“koa之中间件流程控制的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“koa之中间件流程控制的示例分析”这篇文章吧。1. ko...
    99+
    2024-04-02
  • redis中redisson限流器的示例分析
    这篇文章主要介绍了redis中redisson限流器的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。redis redisson 限流器实例作用:限制一段时间内对数据...
    99+
    2023-06-20
  • 实用Nodejs npm包:koa-csrf的示例分析
    这篇文章将为大家详细讲解有关实用Nodejs npm包:koa-csrf的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。JS是什么JS是JavaScript的简称,它是一种直译式的脚本语言,其解释...
    99+
    2023-06-14
  • 浅谈Koa服务限流方法实践
    最近接了一个需求,很简单,就是起一个server,收到请求时调用某个提供好的接口,然后把结果返回。因为这个接口的性能问题,同时在请求的不能超过特定数目,要在服务中进行限流。 限流的要求是,限制同时执行的数目...
    99+
    2022-06-04
    浅谈 方法 Koa
  • 实现redux, koa, express中间件的示例分析
    小编给大家分享一下实现redux, koa, express中间件的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!如果你...
    99+
    2024-04-02
  • koa router中多文件引入的示例分析
    小编给大家分享一下koa router中多文件引入的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!背景koa-route...
    99+
    2024-04-02
  • koa之异步回调处理的示例分析
    这篇文章主要介绍koa之异步回调处理的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 回调金字塔及理想中的解决方案我们都知道javascript是一门单线程异步非阻塞语言...
    99+
    2024-04-02
  • laravel5权限的示例分析
    这篇文章主要介绍laravel5权限的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!角色权限管理是我们在laravel开发过程中必然会遇到的,问题是laravel自带的权限逻...
    99+
    2024-04-02
  • Java-IO流的示例分析
    小编给大家分享一下Java-IO流的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言项目结构如下,在使用代码的时候注意修改成你自己的包名和类名一、资源管...
    99+
    2023-06-20
  • Koa日志中间件封装开发的示例分析
    小编给大家分享一下Koa日志中间件封装开发的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!对于一个服务器应用来说,日志的记录是必不可少的,我们需要使用其记录项目程序每天都做了什么,...
    99+
    2024-04-02
  • MySQL中权限的示例分析
    小编给大家分享一下MySQL中权限的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、前言很多文章中会说,数据库的权限按...
    99+
    2024-04-02
  • JavaScript中节流的示例分析
    小编给大家分享一下JavaScript中节流的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言我们来聊一聊节流——另一个优化函数的思想。我们还是以移动事...
    99+
    2023-06-06
  • Java中IO流的示例分析
    这篇文章主要为大家展示了“Java中IO流的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java中IO流的示例分析”这篇文章吧。I/O简介I/O是Input/output的缩写,在ja...
    99+
    2023-06-20
  • JavaScript事件流的示例分析
    这篇文章主要介绍JavaScript事件流的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.什么是事件流 ?在学习事件流之前我们先看看什么是事件 ?事件代表文档或浏览器窗口中某个有意义的时刻即用户与页面的交...
    99+
    2023-06-29
  • HDFS读流程的示例分析
    这篇文章给大家分享的是有关HDFS读流程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。客户端或者用户通过调用FileSystem对象的Open()方法打开需要读取的文件,这时就是HDSF分布式系统所获取...
    99+
    2023-06-02
  • vue框架与koa框架通信及服务器跨域配置的示例分析
    这篇文章将为大家详细讲解有关vue框架与koa框架通信及服务器跨域配置的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前后端框架(本例中是vue和koa)如何发送...
    99+
    2024-04-02
  • angular服务的示例分析
    小编给大家分享一下angular服务的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!依赖注入创建服务需要用到Inject...
    99+
    2024-04-02
  • RBAC权限模型的示例分析
    小编给大家分享一下RBAC权限模型的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!权限系统与RBAC模型概述RBAC(R...
    99+
    2024-04-02
  • mysql权限操作的示例分析
    这篇文章给大家分享的是有关mysql权限操作的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 1、创建新用户: create user mark@localhost ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作