C++లో మైక్రోసర్వీసెస్. ఫిక్షన్ లేదా రియాలిటీ?

C++లో మైక్రోసర్వీసెస్. ఫిక్షన్ లేదా రియాలిటీ?

ఈ వ్యాసంలో నేను ఒక టెంప్లేట్ (కుకీకట్టర్)ని ఎలా సృష్టించాను మరియు డాకర్/డాకర్-కంపోజ్ మరియు కోనన్ ప్యాకేజీ మేనేజర్‌ని ఉపయోగించి C++లో REST API సేవను వ్రాయడానికి వాతావరణాన్ని ఎలా సెటప్ చేసాను అనే దాని గురించి మాట్లాడుతాను.

నేను బ్యాకెండ్ డెవలపర్‌గా పాల్గొన్న తదుపరి హ్యాకథాన్ సమయంలో, తదుపరి మైక్రోసర్వీస్‌ను వ్రాయడానికి ఏమి ఉపయోగించాలనే ప్రశ్న తలెత్తింది. ఇప్పటి వరకు రాసినవన్నీ నేను, నా రాసినవే సహచరుడు పైథాన్‌లో, నా సహోద్యోగి ఈ రంగంలో నిపుణుడు మరియు వృత్తిపరంగా అభివృద్ధి చెందిన బ్యాకెండ్‌లను కలిగి ఉన్నందున, నేను సాధారణంగా ఎంబెడెడ్ సిస్టమ్స్ డెవలపర్‌గా ఉన్నప్పుడు మరియు గొప్ప మరియు భయంకరమైన C++లో వ్రాసాను మరియు నేను విశ్వవిద్యాలయంలో పైథాన్ నేర్చుకున్నాను.

కాబట్టి, మేము అధిక-లోడ్ సేవను వ్రాసే పనిని ఎదుర్కొన్నాము, దాని ప్రధాన పని దానికి వచ్చే డేటాను ముందుగా ప్రాసెస్ చేయడం మరియు డేటాబేస్కు వ్రాయడం. మరియు మరొక పొగ విరామం తర్వాత, ఒక స్నేహితుడు నేను, C++ డెవలపర్‌గా, ప్రోస్ ఉపయోగించి ఈ సేవను వ్రాయమని సూచించాడు. ఇది వేగవంతమైనది, మరింత ఉత్పాదకమైనది మరియు సాధారణంగా, జ్యూరీ జట్టు వనరులను ఎలా నిర్వహించాలో మాకు తెలుసు అని వాదిస్తారు. దానికి నేను C++లో ఎప్పుడూ అలాంటివి చేయలేదని మరియు మిగిలిన 20+ గంటలను తగిన లైబ్రరీలను శోధించడం, కంపైల్ చేయడం మరియు లింక్ చేయడం కోసం సులభంగా వెచ్చించగలనని సమాధానం ఇచ్చాను. సరళంగా చెప్పాలంటే, నేను బయటకు వచ్చాను. మేము పైథాన్‌లో ప్రతిదీ నిర్ణయించుకుని ప్రశాంతంగా పూర్తి చేసాము.

ఇప్పుడు, బలవంతంగా స్వీయ-ఐసోలేషన్ సమయంలో, నేను C++లో సేవలను ఎలా వ్రాయాలో గుర్తించాలని నిర్ణయించుకున్నాను. ముందుగా చేయవలసింది తగిన లైబ్రరీని నిర్ణయించడం. నా ఎంపిక మీద పడింది Poco, ఇది ఆబ్జెక్ట్-ఓరియెంటెడ్ స్టైల్‌లో వ్రాయబడింది మరియు సాధారణ డాక్యుమెంటేషన్‌ను కూడా గొప్పగా చెప్పుకుంది. అలాగే, అసెంబ్లీ వ్యవస్థను ఎంచుకోవడం గురించి ప్రశ్న తలెత్తింది. ఈ సమయం వరకు నేను విజువల్ స్టూడియో, IAR మరియు బేర్ మేక్‌ఫైల్స్‌తో మాత్రమే పని చేసాను. మరియు ఈ సిస్టమ్‌లు ఏవీ నన్ను ఆకర్షించలేదు, ఎందుకంటే నేను మొత్తం సేవను డాకర్ కంటైనర్‌లో అమలు చేయాలని ప్లాన్ చేసాను. అప్పుడు నేను cmake మరియు ఆసక్తికరమైన ప్యాకేజీ నిర్వాహకుడిని గుర్తించడానికి ప్రయత్నించాలని నిర్ణయించుకున్నాను కోనన్. ఈ ప్యాకేజీ మేనేజర్ మిమ్మల్ని ఒకే ఫైల్‌లో అన్ని డిపెండెన్సీలను నమోదు చేయడానికి అనుమతించారు

conanfile.txt
[అవసరం]poco/1.9.3
libpq/11.5

[జనరేటర్లు] cmake

మరియు సాధారణ ఆదేశంతో "conan install ." అవసరమైన లైబ్రరీలను ఇన్స్టాల్ చేయండి. సహజంగానే, మార్పులు చేయడం కూడా అవసరం

CMakeLists.txt

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

ఆ తర్వాత, నేను PostgreSQLతో పని చేయడానికి లైబ్రరీ కోసం వెతకడం ప్రారంభించాను, ఎందుకంటే అది నాకు పని చేసిన అనుభవం చాలా తక్కువ, మరియు మా పైథాన్ సేవలతో పరస్పర చర్య చేసేది కూడా ఇదే. మరి నేను ఏం నేర్చుకున్నానో తెలుసా? ఇది POCOలో ఉంది! కానీ అది POCOలో ఉందని కానన్‌కు తెలియదు మరియు దానిని ఎలా నిర్మించాలో తెలియదు; రిపోజిటరీలో పాత కాన్ఫిగరేషన్ ఫైల్ ఉంది (ఈ లోపం గురించి నేను ఇప్పటికే POCO సృష్టికర్తలకు వ్రాసాను). దీని అర్థం మీరు మరొక లైబ్రరీ కోసం వెతకవలసి ఉంటుంది.

ఆపై నా ఎంపిక తక్కువ జనాదరణ పొందిన లైబ్రరీలో పడింది libpg. మరియు నేను చాలా అదృష్టవంతుడిని, ఇది ఇప్పటికే కోనన్‌లో ఉంది మరియు సమావేశమై మరియు సమావేశమై ఉంది.

అభ్యర్థనలను ప్రాసెస్ చేయగల సేవా టెంప్లేట్‌ను వ్రాయడం తదుపరి దశ.
మేము తప్పనిసరిగా Poco::Util::ServerApplication నుండి మా TemplateServerApp తరగతిని వారసత్వంగా పొందాలి మరియు ప్రధాన పద్ధతిని భర్తీ చేయాలి.

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

ప్రధాన పద్ధతిలో మనం తప్పనిసరిగా పారామితులను సెట్ చేయాలి: పోర్ట్, థ్రెడ్ల సంఖ్య మరియు క్యూ పరిమాణం. మరియు ముఖ్యంగా, మీరు ఇన్‌కమింగ్ అభ్యర్థనల కోసం హ్యాండ్లర్‌ను తప్పనిసరిగా పేర్కొనాలి. ఇది ఒక కర్మాగారాన్ని సృష్టించడం ద్వారా జరుగుతుంది

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(). మరింత సంక్లిష్టమైన ప్రశ్నలు లేదా డేటా పునరుద్ధరణ కోసం, మీరు దీని ద్వారా కనెక్షన్‌ని పొందవలసి ఉంటుంది GetConection() మరియు 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

మీరు అన్ని కోడ్‌లను ఇక్కడ చూడవచ్చు గితుబ్.

C++లో మైక్రోసర్వీసెస్. ఫిక్షన్ లేదా రియాలిటీ?

ఇప్పుడు dockerfile మరియు docker-compose.yml వ్రాసే చివరి దశ వస్తుంది. నిజం చెప్పాలంటే, ఇది చాలా సమయం పట్టింది, మరియు నేను నూబ్‌గా ఉన్నందున మాత్రమే కాదు, ప్రతిసారీ లైబ్రరీలను పునర్నిర్మించాల్సిన అవసరం ఉంది, కానీ కానన్ యొక్క ఆపదల కారణంగా. ఉదాహరణకు, కోనన్ డౌన్‌లోడ్ చేయడానికి, ఇన్‌స్టాల్ చేయడానికి మరియు అవసరమైన డిపెండెన్సీలను రూపొందించడానికి, అది “conan install .”ని డౌన్‌లోడ్ చేయడానికి సరిపోదు, అది -s compiler.libcxx=libstdc++11 పారామీటర్‌ను కూడా పాస్ చేయాలి, లేకపోతే మీ అప్లికేషన్‌ను లింక్ చేసే దశలో మీరు అనేక లోపాలు వచ్చే ప్రమాదం ఉంది. నేను చాలా గంటలుగా ఈ లోపంతో చిక్కుకుపోయాను మరియు ఈ సమస్యను ఇతర వ్యక్తులకు తక్కువ సమయంలో పరిష్కరించడానికి ఈ కథనం సహాయపడుతుందని నేను ఆశిస్తున్నాను.

తర్వాత, docker-compose.yml వ్రాసిన తర్వాత, నా స్నేహితుని సలహా మేరకు, నేను మద్దతును జోడించాను కుక్కీకట్టర్ మరియు ఇప్పుడు మీరు C++లో అనుకూలీకరించిన పర్యావరణంతో REST API సేవ కోసం పూర్తి స్థాయి టెంప్లేట్‌ను పొందవచ్చు మరియు కేవలం కన్సోల్‌లో “కుకీకట్టర్”ని నమోదు చేయడం ద్వారా PostgreSQL ఇన్‌స్టాల్ చేయవచ్చు. https://github.com/KovalevVasiliy/cpp_rest_api_template.git" ఆపై "డాకర్-కంపోజ్ అప్ -బిల్డ్".

REST API అప్లికేషన్‌లను గొప్ప మరియు శక్తివంతమైన, కానీ C++ వంటి వికృతమైన భాషలో అభివృద్ధి చేయడంలో ప్రారంభకులకు ఈ టెంప్లేట్ సహాయపడుతుందని నేను ఆశిస్తున్నాను.
అలాగే, ఇక్కడ చదవడానికి నేను బాగా సిఫార్సు చేస్తున్నాను వ్యాసం. ఇది POCOతో ఎలా పని చేయాలో మరియు మీ స్వంత REST API సేవను ఎలా వ్రాయాలో మరింత వివరంగా వివరిస్తుంది.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి