PHP 8.2: Mis on uus?
PHP uus versioon on kohe nurga taga. Milliseid uusi rakendusi peaksite teadma? Vaadake seda artiklit, et teada saada!

Lugege meie PHP sarja esimest osa, mis on pühendatud mikroteenuste suhtlusele Symfony raamistikus ja kõige populaarsemale viisile - AMQP suhtlusele RabbitMQ abil.
Kaasaegne rakendusarhitektuur on sundinud arendajaid muutma mõtteviisi IT-süsteemide erinevate komponentide vahelisest suhtlusest. Kunagi oli asi lihtsam - enamik süsteeme loodi monoliitsete struktuuridena, mis olid omavahel ühendatud äriloogikaühenduste võrgustikuga. Selliste sõltuvuste säilitamine PHP projekt oli suur väljakutse PHP arendajad, ning SaaS-lahenduste kasvav populaarsus ja tohutu kasvav populaarsus pilv teenused põhjustasid selle, et tänapäeval kuuleme üha enam mikroteenustest ja rakenduste modulaarsusest.
Kuidas saame iseseisvaid mikroteenuseid luues panna neid omavahel teavet vahetama?
See artikkel on esimene postituste seeriast, mis käsitleb mikroteenuste kommunikatsioon Symfony's raamistikku ja see hõlmab kõige populaarsemat viisi - AMQP-suhtlust RabbitMQ abil.
Luua kaks sõltumatut rakendust ja saavutada nende vaheline suhtlus, kasutades ainult sõnumivõrku.
Meil on kaks, kujuteldavat, sõltumatut rakendust:
* app1
: mis saadab töötajatele e-posti ja SMS-teateid.
* app2
: mis võimaldab teil hallata töötajate tööd ja anda neile ülesandeid.
Tahame luua kaasaegse ja lihtsa süsteemi, mille abil töö määramine töötajale on app2
saadab kliendile teate, kasutades app1
. Hoolimata näilisest, on see väga lihtne!
Selle artikli jaoks kasutame kõige uuemat Symfony't (kirjutamise ajal versioon 6.1) ja PHP uusimat versiooni (8.1). Mõne väga lihtsa sammuga loome toimiva lokaalse Docker-keskkonna kahe mikroteenusega. Kõik, mida vajate, on:
* töötav arvuti,
* paigaldatud Docker + Docker Compose keskkond
* ja kohapeal konfigureeritud Symfony CLI ja veidi vaba aega.
Me kasutame Dockeri võimalusi rakenduse virtualiseerimise ja konteinerdamise vahendina. Alustame kataloogipuu loomisega, mis on raamistikuks kahele Symfony rakendused, ja kirjeldada meie keskkondade infrastruktuuri, kasutades selleks docker-compose.yml
faili.
cd ~
mkdir microservices-in-symfony
cd microservices-in-symfony
symfony new app1
symfony new app2
touch docker-compose.yml
Oleme loonud kaks kataloogi kahe eraldi Symfony rakenduse jaoks ja loonud tühja docker-compose.yml
faili, et käivitada meie keskkond.
Lisame järgmised lõigud docker-compose.yml
file:
versioon: '3.8'
teenused:
app1:
sisaldav nimi: app1
build: app1/.
restart: on-failure
envfile: app1/.env
keskkond:
APPNAME: app1
tty: true
stdinopen: true
app2:
containername: app2
build: app2/.
restart: on-failure
envfile: app2/.env
keskkond:
APPNAME: app2
tty: true
stdinopen: true
rabbitmq:
containername: rabbitmq
image: rabbitmq:management
ports:
- 15672:15672
- 5672:5672
keskkond:
- RABBITMQDEFAULTUSER=user
- RABBITMQDEFAULT_PASS=password
Allikas kood saadaval otse: thecodest-co/microservices-in-symfony/blob/main/docker-compose.yml
Aga oodake, mis siin juhtus? Neile, kes ei ole Dockeriga kursis, võib ülaltoodud konfiguratsioonifail tunduda mõistatuslik, kuid selle eesmärk on väga lihtne. Docker Compose'i kasutades ehitame kolm "teenust":
Korralikuks toimimiseks on meil siiski vaja Dockerfile
failid, mis on kujutiste koostamise allikas. Nii et loome need:
touch app1/Dockerfile
touch app2/Dockerfile
Mõlemad failid on täpselt sama struktuuriga ja näevad välja järgmiselt:
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/*
Käivitage docker-php-ext-install zip;
CMD bash -c "cd /app && composer install && php -a"
Lähtekood on saadaval otse: /thecodest-co/microservices-in-symfony/blob/main/app1/Dockerfile /thecodest-co/microservices-in-symfony/blob/main/app1/Dockerfile
Ülaltoodud faili kasutab Docker Compose konteineri loomiseks PHP 8.1 kujutisest koos Composeri ja AMQP laiendusega, mis on paigaldatud. Lisaks käivitab see PHP intepreteri append-režiimis, et konteiner töötaks taustal.
Teie kataloogi- ja failipuu peaks nüüd välja nägema järgmine:
.
├─ app1
│ └── Dockerfile
| (...) # Symfony rakenduse struktuur
├─ app2
│ └ └── Dockerfile
| (...) # Symfony App Structure | (...) # Symfony App Structure
└── docker-compose.yml
Alustame app1
kataloogi ja esimese rakenduse.
Meie näites on tegemist rakendusega, mis kuulab ja tarbib sõnumeid järjekorrast, mida saadab app2
nagu on kirjeldatud nõuetes:
töö määramine töötajale
app2
saadab kliendile teate
Alustame vajalike raamatukogude lisamisega. AMQP on algselt toetatud symfony/messenger
pikendus. Me paigaldame täiendavalt monoloog/monoloog
süsteemi logide jälgimiseks, et lihtsustada rakenduste käitumise analüüsi.
cd app1/
symfony composer req amqp ampq-messenger monolog
Pärast paigaldamist lisati täiendav fail aadressile config/packages/messenger.yaml
. See on Symfony Messenger komponendi konfiguratsioonifail ja me ei vaja selle täielik konfiguratsioon.
Asendage see alljärgneva YAML-failiga:
raamistik:
messenger:
# Võtke see (ja allpool olev ebaõnnestunud transport) lahti, et saata ebaõnnestunud sõnumid sellele transpordile hilisemaks käitlemiseks.
# failure_transport: failed
transport:
# 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
järjekorrad:
sõnumid:
binding_keys: [from_external]
Lähtekood on saadaval otse: thecodest-co/microservices-in-symfony/blob/main/app1/config/packages/messenger.yaml
Symfony Messengerit kasutatakse Symfony rakendustes sünkroonse ja asünkroonse suhtluse jaoks. See toetab erinevaid transpordib, või transpordikihi tõeallikad. Meie näites kasutame AMQP laiendust, mis toetab RabbitMQ sündmuste järjekorrasüsteemi.
Ülaltoodud konfiguratsioon määratleb uue transpordi nimega external_messages
, mis viitab MESSENGER_TRANSPORT_DSN
keskkonnamuutuja ja määratleb otsekuulamise sõnumid
kanal Sõnumibussis. Siinkohal redigeerige ka app1/.env
faili ja lisage sobiv transpordiaadress.
"env
(...)
MESSENGERTRANSPORTDSN=amqp://user:password@rabbitmq:5672//messages
(...)
"
Pärast rakenduse raamistiku ettevalmistamist ja raamatukogude konfigureerimist on aeg rakendada äriloogika. Me teame, et meie rakendus peab reageerima töö määramisele töötajale. Samuti teame, et töö määramine rakendussüsteemisapp2 muudab töö staatust. Seega loome mudeli, mis jäljendab staatuse muutust ja salvestame selle failiapp1/Message/StatusUpdate.php`i:
{
public function __construct(protected string $status){}
public function getStatus(): string
{
return $this->status;
}
}
Lähtekood on saadaval otse: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Message/StatusUpdate.php
Me vajame veel klassi, mis rakendab äriloogikat, kui meie mikroteenus saab järjekorrast ülaltoodud sündmuse. Nii et loome Sõnumikäsitleja aastal app1/Handler/StatusUpdateHandler.php
tee:
kasutada 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);
// ülejäänud äriloogika, st e-posti saatmine kasutajale.
// $this->emailService->email()
}
}
Lähtekood on saadaval otse: /thecodest-co/microservices-in-symfony/blob/main/app1/src/Handler/StatusUpdateHandler.php
PHP atribuudid muudavad asjad palju lihtsamaks ja tähendavad, et antud juhul ei pea me muretsema autowiringi või teenindusdeklaratsiooni pärast. Meie mikroteenus domeeni sündmuste käsitlemiseks on valmis, on aeg asuda teise rakenduse juurde.
Me vaatleme app2
kataloogi ja teise Symfony rakendus. Meie idee on saata sõnum järjekorda, kui töötajale on süsteemis määratud ülesanne. Seega teeme kiire AMQP konfiguratsiooni ja paneme meie teise mikroservice'i avaldama. StatusUpdate
sündmused sõnumivõrku.
Raamatukogude paigaldamine on täpselt sama, mis esimese rakenduse puhul.
cd ..
cd app2/
symfony composer req amqp ampq-messenger monolog
Veendume, et app2/.env
fail sisaldab kehtivat DSN-kirjet RabbitMQ jaoks:
(...)
MESSENGER_TRANSPORT_DSN=amqp://user:password@rabbitmq:5672//messages
(...)
Kõik, mis jääb, on Symfony Messengeri seadistamine failis app2/config/packages/messenger.yaml
file:
raamistik:
messenger:
# Võtke see (ja allpool olev ebaõnnestunud transport) lahti, et saata ebaõnnestunud sõnumid sellele transpordile hilisemaks käitlemiseks.
# failure_transport: failed
transport:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
marsruutimine:
# Suunata oma sõnumid transportidele.
'AppMessageStatusUpdate': async
Nagu näete, viitab transpordimääratlus seekord otse aadressile asünkroonne
ja määratleb marsruutimise kujul saatmise meie StatusUpdate
sõnum konfigureeritud DSN-ile. See on ainus konfigureerimisvaldkond, kõik, mis jääb, on AMQP järjekorra loogika ja rakenduskihi loomine. Selleks loome kaksikliigi StatusUpdateHandler
ja StatusUpdate
klassid app2
.
kasutada 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);
## äriloogika, st sisemise teate saatmine või mõne muu süsteemi järjekorda seadmine.
}
}
{
public function __construct(protected string $status){}
public function getStatus(): string
{
return $this->status;
}
}
Lähtekood on saadaval otse: /thecodest-co/microservices-in-symfony/blob/main/app2/src/Message/StatusUpdate.php
Lõpuks tuleb vaid luua võimalus sõnumi saatmiseks sõnumivõrku. Me loome lihtsa Symfony käsk selle eest:
kasutada 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(
message: new StatusUpdate($status)
);
return Command::SUCCESS;
}
}
Tänu Sõltuvuse süstimine saame kasutada instantsi MessageBusInterface
meie komandos ja saata StatusUpdate
sõnumi kaudu dispatch()
meetodi meie järjekorda. Lisaks kasutame siin ka PHP atribuute.
See on kõik - kõik, mis on jäänud, on käivitada meie Docker Compose keskkond ja näha, kuidas meie rakendused käituvad.
Docker Compose'i abil ehitatakse ja käivitatakse konteinerid meie kahe rakendusega eraldi instantsidena, ainuke vahepealne kiht on rabbitmq
konteiner ja meie sõnumibussi rakendamine.
Projekti juurkataloogist käivitame järgmised käsud:
cd ../ # veenduge, et olete põhikataloogis.
docker-compose up --build -d
See käsk võib võtta aega, kuna see ehitab kaks eraldi konteinerit PHP 8.1 + AMQP ja tõmbab RabbitMQ kujutise. Olge kannatlik. Pärast kujutiste ehitamist saate tulistada meie käsu alates app2
ja saata mõned sõnumid järjekorda.
docker exec -it app2 php bin/console app:send
Te võite seda teha nii mitu korda kui võimalik. Niikaua kui ei ole tarbija teie sõnumeid ei töödelda. Niipea, kui te käivitate app1
ja tarbida kõik sõnumid, mida nad teie ekraanil näitavad.
docker exec -it app1 php bin/console messenger:consume -vvv external_messages
Täielik lähtekood koos README-ga võib leida meie avalikust repositooriumist The Codest Github
Symfony koos oma raamatukogude ja tööriistadega võimaldab kiiret ja tõhusat lähenemist kaasaegsete veebirakendused. Mõne käsu ja mõne koodireaga saame luua kaasaegse rakenduste vahelise kommunikatsioonisüsteemi. Symfony, nagu ka PHP, on ideaalne veebirakenduste arendamine ning tänu ökosüsteemile ja selle rakendamise lihtsusele saavutab see ökosüsteem mõned parimad turule jõudmise aja näitajad.
Kuid kiire ei tähenda alati head - eespool toodud näites esitlesime kõige lihtsamat ja kiiremat suhtlusviisi. Mida uudishimulikumad kindlasti märkavad, on puudu domeeni sündmuste lahtiühendamine väljaspool rakenduskihti - praeguses versioonis on need dubleeritud ja puudub täielik tugi, et Ümbrik
, muu hulgas ei ole Margid
. Nende ja teiste jaoks kutsun teid üles lugema II osa, kus käsitleme Symfony rakenduste domeenistruktuuri ühtlustamise teemat mikroteenuste keskkonnas ning arutame teist populaarset mikroteenuste kommunikatsioonimeetodit - seekord sünkroonset, mis põhineb REST API-l.