Microservices ann an C++. Ficsean neo fìrinn?

Microservices ann an C++. Ficsean neo fìrinn?

San artaigil seo bruidhnidh mi air mar a chruthaich mi teamplaid (briosgaid) agus stèidhich mi àrainneachd airson seirbheis REST API a sgrìobhadh ann an C ++ a’ cleachdadh docker/docker-compose agus am manaidsear pacaid conan.

Rè an ath hackathon, anns an do ghabh mi pàirt mar leasaiche backend, dh ’èirich a’ cheist mu dè a bu chòir a chleachdadh airson an ath microservice a sgrìobhadh. Bha a h-uile dad a chaidh a sgrìobhadh gu ruige seo air a sgrìobhadh leam fhèin agus leamsa chompanach ann am Python, leis gu robh mo cho-obraiche na eòlaiche san raon seo agus air cùl-taic proifeasanta a leasachadh, fhad ‘s a bha mi mar leasaiche siostaman freumhaichte agus sgrìobh mi anns an C ++ sgoinneil agus uamhasach, agus dh’ ionnsaich mi Python aig an oilthigh.

Mar sin, bha e mar dhleastanas oirnn seirbheis làn luchd a sgrìobhadh, agus b’ e am prìomh obair aige an dàta a bha a’ tighinn thuige ro-làimh agus a sgrìobhadh chun stòr-dàta. Agus às deidh briseadh ceò eile, mhol caraid dhomh, mar leasaiche C ++, an t-seirbheis seo a sgrìobhadh a’ cleachdadh na buannachdan. Is e a bhith ag argamaid seo gum bi e nas luaithe, nas cinneasaiche, agus san fharsaingeachd, bidh an diùraidh air leth toilichte leis mar a tha fios againn mar a stiùireas sinn goireasan na sgioba. Dh’ fhreagair mi nach robh mi riamh air rudan mar sin a dhèanamh ann an C ++ agus gum b’ urrainn dhomh na 20+ uairean a bha air fhàgail a chaitheamh gu furasta airson leabharlannan iomchaidh a lorg, a chur ri chèile agus a cheangal. Gu sìmplidh, chuir mi às. Sin a cho-dhùin sinn agus chuir sinn crìoch air a h-uile càil ann am Python gu socair.

A-nis, rè an fèin-aonaranachd èiginneach, chuir mi romham faighinn a-mach ciamar a sgrìobhas mi seirbheisean ann an C ++. B’ e a’ chiad rud a bu chòir a dhèanamh co-dhùnadh mu leabharlann iomchaidh. Thuit mo roghainn air adhart Poco, leis gun deach a sgrìobhadh ann an stoidhle a bha ag amas air nithean agus bha sgrìobhainnean àbhaisteach ann cuideachd. Cuideachd, dh'èirich a 'cheist mu bhith a' taghadh siostam cruinneachaidh. Gu ruige seo cha robh mi ag obair ach le Visual Studio, IAR agus lom makefiles. Agus cha do chòrd gin de na siostaman sin rium, leis gu robh mi an dùil an t-seirbheis gu lèir a ruith ann an soitheach docker. An uairsin chuir mi romhpa feuchainn ri cmake agus manaidsear pacaid inntinneach fhaighinn a-mach conan. Leig am manaidsear pacaid seo leat a h-uile eisimeileachd a chlàradh ann an aon fhaidhle

conanfile.txt
[feumar] poco/1.9.3
lipq/11.5

[gineadairean] cmake

agus le àithne shìmplidh "conan install." stàlaich na leabharlannan riatanach. Gu nàdarra, bha e riatanach cuideachd atharrachaidhean a dhèanamh air

CMakeLists.txt

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

Às deidh sin, thòisich mi a’ coimhead airson leabharlann airson a bhith ag obair le PostgreSQL, leis gur e am fear air nach robh mòran eòlais agam a bhith ag obair leis, agus b’ e cuideachd am fear leis an robh na seirbheisean Python againn ag eadar-obrachadh. Agus a bheil fios agad dè a dh'ionnsaich mi? Tha e ann am POCO! Ach chan eil fios aig Conan gu bheil e ann am POCO agus chan eil fios aige ciamar a thogas e e; tha faidhle rèiteachaidh seann-fhasanta anns an stòr (tha mi air sgrìobhadh mun mhearachd seo gu luchd-cruthachaidh POCO mu thràth). Tha seo a’ ciallachadh gum feum thu leabharlann eile a lorg.

Agus an uairsin thuit mo roghainn air leabharlann nach robh cho measail libpg. Agus bha mi air leth fortanach, bha e mu thràth ann an conan agus bha e eadhon ga chruinneachadh agus ga chruinneachadh.

B’ e an ath cheum teamplaid seirbheis a sgrìobhadh as urrainn iarrtasan a làimhseachadh.
Feumaidh sinn ar clas TemplateServerApp a shealbhachadh bho Poco ::Util :: ServerApplication agus a dhol thairis air a’ phrìomh dhòigh.

Teamplaid ServerApp

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

Anns a 'phrìomh dhòigh feumaidh sinn na crìochan a shuidheachadh: port, àireamh snàithleanan agus meud ciudha. Agus as cudromaiche, feumaidh tu inneal-làimhseachaidh a shònrachadh airson iarrtasan a tha a 'tighinn a-steach. Tha seo air a dhèanamh le bhith a 'cruthachadh factaraidh

TemplateRequestHandlerFactory

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

Anns a 'chùis agam, bidh e dìreach a' cruthachadh an aon inneal-làimhseachaidh a h-uile turas - TemplateServerAppHandler. Seo far an urrainn dhuinn ar loidsig gnìomhachais a shuidheachadh.

Teamplaid ServerAppHandler

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

Chruthaich mi teamplaid clas cuideachd airson obrachadh le PostgreSQL. Gus SQL sìmplidh a dhèanamh, leithid cruthachadh clàr, tha dòigh ann Cuir an gnìomhSQL(). Airson ceistean nas iom-fhillte no trusadh dàta, bidh agad ri ceangal fhaighinn tro Faigh Ceangal() agus cleachd an API libpg. (Is dòcha nas fhaide air adhart cuiridh mi ceart air an ana-ceartas seo).

stòr-dàta

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

Tha a h-uile paramadair airson ceangal ris an stòr-dàta air a thoirt bhon àrainneachd, agus mar sin feumaidh tu cuideachd am faidhle .env a chruthachadh agus a rèiteachadh

.env

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

Chì thu an còd gu lèir aig github.

Microservices ann an C++. Ficsean neo fìrinn?

Agus a-nis thig an ìre mu dheireadh de sgrìobhadh an dockerfile agus docker-compose.yml. Gus a bhith onarach, thug seo a’ mhòr-chuid den ùine, agus chan ann a-mhàin air sgàth ‘s gur e noob a th’ annam, oir bha e riatanach na leabharlannan ath-thogail a h-uile uair, ach air sgàth cho duilich ‘s a bha e conan. Mar eisimpleir, gus an urrainn dha Conan na h-eisimeileachdan riatanach a luchdachadh sìos, a stàladh agus a thogail, chan eil e gu leòr dha “conan install .” a luchdachadh sìos, feumaidh e cuideachd a dhol seachad air an -s compiler.libcxx=libstdc++11 paramadair, air dhòigh eile tha cunnart ann gum faigh thu dòrlach de mhearachdan aig ìre ceangail an tagraidh agad. Tha mi air a bhith glaiste leis a’ mhearachd seo airson grunn uairean a thìde agus tha mi an dòchas gun cuidich an artaigil seo daoine eile gus an duilgheadas seo fhuasgladh ann an nas lugha de ùine.

An ath rud, às deidh dhomh docker-compose.yml a sgrìobhadh, air comhairle mo charaid, chuir mi taic ris briosgaid agus a-nis gheibh thu teamplaid làn-chuimseach dhut fhèin airson seirbheis REST API ann an C ++, le àrainneachd àbhaisteach, agus PostgreSQL air a chuir a-steach, dìreach le bhith a’ dol a-steach do “briosgaid” a-steach don consol https://github.com/KovalevVasiliy/cpp_rest_api_template.git" Agus an uairsin “docker-compose up -build”.

Tha mi an dòchas gun cuidich an teamplaid seo luchd-tòiseachaidh air an t-slighe dhoirbh aca ann a bhith a’ leasachadh thagraidhean REST API anns a’ chànan mhòr agus chumhachdach, ach a tha cho sgiobalta mar C ++.
Cuideachd, tha mi gu mòr a’ moladh leughadh an seo seo artaigil. Tha e a’ mìneachadh nas mionaidiche mar a dh’ obraicheas tu le POCO agus mar a sgrìobhas tu an t-seirbheis REST API agad fhèin.

Source: www.habr.com

Cuir beachd ann