The Codest
  • Par mums
  • Pakalpojumi
    • Programmatūras izstrāde
      • Frontend izveide
      • Backend izstrāde
    • Staff Augmentation
      • Frontend izstrādātāji
      • Backend izstrādātāji
      • Datu inženieri
      • Mākoņa inženieri
      • QA inženieri
      • Citi
    • Tā Konsultatīvais dienests
      • Audits un konsultācijas
  • Nozares
    • Fintech un banku darbība
    • E-commerce
    • Adtech
    • Healthtech
    • Ražošana
    • Loģistika
    • Automobiļu nozare
    • IOT
  • Vērtība par
    • CEO
    • CTO
    • Piegādes vadītājs
  • Mūsu komanda
  • Case Studies
  • Zināt, kā
    • Blogs
    • Tikšanās
    • Tiešsaistes semināri
    • Resursi
Karjera Sazinieties ar mums
  • Par mums
  • Pakalpojumi
    • Programmatūras izstrāde
      • Frontend izveide
      • Backend izstrāde
    • Staff Augmentation
      • Frontend izstrādātāji
      • Backend izstrādātāji
      • Datu inženieri
      • Mākoņa inženieri
      • QA inženieri
      • Citi
    • Tā Konsultatīvais dienests
      • Audits un konsultācijas
  • Vērtība par
    • CEO
    • CTO
    • Piegādes vadītājs
  • Mūsu komanda
  • Case Studies
  • Zināt, kā
    • Blogs
    • Tikšanās
    • Tiešsaistes semināri
    • Resursi
Karjera Sazinieties ar mums
Atpakaļ bultiņa ATGRIEZTIES ATPAKAĻ
2022-06-28
Programmatūras izstrāde

Symfony: Mikroservisu komunikācija I daļa

The Codest

Sebastian Luczak

PHP Vienības vadītājs

Izlasiet mūsu PHP sērijas pirmo daļu, kas veltīta mikropakalpojumu komunikācijai Symfony ietvarstruktūrā un populārākajam veidam - AMQP komunikācijai, izmantojot RabbitMQ.

Mūsdienu lietojumprogrammu arhitektūra ir piespiedusi izstrādātājus mainīt domāšanas veidu par saziņu starp dažādām IT sistēmu sastāvdaļām. Kādreiz viss bija vienkāršāk - lielākā daļa sistēmu tika veidotas kā monolītas struktūras, kas savā starpā bija savienotas ar biznesa loģikas savienojumu tīklu. Šādu atkarību uzturēšana PHP projekts bija liels izaicinājums PHP izstrādātāji, kā arī pieaugošā popularitāte SaaS risinājumus un milzīgo popularitātes pieaugumu, ko rada mākonis pakalpojumi izraisīja, ka šodien mēs arvien vairāk dzirdam par mikroservisi un lietojumprogrammu modularitāte.

Kā, izveidojot neatkarīgus mikropakalpojumus, mēs varam panākt, lai tie savstarpēji apmainās ar informāciju?

Šis raksts ir pirmais publikāciju sērijā par mikropakalpojumu komunikācija Symfony ietvarstruktūra, un tā aptver populārāko veidu - AMQP saziņu, izmantojot RabbitMQ.

Mērķis

Izveidot divas neatkarīgas lietojumprogrammas un nodrošināt saziņu starp tām, izmantojot tikai ziņojumu kopni.

Koncepcija

Mums ir divas iedomātas, neatkarīgas lietojumprogrammas:
* app1: kas nosūta e-pasta un SMS paziņojumus darbiniekiem
* lietotne2: kas ļauj pārvaldīt darbinieku darbu un piešķirt viņiem uzdevumus.

Mēs vēlamies izveidot mūsdienīgu un vienkāršu sistēmu, ar kuras palīdzību darba piešķiršana darbiniekam, kas lietotne2 nosūtīs paziņojumu klientam, izmantojot app1. Neskatoties uz šķietamību, tas ir ļoti vienkārši!

Sagatavošana

Šajā rakstā mēs izmantosim jaunāko Symfony versiju (6.1 versija rakstīšanas laikā) un jaunāko PHP versiju (8.1). Dažos ļoti vienkāršos soļos mēs izveidosim darbojošos vietējo Docker vide ar divām mikropakalpojumiem. Viss, kas jums nepieciešams, ir:
* darbojošos datoru,
* instalēta Docker + Docker Compose vide
* un lokāli konfigurētu Symfony CLI un nedaudz brīvā laika.

Runtime vide

Mēs izmantosim Docker kā lietojumprogrammu virtualizācijas un konteinerizācijas rīka iespējas. Sāksim, izveidojot direktoriju koku, sistēmu diviem Symfony lietojumprogrammas, un aprakstīt mūsu vides infrastruktūru, izmantojot docker-compose.yml failu.

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

Mēs esam izveidojuši divus direktorijus divām atsevišķām Symfony lietojumprogrammām un izveidojuši tukšu docker-compose.yml failu, lai palaistu mūsu vidi.

Pievienosim šādas sadaļas docker-compose.yml file:

versija: '3.8'

pakalpojumi:
app1:
containername: app1
build: app1/.
restart: on-failure
envfile: app1/.env
vide:
APPNAME: app1
tty: true
stdinopen: true

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

rabbitmq:
containername: rabbitmq
attēls: rabbitmq:management
ports:
- 15672:15672
- 5672:5672
vide:
- RABBITMQDEFAULTUSER=user
- RABBITMQDEFAULT_PASS=password

Avots: kods pieejams tieši: thecodest-co/microservices-in-symfony/blob/main/docker-compose.yml

Bet pagaidiet, kas šeit notika? Tiem, kas nav pazīstami ar Docker, iepriekš minētais konfigurācijas fails var šķist mīklains, tomēr tā mērķis ir ļoti vienkāršs. Izmantojot Docker Compose, mēs veidojam trīs "pakalpojumus":

  • app1: kas ir konteiners pirmajai Symfony lietojumprogrammai.
  • app2: kas ir konteiners otrajai Symfony lietojumprogrammai.
  • rabbitmq: RabbitMQ lietojumprogrammas attēls kā sakaru starpprogrammatūras slānis.

Lai nodrošinātu pareizu darbību, mums joprojām ir nepieciešams Dockerfile faili, kas ir avots attēlu veidošanai. Tāpēc izveidosim tos:

 touch app1/Dockerfile
 touch app2/Dockerfile

Abiem failiem ir tieši tāda pati struktūra, un tie izskatās šādi:

NO php:8.1

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

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

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

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

Palaidiet docker-php-ext-install zip;

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

Avota kods ir pieejams tieši: /thecodest-co/microservices-in-symfony/blob/main/app1/Dockerfile

Iepriekš minēto failu izmanto Docker Compose, lai izveidotu konteineru no PHP 8.1 attēla ar Kompozitoru un instalētu AMQP paplašinājumu. Turklāt tas palaiž PHP intepreter pievienošanas režīmā, lai konteiners darbotos fonā.

Tagad jūsu direktoriju un failu kokam vajadzētu izskatīties šādi:

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

Pirmā Symfony mikroservisa izveide

Sāksim ar app1 direktoriju un pirmo lietojumprogrammu.
Mūsu piemērā tā ir lietojumprogramma, kas klausās un patērē ziņojumus no rindas, ko sūta lietotne2 kā aprakstīts prasībās:

piešķirot darbu darbiniekam lietotne2 nosūtīs paziņojumu klientam

Sāksim ar nepieciešamo bibliotēku pievienošanu. AMQP ir dabiski atbalstīta symfony/messenger pagarinājums. Mēs papildus instalēsim monologs/monologs lai varētu sekot līdzi sistēmas žurnāliem, kas atvieglo lietojumprogrammu uzvedības analīzi.

 cd app1/
 symfony composer req amqp ampq-messenger monolog

Pēc instalēšanas tika pievienots papildu fails zem config/packages/messenger.yaml. Tas ir Symfony Messenger komponenta konfigurācijas fails, un mums tas nav nepieciešams. pilnīga konfigurācija.
Aizstājiet to ar tālāk norādīto YAML failu:

ietvars:
messenger:
# Atceliet šo (un zemāk norādīto neveiksmīgo transportu), lai uz šo transportu nosūtītu neveiksmīgus ziņojumus vēlākai apstrādei.
# failure_transport: failed

    transports:
        # https://symfony.com/doc/current/messenger.html#transport-configuration
        external_messages:
            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
            opcijas:
                auto_setup: false
                maiņa:
                    nosaukums: ziņojumi
                    tips: direct
                    default_publish_routing_key: from_external
                rindas:
                    : ziņojumi: ārējās: ārējās: ārējās: ārējās: ārējās: ārējās: ārējās
                        Saistošie_atslēgas: ziņojumi: ziņojumi: ziņojumi: saistošās_ atslēgas: [from_external]

Avota kods ir pieejams tieši: thecodest-co/microservices-in-symfony/blob/main/app1/config/packages/messenger.yaml

Symfony Messenger tiek izmantots sinhronajai un asinhronajai saziņai Symfony lietojumprogrammās. Tas atbalsta dažādas transportsvai transporta slāņa patiesības avoti. Mūsu piemērā mēs izmantojam AMQP paplašinājumu, kas atbalsta notikumu rindu sistēmu RabbitMQ.

Iepriekš minētā konfigurācija definē jaunu transportu ar nosaukumu external_messages, kas atsaucas uz MESSENGER_TRANSPORT_DSN vides mainīgo un definē tiešo klausīšanos uz ziņojumi ziņu kopnes kanāls. Šajā brīdī rediģējiet arī app1/.env failu un pievienojiet attiecīgo transporta adresi.

"`env

(...)
MESSENGERTRANSPORTDSN=amqp://user:password@rabbitmq:5672//messages
(...)
"
Pēc lietojumprogrammas ietvara sagatavošanas un bibliotēku konfigurēšanas ir pienācis laiks īstenot biznesa loģiku. Mēs zinām, ka mūsu lietojumprogrammai ir jāreaģē uz uzdevuma piešķiršanu darbiniekam. Mēs arī zinām, ka, piešķirot darbuapp2system, mainās darba statuss. Tāpēc izveidosim modeli, kas imitē statusa maiņu, un saglabāsim toapp1/Message/StatusUpdate.php` ceļā:
attēls
 {
publiskā funkcija __construct(protected string $status){}

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

}

Avota kods ir pieejams tieši: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Message/StatusUpdate.php

Mums joprojām ir nepieciešama klase, kas īstenos biznesa loģiku, kad mūsu mikroserviss saņem iepriekš minēto notikumu no rindas. Tātad izveidosim Ziņojuma apstrādātājs in the app1/Handler/StatusUpdateHandler.php ceļš:

attēls
 izmantot PsrLogLoggerInterface;
use SymfonyComponentMessengerAttributeAsMessageHandler;

[AsMessageHandler]

klase StatusUpdateHandler
{
publiskā funkcija __construct(
protected LoggerInterface $logger,
) {}

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

    $this->logger->brīdinājums('APP1: {STATUS_UPDATE} - '.$statusDescription);

    // pārējā biznesa loģika, t. i., e-pasta nosūtīšana lietotājam
    // $this->emailService->email()
}

}

Avota kods ir pieejams tieši: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Handler/StatusUpdateHandler.php

PHP atribūti ievērojami atvieglo darbu un nozīmē, ka šajā konkrētajā gadījumā mums nav jāuztraucas par automātisko vadu vai servisa deklarāciju. Mūsu mikroserviss domēna notikumu apstrādei ir gatavs, ir pienācis laiks ķerties pie otrās lietojumprogrammas.

Otra Symfony mikroservisa pakalpojums

Mēs aplūkosim lietotne2 direktoriju un otro Symfony lietojumprogramma. Mūsu ideja ir nosūtīt ziņojumu uz rindu, kad sistēmā darbiniekam tiek piešķirts uzdevums. Veiksim ātru AMQP konfigurāciju un sāksim publicēt mūsu otro mikroservisu. StatusUpdate notikumi uz ziņojumu kopni.

Bibliotēku instalēšana ir tieši tāda pati kā pirmajā lietojumprogrammā.

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

Pārliecināsimies, ka app2/.env failā ir derīgs DSN ieraksts RabbitMQ:

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

Atliek tikai konfigurēt Symfony Messenger programmā app2/config/packages/messenger.yaml file:

ietvars:
messenger:
# Atceliet šo (un zemāk norādīto neveiksmīgo transportu), lai uz šo transportu nosūtītu neveiksmīgus ziņojumus vēlākai apstrādei.
# failure_transport: failed

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

    maršrutēšana:
        # Novirzīt ziņojumus uz transportu
        'AppMessageStatusUpdate': async

Kā redzat, šoreiz transporta definīcija norāda tieši uz async un definē maršrutēšanu, nosūtot mūsu StatusUpdate ziņojumu uz konfigurēto DSN. Šī ir vienīgā konfigurācijas joma, atliek tikai izveidot AMQP rindas loģiku un īstenošanas slāni. Šim nolūkam mēs izveidosim dvīņu StatusUpdateHandler un StatusUpdate klases lietotne2.

attēls
 izmantot PsrLogLoggerInterface;
use SymfonyComponentMessengerAttributeAsMessageHandler;

[AsMessageHandler]

klase StatusUpdateHandler
{
publiskā funkcija __construct(
private readonly LoggerInterface $logger,
) {}

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

    $this->logger->brīdinājums('APP2: {STATUS_UPDATE} - '.$statusDescription);

    ## darbības loģika, t. i., iekšējā paziņojuma nosūtīšana vai rindas veidošana citās sistēmās
}

}
attēls
 {
publiskā funkcija __construct(protected string $status){}

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

}


Avota kods ir pieejams tieši: /thecodest-co/microservices-in-symfony/blob/main/app2/src/Message/StatusUpdate.php

Visbeidzot, atliek tikai izveidot veidu, kā nosūtīt ziņojumu uz ziņojumu kopni. Mēs izveidosim vienkāršu Symfony komanda šim nolūkam:

attēls
izmantot SymfonyComponentConsoleAttributeAsCommand;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
use SymfonyComponentMessengerMessageBusInterface;

[AsCommand(

name: "app:send"

)]
klase SendStatusCommand extends 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(
        ziņojums: new StatusUpdate($status)
    );

    return Command::SUCCESS;
}

}

Paldies Atkarību ieiegriešana mēs varam izmantot MessageBusInterface mūsu komandā un nosūtiet StatusUpdate ziņojumu, izmantojot nosūtīšana() metode mūsu rindā. Turklāt mēs šeit izmantojam arī PHP atribūtus.

Tas ir viss - atliek tikai palaist mūsu Docker Compose vidi un apskatīt, kā uzvedīsies mūsu lietojumprogrammas.

Vides palaišana un testēšana

Izmantojot Docker Compose, konteineri ar mūsu divām lietojumprogrammām tiks izveidoti un palaisti kā atsevišķi gadījumi, un vienīgais starpprogrammatūras slānis būs rabbitmq konteiners un mūsu ziņojumu kopnes implementācija.

No projekta saknes direktorija palaidīsim šādas komandas:

cd ../ # pārliecinieties, ka atrodaties galvenajā direktorijā
 docker-compose up --build -d

Šī komanda var aizņemt kādu laiku, jo tā izveido divus atsevišķus konteinerus ar PHP 8.1 + AMQP un velk RabbitMQ attēlu. Esiet pacietīgi. Pēc tam, kad attēli ir izveidoti, varat palaist mūsu komandu no lietotne2 un nosūtīt dažus ziņojumus uz rindu.

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

Jūs varat to darīt tik reižu, cik vien varat. Kamēr nav patērētājs jūsu ziņojumi netiks apstrādāti. Tiklīdz iedarbināsiet app1 un izmantot visus ziņojumus, kas tiek rādīti ekrānā.

docker exec -it app1 php bin/console messenger:consume -vvv external_messages
attēls

Pilnīga avota kods kopā ar README var atrast mūsu publiskajā repozitorijā The Codest Github

Kopsavilkums

Symfony ar tās bibliotēkām un rīkiem ļauj ātri un efektīvi izstrādāt modernu tīmekļa vietne lietojumprogrammas. Ar dažām komandām un dažām koda rindiņām mēs varam izveidot mūsdienīgu saziņas sistēmu starp lietojumprogrammām. Symfony, tāpat kā PHP, ir ideāli piemērots tīmekļa lietojumprogrammu izstrāde un, pateicoties tās ekosistēmai un vieglai ieviešanai, šī ekosistēma sasniedz vienus no labākajiem tirgus ieviešanas laika rādītājiem.

Tomēr ātrs ne vienmēr nozīmē labs - iepriekš minētajā piemērā mēs piedāvājām vienkāršāko un ātrāko saziņas veidu. Zinātkārākie noteikti pamanīs, ka trūkst domēna notikumu atslēgšanas ārpus lietojumprogrammu slāņa - pašreizējā versijā tie tiek dublēti, un nav pilnīga atbalsta Aploksne, cita starpā nav Pastmarkas. Šiem un citiem interesentiem aicinu izlasīt II daļu, kurā aplūkosim tēmu par Symfony lietojumprogrammu domēna struktūras unifikāciju mikropakalpojumu vidē un apspriedīsim otru populāro mikropakalpojumu saziņas metodi - šoreiz sinhrono, kas balstīta uz REST API.

sadarbības baneris

Saistītie raksti

Abonējiet mūsu zināšanu bāzi un saņemiet jaunāko informāciju par IT nozares pieredzi.

    Par mums

    The Codest - starptautisks programmatūras izstrādes uzņēmums ar tehnoloģiju centriem Polijā.

    Apvienotā Karaliste - Galvenā mītne

    • 303B birojs, 182-184 High Street North E6 2JA
      Londona, Anglija

    Polija - Vietējie tehnoloģiju centri

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Krakova
    • Brain Embassy, Konstruktorska
      11, 02-673 Varšava, Polija

      The Codest

    • Sākums
    • Par mums
    • Pakalpojumi
    • Case Studies
    • Zināt, kā
    • Karjera
    • Vārdnīca

      Pakalpojumi

    • Tā Konsultatīvais dienests
    • Programmatūras izstrāde
    • Backend izstrāde
    • Frontend izveide
    • Staff Augmentation
    • Backend izstrādātāji
    • Mākoņa inženieri
    • Datu inženieri
    • Citi
    • QA inženieri

      Resursi

    • Fakti un mīti par sadarbību ar ārējo programmatūras izstrādes partneri
    • No ASV uz Eiropu: Kāpēc Amerikas jaunuzņēmumi nolemj pārcelties uz Eiropu?
    • Tehnoloģiju ārzonas attīstības centru salīdzinājums: Tech Offshore Eiropa (Polija), ASEAN (Filipīnas), Eirāzija (Turcija)
    • Kādi ir galvenie CTO un CIO izaicinājumi?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Autortiesības © 2026 The Codest. Visas tiesības aizsargātas.

    lvLatvian
    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 lt_LTLithuanian lvLatvian