关于高性能网络编程的一些总结与思考

从IO说起

一直以来我很欣赏Google I/O大会,一方面是由于一些新技术与新产品的介绍让人兴奋,更重要的是我太爱这个名字了^_^,我觉得正好符合了我对整个互联网技术的浅薄思考与认识。I/O系统就是整个互联网的关键接口,整个互联网的底层就是I/O系统织成的抽象意义上的net,建立在物理线路之上。而网络编程显然是合理创造与利用I/O的重要工具。而以太网的TCP/UDP则在通常的网络编程中占据了核心的地位。本文主要基于Linux平台,其他如Windows NT以及一些Unix衍生版都提供了对应的解决方案。

网络编程是一个很大也很有趣的话题,要写好一个高性能并且bug少的服务端或者客户端程序还是挺不容易的,而且往往涉及到进程线程管理/内存管理/NFS/协议栈等许多相关的知识,所以不仅仅只是会使用socket那么简单。

网络编程模型

首先简单解释几个相关概念:

  • 阻塞/非阻塞

    阻塞和非阻塞通常是指文件描述符本身的属性,拿socket来说,当socket读缓冲区中没有数据时或者写缓冲区满时,都会造成我们read/recv或者write/send系统调用阻塞。而非阻塞socket在这种情况下会产生EWOULDBLOCK或者EAGAIN等错误并立即返回,不会等待socket变得可读或者可写。当然这只是理解阻塞和非阻塞的一个简单例子,并不全面。在Linux下我们可以通过accept4/fcntl等函数设置socket为非阻塞。

  • 同步/异步

    同步和异步更多地是我们怎么处理读写问题的一种手段,这里仅仅限制在IO读写上,真正的这两个概念个人觉得可以推得更广。通常这也对应着两种高性能网络编程模式reactor和proactor,同步通常是我们主动读写数据,而异步通常是我们交给操作系统帮我们读写,只需要注册读写完成后的回调函数。

  • IO复用

    IO复用通常是用select/poll/epoll等来统一代理多个socket的事件的发生,select是一种比较通用的多路复用技术,很多平台都支持,poll是Linux平台下对select做的改进,而epoll可以说是目前Linux平台下性能最高的一种multiplexing技术,当然你得用好,尤其是LT和ET两种触发方式的使用。

下面简单总结了常见的服务器端使用的网络编程模型(包含线程模型)

先看看常见组件采用的模型(只看epoll):

nginx:master进程+多个worker进程,每个进程一个epoll eventloop

memcached: 主线程+多个worker线程,每个线程一个epoll eventloop

tornado:单线程,一个epoll eventloop

libevent:对于Linux平台封装了epoll

libev:对于Linux平台封装了epoll

boost.asio:对于Linux平台封装了epoll

muduo:对于Linux平台封装了epoll

swoole:对于Linux平台封装了epoll

nodejs的libuv:基于libev对epoll的封装

所以排除掉传统的单线程,多进程,多线程等模型,常见的高性能网络编程模型通常是one eventloop per thread与多线程的组合,或者为了处理耗时的任务再加上threadpool。通常为了更好地性能与并发,以master/worker的形式来配置进程线程模型。其实说到底各种高性能网络库或者框架还是在玩epoll+非阻塞。

值得注意的问题

  • 选择线程模型

    单线程下不用考虑同步等问题,one eventloop,相对容易很多

    多线程下要考虑多线程编程可能产生的各种竞争同步问题,协调各个thread里面的eventloop。

    多进程下要考虑各个eventloop thread的通信等问题

  • socket的读写

    这也是一大难点,尤其是epoll LT和ET方式下的读写,还有怎么优雅地处理各种错误。

  • 协议的设计
  • 使用文本还是二进制?json,xml,pb等等?
  • TCP/IP协议本身的深入理解
  • 日志
  • ……

应用层之外

前面都是基于应用层对于C10K这类问题的解决方案,在更高并发要求的环境下就得在内核态下做手脚了,如零拷贝等技术,直接越过内核协议栈,实现高速数据包的传递。相应的内核模块也早有实现。

相关资源

  • 书籍:

    《UNIX环境高级编程》

    《UNIX网络编程》两卷

    《TCP/IP协议》三卷

    《Linux内核设计与实现》

    《深入理解Linux内核》

    《Linux多线程服务端编程》

  • 各种开源组件:

    nginx

    memcached

    beanstalkd

    libevent

    libev

    muduo

    boost.asio

    ace

    tornado

    swoole

时间: 2024-10-01 20:39:03

关于高性能网络编程的一些总结与思考的相关文章

高性能网络编程 - select系统调用

IO复用使得程序能够同时监听多个文件描述符,比如客户端需要同时处理用户输入和网络连接,服务器端需要同时处理监听套接字和连接套接字,select系统调用可以使得我们监听自己感兴趣描述符,可读,可写,异常等事件.select能处理的异常只有带外数据.能同时处理描述符的数量受限于FD_SETSIZE的大小(一般1024).下面这个程序展示了它的一般用法. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #i

高性能网络编程 - epoll机制

select系统调用不仅对描述符的数量有限制,而且在高并发的情况下,哪怕只有一个活跃的套接字,也要轮询全部的fd set,而epoll采用回调的事件通知机制,只需要处理活跃的套接字.比如Nginx服务器采用的就是epoll,下面这个程序(当接收到大于10B的数据时)展示了epoll在边沿触发和电平触发的不同表现,在edge-trigger模式下,需要我们的程序一次将这次的事情处理完成(比如把数据全部读取),因为这个事件下次不会加到内核事件注册表中了,相反level-trigger模式下就跟我们的

学习编程是否做笔记的思考

做编程是否做笔记的思考: 做笔记的目的是将来怕忘.什么东西是重要的怕将来忘掉?1.需要记得东西:你自己的体会.经验.这些东西怕忘了,需要记笔记.2.什么不用记: 网上.书上随手可得的东西,没必要花时间记. 语言只是一门工具,精通工具的唯一手段就是熟练使用. 此外,编程又是一门语言,语言就是要多练才能熟练掌握. 所以,通常来说,学编程的时候不需要做笔记. 回到学习一门新语言的问题.可以有两种办法检验你是否学会了一门新语言:你可以用这个语言,做个实际项目:或者你可以教别人学会这个语言. 注:主要是自

python之高性能网络编程并发框架eventlet实例

http://blog.csdn.net/mingzznet/article/details/38388299 前言: 虽然 eventlet 封装成了非常类似标准线程库的形式,但线程和eventlet在实际并发执行流程仍然有明显区别.在没有出现 I/O 阻塞时,除非显式声明,否则当前正在执行的 eventlet 永远不会把 cpu 交给其他的 eventlet,而标准线程则是无论是否出现阻塞,总是由所有线程一起争夺运行资源.所有 eventlet 对 I/O 阻塞无关的大运算量耗时操作基本没有

高性能网络编程(1)—accept建立连接?(转载,作者:陶辉)

编 写服务器时,许多程序员习惯于使用高层次的组件.中间件(例如OO(面向对象)层层封装过的开源组件),相比于服务器的运行效率而言,他们更关注程序开发 的效率,追求更快的完成项目功能点.希望应用代码完全不关心通讯细节.他们更喜欢在OO世界里,去实现某个接口.实现这个组件预定义的各种模式.设置组件 参数来达到目的.学习复杂的通讯框架.底层细节,在习惯于使用OO语言的程序员眼里是绝对事倍功半的.以上做法无可厚非,但有一定的局限性,本文讲述的网 络编程头前冠以“高性能”,它是指程序员设计编写的服务器需要

高性能网络编程技术

高性能网络编程技术 作者:jmz (360电商技术组) 如何使网络服务器能够处理数以万计的客户端连接,这个问题被称为C10K Problem.在很多系统中,网络框架的性能直接决定了系统的整体性能,因此研究解决高性能网络编程框架问题具有十分重要的意义. 1. 网络编程模型 在C10K Problem中,给出了一些常见的解决大量并发连接的方案和模型,在此根据自己理解去除了一些不实际的方案,并做了一些整理. 1.1.PPC/TPC模型 典型的Apache模型(Process Per Connectio

【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了

转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上篇请见:<高性能网络编程(二):上一个10年,著名的C10K并发连接问题>).本文将讨论单机服务器实现C10M(即单机千万并发连接)的可能性及其思路. 截至目前,40gpbs.32-cores.256G RAM的X86服务器在Newegg网站上的报价是几千美元.实际上以这样的硬件配置来看,它完全可

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

阅读(81374) | 评论(9)收藏16 淘帖1 赞3 JackJiang Lv.9    1 年前 | 前言 曾几何时我们还在寻求网络编程中C10K问题(有关C10K问题请见文章<The C10K problem(英文在线阅读.英文PDF版下载.中文译文)>)的解决方案,但是现在从硬件和操作系统支持来看单台服务器支持上万并发连接已经没有多少挑战性了. 我们先假设单台服务器最多只能支持万级并发连接,其实对绝大多数应用来说已经远远足够了,但是对于一些拥有很大用户基数的互联网公司,往往面临的并发

一文读懂高性能网络编程中的I/O模型

1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的高性能网络编程的I/O模型概览以及网络服务进程模型的比较,以揭开设计和实现高性能网络架构的神秘面纱. 限于篇幅原因,请将本文与<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>连起来读,这样会让知识更连贯. 学习交流: - 即时通讯开发交流3群:185926912[推荐] - 移动端IM