Symfony: Samskipti örþjónusta, hluti I
Lesið fyrsta hluta af PHP-seríunni okkar sem fjallar um örþjónustutengingar í Symfony-rammanum og vinsælasta aðferðina – AMQP-samskipti með RabbitMQ.
Hér er tómt.Nútíma forritagerð hefur þvingað forritara til að breyta hugsunarhætti sínum varðandi samskipti milli mismunandi þátta upplýsingatæknikerfa. Áður var málið einfaldara – flest kerfi voru búin til sem einheildarbyggingar tengdar saman með neti viðskiptalegra tenginga. Viðhald slíkra háðatengsla í a PHP verkefni var gríðarleg áskorun fyrir PHP forritarar, og vaxandi vinsældir SaaS lausnir og gífurleg aukning í vinsældum ský þjónustur hafa valdið því að í dag heyrum við sífellt meira um örþjónustur og forritamódelgerð.
Hvernig getum við, með því að búa til sjálfstæðar örþjónustur, látið þær skiptast á upplýsingum sín á milli?
Þessi grein er sú fyrsta í röð færslna um Samskipti örþjónusta í Symfony rammi og hann fjallar um vinsælasta aðferðina – AMQP-samskipti með RabbitMQ.
Markmið
Að búa til tvær sjálfstæðar forritanir og koma á samskiptum milli þeirra með því að nota eingöngu skilaboðabyssu.
Hugmyndin
Við höfum tvær ímyndaðar, sjálfstæðar forritanir:
* app1sem sendir tölvupóst- og SMS-tilkynningar til starfsmanna
* app2sem gerir þér kleift að stýra vinnu starfsmanna og úthluta þeim verkefnum.
Við viljum búa til nútímalegt og einfalt kerfi þar sem vinnu er úthlutað til starfsmanns í app2 mun senda tilkynningu til viðskiptavinarins með app1. Þrátt fyrir útlit er þetta mjög einfalt!
Undirbúningur
Tilgangur þessa greinar er að nota nýjustu útgáfu Symfony (útgáfa 6.1 við ritun) og nýjustu útgáfu PHP (8.1). Í nokkrum mjög einföldum skrefum munum við búa til virkt staðbundið Docker umhverfi með tveimur örþjónustum. Allt sem þú þarft er:
* virkt tölvu,
Setti upp Docker + Docker Compose umhverfi
* og staðbundið stillt Symfony skipanalína og smá frítíma.
Keyrslutímaumhverfi
Við munum nota möguleika Docker sem tól til forritavirtualunar og ílátavirtualunar. Byrjum á því að búa til möppuuppbyggingu, ramma fyrir tvö Symfony-forrit, og lýsa innviðum umhverfa okkar með því að nota docker-compose.yml skrá.
cd ~
mkdir microservices-in-symfony
cd microservices-in-symfony
symfony new app1
symfony new app2
touch docker-compose.ymlHljóðskrift
Við höfum búið til tvær skráarstjóra fyrir tvær aðskildar Symfony-forrit og búið til tóma docker-compose.yml Skrá til að ræsa umhverfi okkar.
Bætum eftirfarandi köflum við docker-compose.yml file:
útgáfa: '3.8'
þjónustur:
app1:
ílátsnafn: app1
smíði: app1/.
endurupphaf: við bilun
umhverfisskrá: app1/.env
umhverfi:
APPNAME: app1
tty: satt
stdinopnun: satt
app2:
ílátsnafn: app2
smíði: app2/.
restart: on-failure
envfile: app2/.env
environment:
APPNAME: app2
tty: true
stdinopen: true
rabbitmq:
containername: rabbitmq
image: rabbitmq:management
ports:
- 15672:15672
- 5672:5672
umhverfi:
- RABBITMQDEFAULTUSER=notandi
- RABBITMQDEFAULT_PASS=leyfilord
Heimild kóði fáanlegt beint: thecodest-co/örþjónustur-í-symfony/blob/aðal/docker-compose.yml
En bíddu, hvað gerðist hér? Fyrir þá sem ekki þekkja Docker getur ofangreind stillingarskrá virst ráðgátukennd, en tilgangur hennar er mjög einfaldur. Með Docker Compose erum við að byggja upp þrjár “þjónustur”:
- app1: sem er gámur fyrir fyrstu Symfony-forritið
- app2: sem er ílátið fyrir annað Symfony-forritið
- rabbitmq: RabbitMQ forritamynd sem miðlaraþrep í samskiptum
Til að tryggja eðlilega virkni þurfum við ennþá Dockerfile skrár sem eru uppspretta til að byggja myndirnar. Svo skulum við búa þær til:
touch app1/Dockerfile
touch app2/DockerfileHljóðskrift
Báðar skrárnar hafa nákvæmlega sömu uppbyggingu og líta svona út:
FROM 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/
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-install-recommends
&& apt-get clean
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN docker-php-ext-install zip;
CMD bash -c "cd /app && composer install && php -a"
Uppsprettukóði er fáanlegur beint: /thecodest-co/örþjónustur-í-symfony/blob/aðal/app1/Dockerfile
Skráin hér að ofan er notuð af Docker Compose til að byggja gám út frá PHP 8.1 mynd með Composer og AMQP-viðbótinni uppsetta. Að auki keyrir hún PHP-túlkarann í viðbótarham til að halda gámnum gangandi í bakgrunni.
Skjalastjórnunarkerfið þitt og skráartréð ættu nú að líta svona út:
.
├── app1
│ └── Dockerfile
| (...) # Uppbygging Symfony-forrits
├── app2
│ └── Dockerfile
| (...) # Uppbygging Symfony-forrits
└── docker-compose.ymlHljóðskrift
Fyrsta Symfony örþjónustan
Skulum byrja á app1 Skjaldeili og fyrsta forritið.
Í dæminu okkar er þetta forrit sem hlustar á og neytir skilaboða úr biðröðinni sem send eru af app2 eins og lýst er í kröfunum:
úthluta starfi til verkamanns í
app2mun senda tilkynningu til viðskiptavinarins
Byrjum á því að bæta við nauðsynlegum bókasöfnum. AMQP er innfæddur stuðningur fyrir symfony/sendi viðbót. Við munum einnig setja upp mónólóg/mónólóg til að fylgjast með kerfislógum til að auðvelda greiningu á hegðun forritsins.
cd app1/
symfony composer req amqp ampq-messenger monologHljóðskrift
Eftir uppsetninguna var bætt við viðbótarskrá undir stillingar/pakkar/sendiherra.yaml. Þetta er stillingarskrá fyrir Symfony Messenger-hlutann og við þurfum hana ekki fullkomið uppsetning.
Skiptu því út fyrir YAML-skrána hér að neðan:
rammi:
sendiherra:
# Athugaðu þessa línu (og misheppnaða flutninginn hér að neðan) til að senda misheppnuð skilaboð til þessa flutnings til frekari vinnslu.
# failure_transport: failed
flutningar:
# https://symfony.com/doc/current/messenger.html#transport-configuration
ytri_skilaboð:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
auto_setup: false
exchange:
name: messages
type: direct
default_publish_routing_key: from_external
queues:
messages:
binding_keys: [from_external]
Uppsprettukóði er fáanlegur beint: thecodest-co/örþjónustur-í-symfony/blob/aðal/app1/stillingar/pakkar/messenger.yaml
Symfony Messenger er notað til samstilltrar og ósamstilltrar samskipta í Symfony-forritum. Það styður fjölbreytt úrval af flutningar, eða sannleikskelda flutningslagsins. Í dæminu okkar notum við AMQP-viðbótina sem styður RabbitMQ atburðaraðarröðarkerfið.
Ofangreind stilling skilgreinir nýjan flutning sem nefndur er Ytri skilaboð, sem vísar til MESSENGER_TRANSPORT_DSN umhverfisbreytur og skilgreinir beina hlustun á skilaboð rás í skilaboðabyssu. Á þessum tímapunkti, breyttu einnig app1/.env Skrá og bæta við viðeigandi flutningsfangi.
“`env
(…)
MESSENGERTRANSPORTDSN=amqp://user:password@rabbitmq:5672//messages
(…)
“
Eftir að hafa undirbúið forritarammann og stillt bókasöfnin er kominn tími til að innleiða viðskiptalógíkina. Við vitum að forritið okkar þarf að bregðast við þegar starfi er úthlutað til starfsmanns. Við vitum líka að úthlutun starfs í inapp2system breytir stöðu þess. Svo skulum við búa til líkan sem hermir eftir stöðubreytingunni og vista það í slóðinni `app1/Message/StatusUpdate.php`:

{
public function __construct(protected string $status){}
public function getStatus(): string
{
return $this->status;
}
}
Uppsprettukóði er fáanlegur beint: /thecodest-co/örþjónustur-í-symfony/blob/aðal/app1/uppspretta/Skilaboð/StaðaUppfærsla.php
Við þurfum ennþá bekk sem mun innleiða viðskiptalógikann þegar okkar örþjónusta fær ofangreinda atburð úr biðröðinni. Svo skulum við búa til Skilaboðameðhöndlari í app1/Handler/StatusUpdateHandler.php leið:

use 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);
// restin af viðskiptalógíkinni, þ.e. að senda tölvupóst til notanda
// $this->emailService->email()
}
}
Uppsprettukóði er fáanlegur beint: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Handler/StatusUpdateHandler.php
PHP Eiginleikar gera hlutina mun auðveldari og þýða að í þessu tiltekna tilfelli þurfum við ekki að hafa áhyggjur af sjálfvirkri tengingu né þjónustuyfirlýsingu. örþjónustan okkar til að meðhöndla sviðsviðburði er tilbúin, nú er kominn tími til að hefja vinnu við aðra forritið.
Önnur Symfony örþjónusta
Við munum líta á app2 skrá og annar Symfony-forrit. Hugmyndin okkar er að senda skilaboð í biðröðina þegar starfsmaður fær verkefni úthlutað í kerfinu. Svo skulum við fljótt stilla AMQP og láta annan örþjónustuna okkar byrja að birta. Staðfesting uppfærslu atburðir til skilaboðabussins.
Að setja upp bókasöfnin er nákvæmlega það sama og fyrir fyrstu forritið.
cd ..
cd app2/
symfony composer req amqp ampq-messenger monologHljóðskrift
Við skulum ganga úr skugga um að app2/.env Skráin inniheldur gilda DSN-færslu fyrir RabbitMQ:
(...)
MESSENGER_TRANSPORT_DSN=amqp://notandi:lykill@rabbitmq:5672//messages
(...)Hljóðskrift
Það sem eftir er að stilla Symfony Messenger í app2/config/packages/messenger.yaml file:
rammi:
sendiþjónn:
# Afkommentaðu þetta (og misheppnaða flutninginn hér að neðan) til að senda misheppnuð skilaboð til þessa flutnings til frekari vinnslu.
# failure_transport: misheppnaður
flutningar:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
# Leiðir skilaboðin þín til flutninganna
'AppMessageStatusUpdate': async
Eins og þú sérð bendir skilgreining flutningsins nú beint á ósamstilltur og skilgreinir leiðsögn í formi sendingar okkar Staðfesting uppfærslu Skilaboð til stillts DSN. Þetta er eini hluti stillinganna; allt sem eftir er er að búa til röksemdafærslu- og framkvæmdarlag AMQP-raðarinnar. Fyrir þetta munum við búa til tvíburann Staðfestingaruppfærsluhöndlari og Staðfesting uppfærslu tímar í app2.

use 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);
## viðskiptalógík, þ.e. að senda innri tilkynningu eða raða í biðröð öðrum kerfum
}
}

{
public function __construct(protected string $status){}
public function getStatus(): string
{
return $this->status;
}
}
Uppsprettukóði er fáanlegur beint: /thecodest-co/örþjónustur-í-symfony/blob/aðal/app2/uppspretta/Skilaboð/Staðsetningaruppfærsla.php
Að lokum þarf aðeins að búa til leið til að senda skilaboð til skilaboðabussins. Við munum búa til einfalda Symfony skipun fyrir þetta:

use 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 = "Verkmaður X úthlutaður til Y";
$this->messageBus->dispatch(
message: new StatusUpdate($status)
);
return Command::SUCCESS;
}
}
Þökk sé Áhættuprófun Við getum notað eintak af Skilaboðabussviðmót í okkar skipun og sendu a Staðfesting uppfærslu skilaboð í gegnum sendast() aðferð í biðröðinni okkar. Auk þess notum við hér einnig PHP-eiginleika.
Þetta er það – allt sem eftir er að gera er að keyra Docker Compose-umhverfið okkar og sjá hvernig forritin okkar haga sér.
Kjørum umhverfið og prófum
Með Docker Compose verða gámarnir með tvö forritin okkar smíðaðir og keyrðir sem aðskildar einingar, eini milliforritslagið verður rabbitmq ílát og okkar Message Bus-framkvæmd.
Frá rótaröppum verkefnisins skulum við keyra eftirfarandi skipanir:
cd ../ # vertu viss um að þú sért í aðalmappunni
docker-compose up --build -dHljóðskrift
Þessi skipun getur tekið nokkurn tíma, þar sem hún byggir tvo aðskilda gám með PHP 8.1 + AMQP og sækir RabbitMQ-ímynd. Vertu þolinmóður. Eftir að ímyndirnar hafa verið byggðar geturðu keyrt skipunina okkar frá app2 og senda nokkur skilaboð í biðröð.
docker exec -it app2 php bin/console app:sendHljóðskrift
Þú getur gert það eins oft og þú getur. Svo lengi sem ekkert er neytandi Skilaboðin þín verða ekki afgreidd. Um leið og þú ræsir upp app1 og neyta allra skilaboða sem birtast á skjánum þínum.
docker exec -it app1 php bin/console messenger:consume -vv external_messagesHljóðskriftHljóðskrift

Heildin uppsprettukóði ásamt README má finna í opinberu geymslu okkar The Codest GitHub
Yfirlit
Symfony með bókasöfnum sínum og verkfærum gerir kleift að þróa nútímalega með hraða og skilvirkni vefur forrit. Með nokkrum skipunum og nokkrum kóðalínum getum við búið til nútímalegt samskiptakerfi milli forrita. Symfony, eins og PHP, er tilvalið fyrir þróun vefforrita og þökk sé vistkerfi þess og einfaldleika í innleiðingu nær þetta vistkerfi nokkrum af bestu tímanna til markaðssetningar.
Hins vegar þýðir hraður ekki alltaf gott – í dæminu hér að ofan kynntum við einfaldasta og hraðasta samskiptamáta. Þeir sem eru forvitnari munu vissulega taka eftir því að skortur er á aðskilnaði sviðsviðburða utan forritalagsins – í núverandi útgáfu eru þeir endurteknir og engin fullkomin stuðningur er fyrir Umslag, meðal annars er enginn Stimplar. Fyrir þá og aðra býð ég ykkur að lesa hluta II, þar sem við munum fjalla um samræmingu lénsbyggingar Symfony-forrita í örþjónustuumhverfi og ræða aðra vinsæla örþjónustutækni í samskiptum – að þessu sinni samstillta, byggða á REST. forritaskil.
