论坛首页 编程语言技术论坛

探讨一下web服务器的设计,有没有更好的设计方法

浏览 6291 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-23  
C

在学习 Linux编程方面,最近我写了一个 web服务器程序,使用 linux下的纯 c写的, web服务器能基本实现动态服务请求和静态服务请求。但是我总觉得我的设计不是很好,下面我说一说我的设计,你们看看有没有什么更好的设计。

web服务器的静态服务请求的实现使用的是线程池,由主线程统一获得连接请求,然后将已连接描述符压到一个缓冲区中,线程池中的空闲线程从缓冲区中获得描述符(这里使用互斥量维持线程间的同步),如果发现是静态的请求,就直接回应请求,如果是动态请求,就将描述符压到另一个缓冲区中。

这里有一个线程,和一个进程池共同来服务动态请求。这个线程使用i/o 复用和进程通信,发现进程有空闲的就将缓冲区中的动态请求的描述符发送给这个进程,因此这个线程主要作为进程的调度。

进程通过生成一个子进程,调用服务器目录中的cgi 程序来服务动态请求。

虽然程序已经编出来了,但是我总感觉程序太复杂,为了实现两个简简单单的功能( 动态服务和静态服务) ,居然要使用如此多的复杂的技术。之所以使用线程,是因为他在性能方面高于进程,之所以使用线程池,是因为这样能减少后期生成线程的性能影响。之所以又使用进程,是因为我还不知道如何使用线程来服务动态请求。

我问过几个老师,但可能他们的方向没有在这里,因此都没有提出多少可行的建议。我总感觉这个设计方法不是很好,一定会有很多需要改进的地方,比如在设计复杂度上需要改进,比如在描述符的共享上会有更好的设计,等等。我也不知道apache 的设计是怎样的,希望大家讨论给点指点,非常感谢

   发表时间:2007-06-24  
关于使用线程池实现 web server ,可以对照一下
http://iunknown.iteye.com/blog/78561

关于 apache 提供的不同 MPM 模块,可以参考

http://blog.csdn.net/tingya/archive/2006/08/09/1040799.aspx

http://blog.csdn.net/tingya/archive/2006/08/28/1133825.aspx

http://blog.csdn.net/tingya/archive/2006/08/28/1133836.aspx

Apache中预创建Preforking MPM 机制剖析
0 请登录后投票
   发表时间:2007-07-03  
我在圈子里提了这个问题。http://cpp-circle.group.iteye.com/group/topic/1823
然后你如下回复。
xombat 写道
自己写? 我也用c语言写过web服务器,你那个问题我解决过,就是sigpipe信号的处理问题。

我没看你的代码,不知道你的服务器是怎么设计的,我可以说一说我的服务器设计,我总觉得不好,太过复杂,大家可以商讨商讨。

索性写了一篇博客,设计就在这里了:
http://xombat.iteye.com/admin/show/93518

我就来了。
0 请登录后投票
   发表时间:2007-07-03  
说实话,看了你的关于这个讨论。我觉得我没有到你的层次。至少我都不晓得你这得动态请求和静态请求都是什么。我现在做的只是一个简单的socket通信。因为要把一台服务器的的数据分散到几台服务器上。所以,才开始做这个东西的。我实现的东西比较简单:1个Thread,一直在accept,一旦accept成功,则把socket加入到一个序列中。然后一堆的线程去不停的访问这个序列。有东西,则拿出来,然后作相应的处理。原理就是这么简单。没有用到socket池。线程池也没有用到。只是一个线程数组而已。下一步,就是想做成socket池的。然后想采用你说的io复用。说来惭愧,查了n多资料。至今对io复用也没有一个完整的认识。也不知道什么是io复用。不知道你能否说一下。如果能有一个小demo,那就更好。嘻嘻。没想到到头来变成要代码的了。惭愧啊,惭愧!
0 请登录后投票
   发表时间:2007-07-03  
引用
然后一堆的线程去不停的访问这个序列。
这堆线程是哪里来的?预先创建的话,这些线程就组成了线程池。

socket池这个名词我也没接触过。
用c语言写的东西,即使你实现了一个功能我也不知道它能对上哪个名词,当时实现线程池的时候,我自己给他选了个名字,叫预线程,因为是预先生成一堆线程,让老师看的时候这把老师给弄懵了,我说了说原理,老师说这不就是线程池嘛。

io复用:
假如要编写一个特殊的服务器,它既要对网络客户端的请求作出反应,又要对用户从标准输入端的交互命令作出反应,怎么办呢?如果先等待前者,后者就不会被响应,反之又会影响前者的响应。io复用就可以解决这个问题,它使用select函数,要求内河挂起进程,当有一个或多个i/o事件发生时,才将控制权返回给应用进程,同时通知应用程序准备好的描述符集合。
0 请登录后投票
   发表时间:2007-07-04  

这堆线程是哪里来的?预先创建的话,这些线程就组成了线程池。

我说了。我只是做了一个线程数组而已。这个离一个线程池还有很远的距离。一个线程池至少要能管理这堆线程,包括运行,挂起,休眠,中断等等。而我的却很简单。这个数组里面的线程一直都活着。每次都去任务队列里面取任务。没有取到就休眠一段时间。然后再取。取到即工作。
关于IO复用。我看了你的说明。然后又找了点资料。发现是自己把问题想错了。我把非阻塞的socket误当成是io复用。
然后,查了些资料。发现,对于select函数。效率不是很高。因为是采用轮询的方式来判断。现在很多人都推荐使用epoll。
我想,我离实现web服务器应该还有段距离。首先,工作重心不在这。然后,目前空闲时间也不多。等我把这段时间的工作搞定,我再研究下。到时候,跟你讨论。
0 请登录后投票
   发表时间:2007-07-04  
上面发贴格式错了,删了吧。
我重发。

引用

这堆线程是哪里来的?预先创建的话,这些线程就组成了线程池。

我说了。我只是做了一个线程数组而已。这个离一个线程池还有很远的距离。一个线程池至少要能管理这堆线程,包括运行,挂起,休眠,中断等等。而我的却很简单。这个数组里面的线程一直都活着。每次都去任务队列里面取任务。没有取到就休眠一段时间。然后再取。取到即工作。
关于IO复用。我看了你的说明。然后又找了点资料。发现是自己把问题想错了。我把非阻塞的socket误当成是io复用。
然后,查了些资料。发现,对于select函数。效率不是很高。因为是采用轮询的方式来判断。现在很多人都推荐使用epoll。
我想,我离实现web服务器应该还有段距离。首先,工作重心不在这。然后,目前空闲时间也不多。等我把这段时间的工作搞定,我再研究下。到时候,跟你讨论。
0 请登录后投票
   发表时间:2007-07-25  
恩 楼上的想法 跟我差不多 而且我正在想一个socks5 server的实现。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics