用C/C++编写的高性能应用Web服务器

44

是否有高性能(最好是事件驱动和开源的)C或C++网络服务器?

我希望能够在我的应用程序中调用填充了HTTP请求类/结构的方法/函数,然后我可以返回填充了HTTP响应类/结构的内容。

如果它不是开源的,我需要内置支持长轮询连接、保持活动状态等功能,否则,我认为我可以自己添加这些内容。

如果您不知道是否有可用的此类服务器,您会建议我编写自己的Web服务器以适合任务吗?它不能基于文件,并且必须使用高性能的C/C++编写。


编辑:我正在考虑像Ruby Mongrel一样的C版本,如果这有助于解释。


1
ajax: fastcgi++. websockets: websocket++ ajax:fastcgi++。websockets:websocket++。 - user1382306
我认为你需要的是一个http服务器库,而不是一个独立的服务器。 - haneefmubarak
5个回答

70

我对工作有非常相似的要求,所以我评估了许多解决方案:mongoose、libmicrohttpd和libevent。我还考虑编写nginx模块。以下是我的发现总结:

nginx

nginx项目页面

我非常喜欢这个服务器并经常使用它。它的性能和资源使用比Apache要好得多,虽然我仍然使用Apache但计划迁移到nginx。

  • 非常出色的可调节性能。丰富的功能。易移植性。
  • 模块API没有文档,并且似乎非常冗长。参见nginx hello world module
  • Nginx不使用线程而使用多个进程。这使得编写模块更加困难,需要学习nginx API来进行共享内存等操作。

mongoose

mongoose项目页面

  • 所有服务器代码都在单个mongoose.c文件中(约130K),没有依赖项,这很好。
  • 每个连接一个线程,因此如果需要并发,必须配置大量线程,即高RAM使用率,这不太好。
  • 性能良好,虽然不是特别突出。
  • API很简单,但必须自己组合所有响应的HTTP头,即详细了解HTTP协议。

libmicrohttpd

libmicrohttpd项目页面

  • 官方GNU项目。
  • API冗长,对我来说似乎很奇怪,尽管比编写nginx模块要简单得多。
  • 在保持连接模式下表现良好(链接到我的基准测试下面),没有保持连接模式性能不太好。

libevent

libevent项目页面

Libevent库内置了名为evhttp的Web服务器。

  • 事件驱动,使用libevent实现。
  • 易于使用API。自动构建HTTP头部。
  • 官方是单线程的,这是一个主要的劣势。我发现了一个技巧,可以使几个evhttp实例同时运行并从同一套接字接受连接。不确定它是否安全和稳健。
  • 单线程evhttp的性能出乎意料的差。多线程hack效果更好,但仍然不好。

G-WAN

G-WAN项目不是开源的,但我想说几句话。

  • 非常好的性能,低内存占用,150 KB可执行文件。
  • 非常方便的“servlet”部署:只需将.c文件复制到csp目录中,运行服务器会自动编译它。代码修改也会即时编译。
  • 简单的API。虽然在某些方面受限,但功能丰富(json,key-value store等)。
  • 不稳定。我在静态文件上遇到过段错误。在一些样例脚本上挂起。(在干净的安装上经验丰富。从未混合不同版本的文件)。
  • 只有32位二进制(现在不再是这样了)。

因此,正如您所看到的,目前没有一个替代方案完全满足我的需求。于是我开发了自己的服务器,它是...

NXWEB

NXWEB项目页面

主要功能:

  • 非常好的性能;请参阅项目页面上的基准测试结果。
  • 可以处理数万个并发请求。
  • 小内存占用。
  • 多线程模型,旨在扩展。
  • 异常轻的代码库。
  • 简单的API。
  • 良好的HTTP协议处理。
  • 保持连接。
  • SSL支持(通过GNUTLS)。
  • HTTP代理(带有保持活动连接池)。
  • 非阻塞 sendfile 支持(带有可配置的小文件内存缓存;gzip 预编码文件服务)
  • 面向开发者的模块化设计
  • 可作为守护进程运行,并在出现错误时自动重新启动
  • 开源
  • 限制:

    • 依赖 libev 库(不再需要)
    • 只在 Linux 上进行过测试

    2
    NXWeb的基准测试并不是非常严格:G-WAN只占用了105 MB的内存?(这在3年时间里从未见过)NXWeb受益于req/s范围,而其他人只有一个值?尝试使用1-1000并发范围,而不是一次性并发,这将使您的测试更具相关性。如果您的项目很好,那么说其他项目崩溃或不稳定,这是很严重的,它不需要冒着这种卑劣行径的风险。 - Gil
    2
    这里有图表:http://gwan.com/imgs/nxweb_3.0.1_100k.png 和 http://gwan.com/imgs/localhost_gwan2.10.8.png,胜者是... G-WAN(在速度、CPU和RAM方面)- 而不是像上面所宣传的nxWeb。Yaroslav,这是测试的源代码:http://gwan.com/source/ab.c,我尊重你的工作,请对G-WAN做同样的事情。nxWEB仍有改进的空间,以匹配G-WAN的性能。 - Gil
    3
    关于基准测试:我认为这不是讨论的合适场所。在这篇文章中,我没有说nxweb比g-wan更快,因此你的论点似乎不相关。我建议在这里讨论:https://groups.google.com/forum/?hl=en&fromgroups#!topic/nxweb/hA7b4v2hVdE - Yaroslav Stavnichiy
    1
    关于nxweb的线程安全性:您能否向问题跟踪器提交错误报告。通常,模块代码的线程安全性是模块的责任。再次强调,这不是讨论它的正确场所。 - Yaroslav Stavnichiy
    显示剩余2条评论

    7

    我建议编写一个FastCGI可执行文件,可以与许多高性能Web服务器(甚至是闭源的)一起使用。


    我不喜欢FastCGI的一件事是,你最终需要每个基本HTTP请求两个套接字,而通常情况下,这会变成3个套接字,因为还要连接数据库。 - Aaron Yodaiken
    1
    IPC套接字真的是可扩展性问题吗?我不这么认为。TCP/IP协议栈并没有用于此。 - Axel Gneiting
    如果您有效地管理资源(就像fastCGI可以做的那样),则不需要为每个请求打开/关闭后端套接字。 - symcbean

    4
    我建议与Axel Gneiting相同的做法 - 但是我提供了我的原因,以采取这种方法:
    1)HTTP作为协议并不简单 - 编写自己的服务器或修改现有解决方案是非常复杂的任务 - 比使用可用的API实现单独的处理引擎要复杂得多。
    2)使用(未修改的)主流Web服务器应该为您提供比您需要的更多功能(因此您有增长空间)。
    3)使用(未修改的)主流Web服务器通常意味着其已经得到了比自制系统更广泛的测试和记录。
    4)..它更可能是安全和稳定的。
    5)使用fastCGI,您可以使用各种语言来开发后端处理,包括C++和C。有可用的标准工具包来促进这一点。
    6)或者,许多Web服务器提供支持在进程中运行解释器引擎的支持(例如mod_php,mod_perl)。虽然我不建议将自己的本机代码作为模块运行。
    “它不能基于文件。”这是什么意思?

    我不希望服务器的想法是,请求URI为/my/something,然后找到文件something - 你可以在Apache中使用.htaccess来解决这个问题,但这很丑陋,我宁愿不这样做。我希望服务器在准备好时直接调用我的函数。 - Aaron Yodaiken
    Re模块 - 请参见上面的3和4。Re文件引用 - 然后将文档根目录设置为空目录。 - symcbean

    4

    mongoose: 一款文件简单易用的数据库。虽不支持异步 I/O,但非常适合嵌入式和特定目的。

    gwan:优秀且稳定,没有崩溃记录,配置超级好。相比 Nginx,它有一个非常聪明、干净、易于 C/C++ 开发的 API。提供每核一个线程或您指定的任何线程。是一个很好的选择。最大的缺点(也许是我的不足):不能通过代码进行调试。

    libevent:单线程对于单核机器来说不是缺点。毕竟它的重点是异步 I/O。同时也可以为其他核心使用多线程。

    nginx:没有个人经验。但在 a-patchy 服务器上获得了严肃的地位。(API 非常混乱)

    boost asio:一个用于异步 I/O 的 C++ 库(asio)。非常棒。需要一个友好的高级 API,以方便像我这样的新手和其他从 PHP、Java、JavaScript、Node.js 和其他 Web 语言转换而来的开发者。

    Python Bottle:一个非常棒的一体化库(框架/系统),使构建 Python Web 应用程序变得容易。它内置了 HTTPD 服务器,就像 libevent 和 Node.js 一样。

    Node.js:JavaScript 异步 I/O 服务器。是一个非常好的选择。不幸的是,必须使用 JavaScript 进行编程,这会变得很繁琐。虽然完成工作的重要性不言而喻,但在过程中享受自己也同样重要。希望没有人会推出 Node.php。


    2
    看看libuv和http-parser,这是node.js的C库。 - pcunite
    1
    看看 civetweb,它是 mongoose 的 MIT 许可版本。 - gbjbaanb

    3
    我是一名热衷于使用nginx的用户;nginx是用C语言编写的;nginx似乎很适合您的需求。如果您想要最快的速度,我建议您制作一个nginx模块。这里有第三方模块,您可以查看以了解所需内容。
    至于长轮询需求,您可能需要查看http推送模块。

    nginx 模块 API 会有多频繁地更改?(自从主要指南编写以来,它似乎至少已经更改了一次。) - Aaron Yodaiken
    虽然我自己没有编写任何模块的需要,但据我所知,模块 API 应该是相当稳定的。如果有更改,我怀疑作者不会没有充分理由就进行破坏性更改。 - pcting
    1
    这是一个关于 Nginx 模块开发的不错指南:http://www.evanmiller.org/nginx-modules-guide.html - pcting

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接