Microservices sa C++. Fiction o reyalidad?

Microservices sa C++. Fiction o reyalidad?

Niini nga artikulo maghisgot ako kung giunsa nako paghimo ang usa ka template (cookiecutter) ug gipahimutang ang usa ka palibot alang sa pagsulat sa usa ka serbisyo sa REST API sa C++ gamit ang docker/docker-compose ug ang conan package manager.

Atol sa sunod nga hackathon, diin miapil ko isip backend developer, mitungha ang pangutana kon unsay gamiton sa pagsulat sa sunod nga microservice. Ang tanan nga nasulat hangtod karon gisulat nako ug nako kauban sa Python, tungod kay ang akong kauban usa ka eksperto sa kini nga natad ug propesyonal nga nagpalambo sa mga backend, samtang ako sa kasagaran usa ka embedded system developer ug nagsulat sa maayo ug makalilisang nga C ++, ug bag-o lang ako nakakat-on sa Python sa unibersidad.

Mao nga, nag-atubang kami sa tahas sa pagsulat sa usa ka serbisyo nga adunay taas nga karga, ang panguna nga tahas niini mao ang pag-preprocess sa datos nga moabut niini ug isulat kini sa database. Ug pagkahuman sa us aka us aka smoke break, gisugyot sa usa ka higala nga ako, ingon usa ka developer sa C ++, isulat kini nga serbisyo gamit ang mga pro. Ang paglalis niini mao nga kini mahimong mas paspas, mas produktibo, ug sa kinatibuk-an, ang hurado malipay kung giunsa naton nahibal-an kung giunsa pagdumala ang mga kapanguhaan sa team. Nga ako mitubag nga wala pa ako makahimo sa ingon nga mga butang sa C ++ ug dali nga makagugol sa nahabilin nga 20+ ka oras sa pagpangita, pag-compile ug pag-link sa angay nga mga librarya. Sa yano nga pagkasulti, ako nasuko. Mao kana ang among gidesisyonan ug kalmado nga nahuman ang tanan sa Python.

Karon, sa panahon sa pinugos nga pag-inusara sa kaugalingon, nakahukom ko nga mahibal-an kung giunsa pagsulat ang mga serbisyo sa C ++. Ang unang butang nga buhaton mao ang pagdesisyon sa usa ka angay nga librarya. Ang akong gipili nahulog sa poco, tungod kay kini gisulat sa usa ka object-oriented nga estilo ug gipasigarbo usab ang normal nga dokumentasyon. Usab, mitungha ang pangutana bahin sa pagpili sa sistema sa asembliya. Hangtud niini nga punto nagtrabaho lamang ako sa Visual Studio, IAR ug mga hubo nga makefile. Ug walay bisan usa niini nga mga sistema ang nakadani kanako, tungod kay nagplano ako nga ipadagan ang tibuok serbisyo sa usa ka sudlanan sa pantalan. Unya nakahukom ko nga sulayan nga mahibal-an ang cmake ug usa ka makapaikag nga manager sa package conan. Gitugotan ka sa manager sa package nga irehistro ang tanan nga dependency sa usa ka file

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

[mga generator] cmake

ug sa usa ka yano nga sugo "conan install ." instalar sa gikinahanglan nga mga librarya. Natural, kinahanglan usab nga maghimo mga pagbag-o sa

CMakeLists.txt

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

Pagkahuman niana, nagsugod ako sa pagpangita alang sa usa ka librarya nga magamit sa PostgreSQL, tungod kay kini ang usa nga gamay ra ang akong kasinatian sa pagtrabaho, ug kini usab ang nakig-uban sa among mga serbisyo sa Python. Ug nahibal-an ba nimo kung unsa ang akong nakat-unan? Naa sa POCO! Apan wala mahibal-an ni conan nga naa kini sa POCO ug wala mahibal-an kung giunsa kini pagtukod; adunay usa ka wala’y katapusan nga file sa pag-configure sa repository (nagsulat na ako bahin sa kini nga sayup sa mga nagmugna sa POCO). Kini nagpasabut nga kinahanglan ka mangita alang sa lain nga librarya.

Ug unya ang akong gipili nahulog sa usa ka dili kaayo sikat nga librarya libpg. Ug swerte kaayo ko, naa na sa conan ug gi assemble ug gi assemble.

Ang sunod nga lakang mao ang pagsulat sa usa ka template sa serbisyo nga makaproseso sa mga hangyo.
Kinahanglan natong mapanunod ang atong TemplateServerApp nga klase gikan sa Poco::Util::ServerApplication ug i-override ang main method.

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;
}

Sa panguna nga pamaagi kinahanglan naton itakda ang mga parameter: pantalan, gidaghanon sa mga hilo ug gidak-on sa pila. Ug ang labing hinungdanon, kinahanglan nimong ipiho ang usa ka handler alang sa umaabot nga mga hangyo. Gihimo kini pinaagi sa paghimo og pabrika

TemplateRequestHandlerFactory

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

Sa akong kaso, nagmugna lang kini sa parehas nga handler matag higayon - TemplateServerAppHandler. Dinhi atong ibutang ang atong lohika sa negosyo.

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();
    }
};

Naghimo usab ako usa ka template sa klase aron magamit sa PostgreSQL. Aron mahimo ang yano nga SQL, sama sa paghimo sa usa ka lamesa, adunay usa ka pamaagi ExecuteSQL(). Alang sa labi ka komplikado nga mga pangutana o pagkuha sa datos, kinahanglan nimo nga makakuha usa ka koneksyon pinaagi sa GetConnection() ug gamita ang libpg API. (Basin sa ulahi akong tul-iron kining inhustisya).

database

#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;
};

Ang tanan nga mga parameter alang sa pagkonektar sa database gikuha gikan sa palibot, mao nga kinahanglan nimo usab nga maghimo ug i-configure ang .env file

.env

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

Makita nimo ang tanan nga code sa github.

Microservices sa C++. Fiction o reyalidad?

Ug karon moabut na ang katapusang yugto sa pagsulat sa dockerfile ug docker-compose.yml. Sa pagkamatinud-anon, kini nagkinahanglan sa kadaghanan sa panahon, ug dili lamang tungod kay ako usa ka noob, tungod kay kini gikinahanglan sa pagtukod pag-usab sa mga librarya sa matag higayon, apan tungod sa mga lit-ag sa conan. Pananglitan, aron ma-download, ma-install ug matukod ni conan ang kinahanglan nga mga dependency, dili igo nga i-download ang "conan install.", kinahanglan usab nga ipasa ang -s compiler.libcxx=libstdc++11 parameter, kung dili. nameligro ka nga makakuha og daghang mga sayup sa yugto sa pag-link sa imong aplikasyon. Gipugngan ko kini nga sayup sa daghang oras ug nanghinaut ko nga kini nga artikulo makatabang sa ubang mga tawo nga masulbad kini nga problema sa gamay nga oras.

Sunod, pagkahuman sa pagsulat sa docker-compose.yml, sa tambag sa akong higala, gidugang nako ang suporta tigputol sa biskwit ug karon mahimo nimong makuha ang imong kaugalingon nga usa ka hingpit nga template alang sa usa ka serbisyo sa REST API sa C++, nga adunay usa ka naandan nga palibot, ug na-install ang PostgreSQL, pinaagi lamang sa pagsulod sa "cookiecutter" sa console https://github.com/KovalevVasiliy/cpp_rest_api_template.git" Ug dayon "docker-compose up -build".

Nanghinaut ko nga kini nga template makatabang sa mga nagsugod sa ilang lisud nga dalan sa pagpalambo sa REST API nga mga aplikasyon sa maayo ug gamhanan, apan ang ingon nga clumsy nga pinulongan sama sa C++.
Usab, girekomenda ko kaayo ang pagbasa dinhi kini artikulo. Gipatin-aw niini sa mas detalyado kung giunsa ang pagtrabaho sa POCO ug pagsulat sa imong kaugalingon nga serbisyo sa REST API.

Source: www.habr.com

Idugang sa usa ka comment