The requirement of current limiting is to limit the number of simultaneous executions. After this number is exceeded, it must be cached in a queue. This article mainly introduces the practice of Koa service current limiting method. The editor thinks it is quite good. Now I will share it with you and give you a reference. Let’s follow the editor to take a look, I hope it can help everyone.
I recently received a request. It is very simple, just set up a server, call a provided interface when receiving the request, and then return the result. Because of the performance issues of this interface, the number of requests at the same time cannot exceed a certain number, and the current must be limited in the service.
koa middleware does not call next
The original idea is to count in koa middleware, and cache the next function when there are more than 6. When the ongoing task ends, call next to continue other requests.
Later I found that in koa middleware, if the next function request is not executed, it will not stop. Instead, the subsequent middleware will no longer be called and the content will be returned directly.
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);
The above code first prints ‘middleware 1’ on the console => The browser receives ‘hello’ => The console prints ‘middleware 2’.
Another thing to note here is that after a request has ended (finish), its next method can still be called, and the subsequent middleware will continue to run (but the modification to ctx will not take effect , because the request has been returned). Similarly, the close request (close) behaves in the same way.
Use await to make the request wait
Delaying the execution of the next function cannot achieve the purpose. The next natural thing to think of is to use await to wait for the current request. The await function returns a Promise. We store the resolve function in this Promise in the queue and delay the call.
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);
The above code returns a Promise in the delay function, and the resolve function of the Promise is stored in the queue. Set the timer to execute the resolve function in the queue after 3 seconds, so that the request can continue to be executed.
Is the current flow limited for routes or for requests?
After the basic principle of current limiting is implemented, the next question is where should the current limiting code be written? Basically, there are two locations:
Current limiting for interfaces
Due to our needs, current limiting is due to the limited performance of the requested interface. So we can limit the flow of this request separately:
async function requestSomeApi() { // 如果已经超过了最大并发 if (counter > maxAllowedRequest) { await delay(); } counter++; const result = await request('http://some.api'); counter--; queue.shift()(); return result; }
There is also a convenient reusable version below.
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; } }
Current limiting for routing
This method is to write a koa middleware and limit the current in the middleware:
async function limiter(ctx, next) => { // 如果超过了最大并发数目 if (counter >= maxAllowedRequest) { // 如果当前队列中已经过长 await new Promise((resolve, reject) => { queue.push(resolve); }); } store.counter++; await next(); store.counter--; queue.shift()(); };
After Just use this middleware in the router for different routes:
router.use('/api', rateLimiter);
Comparison
implemented current limiting for the interface. I felt that the logic was a bit confusing, so I used In order to limit the flow of routing, everything works perfectly.
Until I received another request, I had to request this interface three times to return the result array of the three requests. Now the problem comes, we can't call the interface directly because the current is limited. You cannot directly call the function of the request interface because our current limit is based on routing. then what should we do? We can only request this route and request it ourselves. . .
Things to note
Listen to the close event and remove the request from the queue
Requests that have been stored in the queue may be canceled by the user Condition. As mentioned before, even if the request is canceled in koa, subsequent middleware will still run, which means that interfaces that require current limiting will also be executed, causing waste.
You can listen to the close event to achieve this purpose. We need to mark each request with a hash value:
ctx.res.on('close', () => { const index = queue.findIndex(item => item.hash === hash); if (index > -1) { queue.splice(index, 1); } });
Set the timeout
In order to prevent the user from waiting too long For a long time, you need to set a timeout, which is easy to implement in koa:
const server = app.listen(config.port); server.timeout = DEFAULT_TIMEOUT;
The current queue is too long
If the current queue is too long, even if you join the queue will time out. Therefore, we also need to deal with the situation where the queue is too long:
if (queue.length > maxAllowedRequest) { ctx.body = 'error message'; return; }
Related recommendations:
The Road of Java Architect--Current Limiting Technology and Various Programming Languages
nginx current limiting algorithm
Use redis for current limiting
The above is the detailed content of Koa service current limiting method example. For more information, please follow other related articles on the PHP Chinese website!

Python中的支持向量机(SupportVectorMachine,SVM)是一个强大的有监督学习算法,可以用来解决分类和回归问题。SVM在处理高维度数据和非线性问题的时候表现出色,被广泛地应用于数据挖掘、图像分类、文本分类、生物信息学等领域。在本文中,我们将介绍在Python中使用SVM进行分类的实例。我们将使用scikit-learn库中的SVM模

Golang是一门功能强大且高效的编程语言,可以用于开发各种应用程序和服务。在Golang中,指针是一种非常重要的概念,它可以帮助我们更灵活和高效地操作数据。指针转换是指在不同类型之间进行指针操作的过程,本文将通过具体的实例来学习Golang中指针转换的最佳实践。1.基本概念在Golang中,每个变量都有一个地址,地址就是变量在内存中的位置。

随着新一代前端框架的不断涌现,VUE3作为一个快速、灵活、易上手的前端框架备受热爱。接下来,我们就来一起学习VUE3的基础知识,制作一个简单的视频播放器。一、安装VUE3首先,我们需要在本地安装VUE3。打开命令行工具,执行以下命令:npminstallvue@next接着,新建一个HTML文件,引入VUE3:<!doctypehtml>

随着互联网的普及,验证码已经成为了登录、注册、找回密码等操作的必要流程。在Gin框架中,实现验证码功能也变得异常简单。本文将介绍如何在Gin框架中使用第三方库实现验证码功能,并提供示例代码供读者参考。一、安装依赖库在使用验证码之前,我们需要安装一个第三方库goCaptcha。安装goCaptcha可以使用goget命令:$goget-ugithub

VAE是一种生成模型,全称是VariationalAutoencoder,中文译作变分自编码器。它是一种无监督的学习算法,可以用来生成新的数据,比如图像、音频、文本等。与普通的自编码器相比,VAE更加灵活和强大,能够生成更加复杂和真实的数据。Python是目前使用最广泛的编程语言之一,也是深度学习的主要工具之一。在Python中,有许多优秀的机器学习和深度

生成对抗网络(GAN,GenerativeAdversarialNetworks)是一种深度学习算法,它通过两个神经网络互相竞争的方式来生成新的数据。GAN被广泛用于图像、音频、文字等领域的生成任务。在本文中,我们将使用Python编写一个GAN算法实例,用于生成手写数字图像。数据集准备我们将使用MNIST数据集作为我们的训练数据集。MNIST数据集包含

随着互联网的迅速发展,数据已成为了当今信息时代最为重要的资源之一。而网络爬虫作为一种自动化获取和处理网络数据的技术,正越来越受到人们的关注和应用。本文将介绍如何使用PHP开发一个简单的网络爬虫,并实现自动化获取网络数据的功能。一、网络爬虫概述网络爬虫是一种自动化获取和处理网络资源的技术,其主要工作过程是模拟浏览器行为,自动访问指定的URL地址并提取所

快速上手Django框架:详细教程和实例引言:Django是一款高效灵活的PythonWeb开发框架,由MTV(Model-Template-View)架构驱动。它拥有简单明了的语法和强大的功能,能够帮助开发者快速构建可靠且易于维护的Web应用程序。本文将详细介绍Django的使用方法,并提供具体实例和代码示例,帮助读者快速上手Django框架。一、安装D


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SublimeText3 Linux new version
SublimeText3 Linux latest version

SublimeText3 Chinese version
Chinese version, very easy to use

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Mac version
God-level code editing software (SublimeText3)
