创建 C++ 应用程序以与 Nginx 通信的最佳方法

Posted

技术标签:

【中文标题】创建 C++ 应用程序以与 Nginx 通信的最佳方法【英文标题】:Best method to create a c++ app to communicate with nginx 【发布时间】:2012-02-23 10:15:40 【问题描述】:

我需要编写一个 C++ 接口,它可以读取我们的数据结构并使用 http 协议提供基于查询的 o/p。

服务器需求 它应该能够同时为 100 个客户提供服务。

为什么选择 C++ 所有代码都已经用 C++ 编写。所以我们只需要用 C++ 编写一个 http 层。这就是我选择 C++ 而不是更传统的 Web 编程语言的原因。

我正在考虑使用 nginx 来提供静态文件并使用它的代理通行证与 C++ 进行通信。

我发现了两种方法:

编写一个 FastCGI c++ 模块。

编写一个 node.js c++ 模块。

如果您有任何其他建议,请提出

您能否根据以往的经验列出每种方法的优缺点?

【问题讨论】:

您可能想要更改问题的措辞。哪一个是“最好的”可能会涉及很多意见。 您说“同时有 100 个客户”。您真的需要 100 个连接重叠,还是在寻找一些特定的吞吐量(例如每秒 100 个“事务”)?如果您的连接很长(与通常较短的 HTTP 周期相比),这可能会对答案产生很大影响。 好的,我正在考虑问题的标题。如果找到会改变它,你能推荐一个吗? 我建议更改最后一句而不是标题。您可以将其更改为“您能否根据先前的经验列出每种方法的优缺点”或类似的内容。只要确保它看起来像是对事实的需求,而不是意见。 我将同时连接 100 个客户端。每秒触发 2-3 个查询。每个查询将需要 20-200 毫秒的响应时间。 (不包括http服务器响应时间) 【参考方案1】:

这里似乎没有人解决实际问题,尽管已经提供了一些不错的解决方法。我已经能够为 nginx 构建 C++ 模块,只需进行一些小的更改。

    将模块源文件名更改为以.cpp 结尾,以便 gcc 意识到它正在处理 C++。 确保您的所有 Nginx 包含(例如ngx_config.hngx_core.h 等)都用extern "C" 结构包裹。同样,确保通过 Nginx 函数指针调用的任何函数都使用包装器声明。 在设置 Nginx 时将 --with-ld-opt="-lstdc++" 添加到您的“配置”调用中。

通过这三个步骤,您的模块应该可以编译、构建、链接并实际工作。

【讨论】:

克里斯托弗,你有一个简单的骨架吗?只是好奇 您已经解决了这个问题,但没有任何代码示例:)【参考方案2】:

我想我会继续推进 Nginx 模块开发http://www.evanmiller.org/nginx-modules-guide.html

为什么?

    它不需要任何其他库依赖项,例如 fastcgi 和 其他。 我可以在我的模块中使用 nginx 的所有功能。

【讨论】:

你是怎么理解这个的? @Homer6 我选择 nginx 模块进行开发的唯一原因是,我不需要任何第三个库。 听起来不错。只是想知道你是否成功了。如果是这样,我可能会按照您的路径自己编写模块。您对他们的模块 API 的总体印象如何? 这更直接。 nutrun.com/weblog/2009/08/15/hello-world-nginx-module.html【参考方案3】:

您要问的基本上是如何将保存数据结构的 c++ 进程转变为网络服务器。这可能不是最好的方法。 (话又说回来,也许是你的情况。这取决于我想你试图公开的 c++ 进程接口的复杂性。)

无论如何,我会尝试在 c++ 进程和可以执行 http 工作并使用一些简单的消息传递协议(如 ZeroMQ/zmq)与 c++ 后端进程通信的客户端之间插入一个小型 http 前端。

zmq 在 c/c++ 中是相当直接的,而且它非常高效和快速。使用 zmq,您可以非常快速地在 python 或任何您喜欢的具有zmq bindings 的语言中设置一个简单的网络服务器前端,并让该前端使用 zmq 与后端 c++ 进程异步或同步通信。

如果您正在考虑使用 zmq,c++ examples 和 the guide 是不错的起点。

对于 Node.js,也有 a few examples。

【讨论】:

为什么要在 python 中编写一个网络服务器并使用套接字连接到它,而您只需将套接字添加到您的主应用程序并自己提供 http 服务?【参考方案4】:

试试 G-WAN,它可以让你直接使用你的 c++ 应用程序。

【讨论】:

如果您的回答没有为已经接受的答案添加任何内容,则不应回答旧问题。 IMO,总是有助于查看更多替代方案。【参考方案5】:

你可以试试nginx c function

使用简单,应用层内置nginx缓存,wiki for nginx c function

Example project with cpp

示例代码:

#include <stdio.h>
#include <ngx_http_c_func_module.h>

/*** build the program as .so library and copy to the preferred place for nginx to link this library ***/
/*** gcc -shared -o libcfuntest.so -fPIC cfuntest.c ***/
/*** cp libcfuntest.so /etc/nginx/ ***/

int is_service_on = 0;

void ngx_http_c_func_init(ngx_http_c_func_ctx_t* ctx) 
    ngx_http_c_func_log(info, ctx, "%s", "Starting The Application");


    is_service_on=1;




void my_app_simple_get_greeting(ngx_http_c_func_ctx_t *ctx) 
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get");

    ngx_http_c_func_write_resp(
        ctx,
        200,
        "200 OK",
        "text/plain",
        "greeting from ngx_http_c_func testing"
    );


void my_app_simple_get_args(ngx_http_c_func_ctx_t *ctx) 
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_args");

    ngx_http_c_func_write_resp(
        ctx,
        200,
        "200 OK",
        "text/plain",
        ctx->req_args
    );


void my_app_simple_get_token_args(ngx_http_c_func_ctx_t *ctx) 
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_token_args");

    char * tokenArgs = ngx_http_c_func_get_query_param(ctx, "token");
    if (! tokenArgs) 
        ngx_http_c_func_write_resp(
            ctx,
            401,
            "401 unauthorized",
            "text/plain",
            "Token Not Found"
        );
     else 
        ngx_http_c_func_write_resp(
            ctx,
            401,
            "401 unauthorized",
            "text/plain",
            tokenArgs
        );
    


void my_app_simple_post(ngx_http_c_func_ctx_t *ctx) 
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_post");

    ngx_http_c_func_write_resp(
        ctx,
        202,
        "202 Accepted and Processing",
        "text/plain",
        ctx->req_body
    );




void my_app_simple_get_no_resp(ngx_http_c_func_ctx_t *ctx) 
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_no_resp");




void ngx_http_c_func_exit(ngx_http_c_func_ctx_t* ctx) 
    ngx_http_c_func_log(info, ctx, "%s\n", "Shutting down The Application");

    is_service_on = 0;

【讨论】:

【参考方案6】:

只需将 HTTP 前端添加到您的 C++ 代码中,可能使用 Beast 等库,然后从 nginx 到您的 C++ 服务器的 proxy_pass。根据您的使用情况,您可能需要也可能根本不需要 nginx。

【讨论】:

以上是关于创建 C++ 应用程序以与 Nginx 通信的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

以与数据库无关的方式构建查询

Django+uwsgi+Nginx上线最佳实战

在硬件上 C++ 和 Python 之间进行通信的最佳方式是啥? [关闭]

跨页面存储会话数据最佳实践

为啥我不能让我的 RN 应用程序在本地运行以与本地 api 服务器通信?

将 javascript 连接到 php 套接字以与 Flash 通信