The Codest
  • O nás
  • Služby
    • Vývoj softwaru
      • Vývoj frontendů
      • Vývoj backendu
    • Staff Augmentation
      • Vývojáři frontendů
      • Vývojáři backendu
      • Datoví inženýři
      • Cloudoví inženýři
      • Inženýři QA
      • Další
    • To Advisory
      • Audit a poradenství
  • Odvětví
    • Fintech a bankovnictví
    • E-commerce
    • Adtech
    • Healthtech
    • Výroba
    • Logistika
    • Automobilový průmysl
    • IOT
  • Hodnota za
    • CEO
    • CTO
    • Manažer dodávek
  • Náš tým
  • Case Studies
  • Vědět jak
    • Blog
    • Setkání
    • Webové semináře
    • Zdroje
Kariéra Spojte se s námi
  • O nás
  • Služby
    • Vývoj softwaru
      • Vývoj frontendů
      • Vývoj backendu
    • Staff Augmentation
      • Vývojáři frontendů
      • Vývojáři backendu
      • Datoví inženýři
      • Cloudoví inženýři
      • Inženýři QA
      • Další
    • To Advisory
      • Audit a poradenství
  • Hodnota za
    • CEO
    • CTO
    • Manažer dodávek
  • Náš tým
  • Case Studies
  • Vědět jak
    • Blog
    • Setkání
    • Webové semináře
    • Zdroje
Kariéra Spojte se s námi
Šipka zpět ZPĚT
2022-06-28
Vývoj softwaru

Symfony: Komunikace mikroslužeb část I

The Codest

Sebastian Luczak

PHP Vedoucí jednotky

Přečtěte si první díl seriálu PHP věnovaný komunikaci mikroslužeb ve frameworku Symfony a nejoblíbenějšímu způsobu - komunikaci AMQP pomocí RabbitMQ.

Moderní architektura aplikací donutila vývojáře změnit způsob uvažování o komunikaci mezi různými komponentami IT systémů. Kdysi byla věc jednodušší - většina systémů byla vytvářena jako monolitické struktury propojené navzájem sítí vazeb obchodní logiky. Udržování takových závislostí v PHP projekt byla pro Vývojáři PHPa rostoucí popularita SaaS řešení a obrovský nárůst popularity cloud služby způsobily, že dnes stále častěji slyšíme o mikroslužby a modularita aplikací.

Jak můžeme vytvořením nezávislých mikroslužeb dosáhnout toho, aby si mezi sebou vyměňovaly informace?

Tento článek je prvním ze série příspěvků o komunikace mikroslužeb v Symfony a pokrývá nejoblíbenější způsob - komunikaci AMQP pomocí RabbitMQ.

Cíl

Vytvoření dvou nezávislých aplikací a dosažení komunikace mezi nimi pouze pomocí sběrnice Message Bus.

Koncept

Máme dvě pomyslné nezávislé aplikace:
* app1: který zasílá zaměstnancům e-mailová a SMS oznámení
* app2: který umožňuje řídit práci zaměstnanců a přidělovat jim úkoly.

Chceme vytvořit moderní a jednoduchý systém, v němž bude přidělování práce zaměstnanci v rámci app2 odešle zákazníkovi oznámení pomocí app1. Navzdory zdání je to velmi jednoduché!

Příprava

Pro účely tohoto článku použijeme nejnovější verzi Symfony (v době psaní článku verze 6.1) a nejnovější verzi PHP (8.1). V několika velmi jednoduchých krocích vytvoříme funkční lokální Docker prostředí se dvěma mikroslužbami. Vše, co potřebujete, je:
* funkční počítač,
* nainstalovaný Docker + Prostředí Docker Compose
* a místně nakonfigurovanou Symfony CLI a nějaký volný čas.

Prostředí runtime

Využijeme možnosti nástroje Docker jako nástroje pro virtualizaci a kontejnerizaci aplikací. Začneme vytvořením adresářového stromu, rámce pro dva Aplikace Symfony, a popsat infrastrukturu našich prostředí pomocí docker-compose.yml soubor.

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

Vytvořili jsme dva adresáře pro dvě samostatné aplikace Symfony a vytvořili prázdný adresář docker-compose.yml spustit naše prostředí.

Přidejme následující sekce do docker-compose.yml file:

verze: '3.8'

služby:
app1:
containername: app1
build: app1/.
restart: při selhání
envfile: app1/.env
environment:
APPNAME: app1
tty: true
stdinopen: true

app2:
containername: app2
build: app2/.
restart: při selhání
envfile: app2/.env
environment:
APPNAME: app2
tty: true
stdinopen: true

rabbitmq:
containername: rabbitmq
image: rabbitmq:management
ports:
- 15672:15672
- 5672:5672
prostředí:
- RABBITMQDEFAULTUSER=user
- RABBITMQDEFAULT_PASS=password

Zdroj: kód k dispozici přímo: thecodest-co/microservices-in-symfony/blob/main/docker-compose.yml

Ale počkejte, co se tu stalo? Těm, kdo neznají Docker, se výše uvedený konfigurační soubor může zdát záhadný, jeho účel je však velmi jednoduchý. Pomocí nástroje Docker Compose vytváříme tři "služby":

  • app1: což je kontejner pro první aplikaci Symfony
  • app2: což je kontejner pro druhou aplikaci Symfony
  • rabbitmq: obraz aplikace RabbitMQ jako komunikační middleware vrstvy

Pro správnou funkci stále potřebujeme Soubor Dockerfile soubory, které jsou zdrojem pro vytváření obrazů. Pojďme je tedy vytvořit:

 touch app1/Dockerfile
 touch app2/Dockerfile

Oba soubory mají naprosto stejnou strukturu a vypadají následovně:

Z 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/

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

Spustit 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/*

Spustit docker-php-ext-install zip;

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

Zdrojový kód je k dispozici přímo: /thecodest-co/microservices-in-symfony/blob/main/app1/Dockerfile

Výše uvedený soubor používá nástroj Docker Compose k sestavení kontejneru z obrazu PHP 8.1 s nainstalovaným nástrojem Composer a rozšířením AMQP. Navíc spustí intepreter PHP v režimu doplňování, aby kontejner běžel na pozadí.

Strom adresářů a souborů by nyní měl vypadat následovně:

 .
 ├── app1
 │ └── Dockerfile
 | (...) # Struktura aplikace Symfony
 ├── app2
 │ └── Dockerfile
 | (...) # Struktura aplikace Symfony
 └── docker-compose.yml

První mikroslužba Symfony

Začněme s app1 a první aplikaci.
V našem příkladu se jedná o aplikaci, která naslouchá a přijímá zprávy z fronty odeslané pomocí nástroje app2 jak je popsáno v požadavcích:

přiřazení práce pracovníkovi v app2 odešle klientovi oznámení

Začněme přidáním požadovaných knihoven. AMQP je nativně podporováno pro symfony/messenger rozšíření. Navíc nainstalujeme monolog/monolog sledovat systémové protokoly pro snadnější analýzu chování aplikací.

 cd app1/
 symfony composer req amqp ampq-messenger monolog

Po instalaci byl přidán další soubor pod položkou config/packages/messenger.yaml. Jedná se o konfigurační soubor pro komponentu Symfony Messenger a my nepotřebujeme jeho úplná konfigurace.
Nahraďte jej níže uvedeným souborem YAML:

rámec:
messenger:
# Odkomentujte tuto položku (a níže uvedený neúspěšný transport), abyste neúspěšné zprávy odesílali na tento transport pro pozdější zpracování.
# failure_transport: failed

    transporty:
        # https://symfony.com/doc/current/messenger.html#transport-configuration
        external_messages:
            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
            options:
                auto_setup: false
                exchange:
                    name: messages
                    type: direct
                    default_publish_routing_key: from_external
                fronty:
                    Zprávy: externí: zprávy:
                        binding_keys: [from_external]

Zdrojový kód je k dispozici přímo: thecodest-co/microservices-in-symfony/blob/main/app1/config/packages/messenger.yaml

Symfony Messenger se používá pro synchronní a asynchronní komunikaci v aplikacích Symfony. Podporuje řadu transportynebo zdroje pravdy dopravní vrstvy. V našem příkladu používáme rozšíření AMQP, které podporuje systém front událostí RabbitMQ.

Výše uvedená konfigurace definuje nový transport s názvem external_messages, který odkazuje na MESSENGER_TRANSPORT_DSN a definuje přímé naslouchání na zprávy kanál ve sběrnici zpráv. V tomto okamžiku také upravte app1/.env a přidejte příslušnou transportní adresu.

"`env

(...)
MESSENGERTRANSPORTDSN=amqp://user:password@rabbitmq:5672//messages
(...)
"
Po přípravě aplikačního rámce a konfiguraci knihoven je čas implementovat obchodní logiku. Víme, že naše aplikace musí reagovat na přiřazení úlohy pracovníkovi. Víme také, že přiřazení úlohy v systémuapp2system změní stav úlohy. Vytvoříme tedy model, který napodobuje změnu stavu, a uložíme jej do cestyapp1/Message/StatusUpdate.php`:
obrázek
 {
public function __construct(protected string $status){}

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

}

Zdrojový kód je k dispozici přímo: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Message/StatusUpdate.php

Ještě potřebujeme třídu, která bude implementovat obchodní logiku, když naše mikroslužba obdrží výše uvedenou událost z fronty. Vytvořme tedy třídu Obsluha zpráv v app1/Handler/StatusUpdateHandler.php cesta:

obrázek
 použít PsrLogLoggerInterface;
use SymfonyComponentMessengerAttributeAsMessageHandler;

[AsMessageHandler]

class StatusUpdateHandler
{
public function __construct(
protected LoggerInterface $logger,
) {}

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

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

    // zbytek obchodní logiky, tj. odeslání e-mailu uživateli
    // $this->emailService->email()
}

}

Zdrojový kód je k dispozici přímo: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Handler/StatusUpdateHandler.php

PHP atributy značně usnadňují práci a znamenají, že se v tomto konkrétním případě nemusíme starat o automatické zapojení nebo servisní prohlášení. Naše mikroslužba pro zpracování událostí domény je připravena, je čas pustit se do druhé aplikace.

Druhá mikroslužba Symfony

Podíváme se na app2 a druhý adresář Aplikace Symfony. Naší myšlenkou je poslat zprávu do fronty, když je pracovníkovi v systému přidělen úkol. Provedeme tedy rychlou konfiguraci AMQP a přimějeme naši druhou mikroslužbu, aby začala publikovat. StatusUpdate události do sběrnice zpráv.

Instalace knihoven je úplně stejná jako u první aplikace.

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

Ujistěme se, že app2/.env obsahuje platnou položku DSN pro RabbitMQ:

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

Zbývá jen nakonfigurovat aplikaci Symfony Messenger v adresáři app2/config/packages/messenger.yaml file:

rámec:
messenger:
# Odkomentujte tuto položku (a níže uvedený neúspěšný transport), abyste neúspěšné zprávy odesílali na tento transport pro pozdější zpracování.
# failure_transport: failed

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

    routing:
        # Směrování zpráv na transporty
        'AppMessageStatusUpdate': async

Jak vidíte, tentokrát definice transportu směřuje přímo k asynchronní a definuje směrování v podobě odeslání našeho StatusUpdate zprávu do nakonfigurované sítě DSN. To je jediná oblast konfigurace, zbývá jen vytvořit logickou a implementační vrstvu fronty AMQP. Za tímto účelem vytvoříme dvojče StatusUpdateHandler a StatusUpdate třídy v app2.

obrázek
 použít PsrLogLoggerInterface;
use SymfonyComponentMessengerAttributeAsMessageHandler;

[AsMessageHandler]

class StatusUpdateHandler
{
public function __construct(
private readonly LoggerInterface $logger,
) {}

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

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

    ## obchodní logika, tj. odeslání interního oznámení nebo zařazení do fronty některých jiných systémů
}

}
obrázek
 {
public function __construct(protected string $status){}

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

}


Zdrojový kód je k dispozici přímo: /thecodest-co/microservices-in-symfony/blob/main/app2/src/Message/StatusUpdate.php

Nakonec zbývá jen vytvořit způsob, jak odeslat zprávu do sběrnice zpráv. Vytvoříme jednoduchý Příkaz Symfony k tomu:

obrázek
použít SymfonyComponentConsoleAttributeAsCommand;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
use SymfonyComponentMessengerMessageBusInterface;

[AsCommand(

name: "app:send"

)]
class 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(
        zpráva: new StatusUpdate($status)
    );

    return Command::SUCCESS;
}

}

Díky Vstřikování závislostí můžeme použít instanci MessageBusInterface v našem příkazu a odeslat StatusUpdate zprávu prostřednictvím dispatch() do naší fronty. Kromě toho zde používáme také atributy PHP.

To je vše - zbývá jen spustit prostředí Docker Compose a zjistit, jak se naše aplikace chovají.

Spuštění prostředí a testování

Pomocí nástroje Docker Compose budou kontejnery s našimi dvěma aplikacemi sestaveny a spuštěny jako samostatné instance, jedinou vrstvou middlewaru bude nástroj rabbitmq kontejneru a naší implementace sběrnice Message Bus.

Z kořenového adresáře projektu spusťme následující příkazy:

cd ../ # ujistěte se, že jste v hlavním adresáři
 docker-compose up --build -d

Tento příkaz může chvíli trvat, protože vytváří dva samostatné kontejnery s PHP 8.1 + AMQP a stahuje obraz RabbitMQ. Buďte trpěliví. Po sestavení obrazů můžete spustit náš příkaz z adresy app2 a odeslat některé zprávy do fronty.

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

Můžete to udělat tolikrát, kolikrát jen můžete. Dokud není spotřebitel vaše zprávy nebudou zpracovány. Jakmile spustíte app1 a spotřebovat všechny zprávy, které se zobrazí na obrazovce.

docker exec -it app1 php bin/console messenger:consume -vv externí_zprávy
obrázek

Kompletní zdrojový kód spolu s README naleznete v našem veřejném úložišti The Codest Github

Souhrn

Symfony se svými knihovnami a nástroji umožňuje rychlý a efektivní přístup k vývoji moderních technologií. webové aplikace. Pomocí několika příkazů a několika řádků kódu jsme schopni vytvořit moderní komunikační systém mezi aplikacemi. Symfony, stejně jako PHP, je ideální pro vývoj webových aplikací a díky svému ekosystému a snadné implementaci tento ekosystém dosahuje jedněch z nejlepších ukazatelů doby uvedení na trh.

Rychlost však nemusí vždy znamenat kvalitu - ve výše uvedeném příkladu jsme uvedli nejjednodušší a nejrychlejší způsob komunikace. Zvídavější si jistě všimnou, že chybí odpojování doménových událostí mimo aplikační vrstvu - v současné verzi se duplikují a chybí plná podpora pro tzv. Obálka, mimo jiné není Známky. Pro tyto a další zájemce vás zvu k přečtení druhého dílu, kde se budeme věnovat tématu sjednocení doménové struktury aplikací Symfony v prostředí mikroslužeb a probereme druhou populární metodu komunikace mikroslužeb - tentokrát synchronní, založenou na rozhraní REST API.

banner spolupráce

Související články

Vývoj softwaru

PHP 8.2: Co je nového?

Nová verze PHP je již za rohem. O jakých nových implementacích byste měli vědět? Podívejte se na tento článek a zjistěte to!

The Codest
Sebastian Luczak PHP Vedoucí jednotky
Vývoj softwaru

PHP Vývoj. Komponenta Symfony Console - Tipy a triky

Tento článek byl vytvořen s cílem ukázat vám nejužitečnější a nejpoužívanější tipy a triky o vývoji konzole Symfony.

The Codest
Sebastian Luczak PHP Vedoucí jednotky

Přihlaste se k odběru naší znalostní databáze a získejte aktuální informace o odborných znalostech z oblasti IT.

    O nás

    The Codest - Mezinárodní společnost zabývající se vývojem softwaru s technologickými centry v Polsku.

    Spojené království - ústředí

    • Kancelář 303B, 182-184 High Street North E6 2JA
      Londýn, Anglie

    Polsko - Místní technologická centra

    • Kancelářský park Fabryczna, Aleja
      Pokoju 18, 31-564 Krakov
    • Brain Embassy, Konstruktorska
      11, 02-673 Varšava, Polsko

      The Codest

    • Home
    • O nás
    • Služby
    • Case Studies
    • Vědět jak
    • Kariéra
    • Slovník

      Služby

    • To Advisory
    • Vývoj softwaru
    • Vývoj backendu
    • Vývoj frontendů
    • Staff Augmentation
    • Vývojáři backendu
    • Cloudoví inženýři
    • Datoví inženýři
    • Další
    • Inženýři QA

      Zdroje

    • Fakta a mýty o spolupráci s externím partnerem pro vývoj softwaru
    • Z USA do Evropy: Proč se americké startupy rozhodly přesídlit do Evropy?
    • Srovnání technických vývojových center v zahraničí: Tech Offshore Evropa (Polsko), ASEAN (Filipíny), Eurasie (Turecko)
    • Jaké jsou hlavní výzvy CTO a CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2026 by The Codest. Všechna práva vyhrazena.

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