Microservices ing C++. Fiksi utawa kasunyatan?

Microservices ing C++. Fiksi utawa kasunyatan?

Ing artikel iki aku bakal pirembagan bab carane nggawe cithakan (cookiecutter) lan nyiyapake lingkungan kanggo nulis layanan REST API ing C ++ nggunakake docker / docker-compose lan manager paket conan.

Sajrone hackathon sabanjure, ing ngendi aku melu minangka pangembang backend, ana pitakonan babagan apa sing bakal digunakake kanggo nulis layanan mikro sabanjure. Kabeh sing wis ditulis nganti saiki wis ditulis dening kula lan kula kanca ing Python, wiwit rowange ana pakar ing lapangan iki lan profesional dikembangaké backends, nalika aku umume pangembang sistem ditempelake lan wrote ing gedhe lan elek C ++, lan aku mung sinau Python ing universitas.

Dadi, kita ngadhepi tugas nulis layanan dhuwur-load, tugas utama yaiku preprocess data sing teka lan nulis menyang database. Lan sawise istirahat kumelun liyane, kanca ngusulake aku, minangka pangembang C ++, nulis layanan iki nggunakake pro. Argumentasi iki yaiku bakal luwih cepet, luwih produktif, lan umume, juri bakal seneng karo kepiye carane ngatur sumber daya tim. Aku mangsuli yen aku durung nate nindakake perkara kasebut ing C ++ lan bisa kanthi gampang nyawisake 20+ jam sing isih ana kanggo nggoleki, nyusun lan ngubungake perpustakaan sing cocog. Prasaja, aku pitik. Sing apa kita mutusaké lan kalem rampung kabeh ing Python.

Saiki, sajrone ngasingake awake dhewe, aku mutusake kanggo nemtokake cara nulis layanan ing C ++. Wangsulan: Bab ingkang pisanan sing kudu dilakoni yaiku mutusake perpustakaan sing cocog. Pilihanku tiba Poco, amarga iki ditulis ing gaya obyek-oriented lan uga gumunggung dokumentasi normal. Uga, pitakonan muncul babagan milih sistem perakitan. Nganti titik iki aku mung makarya karo Visual Studio, IAR lan bare makefiles. Lan ora ana sistem iki mréntahaké kanggo kula, awit aku ngrancang kanggo mbukak kabeh layanan ing wadhah docker. Banjur aku mutusake kanggo nyoba ngerteni cmake lan manajer paket sing menarik conan. Manajer paket iki ngidini sampeyan ndhaptar kabeh dependensi ing siji file

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

[generator] cmake

lan kanthi printah prasaja "conan install ." nginstal perpustakaan sing dibutuhake. Alamiah, iku uga perlu kanggo nggawe owah-owahan kanggo

CMakeLists.txt

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

Sawisé iku, Aku miwiti looking for a perpustakaan bisa karo PostgreSQL, awit iku siji aku wis sethitik pengalaman nggarap, lan iku uga layanan Python kita sesambungan karo. Lan sampeyan ngerti apa sing aku sinau? Iku ing POCO! Nanging conan ora ngerti yen ana ing POCO lan ora ngerti carane mbangun; ana file konfigurasi sing wis lawas ing repositori (aku wis nulis babagan kesalahan iki menyang pangripta POCO). Iki tegese sampeyan kudu golek perpustakaan liyane.

Banjur pilihanku ana ing perpustakaan sing kurang populer libpg. Lan aku luar biasa Bejo, iku wis ing conan lan malah lagi nglumpuk lan nglumpuk.

Langkah sabanjure yaiku nulis template layanan sing bisa ngolah panjaluk.
Kita kudu marisi kelas TemplateServerApp saka Poco::Util::ServerApplication lan ngganti cara utama.

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

Ing cara utama kita kudu nyetel paramèter: port, nomer thread lan ukuran antrian. Lan sing paling penting, sampeyan kudu nemtokake pawang kanggo panjaluk sing mlebu. Iki ditindakake kanthi nggawe pabrik

TemplateRequestHandlerFactory

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

Ing kasusku, mung nggawe pawang sing padha saben wektu - TemplateServerAppHandler. Ing kene kita bisa nyelehake logika bisnis kita.

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

Aku uga nggawe template kelas kanggo nggarap PostgreSQL. Kanggo nindakake SQL prasaja, kayata nggawe tabel, ana cara ExecuteSQL(). Kanggo pitakon sing luwih rumit utawa njupuk data, sampeyan kudu entuk sambungan liwat GetConnection() lan nggunakake libpg API. (Mbok mengko aku bakal mbenerake ketidakadilan iki).

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

Kabeh paramèter kanggo nyambungake menyang database dijupuk saka lingkungan, dadi sampeyan uga kudu nggawe lan ngatur file .env

.NS

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

Sampeyan bisa ndeleng kabeh kode ing github.

Microservices ing C++. Fiksi utawa kasunyatan?

Lan saiki ana tahap pungkasan nulis dockerfile lan docker-compose.yml. Jujur, iki njupuk paling wektu, lan ora mung amarga aku noob, amarga iku perlu kanggo mbangun perpustakaan saben wektu, nanging amarga saka pitfalls saka conan. Contone, supaya conan bisa ngundhuh, nginstal lan mbangun dependensi sing dibutuhake, ora cukup kanggo ngundhuh "conan install.", uga kudu ngliwati parameter -s compiler.libcxx = libstdc ++ 11, yen ora. sampeyan duwe risiko entuk akeh kesalahan ing tahap ngubungake aplikasi sampeyan. Aku wis macet karo kesalahan iki kanggo sawetara jam lan muga-muga artikel iki bakal mbantu wong liya ngatasi masalah iki ing wektu sing kurang.

Sabanjure, sawise nulis docker-compose.yml, kanthi saran saka kanca, aku nambah dhukungan tukang cukur lan saiki sampeyan bisa njaluk dhewe cithakan lengkap kanggo layanan REST API ing C ++, karo lingkungan selaras, lan PostgreSQL diinstal, mung kanthi ngetik "cookiecutter" menyang console https://github.com/KovalevVasiliy/cpp_rest_api_template.git" Banjur "docker-compose up -build".

Mugi cithakan iki bakal bantuan wiwitan ing path angel ngembangaken aplikasi REST API ing gedhe lan kuat, nanging basa kikuk kaya C ++.
Uga, aku banget nyaranake maca ing kene iki artikel. Iki nerangake kanthi luwih rinci babagan cara nggarap POCO lan nulis layanan API REST dhewe.

Source: www.habr.com

Add a comment