热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux高性能服务器编程:高性能服务器程序框架

服务器有三个主要模块:(1)IO处理单元(2)逻辑单元(3)存储单元 1.服务器模型CS模型逻辑:服务器启动后,首先创建一个或多个监听socket,并调用bind函数将其绑定到服务

服务器有三个主要模块:

(1)I/O处理单元

(2)逻辑单元

(3)存储单元

 

1.服务器模型

C/S模型

逻辑:服务器启动后,首先创建一个或多个监听socket,并调用bind函数将其绑定到服务器感兴趣的端口上,然后调用listen函数等待客户连接。

服务器运行稳定后,客户端就可以调用connect函数向服务器发起连接了。

P2P模型

P2P模型使得每台机器在消耗服务的同时也给别人提供服务,这样资源能够充分、***的共享。

 

2.服务器编程框架

包含:

I/O处理单元  请求队列   逻辑单元   请求队列  网络存储单元

I/O处理单元:处理客户连接,读写网络数据

逻辑单元:业务进程或线程

网络存储单元:本地数据库、文件或缓存

请求队列:各单元之间的通信方式

 

3. I/O模型

阻塞I/O执行的系统调用可能因为无法立即完成而被操作系统挂起,知道等待的事件发生为止。可能阻塞的系统调用包括:accept,send,recv和connect。

非阻塞I/O执行的系统调用则总是立即返回,而不管时间是否发生。如果事件没有立即发生,这些系统调用就返回-1,和出错的情况一样。必须根据errno来区分这两种情况。

对accept,send和recv而言,事件未发生时errno通常被设置成EAGAIN或者EWOULDBLOCK:对connect而言,errno则被设置成EINPROGRESS。

 

显然,只有在事件已经发生的情况下操作非阻塞I/O,才能提高程序的效率。I/O通知机制有:I/O复用和SIGIO信号。

I/O复用:应用程序通过I/O复用函数向内核注册一组事件,内核通过I/O复用函数把其中就绪的事件通知给应用程序。Linux上常用I/O复用函数是selcet、poll和epoll_wait。I/O复用本身是阻塞的,能提高效率的原因是

它们具有同时监听多个I/O事件的能力。

SIGIO信号:可以为一个目标文件描述符指定宿主进程,那么被指定的宿主进程将捕获到SIGIO信号。这样,当目标文件描述符上有事件发生时,SIGIO信号的信号处理函数将被触发,可以在该信号处理函数中对目标文件描述符执行非阻塞I/O操作了。

 

理论上说,阻塞I/O,I/O复用和信号驱动I/O都是I/O同步模型。在这三种模型中,I/O的读写操作,都是I/O事件发生之后,由应用程序来完成的。

对异步I/O而言,用户可以直接对I/O执行读写操作,这些操作告诉内核用户读写缓冲区的位置,以及I/O操作完成之后内核通知应用程序的方式,异步I/O的读写操作总是立即返回,而不论I/O是否是阻塞的,因为真正的读写操作已经由内核接管。

也就是说,同步I/O模型要求用户代码自行执行I/O操作(将数据从内核缓冲区读入用户缓冲区,或将数据从用户缓冲区写入内核缓冲区),而异步I/O机制则由内核来执行I/O操作(数据在内核缓冲区和用户缓冲区之间的移动是由内核在“后台”完成的)。

同步I/O向应用程序通知的是I/O就绪事件,而异步I/O向应用程序通知的是I/O完成事件。

 

4.两种高效的事件处理模式

使用同步I/O模型实现Reactor模式:

(1)主线程往epoll内核事件表中 注册socket上的读就绪事件。

(2)主线程调用epoll_wait等待socket上有数据可读。

(3)当socket上有数据可读时,epoll_wait通知主线程,主线程将socket事件放入请求队列中。

(4)睡眠在请求队列上的某个工作线程被唤醒,从socket读取数据,并处理客户请求,然后往epoll内核事件表中注册该事件的写就绪事件。

(5)主线程调用epoll_wait等待socket可写。

(6)当socket可写时,epoll_wait通知主线程。主线程将socket可写事件放入请求队列。

(7)睡眠在请求队列上的某个工作线程被唤醒,它往socket上写入服务器处理客户请求的结果。

 

Proactor模式

Proactor模式将所有I/O操作都交给主线程和内核来处理,工作线程仅仅负责业务逻辑。

 

半同步/半异步:

同步线程用于处理客户逻辑,异步线程用于处理I/O事件。

异步线程由主线程充当。负责监听所有socket上的事件。若监听socket上有可读事件发生,即有新的连接到来,主线程就接受之以得到新的连接socket,然后往epoll内核事件表中注册该socket上的读写事件。

如果连接socket上有读写事件发生,即有新的客户请求到来或有数据要发送到客户端,主线程就将该连接socket插入请求队列中。所有工作线程都睡眠在请求队列上,当有任务带来时,将通过竞争获得任务的接管权。

缺点:

主线程和工作线程共享请求队列。主线程往请求队列中添加任务,或者工作线程从请求队列中取出任务,都需要对请求队列加锁保护,从而拜拜浪费CPU时间。

每个工作线程在同一时间只能处理一个客户请求。

 


推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
author-avatar
广东快乐笨人
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有