C++ இல் மைக்ரோ சர்வீஸ்கள். கற்பனையா அல்லது உண்மையா?

C++ இல் மைக்ரோ சர்வீஸ்கள். கற்பனையா அல்லது உண்மையா?

இந்தக் கட்டுரையில் நான் எப்படி ஒரு டெம்ப்ளேட்டை (குக்கீகட்டர்) உருவாக்கினேன் மற்றும் டோக்கர்/டாக்கர்-கம்போஸ் மற்றும் கோனன் பேக்கேஜ் மேனேஜரைப் பயன்படுத்தி சி++ இல் ரெஸ்ட் ஏபிஐ சேவையை எழுதுவதற்கான சூழலை அமைத்தேன்.

நான் பின்தளத்தில் டெவலப்பராகப் பங்கேற்ற அடுத்த ஹேக்கத்தானின் போது, ​​அடுத்த மைக்ரோ சர்வீஸை எழுத எதைப் பயன்படுத்துவது என்ற கேள்வி எழுந்தது. இதுவரை எழுதப்பட்டவை அனைத்தும் நானும், நானும் எழுதியவை தோழர் பைத்தானில், என்னுடைய சக ஊழியர் இந்தத் துறையில் நிபுணராக இருந்து, தொழில்ரீதியாக வளர்ந்த பின்தளங்களில், நான் பொதுவாக ஒரு உட்பொதிக்கப்பட்ட சிஸ்டம் டெவலப்பராக இருந்தபோது, ​​சிறந்த மற்றும் பயங்கரமான C++ இல் எழுதினேன், மேலும் நான் பல்கலைக்கழகத்தில் பைத்தானைக் கற்றுக்கொண்டேன்.

எனவே, அதிக சுமை கொண்ட சேவையை எழுதும் பணியை நாங்கள் எதிர்கொண்டோம், இதன் முக்கிய பணி, அதற்கு வரும் தரவை முன்கூட்டியே செயலாக்கி தரவுத்தளத்தில் எழுதுவதாகும். மற்றொரு புகை இடைவேளைக்குப் பிறகு, ஒரு சி++ டெவலப்பராக நான் இந்தச் சேவையை சாதகத்தைப் பயன்படுத்தி எழுதுமாறு ஒரு நண்பர் பரிந்துரைத்தார். இதை வாதிடுவது என்னவென்றால், இது வேகமானதாகவும், அதிக உற்பத்தித் திறன் கொண்டதாகவும் இருக்கும், பொதுவாக, குழுவின் வளங்களை எவ்வாறு நிர்வகிப்பது என்பது எங்களுக்குத் தெரியும் என்பதில் நடுவர் குழு மகிழ்ச்சியடையும். அதற்கு நான் C++ இல் இதுபோன்ற விஷயங்களைச் செய்ததில்லை என்றும், மீதமுள்ள 20+ மணிநேரத்தை பொருத்தமான நூலகங்களைத் தேடுவதற்கும், தொகுப்பதற்கும், இணைப்பதற்கும் எளிதாக ஒதுக்க முடியும் என்று பதிலளித்தேன். எளிமையாகச் சொன்னால், நான் வெளியேறினேன். அதைத்தான் நாங்கள் முடிவு செய்து பைத்தானில் அனைத்தையும் நிதானமாக முடித்தோம்.

இப்போது, ​​கட்டாய சுய-தனிமைப்படுத்தலின் போது, ​​C++ இல் சேவைகளை எவ்வாறு எழுதுவது என்பதைக் கண்டுபிடிக்க முடிவு செய்தேன். முதலில் செய்ய வேண்டியது பொருத்தமான நூலகத்தைத் தீர்மானிப்பதாகும். என் தேர்வு விழுந்தது poco, இது ஒரு பொருள் சார்ந்த பாணியில் எழுதப்பட்டது மற்றும் சாதாரண ஆவணங்களை பெருமைப்படுத்தியது. மேலும், ஒரு சட்டசபை அமைப்பைத் தேர்ந்தெடுப்பது குறித்து கேள்வி எழுந்தது. இது வரை நான் விஷுவல் ஸ்டுடியோ, ஐஏஆர் மற்றும் வெறும் மேக்ஃபைல்களுடன் மட்டுமே பணிபுரிந்தேன். இந்த அமைப்புகள் எதுவும் என்னை ஈர்க்கவில்லை, ஏனெனில் முழு சேவையையும் டோக்கர் கொள்கலனில் இயக்க நான் திட்டமிட்டேன். பின்னர் 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(). மிகவும் சிக்கலான வினவல்கள் அல்லது தரவு மீட்டெடுப்புகளுக்கு, நீங்கள் ஒரு இணைப்பைப் பெற வேண்டும் 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

நீங்கள் அனைத்து குறியீடுகளையும் பார்க்கலாம் கிதுப்.

C++ இல் மைக்ரோ சர்வீஸ்கள். கற்பனையா அல்லது உண்மையா?

இப்போது dockerfile மற்றும் docker-compose.yml எழுதுவதற்கான இறுதிக் கட்டம் வந்துவிட்டது. உண்மையைச் சொல்வதென்றால், இது பெரும்பாலான நேரத்தை எடுத்தது, நான் ஒரு நோப் என்பதால் மட்டுமல்ல, ஒவ்வொரு முறையும் நூலகங்களை மீண்டும் கட்டியெழுப்ப வேண்டியிருந்தது, ஆனால் கோனனின் ஆபத்துகள் காரணமாக. எடுத்துக்காட்டாக, கோனனைப் பதிவிறக்க, நிறுவ மற்றும் தேவையான சார்புகளை உருவாக்க, அது “conan install” ஐப் பதிவிறக்குவது போதாது, அது -s compiler.libcxx=libstdc++11 அளவுருவையும் அனுப்ப வேண்டும், இல்லையெனில் உங்கள் விண்ணப்பத்தை இணைக்கும் கட்டத்தில் பல பிழைகள் ஏற்படும் அபாயம் உள்ளது. நான் பல மணிநேரங்களாக இந்த பிழையில் சிக்கிக்கொண்டேன், மேலும் இந்த சிக்கலை மற்றவர்களுக்கு குறைந்த நேரத்தில் தீர்க்க இந்த கட்டுரை உதவும் என்று நம்புகிறேன்.

அடுத்து, docker-compose.yml என்று எழுதிய பிறகு, எனது நண்பரின் ஆலோசனையின் பேரில், நான் ஆதரவைச் சேர்த்தேன் குக்கீ கட்டர் இப்போது நீங்கள் தனிப்பயனாக்கப்பட்ட சூழல் மற்றும் PostgreSQL நிறுவப்பட்ட C++ இல் REST API சேவைக்கான முழு அளவிலான டெம்ப்ளேட்டை கன்சோலில் "cookiecutter" ஐ உள்ளிடுவதன் மூலம் பெறலாம். https://github.com/KovalevVasiliy/cpp_rest_api_template.git" பின்னர் "டோக்கர்-கம்போஸ் அப் -பில்ட்".

இந்த டெம்ப்ளேட் REST API பயன்பாடுகளை சிறந்த மற்றும் சக்திவாய்ந்த, ஆனால் C++ போன்ற விகாரமான மொழியில் உருவாக்கும் கடினமான பாதையில் ஆரம்பநிலைக்கு உதவும் என்று நம்புகிறேன்.
மேலும், இங்கே படிக்க நான் மிகவும் பரிந்துரைக்கிறேன் இந்த கட்டுரை. POCO உடன் எவ்வாறு வேலை செய்வது மற்றும் உங்களின் சொந்த REST API சேவையை எழுதுவது எப்படி என்பதை இது விரிவாக விளக்குகிறது.

ஆதாரம்: www.habr.com

கருத்தைச் சேர்