C ++中的微服务。小说还是现实?



在本文中,我将讨论如何创建一个cookiecutter,以及如何使用docker / docker-compose和conan软件包管理器来设置使用C ++编写REST API服务的环境。


在我作为后端开发人员参加的下一次黑客马拉松中,出现了关于编写下一个微服务的内容的问题。此刻编写的所有内容都是由我和我的朋友使用Python 编写的,因为我的同事是该领域的专家,并且专业从事后端的开发,而我通常是嵌入式系统的开发人员,并且使用出色的C语言编写++,而Python刚在大学学习。


因此,我们面临着编写一个高负载服务的任务,该服务的主要任务是预处理进入该服务的数据并将其写入数据库。在又一次抽烟之后,一个朋友建议我,作为C ++开发人员,请在附加代码上编写此服务。将其与这样的事实相提并论,那就是它将更快,更富有成效,而事实上,陪审团将对我们如何管理团队资源感到高兴。我回答说,我从未在C ++中做过这些事情,我可以轻松地将剩下的20多个小时专门用于查找,编译和链接合适的库。简单地说,我很害怕。这就是他们的决定,并平静地将所有内容添加到Python。


, , ++. , , . POCO, - , . , . Visual Studio, IAR «» makefile. , docker-. cmake conan.

conanfile.txt
[requires]
poco/1.9.3
libpq/11.5

[generators]
cmake

并使用简单的命令“ conan install”。安装必要的库。当然,在

CMakeLists.txt
include(build/conanbuildinfo.cmake)
conan_basic_setup()
target_link_libraries(<target_name> ${CONAN_LIBS})

在那之后,我开始寻找一个可以与PostgreSQL一起使用的库,因为我对库的了解很少,而Python服务也正是与之交互的。你知道我发现了什么吗?她在POCO!但是柯南不知道它在POCO中,也不知道如何构建它,过时的配置文件在存储库中(我已经将这个错误写给了POCO的创建者)。因此,您必须寻找另一个库。

然后我的选择落在了不太流行的libpg库上我非常幸运,她已经在柯南,甚至在集会。

下一步是编写可以处理请求的服务模板。
我们必须从Poco :: Util :: ServerApplication继承我们的TemplateServerApp类,并重写main方法。

TemplateServerApp
#pragma once

#include <string>
#include <vector>
#include <Poco/Util/ServerApplication.h>

class TemplateServerApp : public Poco::Util::ServerApplication
{
    protected:
        int main(const std::vector<std::string> &);
};

int TemplateServerApp::main(const vector<string> &)
{
    HTTPServerParams* pParams = new HTTPServerParams;

    pParams->setMaxQueued(100);
    pParams->setMaxThreads(16);

    HTTPServer s(new TemplateRequestHandlerFactory, ServerSocket(8000), pParams);

    s.start();
    cerr << "Server started" << endl;

    waitForTerminationRequest();  // wait for CTRL-C or kill

    cerr << "Shutting down..." << endl;
    s.stop();

    return Application::EXIT_OK;
}


在main方法中,我们必须设置参数:端口,线程数和队列大小。最重要的是,您必须指定一个传入的请求处理程序。这是通过创建工厂来完成的。

TemplateRequestHandlerFactory
class TemplateRequestHandlerFactory : public HTTPRequestHandlerFactory
{
public:
    virtual HTTPRequestHandler* createRequestHandler(const HTTPServerRequest & request)
    {
        return new TemplateServerAppHandler;
    }
};


就我而言,它每次都会创建相同的处理程序-TemplateServerAppHandler。我们可以在这里定位业务逻辑。

TemplateServerAppHandler
class TemplateServerAppHandler : public HTTPRequestHandler
{
public:
    void handleRequest(HTTPServerRequest &req, HTTPServerResponse &resp)
    {
        URI uri(req.getURI());
        string method = req.getMethod();

        cerr << "URI: " << uri.toString() << endl;
        cerr << "Method: " << req.getMethod() << endl;

        StringTokenizer tokenizer(uri.getPath(), "/", StringTokenizer::TOK_TRIM);
        HTMLForm form(req,req.stream());

        if(!method.compare("POST"))
        {
            cerr << "POST" << endl;
        }
        else if(!method.compare("PUT"))
        {
            cerr << "PUT" << endl;
        }
        else if(!method.compare("DELETE"))
        {
            cerr << "DELETE" << endl;
        }

        resp.setStatus(HTTPResponse::HTTP_OK);
        resp.setContentType("application/json");
        ostream& out = resp.send();

        out << "{\"hello\":\"heh\"}" << endl;
        out.flush();
    }
};

我还创建了一个用于PostgreSQL的类模板。为了执行简单的SQL(例如创建表),有一个ExecuteSQL()方法对于更复杂的查询或数据检索,您将必须通过GetConnection()获得连接并使用libpg API。(也许那我会纠正这种不公正)。

数据库
#pragma once

#include <memory>
#include <mutex>
#include <libpq-fe.h>

class Database
{
public:
    Database();
    std::shared_ptr<PGconn> GetConnection() const;
    bool ExecuteSQL(const std::string& sql);

private:
    void establish_connection();
    void LoadEnvVariables();

    std::string m_dbhost;
    int         m_dbport;
    std::string m_dbname;
    std::string m_dbuser;
    std::string m_dbpass;

    std::shared_ptr<PGconn>  m_connection;
};

用于连接数据库的所有参数均来自环境,因此您还需要创建和配置.env文件。

.env
DATABASE_NAME=template
DATABASE_USER=user
DATABASE_PASSWORD=password
DATABASE_HOST=postgres
DATABASE_PORT=5432


您可以在github上看到所有代码



dockerfile docker-compose.yml. , , , , , - conan. , , conan , , «conan install .», -s compiler.libcxx=libstdc++11, . , , .


, docker-compose.yml, cookiecutter REST API ++, c , PostgreSQL, «cookiecutter https://github.com/KovalevVasiliy/cpp_rest_api_template.git». «docker-compose up --build».


, REST API , , ++.
, . POCO REST API .


All Articles