半年前偶然看到一叫spserver的服务器框架,它将windows下ICOP移植到到libevent,并且以HSHA,LF两种模式实现了服务器框架.我做了点功课,写点心得.
一般来说在设计一个服务器网络框架的时候,需要用到线程池,里面的线程负责执行服务端所有代码.这些代码总的来说可以分为两类:
一类负责网络IO部分,也就是从网络读取和发送数据
另一类负责处理各种业务逻辑.
通常情况下他们是分离的,网络IO部分不需要管理业务逻辑具体做什么工作,而后者也不关心数据怎么得来,怎么送到网络上.两者就是一个生产者消费者关系.用JMeter进行性能测试
这里讨论的HSHA就是网络IO部分为异步模式,而业务逻辑部分为同步模式.即:
网络IO请求为非阻塞的异步操作,只要调用了,就立即返回,操作结果不用调用方不断的去问:”发送/接收成功了吗?”.网上有一个比较形象的比喻,叫经典的好莱坞法则:你不用给我们打电话,我们会通知你的(you dont call me,i will call you).
业务逻辑部分是同步的,虽然不确定服务端线程池中,到底是哪一个线程在执行,但同一时刻只会有一个线程在执行这个网络会话上的业务逻辑.
同步和异步两部分采用一个作业队列(jobQueue)来实现结合,一些细节:
服务端定义一组回调函数,用于将网络连接上的OnAccept,OnRecv,OnSend,OnClose等事件通知业务逻辑层,而业务逻辑层的实现代码正是在这些回调函数中实现.
网络连接建立时,服务端会创建一个网络会话对象,并保存有相关回调函数的指针.将回调函数OnAccept和相关上下文打包成一个任务push到作业队列.
网络连接收到数据后,服务端将回调函数OnRecv和相关上下文打包成一个任务push到作业队列.
网络连接发送数据后,服务端将回调函数OnSend和相关上下文打包成一个任务push到作业队列.
网络连接关闭后,服务端将回调函数OnClose和相关上下文打包成一个任务push到作业队列.
负责执行作业的某个线程被唤醒,取出这些作业,并执行.
以下代码说明大概的处理流程:
1: class job_queue;
2: class msg_free_queue;
3: class thread_pool;
4: int main()
5: {
6: job_queue jobs;
7: msg_free_queue msg_to_free;
8: thread_pool job_thread;
9: thread_pool clean_thread;
10: server_init_and_listen();
11: run_accept_thread();
12: while(!exit_falg){
13: run_iocp_event_loop(&jobs,&msg_to_free);
14: while(job_queue.size() > 0){
15: job_thread.push(job_queue.pop_front());
16: }
17: while(msg_to_free.size() > 0){
18: clean_thread.push(msg_to_free.pop_front());
19: }
20: };
21: }
主线程负责完成端口事件的处理,并完成作业任务的打包,保存在一个容器中.
以上代码只说明了服务端如何把IO层收到的数据交给逻辑层,并没有解释逻辑层怎么样把数据交给IO层发送,实际上这个工作是在负责调用回调函数的那个线程完成,当回调函数返回后,作业线程直接将需要发送的数据打包成一个完成事件,post到完成端口句柄上,这样就建立起关系了.
由于是异步的,逻辑层发送的数据不能确定什么时候发送出去,因此需要保存起来,当完成事件到达后,会把已经发送的数据指针放到一个容器中,然后由主线程负责处理善后问题.
下面是一些题外话:
你也看到了,只有一个线程负责处理IO部分,那么性能如何呢?
这个吧,其实大多数时候,你的服务器性能瓶颈不再网络IO部分,而在业务逻辑处理部分,在那里可能产生磁盘IO,数据库操作等.我个人觉得但线程 IO已经足够了.采用IOCP这样高效的IO模型是为业务逻辑处理腾出资源,因为一个高效的服务端不是看你每秒能收发多少数据,而是看业务处理能力.另外单线程的IOCP也有很多好处,首先就是锁的问题解决了,其次就是资源的管理简单了,这两个问题都是比较棘手的东西.
我编译了spserver的代码,用asio的乒乓测试客户端程序做了一下压力测试,结果你可能也猜到了,IO吞吐量并不算很高,而且多核CPU 上,只有一个CPU达到了100%利用率,而另外几个CPU则利用率不足50%.如果你跟我一样,是一个完美主义者,我们可以这样改进它:
将上面的代码中,监听工作和Accept线程分离出来,主循环那的部分(while那一块和相关的上下文环境)封装成一个模块,每一个模块都有自己完成端口句柄,当连接建立时,做一个简单的负载均衡,为新建立的连接的套接字句柄选择一个完成端口句柄并绑定.于是就变成了下面的样子:
1: class job_queue;
2: class msg_free_queue;
3: class thread_pool;
4: int nod();
5: int main()
6: {
7: thread_pool io_thread_nods;
8: io_thread_nods.set_thread_count(4);
9: server_init_and_listen();
10: run_accept_thread();
11: while(true){
12: io_thread_nods.run(nod);
13: }
14: }
15: int nod()
16: {
17: job_queue jobs;
18: msg_free_queue msg_to_free;
19: thread_pool job_thread;
20: thread_pool clean_thread;
21: while(!exit_falg){
22: run_iocp_event_loop(&jobs,&msg_to_free);
23: while(job_queue.size() > 0){
24: job_thread.push(job_queue.pop_front());
25: }
26: while(msg_to_free.size() > 0){
27: clean_thread.push(msg_to_free.pop_front());
28: }
29: };
30: }
分享到:
相关推荐
2. 事件驱动:异步Web服务通常基于事件驱动模型,即服务器在完成任务后触发一个事件,客户端通过监听这个事件来获取结果。 二、异步Web服务的实现技术 1. JAX-WS(Java API for XML Web Services):在Java环境中...
例如,Node.js的事件驱动模型就是一个很好的例子,它的单线程模型中,大部分I/O操作都是异步的,以提高服务器性能,但对于计算密集型任务,可能会引入线程池进行同步计算,以充分利用多核处理器资源。 了解和熟练...
在传统的同步编程模式下,程序执行会按照代码顺序逐行进行,如果某一步骤需要等待(例如I/O操作),那么整个程序都会阻塞,直到这个操作完成。异步编程则不同,它允许程序在等待某些操作(如网络请求或数据库查询)...
5. **多线程或异步处理**:为了处理并发请求,C-Web-Server可能会使用多线程或者异步I/O模型。这涉及到线程创建、同步机制如互斥锁、条件变量等,或者使用epoll等高效I/O模型。 6. **性能优化**:对于高性能Web...
在本项目中,"C# yolov8 OpenVINO 同步、异步接口视频推理.rar" 是一个基于C#编程语言实现的计算机视觉应用,它利用了OpenVINO(Open Visual Inference and Neural Network Optimization)框架进行YOLOv8模型的视频...
5. **WebFlux**:SpringBoot 2.x引入了WebFlux,它支持反应式编程模型,可以在Web层实现异步处理,提高服务器的吞吐量。 在压缩包文件`showandshare.demo.syncevnet`中,可能包含了具体的示例代码或者教程,这些...
异步Web方法的这种工作模式允许服务器在执行耗时操作时处理其他请求,提高了服务器的吞吐量。这对于那些可能需要长时间计算或等待外部资源响应的服务尤其有用,例如数据库查询、文件读写或网络通信。 在实际应用中...
Linux下基于C++的轻量级Web服务器; (1)使用 线程池 + 非阻塞socket + epoll(ET和LT均实现) + 事件处理(Reactor、Proactor) 的并发模型; ... (3)访问服务器数据库...(4)实现同步/异步日志系统,记录服务器运行状态
在IT领域,构建高效、可扩展的Web服务器是至关重要的,而异步处理技术在此扮演着核心角色。本文将深入探讨采用C++实现的异步HTTP服务器程序代码,旨在帮助开发者理解和掌握HTTP服务器的设计原理与实践技巧。 首先,...
### 基于事件驱动和异步通信体系结构的Web服务器设计 #### 一、引言 随着互联网技术的发展,Web服务器面临着越来越高的并发请求挑战。为了满足这种需求,研究者们提出了各种优化方案,其中之一就是采用事件驱动和...
异步请求和同步请求是Web开发中的两个核心概念,它们决定了客户端与服务器之间的交互方式。 同步请求,也称为阻塞请求,是传统的HTTP请求方式。在这种模式下,当用户在浏览器中触发一个操作,比如点击一个链接或者...
在传统的Web框架中,服务器通常采用同步I/O处理模式,即每个请求都会阻塞一个线程,直到响应完成。这种方式在面对高并发场景时,可能会导致大量线程被创建,消耗过多系统资源,性能瓶颈明显。而异步Web框架则解决了...
### 多路IO复用并发服务器模型 #### 一、并发服务器模型概述 并发服务器模型是一种常见的网络编程架构,用于处理客户端与服务器之间的通信。它能够有效地管理多个客户端的连接请求,确保每个客户端都能获得及时的...
本文将深入探讨C#中的异步Socket服务器,特别是使用IOCP(I/O完成端口)的实现方式。IOCP是一种高效的多线程I/O模型,适用于高并发的网络服务。 首先,我们来理解什么是Socket。Socket是网络通信的基础,它提供了...
在某些情况下,尽管异步处理具有很多优点,如提高响应速度和减轻服务器压力,但当业务逻辑要求严格的顺序执行或数据一致性时,可能需要将异步通信转化为同步。Websphere MQ的持久化消息特性允许消息在发送后即使服务...
此外,它还实现了访问数据库的web端用户注册和登录功能,同步/异步日志系统,以及经Webbench压力测试可以实现上万的并发连接数据交换。 Main Function Points 使用线程池、非阻塞socket、epoll(ET和LT)、事件处理...
async: false, // 关闭异步工作模型,使用同步方式工作 success: function(response) { console.log("ajax 函数内部的 success 函数" + response); } }); // 这段代码会在success函数执行完毕后执行 console.log...
这种模式称为同步处理,因为客户端必须等待服务器的响应才能继续执行。而在异步处理中,客户端发起请求后,可以立即继续执行其他任务,而无需等待服务器的响应。服务器处理完请求后,会将结果以回调的形式返回给...
在IT行业中,Web服务是应用程序之间进行通信的一种标准方式,而Web Service异步处理则是一种优化性能和提高系统响应速度的技术。本主题将深入探讨Web Service异步处理的核心概念、实现方式以及相关代码示例。 首先...
常见的I/O模型包括同步阻塞I/O、同步非阻塞I/O、多路复用I/O、信号驱动I/O以及异步I/O。 ##### 3.1 同步阻塞I/O - **定义**:在同步阻塞I/O模型中,发起I/O操作的进程会一直等待直到I/O操作完成。 - **特点**: -...