The Codest
  • Apie mus
  • Paslaugos
    • Programinės įrangos kūrimas
      • Priekinės dalies kūrimas
      • Galinės dalies kūrimas
    • Staff Augmentation
      • Priekinės dalies kūrėjai
      • Atgalinės versijos kūrėjai
      • Duomenų inžinieriai
      • Debesų inžinieriai
      • QA inžinieriai
      • Kita
    • Patariamoji tarnyba
      • Auditas ir konsultacijos
  • Pramonės šakos
    • Fintech ir bankininkystė
    • E-commerce
    • Adtech
    • Sveikatos technologijos
    • Gamyba
    • Logistika
    • Automobiliai
    • IOT
  • Vertė už
    • CEO
    • CTO
    • Pristatymo vadybininkas
  • Mūsų komanda
  • Case Studies
  • Sužinokite, kaip
    • Tinklaraštis
    • Susitikimai
    • Interneto seminarai
    • Ištekliai
Karjera Susisiekite su mumis
  • Apie mus
  • Paslaugos
    • Programinės įrangos kūrimas
      • Priekinės dalies kūrimas
      • Galinės dalies kūrimas
    • Staff Augmentation
      • Priekinės dalies kūrėjai
      • Atgalinės versijos kūrėjai
      • Duomenų inžinieriai
      • Debesų inžinieriai
      • QA inžinieriai
      • Kita
    • Patariamoji tarnyba
      • Auditas ir konsultacijos
  • Vertė už
    • CEO
    • CTO
    • Pristatymo vadybininkas
  • Mūsų komanda
  • Case Studies
  • Sužinokite, kaip
    • Tinklaraštis
    • Susitikimai
    • Interneto seminarai
    • Ištekliai
Karjera Susisiekite su mumis
Atgal rodyklė GRĮŽTI ATGAL
2022-06-28
Programinės įrangos kūrimas

Symfony: Mikroservisų komunikacija I dalis

The Codest

Sebastianas Lučakas

PHP padalinio vadovas

Perskaitykite pirmąją PHP serijos dalį, skirtą mikroservisų komunikacijai Symfony sistemoje ir populiariausiam būdui - AMQP komunikacijai naudojant RabbitMQ.

Šiuolaikinė taikomųjų programų architektūra privertė kūrėjus pakeisti mąstymą apie skirtingų IT sistemų komponentų ryšį. Kadaise viskas buvo paprasčiau - dauguma sistemų buvo kuriamos kaip monolitinės struktūros, tarpusavyje sujungtos verslo logikos jungčių tinklu. Tokių priklausomybių palaikymas PHP projektas buvo didžiulis iššūkis PHP kūrėjai, ir vis didėjantis populiarumas SaaS sprendimus ir labai išaugusį populiarumą debesis paslaugos lėmė, kad šiandien vis dažniau girdime apie mikroservisai ir taikomųjų programų moduliškumą.

Kaip, kurdami nepriklausomas mikroservisus, galime priversti juos keistis informacija tarpusavyje?

Šis straipsnis yra pirmasis iš straipsnių serijos apie mikroservisų bendravimas Symfony sistema ir joje aptariamas populiariausias būdas - AMQP ryšys naudojant RabbitMQ.

Tikslas

Sukurti dvi nepriklausomas programas ir užtikrinti ryšį tarp jų naudojant tik pranešimų magistralę.

Koncepcija

Turime dvi įsivaizduojamas, nepriklausomas programas:
* app1: darbuotojams siunčiami el. pašto ir SMS pranešimai
* programa2: kuri leidžia valdyti darbuotojų darbą ir priskirti jiems užduotis.

Norime sukurti modernią ir paprastą sistemą, pagal kurią darbas darbuotojui būtų priskiriamas programa2 klientui bus išsiųstas pranešimas naudojant app1. Nepaisant to, kas atrodo, tai labai paprasta!

Paruošimas

Šiame straipsnyje naudosime naujausią "Symfony" versiją (6.1 versija rašymo metu) ir naujausią PHP versiją (8.1). Keliais labai paprastais veiksmais sukursime veikiančią vietinę "Docker" aplinka su dviem mikroservisais. Viskas, ko jums reikia:
* veikiantis kompiuteris,
* įdiegta "Docker" + "Docker Compose" aplinka
* ir vietoje sukonfigūruotą Symfony CLI ir šiek tiek laisvo laiko.

Vykdymo aplinka

Naudosimės "Docker" kaip programų virtualizavimo ir konteinerizavimo įrankio galimybėmis. Pradėkime nuo katalogų medžio sukūrimo, dviejų "Symfony" programosir aprašyti mūsų aplinkos infrastruktūrą naudojant docker-compose.yml failas.

 cd ~
 mkdir microservices-in-symfony
 cd microservices-in-symfony
 symfony new app1
 symfony new app2
 touch docker-compose.yml

Sukūrėme du katalogus dviem atskiroms "Symfony" programoms ir sukūrėme tuščią docker-compose.yml failą, kuriuo paleidžiama mūsų aplinka.

Pridėkime šiuos skyrius prie docker-compose.yml file:

versija: '3.8'

paslaugos:
Paslaugos: app1:
containername: app1
build: app1/.
restart: on-failure
envfile: app1/.env
aplinka:
APPNAME: app1
tty: true
stdinopen: true

app2:
containername: app2
build: app2/.
restart: on-failure
envfile: app2/.env
aplinka:
APPNAME: app2
tty: true
stdinopen: true

Rabbitmq:
containername: rabbitmq
vaizdas: rabbitmq:management
ports:
- 15672:15672
- 5672:5672
aplinka:
- RABBITMQDEFAULTUSER=user
- RABBITMQDEFAULT_PASS=password

Šaltinis kodas galima įsigyti tiesiogiai: thecodest-co/microservices-in-symfony/blob/main/docker-compose.yml

Bet palaukite, kas čia nutiko? Tiems, kurie nesusipažinę su "Docker", pirmiau pateiktas konfigūracijos failas gali atrodyti mįslingas, tačiau jo paskirtis labai paprasta. Naudodami "Docker Compose" kuriame tris "paslaugas":

  • app1: tai pirmosios "Symfony" programos konteineris
  • app2: antrosios "Symfony" programos konteineris
  • rabbitmq: "RabbitMQ" programos atvaizdas kaip komunikacijos tarpinės programinės įrangos sluoksnis

Kad tinkamai veiktų, mums vis dar reikia "Docker" failas failai, iš kurių kuriami atvaizdai. Taigi sukurkime juos:

 touch app1/Dockerfile
 touch app2/Dockerfile

Abiejų failų struktūra yra lygiai tokia pati ir atrodo taip:

IŠ php:8.1

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
COPY . /app/
WORKDIR /app/

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

Paleisti chmod +x /usr/local/bin/install-php-extensions && sync &&
install-php-extensions amqp

Paleiskite apt-get update
&& apt-get install -y libzip-dev wget --no-install-recommends
&& apt-get clean
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Paleiskite docker-php-ext-install zip;

CMD bash -c "cd /app && composer install && php -a"

Šaltinio kodas prieinamas tiesiogiai: /thecodest-co/microservices-in-symfony/blob/main/app1/Dockerfile

Pirmiau pateiktą failą "Docker Compose" naudoja konteineriui sukurti iš PHP 8.1 atvaizdo su įdiegtu "Composer" ir AMQP plėtiniu. Be to, jis paleidžia PHP intepreterį priedėlio režimu, kad konteineris veiktų fone.

Dabar jūsų katalogų ir failų medis turėtų atrodyti taip:

 .
 ├──── app1
 │ └── └── Dockerfile
 | (...) # Symfony programėlės struktūra
 ├── app2
 │ └── └── Dockerfile
 | (...) # Symfony programėlės struktūra
 └── docker-compose.yml

Pirmoji "Symfony" mikroserviso paslauga

Pradėkime nuo app1 katalogą ir pirmąją programą.
Mūsų pavyzdyje tai yra programa, kuri klausosi ir vartoja pranešimus iš eilės, siunčiamus programa2 kaip aprašyta reikalavimuose:

darbo priskyrimas darbuotojui programa2 klientui bus išsiųstas pranešimas

Pradėkime nuo reikiamų bibliotekų pridėjimo. AMQP yra natūraliai palaikoma symfony/messenger pratęsimas. Papildomai įdiegsime monologas/monologas sekti sistemos žurnalus, kad būtų lengviau analizuoti programų elgseną.

 cd app1/
 symfony composer req amqp ampq-messenger monolog

Įdiegus buvo pridėtas papildomas failas config/packages/messenger.yaml. Tai "Symfony Messenger" komponento konfigūracijos failas ir mums nereikia jo pilna konfigūracija.
Pakeiskite jį toliau pateiktu YAML failu:

sistema:
messenger:
# Atmeskite šį (ir toliau nurodytą nepavykusį transportą), kad nepavykę pranešimai būtų siunčiami į šį transportą ir vėliau tvarkomi.
# failure_transport: failed

    transportas:
        # https://symfony.com/doc/current/messenger.html#transport-configuration
        external_messages:
            dsn: "%env(MESSENGER_TRANSPORT_DSN)%
            options:
                auto_setup: false
                mainai:
                    pavadinimas: pranešimai
                    tipas: direct
                    default_publish_routing_key: from_external
                eilės:
                    pranešimai: pranešimai: išoriniai: išoriniai: pranešimai: išoriniai:
                        privalomieji raktai: pranešimai: pranešimai: privalomieji_raktai: [from_external]

Šaltinio kodas prieinamas tiesiogiai: thecodest-co/microservices-in-symfony/blob/main/app1/config/packages/messenger.yaml

"Symfony Messenger" naudojamas sinchroniniam ir asinchroniniam bendravimui "Symfony" programose. Jis palaiko įvairias transportuoja, arba transporto sluoksnio tiesos šaltiniai. Savo pavyzdyje naudojame AMQP plėtinį, kuris palaiko įvykių eilių sistemą RabbitMQ.

Pirmiau pateiktoje konfigūracijoje apibrėžiamas naujas transportas pavadinimu external_messages, kuriame pateikiamos nuorodos į MESSENGER_TRANSPORT_DSN aplinkos kintamasis ir apibrėžia tiesioginį klausymąsi pranešimai kanalas pranešimų magistralėje. Šiuo metu taip pat redaguokite app1/.env failą ir pridėkite atitinkamą transporto adresą.

"`env

(...)
MESSENGERTRANSPORTDSN=amqp://user:password@rabbitmq:5672//messages
(...)
"
Parengus taikomosios programos struktūrą ir sukonfigūravus bibliotekas, metas įgyvendinti verslo logiką. Žinome, kad mūsų programa turi reaguoti į darbo priskyrimą darbuotojui. Taip pat žinome, kad darbo priskyrimasapp2system pakeičia darbo būseną. Taigi sukurkime modelį, imituojantį būsenos pasikeitimą, ir išsaugokime jįapp1/Message/StatusUpdate.php` kelyje:
vaizdas
 {
viešoji funkcija __construct(protected string $status){}

public function getStatus(): string
{
    return $this->status;
}

}

Šaltinio kodas prieinamas tiesiogiai: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Message/StatusUpdate.php

Mums vis dar reikia klasės, kuri įgyvendintų verslo logiką, kai mūsų mikroservisas gauna minėtą įvykį iš eilės. Taigi sukurkime Pranešimų tvarkyklė į app1/Handler/StatusUpdateHandler.php kelias:

vaizdas
 naudoti PsrLogLoggerInterface;
use SymfonyComponentMessengerAttributeAsMessageHandler;

[AsMessageHandler]

klasė StatusUpdateHandler
{
viešoji funkcija __construct(
protected LoggerInterface $logger,
) {}

public function __invoke(StatusUpdate $statusUpdate): void
{
    $statusDescription = $statusUpdate->getStatus();

    $this->logger->warning('APP1: {STATUS_UPDATE} - '.$statusDescription);

    // likusi verslo logikos dalis, t. y. el. laiško siuntimas naudotojui
    // $this->emailService->email()
}

}

Šaltinio kodas prieinamas tiesiogiai: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Handler/StatusUpdateHandler.php

PHP atributai gerokai palengvina darbą ir reiškia, kad šiuo konkrečiu atveju mums nereikia rūpintis dėl automatinio įjungimo ar paslaugų deklaracijos. Mūsų mikroservisas, skirtas domeno įvykiams tvarkyti, paruoštas, laikas pereiti prie antrosios programos.

Antroji "Symfony" mikroserviso paslauga

Apžvelgsime programa2 katalogas ir antrasis "Symfony" programa. Mūsų idėja - siųsti pranešimą į eilę, kai darbuotojui sistemoje priskiriama užduotis. Taigi atlikime greitą AMQP konfigūravimą ir priverskime mūsų antrąją mikroservisą pradėti skelbti StatusUpdate įvykius į pranešimų magistralę.

Bibliotekos diegiamos lygiai taip pat, kaip ir pirmosios programos atveju.

 cd ..
 cd app2/
 symfony composer req amqp ampq-messenger monolog

Įsitikinkime, kad app2/.env faile yra galiojantis "RabbitMQ" DSN įrašas:

(...)
 MESSENGER_TRANSPORT_DSN=amqp://user:password@rabbitmq:5672//messages
 (...)

Belieka tik sukonfigūruoti "Symfony Messenger app2/config/packages/messenger.yaml file:

sistema:
messenger:
# Atmeskite šį (ir toliau nurodytą nepavykusį transportą), kad nepavykę pranešimai būtų siunčiami į šį transportą ir vėliau tvarkomi.
# failure_transport: failed

    transportas:
        # https://symfony.com/doc/current/messenger.html#transport-configuration
        async:
            dsn: "%env(MESSENGER_TRANSPORT_DSN)%

    maršrutizavimas:
        # Nukreipti pranešimus į transportą
        "AppMessageStatusUpdate": async

Kaip matote, šį kartą transporto apibrėžtis nukreipia tiesiai į async ir apibrėžia maršruto parinkimą siunčiant mūsų StatusUpdate pranešimą į sukonfigūruotą DSN. Tai vienintelė konfigūravimo sritis, belieka sukurti AMQP eilės loginį ir įgyvendinimo sluoksnį. Tam sukursime dvynį StatusUpdateHandler ir StatusUpdate klasės programa2.

vaizdas
 naudoti PsrLogLoggerInterface;
use SymfonyComponentMessengerAttributeAsMessageHandler;

[AsMessageHandler]

klasė StatusUpdateHandler
{
viešoji funkcija __construct(
private readonly LoggerInterface $logger,
) {}

public function __invoke(StatusUpdate $statusUpdate): void
{
    $statusDescription = $statusUpdate->getStatus();

    $this->logger->warning('APP2: {STATUS_UPDATE} - '.$statusDescription);

    ## verslo logika, t. y. vidinių pranešimų siuntimas arba kai kurių kitų sistemų įrašymas į eilę
}

}
vaizdas
 {
viešoji funkcija __construct(protected string $status){}

public function getStatus(): string
{
    return $this->status;
}

}


Šaltinio kodas prieinamas tiesiogiai: /thecodest-co/microservices-in-symfony/blob/main/app2/src/Message/StatusUpdate.php

Galiausiai belieka sukurti būdą, kaip siųsti pranešimą į pranešimų magistralę. Sukursime paprastą Symfony komanda už tai:

vaizdas
naudoti SymfonyComponentConsoleAttributeAsCommand;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
use SymfonyComponentMessengerMessageBusInterface;

[AsCommand(

name: "app:send"

)]
klasė SendStatusCommand plečia Command
{
public function construct(private readonly MessageBusInterface $messageBus, string $name = null)
{
parent::construct($name);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
    $status = "Worker X assigned to Y";

    $this->messageBus->dispatch(
        pranešimas: new StatusUpdate($status)
    );

    return Command::SUCCESS;
}

}

Ačiū Priklausomybės įterpimas galime naudoti MessageBusInterface komandoje ir išsiųsti StatusUpdate pranešimą per išsiuntimas() metodą į mūsų eilę. Be to, čia taip pat naudojame PHP atributus.

Štai ir viskas - belieka paleisti "Docker Compose" aplinką ir pažiūrėti, kaip elgiasi mūsų programos.

Aplinkos paleidimas ir testavimas

Naudojant "Docker Compose" konteineriai su dviem mūsų programomis bus sukurti ir paleisti kaip atskiri egzemplioriai, o vienintelis tarpinės programinės įrangos sluoksnis bus Rabbitmq konteinerį ir mūsų pranešimų magistralės realizaciją.

Iš projekto šakninio katalogo paleiskime šias komandas:

cd ../ # įsitikinkite, kad esate pagrindiniame kataloge
 docker-compose up --build -d

Ši komanda gali šiek tiek užtrukti, nes sukuriami du atskiri konteineriai su PHP 8.1 + AMQP ir ištraukiamas RabbitMQ atvaizdas. Būkite kantrūs. Sukūrę atvaizdus galite paleisti mūsų komandą iš programa2 ir išsiųsti keletą pranešimų į eilę.

 docker exec -it app2 php bin/console app:send

Galite tai daryti tiek kartų, kiek tik galite. Kol nėra vartotojas jūsų pranešimai nebus apdorojami. Kai tik paleidžiate app1 ir suvalgyti visus pranešimus, kuriuos jie rodys jūsų ekrane.

docker exec -it app1 php bin/console messenger:consume -vvv external_messages
vaizdas

Visas šaltinio kodas kartu su README rasite mūsų viešoje saugykloje The Codest Github

Santrauka

"Symfony" su savo bibliotekomis ir įrankiais leidžia greitai ir efektyviai kurti modernius žiniatinklio svetainė programos. Naudodamiesi keliomis komandomis ir keliomis kodo eilutėmis galime sukurti modernią ryšių tarp programų sistemą. Symfony, kaip ir PHP, idealiai tinka žiniatinklio programų kūrimas o dėl savo ekosistemos ir lengvo įdiegimo ši ekosistema pasiekia vienus iš geriausių pateikimo rinkai laiko rodiklių.

Tačiau greitas ne visada reiškia geras - pirmiau pateiktame pavyzdyje pateikėme paprasčiausią ir greičiausią bendravimo būdą. Labiau smalsūs tikrai pastebės, kad trūksta domeno įvykių atskyrimo už taikomojo sluoksnio ribų - dabartinėje versijoje jie dubliuojami, be to, nėra visiško palaikymo Vokas, be kita ko, nėra Antspaudai. Kviečiu skaityti II dalį, kurioje aptarsime "Symfony" programų domenų struktūros suvienodinimo mikroservisų aplinkoje temą ir aptarsime antrąjį populiarų mikroservisų komunikacijos metodą - šį kartą sinchroninį, paremtą REST API.

bendradarbiavimo vėliava

Susiję straipsniai

Prenumeruokite mūsų žinių bazę ir būkite nuolat informuoti apie IT sektoriaus patirtį.

    Apie mus

    The Codest - tarptautinė programinės įrangos kūrimo bendrovė, turinti technologijų centrus Lenkijoje.

    Jungtinė Karalystė - būstinė

    • 303B biuras, 182-184 High Street North E6 2JA
      Londonas, Anglija

    Lenkija - vietiniai technologijų centrai

    • Fabryczna biurų parkas, Aleja
      Pokoju 18, 31-564 Krokuva
    • Brain Embassy, Konstruktorska
      11, 02-673 Varšuva, Lenkija

      The Codest

    • Pagrindinis
    • Apie mus
    • Paslaugos
    • Case Studies
    • Sužinokite, kaip
    • Karjera
    • Žodynas

      Paslaugos

    • Patariamoji tarnyba
    • Programinės įrangos kūrimas
    • Galinės dalies kūrimas
    • Priekinės dalies kūrimas
    • Staff Augmentation
    • Atgalinės versijos kūrėjai
    • Debesų inžinieriai
    • Duomenų inžinieriai
    • Kita
    • QA inžinieriai

      Ištekliai

    • Faktai ir mitai apie bendradarbiavimą su išoriniu programinės įrangos kūrimo partneriu
    • Iš JAV į Europą: Kodėl Amerikos startuoliai nusprendžia persikelti į Europą?
    • Technikos plėtros centrų užsienyje palyginimas: Tech Offshore Europa (Lenkija), ASEAN (Filipinai), Eurazija (Turkija)
    • Kokie yra svarbiausi CTO ir CIO iššūkiai?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Autorinės teisės © 2026 The Codest. Visos teisės saugomos.

    lt_LTLithuanian
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian es_ESSpanish nl_NLDutch etEstonian elGreek pt_PTPortuguese cs_CZCzech lvLatvian lt_LTLithuanian