Mikroservicer an C++. Fiktioun oder Realitéit?

Mikroservicer an C++. Fiktioun oder Realitéit?

An dësem Artikel wäert ech schwätzen iwwer wéi ech eng Schabloun (CookieCutter) erstallt hunn an en Ëmfeld opgeriicht hunn fir e REST API Service an C ++ ze schreiwen mat Docker / Docker-compose an dem Conan Package Manager.

Wärend dem nächsten Hackathon, un deem ech als Backend-Entwéckler deelgeholl hunn, ass d'Fro opgestan iwwer wat fir de nächste Mikroservice ze schreiwen. Alles wat bis elo geschriwwen ass gouf vu mir a mengem Kamerad am Python, well mäi Kolleg war en Expert an dësem Beräich a berufflech entwéckelt backends, iwwerdeems ech war allgemeng en embedded System Entwéckler an geschriwwen am groussen a schrecklechen C ++, an ech geléiert just Python op der Uni.

Also ware mir mat der Aufgab konfrontéiert fir en High-load-Service ze schreiwen, d'Haaptaufgab vun deem war d'Donnéeën ze preparéieren, déi dohinner kommen an se an d'Datebank schreiwen. An no enger anerer Rauchpaus huet e Frënd proposéiert datt ech als C++ Entwéckler dëse Service mat de Profien schreiwen. Argumentéiert dëst ass datt et méi séier, méi produktiv wäert sinn, an allgemeng wäert d'Jury frou sinn wéi mir wësse wéi d'Ressourcen vum Team verwalten. Op déi ech geäntwert hunn, datt ech nach ni sou Saachen am C++ gemaach hunn an déi reschtlech 20+ Stonnen ganz einfach fir d'Sich, d'Zesummesetzung an d'Verknëppung vun passenden Bibliothéike kéint widmen. Einfach gesot, ech hu gehackt. Dat ass wat mir decidéiert hunn a roueg alles am Python ofgeschloss hunn.

Elo, wärend der gezwongener Selbstisolatioun, hunn ech beschloss erauszefannen wéi ech Servicer an C++ schreiwen. Déi éischt Saach ze maachen war decidéieren op eng gëeegent Bibliothéik. Mäi Choix gefall op POCO, well et an engem objektorientéierte Stil geschriwwe gouf an och mat normaler Dokumentatioun geprägt ass. Och ass d'Fro opgestan iwwer d'Auswiel vun engem Montagesystem. Bis zu dësem Zäitpunkt hunn ech nëmme mat Visual Studio, IAR a bare Makefiles geschafft. A keng vun dëse Systemer huet mech ugedoen, well ech geplangt hunn de ganze Service an engem Docker Container ze lafen. Dunn hunn ech beschloss ze probéieren cmake erauszefannen an en interessante Package Manager conan. Dëse Package Manager erlaabt Iech all Ofhängegkeeten an enger Datei anzeschreiwen

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

[Generateuren] cmake

a mat engem einfachen Kommando "conan installéieren." installéiert déi néideg Bibliothéiken. Et war natierlech och néideg Ännerungen ze maachen

CMakeLists.txt

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

Duerno hunn ech ugefaang no enger Bibliothéik ze sichen fir mat PostgreSQL ze schaffen, well et war dee mat deem ech wéineg Erfahrung hat mat ze schaffen, an et war och deen mat eise Python-Servicer interagéiert. A wësst Dir wat ech geléiert hunn? Et ass am POCO! Awer de Conan weess net datt et am POCO ass a weess net wéi et ze bauen; et gëtt eng verännert Konfiguratiounsdatei am Repository (ech hu schonn iwwer dëse Feeler un d'Creatoren vu POCO geschriwwen). Dëst bedeit datt Dir eng aner Bibliothéik muss sichen.

An dunn ass mäi Choix op eng manner populär Bibliothéik gefall libpg. An ech hat onheemlech Gléck, et war schonn am Conan a gouf souguer montéiert a montéiert.

De nächste Schrëtt war eng Service Template ze schreiwen déi Ufroe veraarbecht kann.
Mir mussen eis TemplateServerApp Klass vun Poco::Util::ServerApplication ierwen an d'Haaptmethod iwwerschreiden.

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

An der Haaptmethod musse mir d'Parameteren setzen: Port, Unzuel vun thread an der Schlaanggréisst. A virun allem musst Dir en Handler fir erakommen Ufroe spezifizéieren. Dëst gëtt gemaach andeems Dir eng Fabréck kreéiert

TemplateRequestHandlerFactory

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

A mengem Fall erstellt et einfach all Kéier dee selwechten Handler - TemplateServerAppHandler. Dëst ass wou mir eis Geschäftslogik kënne placéieren.

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

Ech hunn och eng Klass Schabloun erstallt fir mat PostgreSQL ze schaffen. Fir einfach SQL auszeféieren, sou wéi en Dësch erstellen, gëtt et eng Method ExecuteSQL(). Fir méi komplex Ufroen oder Daten Erhuelung, musst Dir eng Verbindung iwwer kréien GetConnection() a benotzt d'libpg API. (Vläicht wäert ech spéider dës Ongerechtegkeet korrigéieren).

Datebank

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

All Parameter fir d'Verbindung mat der Datebank ginn aus der Ëmwelt geholl, also musst Dir och d'.env Datei erstellen an konfiguréieren

.NS

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

Dir kënnt all Code gesinn op github.

Mikroservicer an C++. Fiktioun oder Realitéit?

An elo kënnt déi lescht Etapp vum Schreiwen vun der dockerfile an docker-compose.yml. Fir éierlech ze sinn, huet dëst déi meescht Zäit gedauert, an net nëmme well ech en Noob sinn, well et all Kéier néideg war fir d'Bibliothéiken opzebauen, mee wéinst de Falen vum Conan. Zum Beispill, fir datt de Conan déi néideg Ofhängegkeeten eroflueden, installéiere an opbaut, ass et net genuch fir "conan installéieren ." ze lueden, et muss och de -s compiler.libcxx=libstdc++11 Parameter passéieren, soss Dir riskéiert eng Rëtsch Feeler an der Verbindungsstadium Är Uwendung ze kréien. Ech hu mat dësem Feeler fir e puer Stonnen hänke bliwwen an ech hoffen dësen Artikel hëlleft aner Leit dëse Problem a manner Zäit ze léisen.

Als nächst, nodeems ech docker-compose.yml geschriwwen hunn, op Rot vu mengem Frënd, hunn ech Ënnerstëtzung bäigefüügt cookiecutter an elo kënnt Dir Iech eng vollwäerteg Schabloun fir e REST API Service an C++ kréien, mat engem personaliséierten Ëmfeld, a PostgreSQL installéiert, einfach andeems Dir "CookieCutter" an d'Konsole gitt https://github.com/KovalevVasiliy/cpp_rest_api_template.git" An dann "docker-compose up -build".

Ech hoffen dës Schabloun hëlleft Ufänger op hirem schwieregen Wee fir REST API Uwendungen an der grousser a mächteger, awer sou enger onkloerer Sprooch wéi C ++ z'entwéckelen.
Och, ech recommandéieren héich hei liesen dat Artikel. Et erkläert méi detailléiert wéi Dir mat POCO schafft an Ären eegene REST API Service schreift.

Source: will.com

Setzt e Commentaire