专栏首页技巅开源软件实践之linux高性能服务器编程框架和选型

开源软件实践之linux高性能服务器编程框架和选型

很多人学习编程技术一般都通过一本编程语言的入门书籍,然后尝试做一些例子和小项目。但是这些都不能让我们深入的学习很多的编程技巧和高深技术,当然这个时候很多有经验的学习人员就会告诉大家,找一个好的开源软件理解它的设计与实现原理,阅读开源项目的源代码,都知道源码之前了无秘密。我也承认读源码能够快速提高我们的编程能力和编程思维,我也经常研究很多项目的源代码,有些是工作需要,有些是兴趣。但是我今天想说的都不是这些,我想说的是更高一层的学习方案,就是通过自己的实践实现一个开源软件,也许这个开源软件没有任何人使用,但是在实现的这个过程中你会学习到很多,因为实现一个真正的开源软件需要使用到很多编程知识和技巧,这就会驱使你不断去学习这些编程知识和技巧,学会之后能够马上用于实践,真正实践完成以后你对这些编程知识和技巧理解就更深入了。

        我目前就正在做这样一件事情,我选择的是实现一个类似nginx的高性能http服务器。选择这个的理由很简单,我在一个互联网公司,http协议和http服务器经常和我打交道,在架构设计和分布式系统实现的时候可能都需要考虑这些。我开源的地址如下:https://github.com/brucewoo/JHttpServer,如果你也对这个感兴趣可以一起参与,包括设计功能,架构和实现。做这个开源项目的唯一目的就是学习,通过实践的方式来学习。关于这个开源软件的一切我都会以博客或者wiki的方式记录,包括每一个模块实现的原理,考虑,设计等等,可能还有核心代码的解读,争取做第一个学习型的开源软件。虽然这个开源项目没有实际的需求来驱动,但是nginx就是我的目标和超越的对象,当然实现的过程中肯定会借鉴其他很多开源软件的设计思想和编程思维,也会借鉴某一个模块或者功能的实现,或者基于改进。

       说了这么多一点儿也没有和标题扯上关系,今天就是为我这个开源软件写的第一个博客,实现一个高性能的网络服务器的第一个就需要选择一个很好的高性能编程框架,今天就分析这个,这个也算自己开始前的准备,学习高性能服务器编程框架:

      网络服务器的编程步骤就不需要多介绍了,有网络编程知识的都很清楚。首先对网络服务器组成的基本软件模块做一个简单的说明,如下表:

服务器基本软件模块

模块

单机

集群

I/O处理单元

处理客户端连接,读写网络数据

作为介入服务器,实现负载均衡

逻辑单元

业务进程或者线程

逻辑服务器

网络存储单元

本地数据库,文件或者缓存

数据库服务器

请求队列

各单元之间的同学方式

各服务器之间的永久tcp连接

       既然上面提到的第一个模块是IO处理单元,我们就分析和学习一下IO模型,IO处理单元主要处理客户端连接,接收客户端发送过来的数据,还有就是返回服务器返回给客户端的数据。下面还是通过表格的方式展示IO模型,如下:

IO模型

读写操作和阻塞阶段

阻塞

程序阻塞于读写函数

复用

程序阻塞于IO复用系统调用,但可同时监听多个IO事件。对IO本身的读写操作是非阻塞的

SIGIO信号

信号触发读写就绪事件,用户程序执行读写操作,程序没有阻塞阶段

异步

内核执行读写操作并触发读写完成事件,程序没有阻塞阶段。

   下面在说说高效的事件处理模式:

     三类事件,IO事件,信号和定时事件;两种高效的事件处理模式:Reactor和Proactor。

(1)先说说Reactor模式:主线程负责监听文件描述上的事件,然后把事件丢给工作线程处理。下面以epoll模型为例说明处理流程:

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

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

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

         4)工作线程被唤醒,读取客户端数据,处理客户端请求然后往epoll内核事件表中注册socket上的可写就绪事件;

         5)主线程继续调用 epoll_wait等待socket可写事件;

         6)socket可写,epoll_wait通知主线程,主线程放入socket可写事件到请求队列;

         7)工作线程处理可写事件。

(2)再说说Proactor模式:今天已经很晚,改天再下一篇博客继续介绍。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 大数据实战技术之开篇-学习实践环境搭建

    技巅
  • Glusterfs之nfs模块源码分析(中)之Glusterfs实现NFS服务器

    技巅
  • “我“该学习什么技术

    技巅
  • 在ASPNET中使用JS集锦

    (一).确认删除用法: 1. BtnDel.Attributes.Add("onclick","return confirm('"+"确认删除?"+"')")...

    欢醉
  • LeetCode 424. 替换后的最长重复字符(滑动窗口)

    给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。 在执行上述操作后,找到只包含重复字母的最长子串的长度...

    Michael阿明
  • [分享] SDK 2018.3烧写没有DDR的单板的Flash

    但是SDK 2018.3烧写Flash需要一个FSBL。缺省的FSBL,发现没有定义DDR基地址,会直接退出,导致devcfg、QSPI等模块没有初始化,从而导...

    hankfu
  • audio当监听音乐播放完毕,暂停图标如何自动变为播放图标?

    各位大神:audio当监听音乐播放完毕,音乐停止后,暂停图标如何自动变为播放图标?

    用户6456322
  • AQS源码分析之CountDownLatch

    tryAcquireShared方法在调用时只有在state值为0时才会返回1,否则会一直返回-1。

    开发架构二三事
  • Python开发环境—— jupyter Notebook 安装使用

    这篇说一下 Linux 下配置一个 Python 的 jupyter Notebook并可以外网访问进行开发的方法,这样就可以随时轻松的使用 jupyter N...

    李郑
  • [第32期] Set 和 Map 的简单运用

    #242 字母异位词,中午没事看到了这道题,easy 级别的一个题目, 就用了几种方法做了一下, 给大家伙看看。

    用户6900878

扫码关注云+社区

领取腾讯云代金券