• [原]浅谈几种服务器端模型——同步阻塞迭代


    引言:似乎现在阻碍服务端大部分情况下都属于IO瓶颈,硬盘的转速等,而计算的瓶颈大部分云端计算采用分布式计算,如基于GFS的MapReduce模型,网格计算或者其他的一些分布式处理。所以,现在服务端的服务衡量指标基本集中在并发量,QPS,响应速度,稳定性等。其中一部分也不乏大量的计算,属于CPU密集型的,根据业务的不同应该做相应的调整。今天的话题是浅谈一下几种常用的IO模型。

    理解IO 模型是网络编程的重点。

    最简单的同步迭代IO模型:

    核心代码就是这样,这里我们假设前面的监听套接口已建立。即已绑定套接口,并调用了listen()函数。

    同步迭代IO大致如下,我们假设现在的模型是这样的,服务端监听客户端的连接,并通过读取fd的内容,处理后返回给客户端,类似于http机制。这里省去了一些包裹函数等。

    for(;;){
      fd = accept(...);
    
      read(fd,buf,n);
    
      dosomtething(buf);
    
      write(fd,buf,n);
    
        close(fd);
    }
    

      

    单进程模式下,如果没有客户端到来,进程一直阻塞在 accept调用上,对于新手来说,有点难理解阻塞的概念,总的来说,就是经过accept调用,陷入内核以后,进程停止其他的工作,等待accept()返回。阻塞在accept()不可怕,如果阻塞在read()系统调用,将导致整个服务器不能对其他的客户端提供服务。

    现在假设一个情景:

    accept()得到一个客户端的连接,此时的fd唯一标示该连接。

    现在服务器进入read()系统调用,但是此时的客户端并没有发送数据,那么服务端一直阻塞在read系统调用。此时来了一个新的连接,但是服务端不能予以相应,就是accept()函数不能被服务器调用。那么这个连接是失败的。可想而知,这样的服务器模型是有多么的低效。不过,UDP恰恰常用这种方式,因为UDP 是非面向连接的,整个过程就是两个函数

    recvfrom(buf);
    dosomething(buf);
    sendto(buf);
    

    因为UDP 的非面向连接性,而且采用的是费可靠传输,传输速率较TCP快。读者可以查阅相关资料,但是最好需要设置客户端的recvfrom()超时,因为在传输过程中数据丢失,会导致客户端阻塞在recvfrom()调用上。

    附一张图说明read()的系统调用的阻塞:

    即进程需要等待内核返回结果以后才能继续处理其他业务。

    总结:同步阻塞迭代方式的IO是最简单的一种形式的IO模型,也是最低效的一种,但是研究东西都需要从最简单的开始。吸取经验。下一章讲解多进程的并发式IO模型。

      

      

    文章属原创,转载请注明出处 联系作者: Email:zhangbolinux@sina.com QQ:513364476
  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/Bozh/p/2460998.html
Copyright © 2020-2023  润新知