`
csd_ali
  • 浏览: 137361 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

客户/服务器程序设计范式

阅读更多

 

  

                           本篇从基于TCP/IP协议出发,探讨现代流行的应对高并发请求网络服务端设计架构;

1. TCP/IP 模型

首先回顾一下TCP/IP模型,并知道各个层次在操作系统的哪一个层次;


 

   看上图,OSI模型的底下两层是随系统提供的设备驱动程序和网络硬件。通常情况下,除需知道数据链路的某些特性外,我们不用关心这两层的情况。网络层由IPv4和IPv6两个协议处理,可以选择的传输层有TCP或UDP。OSI模型的顶上三层被合并为一层,称为应用层,这就是web客户(浏览器)、telnet客户、web服务器等都所在的层。

   可见OSI模型以传输层为分界线;套接字编程接口为应用层进入传输层的接口;也符合抽象的目的:对应用层隐藏网络协议的具体通信细节,应用层只处理具体网络应用;而底下四层(从传输层到物理层)对具体网络应用了解不多,却处理所有的通信细节:发送数据,等待确认,给无序到达的数据排序,计算并验证校验和,等等。

   其次,顶上三层通常构成所谓的用户进程,底下四层却通常作为操作系统内核的一部分提供。完全符合Unix和其他现代操作系统都提供分割用户进程和内核的机制。

2. 基本TCP 套接字编程

   TCP:传输控制协议(Transmission Control Protocol).TCP是一个面向连接的协议,为用户进程提供可靠的全双工字节流。TCP套接字是一种流套接字(stream socket). TCP关心确认,超时和重传之类的细节。大多数网络应用程序使用TCP;

    以apache为例子;apache工作在OSI模型的应用层;我们都知道启动apache后他会监听在80端口,并通过线程池来响应每个客户请求;即来一个客户请求,从连接池那出一个线程去处理这个请求;那么apache的内部是如何针对每个请求创建套接字,然后分配一个线程的呢?

    看图2,apache服务器启动后通过创建监听套接字listensocket,通过调用bind(),listen(),accept(),让主线程监听在80端口;客户请求过来后tcp三次握手,握手成功后accept()返回一个已连接套接字connsocket,代表与所返回客户的tcp连接;然后apache从连接池里拉出一个线程,并将这个已连接套接字给这个线程,让次线程处理这个请求;请求处理完毕后关闭连接,已连接套接字相应的回收;

注:监听套接字(listening socket)是在该tcp服务进程生命周期内一直存在。而已连接套接字代表一个和客户请求建立的一个套接字,生命周期为一次请求;



 

                     图2 : 基本TCP客户/服务器程序套接字函数

注:我们的jms客户端程序也是采用主线程监听队列消息,并将收到的消息给线程池里的一个线程去处理的方式来并发处理消息;

3. 现代并发web服务器的设计范式:

     但是apache真的是一个主线程在监听80端口么? 不是的,一个主线程监听80端口,然后将已连接套接字抛给线程池里的线程去处理,有些缺点;

     缺点如下:1. 只有一个线程监听80端口,并负责三次握手和转发已连接套接字;万一此线程挂了,整个web server就没有服务能力了,容错能力不强;

                    2. 因为connect(),accept()都是阻塞函数。所以每个客户请求来都阻塞在主线程,导致不能很好的应对并发;

     基于这些缺点;apache采用每个线程都去监听80端口,当然同一时刻,只有一个线程在监听80端口;其他线程属于空闲状态;一个客户请求过来,正在监听的线程会处理这个请求并转换为工作者线程;并让出监听者的角色,这样其他线程竞争监听者的角色,并最终有一个线程监听80端口;当一个工作线程处理完请求后,回到连接池中,又处于空闲状态;

但是这样又有问题,如果一个客户请求过来,会导致所有的空闲线程都去竞争监听者的角色。会导致很多空闲线程一下被唤醒,并只有一个线程获得监听者角色,其他线程继续空闲(睡觉),这种大批线程从空闲状态突然被唤醒有突然又睡过去,就是惊群现象;惊群现象会导致性能下降;

     apache通过在每个accept()函数上 增加互斥锁和条件变量 来解决这个惊群问题。保证每个请求只会被一个线程刚好拿到,不会影响其他线程;

      这里详细介绍下:条件变量与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用;互斥锁提供互斥机制,条件变量提供信号机制;
     那么apache是如何利用条件变量和互斥锁来解决每次只有一个空闲线程被唤醒,并且处于监听者角色呢?
     每次一个新的客户请求过来,正在监听的线程与该请求建立连接,并变为worker工作者线程。让出监听者角色时它同时发送信号到条件变量,并释放锁。这样在空闲(idle)状态的一个线程将被唤醒并获得锁。

     也就是说:条件变量保证了其他线程在等待条件变化期间处于睡眠;互斥锁保证一次只有一个线程被唤醒;



 

                                                      图3 :apache 的preforking 机制

 

 

总结:通过了解了TCP/IP编程模型。和apache的MPM、Preforking机制后,我们再去看jms消息客户端代码,memcache服务器代码,jetty,等流行的web服务器的机制就不是很难了。

                                                                                                                                                       参考:《UNIX网络编程 卷1 :套接字联网API》

  • 大小: 39.4 KB
  • 大小: 48.1 KB
  • 大小: 26.9 KB
2
0
分享到:
评论
2 楼 Tyrion 2013-07-11  
楼主好文,
1 楼 gezhicheng 2012-09-17  
好文章,我想对这方面进行深入了解,有什么建议。

相关推荐

    稳压罐sw16_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    稳压罐sw16_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    基于递推最小二乘法的永磁同步电机参数辨识及其MATLAB仿真

    内容概要:本文详细介绍了利用递推最小二乘法(RLS)进行永磁同步电机参数辨识的方法及其MATLAB仿真过程。首先解释了RLS算法的优势,如不需要概率模型、计算量适中以及适用于嵌入式系统的实时参数更新。接着展示了将电机电压方程转换为标准形式Y=φθ的具体步骤,并提供了核心的RLS迭代代码。文中还讨论了仿真过程中的一些关键技术细节,如遗忘因子的选择、协方差矩阵的初始化和更新方式、电流信号的处理方法等。最终给出了仿真结果,显示电阻和电感的辨识误差分别达到了0.08%和0.12%,并指出了实际应用中需要注意的数据同步和数值稳定性问题。 适合人群:从事电机控制研究的技术人员、研究生及以上学历的学生。 使用场景及目标:①帮助研究人员理解和掌握RLS算法在电机参数辨识中的应用;②提供详细的仿真代码和配置建议,便于快速搭建实验环境;③指导如何优化算法性能,提高参数辨识精度。 其他说明:本文不仅涵盖了理论推导,还包括了大量的实践经验分享和技术细节探讨,有助于读者全面理解RLS算法的实际应用。同时,文中提到的仿真方案可以方便地移植到DSP平台,进一步扩展了其实用价值。

    零起点Python大数据与量化交易

    零起点Python大数据与量化交易

    管道清污机器人sw16可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    管道清污机器人sw16可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    电路仿真:数字电路仿真.zip

    电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。

    电能质量分析:电压暂降与中断分析.zip

    电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。

    thai-scalable-garuda-fonts-0.6.5-1.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统thai-scalable-garuda-fonts-0.6.5-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf thai-scalable-garuda-fonts-0.6.5-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

    基于ABAQUS的滑坡与沉降对埋地管道影响的有限元分析及应用

    内容概要:本文详细介绍了利用ABAQUS进行滑坡和沉降对埋地管道影响的有限元分析方法。主要内容涵盖了几何建模、材料属性定义、接触设置、边界条件与加载等方面的技术细节。通过具体的Python脚本示例展示了如何构建模型,并深入探讨了滑坡和沉降条件下管道的应力、应变分布及其潜在破坏机制。此外,还分享了一些实战经验和优化技巧,如材料模型选择、接触条件设置、边界条件处理等,强调了这些因素对结果准确性的重要影响。 适合人群:从事地下管道工程设计、施工及维护的专业技术人员,尤其是那些希望深入了解滑坡和沉降对管道影响的研究人员和技术专家。 使用场景及目标:适用于评估和预测滑坡和沉降对埋地管道造成的力学响应,帮助工程师们更好地理解和应对复杂的地质灾害环境,从而提高管道系统的安全性与稳定性。 其他说明:文中提供的Python代码片段仅为示意,具体实施时需结合ABAQUS的实际接口和项目需求进行适当调整。同时,对于大规模模型的计算,建议使用高性能计算资源以确保效率和精度。

    Java实习一天高频面试突击!最常见的几种面试题型!!!

    Java一天面试突击,迅速掌握Java常见面试题

    莲子去壳机设计模型SW10_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    莲子去壳机设计模型SW10_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    MFRC-522+RC522+RFID射频+IC卡感应模块

    MFRC-522+RC522+RFID射频+IC卡感应模块

    学术研究学术研究提示设计50招:从论文撰写到润色降重的全方位指南学术研究中常见的

    内容概要:《学术研究提示设计 50 招》是一份详尽的指南,旨在帮助研究人员提高学术写作和研究效率。该文档涵盖了从论文撰写、润色、翻译、查重降重、参考文献管理、投稿审稿到文献阅读等多个方面的具体操作指令。每一章节均针对特定任务提供了详细的步骤和注意事项,例如如何撰写标题、摘要、致谢,如何进行英文润色、中英翻译,以及如何优化逻辑结构等。文档还介绍了如何利用AI工具进行文献分析、术语表提取和研究方向探索等内容,为研究者提供了全面的支持。 适合人群:适用于学术研究人员,特别是那些需要撰写、润色和提交学术论文的研究者,包括研究生、博士生及高校教师等。 使用场景及目标:① 提供一系列具体的指令,帮助研究者高效完成论文的各个部分,如撰写标题、摘要、致谢等;② 提供润色和翻译的详细指导,确保论文语言的准确性和专业性;③ 提供查重降重的方法,确保论文的原创性;④ 提供参考文献管理和投稿审稿的指导,帮助研究者顺利发表论文;⑤ 利用AI工具进行文献分析、术语表提取和研究方向探索,提高研究效率。 阅读建议:此资源不仅提供了具体的指令和方法,更重要的是引导研究者如何思考和解决问题。因此,在学习过程中,不仅要关注具体的步骤,还要理解背后的原理和逻辑,结合实际案例进行实践和反思。

    项目optionc-20250409

    项目optionc-20250409

    2023年c语言程序设计基本概念考点归纳.doc

    2023年c语言程序设计基本概念考点归纳.doc

    电能质量仿真:谐波分析与仿真.zip

    电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。

    基于Matlab的模拟与数字滤波器设计:IIR、FIR及经典滤波器类型的实战详解

    内容概要:本文详细介绍了使用Matlab进行模拟和数字滤波器设计的方法,涵盖了巴特沃斯、切比雪夫等多种经典滤波器类型。首先讲解了模拟滤波器的设计,如巴特沃斯滤波器的通带平坦性和切比雪夫滤波器的通带波纹特性,并提供了具体的代码示例。接着讨论了数字滤波器的设计,包括IIR滤波器的递归特性和FIR滤波器的线性相位特性,同样附有详细的代码实现。文中还特别强调了不同类型滤波器之间的转换方法以及设计过程中常见的注意事项,如频率归一化、阶数选择等。最后推荐了一些实用的Matlab工具,如fvtool和FDATool,帮助用户更直观地理解和调试滤波器设计。 适合人群:具有一定信号处理基础和技术背景的研究人员、工程师及学生。 使用场景及目标:适用于需要进行滤波器设计的实际工程应用,如通信系统、音频处理等领域。目标是让读者掌握滤波器设计的基本原理和具体实现方法,能够独立完成滤波器的设计和调试。 其他说明:文章不仅提供了理论知识,还通过大量实例代码帮助读者更好地理解和应用所学内容。建议读者在实践中多尝试不同的参数配置,以加深对滤波器特性的理解。

    饲料干燥装置sw16_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    饲料干燥装置sw16_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    MATLAB环境下独立分量分析(ICA)在土木、航空航天、机械领域的振动信号处理应用

    内容概要:本文详细介绍了独立分量分析(ICA)在MATLAB环境下的应用,特别是在土木工程、航空航天和机械领域的振动信号处理方面。文章通过具体实例展示了如何利用ICA将复杂的混合信号分解为独立分量,从而帮助识别结构损伤、故障特征等问题。文中提供了详细的MATLAB代码示例,涵盖数据预处理、核心算法实现以及结果可视化的全过程。此外,还讨论了ICA的应用限制及其与其他信号处理方法的结合使用。 适合人群:从事土木工程、航空航天、机械等领域研究和技术工作的工程师及研究人员,尤其是那些需要处理复杂振动信号的人群。 使用场景及目标:① 土木工程中用于结构健康监测,如桥梁、建筑物的振动数据分析;② 航空航天领域用于飞行器复合载荷分离;③ 机械设备故障诊断,如齿轮箱、轴承等部件的故障特征提取。通过ICA能够有效地从多源混合信号中分离出有用的独立分量,辅助决策。 其他说明:ICA并非适用于所有情况,在某些特定条件下可能会失效,因此需要结合实际情况灵活运用。对于初学者来说,可以从简单的仿真数据入手,逐步过渡到真实的工程项目中。

    【Linux详解】常用命令与系统配置:虚拟机搭建、文件管理及网络配置详解

    内容概要:本文详细介绍了Linux操作系统的概念、特点及其常见命令,旨在帮助用户掌握Linux的基础知识和操作技能。文章首先概述了Linux的操作系统特性,如免费、稳定、高效,以及其广泛的应用领域,包括服务器和个人设备。接着介绍了Linux的安装与配置,包括虚拟机的创建、分区设置、网络配置等。随后,重点讲解了Linux命令行的基本命令,涵盖文件和目录管理、用户和权限管理、进程和服务管理等方面。此外,还涉及了远程登录、文件传输、文本编辑器(如vi/vim)、定时任务、磁盘管理、网络配置、服务管理和包管理工具(如rpm/yum)。最后简要介绍了Shell编程的基础知识,包括变量、条件判断和脚本编写。 适合人群:适合初学者和有一定经验的Linux用户,特别是希望深入了解Linux系统管理和操作的IT从业者。 使用场景及目标:①帮助用户熟悉Linux操作系统的特性和应用场景;②掌握Linux系统的基本命令和操作技巧;③学会配置和管理Linux服务器,包括文件系统、用户权限、网络设置和服务管理;④能够编写简单的Shell脚本来自动化日常任务。 阅读建议:由于本文内容丰富且涉及面广,建议读者在学习过程中结合实际操作进行练习,特别是在命令行操作、文件管理、用户权限设置和Shell编程方面。对于复杂命令和概念,可以通过查阅官方文档或在线资源进一步加深理解。

    stm32仿真包-proteus8.15

    stm32仿真包-proteus8.15

Global site tag (gtag.js) - Google Analytics