设计一个具有等待队列的连接池

        说到连接池相关很多人都使用过,常见的有数据连接池,HttpClient连接池等。连接池的作用是保持一定量的连接让交互过程复用这些连接,从而大大节省连接创建过程或过多的损耗。在连接池策略中往往当池没有连接的情况都会抛出异常告诉使用者资源无法使用,正常来说这种做法比较普遍,但并发峰值往往都是瞬间存在的,只要没资源就拒绝这种情况服务上或多或少有些不太友好。

应用需求

        在构建组件网关转发和HttpClient设计中大量加入了连接池,在最开始的设计中只要连接池的连接没有的情况下直接抛出异常拒绝;但实际并发时的峰值往往是瞬间出现,在下一刻就会回落到比较低的水平;在这么短暂的时间内拒绝当前请求的确是没有必要,因此在连接池前置加个等待队列。

设计

        针对等待设计一般两种情况:一种是自旋等待,而另一种则是回调;前者不用说比较占用cpu资源,但好处就是代码结构好;后者则cpu资源利用好,但基于异步回调函数方式代码结构并不友好,集成逻辑比较麻烦。但在.net集成了async/await功能后异步处理再也不需要通讯函数回调的方式编写,整体代码结构和自旋等待方式并没差异。

实现

        接下来讲述BeetleX.Http.Clients是如何实现具有等待队列的连接池的,从而通过这机制保障并发峰值时可以接管更多的请求。针对连接池主要提供两个方法分别是Pop和Push,前者是从池中获取连接,后者则是把连接回收到池里.等待队列基本就围绕着这两个方法处理即可。接下来看一下BeetleX.Http.Clients的HttpClientHandlerPool是怎样实现的。

  • Pop

        该方法是从连接池中获取连接

public Task<HttpClientHandler> Pop()
{lock (this){if (mPools.Count > 0){var result = mPools.Pop();result.Using = true;result.TimeOut = BeetleX.TimeWatch.GetElapsedMilliseconds() + TimeOut;return Task.FromResult(result);}if (Clients.Count < MaxConnections){var result = Create();result.Using = true;result.TimeOut = BeetleX.TimeWatch.GetElapsedMilliseconds() + TimeOut;return Task.FromResult(result);}if (mWaitQueue.Count < MaxWaitLength){TaskCompletionSource<HttpClientHandler> completionSource = new TaskCompletionSource<HttpClientHandler>();mWaitQueue.Enqueue(completionSource);return completionSource.Task;}else{throw new HttpClientException($"Request {Host} connections limit");}}
}
  • 第一步是判断连接池有没有连接,如果有则直接返回可用连接。

  • 第二步如果连接池没有连接,则判断创建的连接数是否超过最大值,如果没有则创建一个新的连接并返回。

  • 第三步判断当前等待队列是否超出最大值,如果不是则创建对应的TaskCompletionSource存储到队列中返回相应的Task对象。

  • Push

    由于涉及到等待队列问题,所以当连接回收的时候也要做特别的处理

public void Push(HttpClientHandler client)
{TaskCompletionSource<HttpClientHandler> result = null;lock (this){if (mWaitQueue.Count > 0){result = mWaitQueue.Dequeue();client.Using = true;client.TimeOut = BeetleX.TimeWatch.GetElapsedMilliseconds() + TimeOut;}else{client.Using = false;mPools.Push(client);}}if (result != null){Task.Run(() => result.SetResult(client));}
}

    当连接回收后需要判断一下是否存在队列,如果存在则获取队列中等待的TaskCompletionSource并设置返回值;这里为何通过Task.Run来调用呢?主要原因是希望启用新线程来回调,不让当前线程处理回调任务影响其后续的工作。

使用

    针对连接池的使用只需要在调用Pop时加个await即可

client = await HttpHost.Pool.Pop();
【BeetleX通讯框架代码详解】
BeetleX

开源跨平台通讯框架(支持TLS)
轻松实现高性能:tcp、http、websocket、redis、rpc和网关等服务应用

https://beetlex.io

如果你想了解某方面的知识或文章可以把想法发送到

henryfan@msn.com|admin@beetlex.io

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode701. 二叉搜索树中的插入操作

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

你不该错过的2020中国开源年报,填开源开发者问卷,成为国内开源的见证者

点击上方“开源社”关注我们| 作者&#xff1a;王伟| 编辑&#xff1a;黄欣宜| 设计&#xff1a;冯艺怡| 责编&#xff1a;王玥敏卷首语一年一度的中国开源年报再度启动&#xff5e;中国开源年报由开源社发起。旨在从多种维度&#xff0c;多种方式&#xff0c;多种协作来呈现国…

leetcode450. 删除二叉搜索树中的节点(java详解版)

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

.NET Core使用FluentEmail发送邮件

前言在实际的项目开发中&#xff0c;我们会遇到许多需要通过程序发送邮件的场景&#xff0c;比如异常报警、消息、进度通知等等。一般情况下我们使用原生的SmtpClient类库居多&#xff0c;它能满足我们绝大多数场景。但是使用起来不够简洁&#xff0c;许多场景需要我们自行封装…

进击吧! Blazor !第四期 组件开发

Blazor 是一个 Web UI 框架&#xff0c;可通过 WebAssembly 在任意浏览器中运行 .Net 。Blazor 旨在简化快速的单页面 .Net 浏览器应用的构建过程&#xff0c;它虽然使用了诸如 CSS 和 HTML 之类的 Web 技术&#xff0c;但它使用 C&#xff03;语言和 Razor 语法代替 JavaScrip…

HttpReports 2.0 发布了 !!!

https://www.cnblogs.com/myshowtime/p/13806631.html来源???? 前言介绍HttpReports 是基于.Net Core 开发的APM监控系统&#xff0c;使用MIT开源协议&#xff0c;主要功能包括&#xff0c;统计, 分析, 可视化&#xff0c; 监控&#xff0c;追踪等&#xff0c;适合在微服务…

.NET Standard 来日苦短去日长

作者&#xff1a;Richard翻译&#xff1a;精致码农-王亮原文&#xff1a;http://dwz.win/Q4h自从 .NET 5 宣贯以来&#xff0c;很多人都在问这对 .NET Standard 意味着什么&#xff0c;它是否仍然重要。在这篇文章中&#xff0c;我将解释 .NET 5 是如何改进代码共用并取代 .NET…

leetcode538. 把二叉搜索树转换为累加树

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

【BCVP升级】泛型主键的使用

&#xff08;图片来源于SqlSugar官网&#xff0c;5年5.0&#xff09;大家假期已经结束了吧&#xff0c;还有80天左右就要到2021年了&#xff0c;你准备好了么&#xff1f;BCVP&#xff08;Blog.Core&Vue Project&#xff09;项目已经开源2年多&#xff0c;从来没有停更过&a…

leetcode404. 左叶子之和(迭代和递归)

一:题目 二:上码 迭代 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right…

Dotnet Core使用特定的SDKRuntime版本

Dotnet Core的SDK版本总在升级&#xff0c;怎么使用一个特定的版本呢&#xff1f;假期过完了&#xff0c;心情还在。今天写个短的。一、前言写这个是因为昨天刷微软官方文档&#xff0c;发现global.json在 SDK 3.0 后&#xff0c;更新了一些内容。文档提到了这个更新&#xff0…

Spring中IOC的理解(通俗易懂版)

文章目录1.IOC提出背景2:IOC的核心概念3:IOC的实现方式4:IOC的入门案例(1):思路分析(2):代码解析5:DI入门案例(1):思路分析(2):代码解析6:DI依赖注入的方式(1):前言(2):Set方式注入(3):构造器注入(4):依赖的自动装配7:注解开发模式的依赖注入(1):前言介绍(2):注解模式的依赖注入…

首个使用Blazor 技术实现的社区软件 BlazorCommunity 发布

BlazorCommunity 是首个使用Blazor 实现的开源社区软件&#xff0c; 其组件基于Element-Blazor &#xff0c; Element-Blazor 是一个 API 模仿 Element&#xff0c;CSS 直接使用 Element 样式&#xff0c;HTML 结构直接使用 Element HTML 结构 的 Web开发库。由于基于了…

leetcode112. 路径总和

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

全球顶级开源大神们现身 COSCon'20

点击上方“开源社”关注我们| 作者&#xff1a;Will Wang| 编辑&#xff1a;沈于蓝| 责编&#xff1a;王皓月业界最具影响力的开源年度盛会2020中国开源年会 (COSCon20) 将于 10月24-25日由开源社举办。COSCon 以其独特定位及日益增加的影响力&#xff0c;吸引越来越多的顶级企…

做.NET开发多年,公司要我转Java...

10月13日&#xff0c;.NET5发布了(Release Candidate)RC2版本&#xff0c;包含语言新版本C#9和F#5等&#xff0c;这是正式版前的最后更新&#xff01;终于&#xff0c;万众期待的.NET5真的要来了&#xff01;公司让我转Java&#xff0c;我成功说服老板&#xff01;机会永远留给…

ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互调

Blazor WebAssembly可以在浏览器上跑C#代码&#xff0c;但是很多时候显然还是需要跟JavaScript打交道。比如操作dom&#xff0c;当然跟angular、vue一样不提倡直接操作dom&#xff1b;比如浏览器的后退导航。反之JavaScript也有可能需要调用C#代码来实现一些功能&#xff0c;毕…

leetcode654. 最大二叉树

一:上码 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

浅议C#客户端和服务端通信的几种方法:Rest和GRPC和其他

本文来自&#xff1a;https://michaelscodingspot.com/rest-vs-grpc-for-asp-net/浅议C#客户端和服务端通信的几种方法&#xff1a;Rest和GRPC在C&#xff03;客户端和C&#xff03;服务器之间进行通信的方法有很多。一些功能强大&#xff0c;而其他功能则不是很多。有些非常快…

leetcode106. 从中序与后序遍历序列构造二叉树(java详解版)

一:题目 二:上码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …