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!

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

The differences in performance and efficiency between Python and JavaScript are mainly reflected in: 1) As an interpreted language, Python runs slowly but has high development efficiency and is suitable for rapid prototype development; 2) JavaScript is limited to single thread in the browser, but multi-threading and asynchronous I/O can be used to improve performance in Node.js, and both have advantages in actual projects.

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.

JavaScript runs in browsers and Node.js environments and relies on the JavaScript engine to parse and execute code. 1) Generate abstract syntax tree (AST) in the parsing stage; 2) convert AST into bytecode or machine code in the compilation stage; 3) execute the compiled code in the execution stage.


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

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Linux new version
SublimeText3 Linux latest version

SublimeText3 Chinese version
Chinese version, very easy to use

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

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function
