服务器(事件驱动)

来源:互联网 发布:手机与单片机蓝牙通讯 编辑:程序博客网 时间:2024/05/17 20:27

《the linux programming interface》的63节

http://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/

http://baike.baidu.com/view/2877739.htm


通常,我们写服务器处理模型的程序时,有以下几种模型:
(1)每收到一个请求,创建一个新的进程,来处理该请求;
(2)每收到一个请求,创建一个新的线程,来处理该请求;
(3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求
上面的几种方式,各有千秋,
第(1)中方法,由于创建新的进程的开销比较大,所以,会导致服务器性能比较差,但实现比较简单。
第(2)种方式,由于要涉及到线程的同步,有可能会面临死锁等问题。
第(3)种方式,在写应用程序代码时,逻辑比前面两种都复杂。
综合考虑各方面因素,一般普遍认为第(3)种方式是大多数网络服务器采用的方式,—事件驱动处理库。

  • 迭代服务器(循环服务器):

串行方式每次处理一个客户的请求,容易遭受Dos攻击;

常用于UDP服务程序;

  • 并发服务器:

利用可动态增加的子进程与事先分配好的子进程相结合的方法;如apache的web服务器。

服务器fork一个新进程或线程来处理客户请求;

  1. 进程或线程开销大;The problems with this approach are expense and complexity.
  2. 进程需要IPC上报I/O状态;Creating and maintaining processes places a load on the system, and, typically, the child processes will need to use some form of IPC to inform the parent about the status of I/O operations.
  3. 库函数需要线程安全。如果需要调用第三方库执行阻断I/O,可以考虑在单独的线程内执行。Using multiple threads instead of processes is less demanding of resources, but the threads will probably still need to communicate information to one another about the status of I/O operations, and the programming can be complex, especially if we are using thread pools to minimize the number of threads used to handle large numbers of simultaneous clients. (One place where threads can be particularly useful is if the application needs to call a third-party library that performs blocking I/O. An application can avoid blocking in this case by making the library call in a separate thread.)
  4. 很多程序员可能会考虑使用“线程池”或“连接池”。“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程,并让空闲的线程重新承担新的执行任务。“连接池”维持连接的缓存池,尽量重用已有的连接、减少创建和关闭连接的频率。这两种技术都可以很好的降低系统开销,都被广泛应用很多大型系统,如 websphere、tomcat 和各种数据库等。
    但是,“线程池”和“连接池”技术也只是在一定程度上缓解了频繁调用 IO 接口带来的资源占用。而且,所谓“池”始终有其上限,当请求大大超过上限时,“池”构成的系统对外界的响应并不比没有池的时候效果好多少。所以使用“池”必须考虑其面临的响应规模,并根据响应规模调整“池”的大小。

例子:

  • scp(fork一个ssh进程和对端的sshd相连接,sshd创建一个新进程来处理此客户端的任务)
  • apache的web服务器
  • 服务器监听socket,当有“业务”进来,发送消息(使用动态内存地址存储“指针,指向能够处理业务的指针”,线程都看见)给“线程池”,线程池进行处理
  • IO复用循环服务器:如nigix web服务器。
    • http://blog.csdn.net/chong232/article/details/6153161
    • http://amix.dk/blog/post/19581#The-main-issue-with-non-blocking-servers
    • 在IO循环中的所有操作都必须是非阻塞,否则会因为你一个操作而阻断了整个循环。
    • select、pselect、poll、ppoll、epoll
    • linux 提供了 epoll,BSD 提供了 kqueue,Solaris 提供了 /dev/poll
    • 有很多高效的事件驱动库可以屏蔽上述的困难,常见的事件驱动库有 libevent 库,还有作为 libevent 替代者的 libev 库。

原创粉丝点击