上海建站网站简洁案例,网站需要维护吗,app浏览器下载,中国电力建设公司官网说到连接池相关很多人都使用过#xff0c;常见的有数据连接池#xff0c;HttpClient连接池等。连接池的作用是保持一定量的连接让交互过程复用这些连接#xff0c;从而大大节省连接创建过程或过多的损耗。在连接池策略中往往当池没有连接的情况都会抛出异常告诉使用者资源无… 说到连接池相关很多人都使用过常见的有数据连接池HttpClient连接池等。连接池的作用是保持一定量的连接让交互过程复用这些连接从而大大节省连接创建过程或过多的损耗。在连接池策略中往往当池没有连接的情况都会抛出异常告诉使用者资源无法使用正常来说这种做法比较普遍但并发峰值往往都是瞬间存在的只要没资源就拒绝这种情况服务上或多或少有些不太友好。应用需求 在构建组件网关转发和HttpClient设计中大量加入了连接池在最开始的设计中只要连接池的连接没有的情况下直接抛出异常拒绝但实际并发时的峰值往往是瞬间出现在下一刻就会回落到比较低的水平在这么短暂的时间内拒绝当前请求的确是没有必要因此在连接池前置加个等待队列。设计 针对等待设计一般两种情况一种是自旋等待而另一种则是回调前者不用说比较占用cpu资源但好处就是代码结构好后者则cpu资源利用好但基于异步回调函数方式代码结构并不友好集成逻辑比较麻烦。但在.net集成了async/await功能后异步处理再也不需要通讯函数回调的方式编写整体代码结构和自旋等待方式并没差异。实现 接下来讲述BeetleX.Http.Clients是如何实现具有等待队列的连接池的从而通过这机制保障并发峰值时可以接管更多的请求。针对连接池主要提供两个方法分别是Pop和Push,前者是从池中获取连接后者则是把连接回收到池里.等待队列基本就围绕着这两个方法处理即可。接下来看一下BeetleX.Http.Clients的HttpClientHandlerPool是怎样实现的。Pop 该方法是从连接池中获取连接public TaskHttpClientHandler 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){TaskCompletionSourceHttpClientHandler completionSource new TaskCompletionSourceHttpClientHandler();mWaitQueue.Enqueue(completionSource);return completionSource.Task;}else{throw new HttpClientException($Request {Host} connections limit);}}
}
第一步是判断连接池有没有连接如果有则直接返回可用连接。第二步如果连接池没有连接则判断创建的连接数是否超过最大值如果没有则创建一个新的连接并返回。第三步判断当前等待队列是否超出最大值如果不是则创建对应的TaskCompletionSource存储到队列中返回相应的Task对象。Push由于涉及到等待队列问题所以当连接回收的时候也要做特别的处理public void Push(HttpClientHandler client)
{TaskCompletionSourceHttpClientHandler 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如果你想了解某方面的知识或文章可以把想法发送到henryfanmsn.com|adminbeetlex.io