Микросервисы на PHP: с чего начать и не сойти с ума
Вы когда-нибудь смотрели на монолитное PHP-приложение, разросшееся до 200 000 строк кода, и чувствовали, как внутри всё сжимается? Один коммит — и всё ломается. Одна ошибка в модуле корзины — и падает весь сайт. Знакомо? Добро пожаловать в клуб выживших в монолитах.
Но есть и хорошая новость: микросервисы на PHP — это не rocket science. Это просто набор маленьких, независимых приложений, которые общаются друг с другом по HTTP или через очереди. И да, PHP для этого подходит идеально. Не верите? Laravel, Symfony и даже «чистый» PHP отлично справляются с ролью микросервисов.
В этой статье я покажу вам архитектуру микросервисов на PHP с реальными примерами кода. Вы узнаете, с чего начать, какие инструменты выбрать и как не наступить на грабли. Поехали!
Что такое микросервисы на PHP простыми словами
Представьте себе пиццерию. Монолит — это когда один повар делает всё: замешивает тесто, режет колбасу, печёт, упаковывает, принимает заказы и моет посуду. Если повар заболел — пиццерия закрыта. Микросервисы — это когда у вас отдельный повар для теста, отдельный для начинки, отдельный для печи и отдельный курьер. Каждый работает автономно, и если заболел «повар теста», остальные продолжают работать.
В мире PHP это выглядит так:
- Сервис пользователей — регистрация, логин, профили
- Сервис заказов — создание, оплата, статусы
- Сервис уведомлений — email, SMS, push
- API Gateway — единая точка входа для клиентов
Каждый сервис — это отдельное PHP-приложение со своей базой данных, своим репозиторием и своей логикой. И всё это работает вместе, образуя микросервисную архитектуру на PHP.
Когда стоит переходить на микросервисы?
Давайте честно: микросервисы — это не серебряная пуля. Если у вас 3 тысячи пользователей и 10 страниц — забудьте. Вам нужен монолит. Но если:
- Команда разработки выросла до 5+ человек
- Вы деплоите каждую мелочь с молитвами
- Одна база данных стала узким горлышком
- Разные части приложения требуют разных технологий (например, Elasticsearch для поиска и PostgreSQL для заказов)
...тогда микросервисы на PHP — ваш выбор.
С чего начать: базовый микросервис на PHP
Начнём с простого. Создадим микросервис, который отдаёт список пользователей. Это будет PHP REST API микросервис.
Шаг 1: Структура проекта
user-service/
├── public/
│ └── index.php
├── src/
│ ├── Controllers/
│ │ └── UserController.php
│ ├── Models/
│ │ └── User.php
│ └── Services/
│ └── UserService.php
├── config/
│ └── database.php
├── composer.json
└── .env
Шаг 2: Точка входа (index.php)
<?php
// public/index.php
require_once __DIR__ . '/../vendor/autoload.php';
use Symfony\Component\Dotenv\Dotenv;
use App\Controllers\UserController;
$dotenv = new Dotenv();
$dotenv->load(__DIR__ . '/../.env');
$uri = $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];
// Простой роутер
if ($uri === '/api/users' && $method === 'GET') {
$controller = new UserController();
echo json_encode($controller->index());
} elseif (preg_match('/\/api\/users\/(\d+)/', $uri, $matches) && $method === 'GET') {
$controller = new UserController();
echo json_encode($controller->show($matches[1]));
} else {
http_response_code(404);
echo json_encode(['error' => 'Not found']);
}
Шаг 3: Контроллер
<?php
// src/Controllers/UserController.php
namespace App\Controllers;
use App\Services\UserService;
class UserController
{
private UserService $userService;
public function __construct()
{
$this->userService = new UserService();
}
public function index(): array
{
return $this->userService->getAllUsers();
}
public function show(int $id): array
{
$user = $this->userService->getUserById($id);
if (!$user) {
http_response_code(404);
return ['error' => 'User not found'];
}
return $user;
}
}
Шаг 4: Сервисный слой
<?php
// src/Services/UserService.php
namespace App\Services;
use App\Models\User;
class UserService
{
private User $userModel;
public function __construct()
{
$this->userModel = new User();
}
public function getAllUsers(): array
{
return $this->userModel->findAll();
}
public function getUserById(int $id): ?array
{
return $this->userModel->findById($id);
}
}
Шаг 5: Модель
<?php
// src/Models/User.php
namespace App\Models;
use PDO;
class User
{
private PDO $pdo;
public function __construct()
{
$dsn = "pgsql:host={$_ENV['DB_HOST']};dbname={$_ENV['DB_NAME']}";
$this->pdo = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASS'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
}
public function findAll(): array
{
$stmt = $this->pdo->query("SELECT id, name, email FROM users");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function findById(int $id): ?array
{
$stmt = $this->pdo->prepare("SELECT id, name, email FROM users WHERE id = ?");
$stmt->execute([$id]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result ?: null;
}
}
Вот и всё. У вас есть работающий микросервис. Запустите его через php -S localhost:8000 -t public и перейдите по http://localhost:8000/api/users. Магия, правда?
Как микросервисы общаются между собой?
Создать один микросервис — полдела. Настоящая магия начинается, когда их несколько. Есть два основных подхода:
1. Синхронное взаимодействие (HTTP)
Сервис А делает HTTP-запрос к сервису Б. Просто, надёжно, но медленно.
<?php
// В сер