Микросервисы на C++: с чего начать в 2024 году
Когда слышишь «микросервисы», обычно на ум приходят Go, Java или Python. Но C++? Кажется, что этот язык слишком низкоуровневый, сложный и вообще не для веба. А зря. В последние годы C++ переживает второе рождение в области бэкенда: современные стандарты (C++17/20), облегчённые фреймворки и зрелые инструменты делают его отличным выбором для высоконагруженных микросервисов. Если ваш проект требует минимального потребления памяти, максимальной производительности или работы на ARM/MIPS, C++ может стать козырем в рукаве.
В этой статье я покажу, с чего реально начать: выберем фреймворк, напишем простой HTTP-сервис, добавим gRPC и завернём всё в Docker. Никакой воды — только код и практика.
Почему C++ для микросервисов — не безумие?
Главный аргумент противников C++: «долго писать, легко ошибиться». Но современный C++ с умными указателями, контейнерами STL и RAII позволяет писать почти так же быстро, как на Go, при этом давая полный контроль над памятью. Плюсы очевидны:
- Скорость — C++ быстрее Java/Python в 2-10 раз на операциях ввода-вывода и вычислениях.
- Потребление памяти — типичный микросервис на C++ занимает 5-15 МБ против 50-150 МБ на Java.
- Отсутствие GC — нет «заморозок» сборщика мусора, предсказуемая latency.
- Экосистема — gRPC, Boost, nlohmann/json, Crow, Drogon — всё работает из коробки.
Минусы тоже есть: строже компилятор, длиннее сборка, сложнее дебаг. Но если вам нужна производительность уровня финансовых систем, игровых серверов или IoT — C++ оправдан.
Выбираем фреймворк: Crow vs Drogon vs Pistache
Для быстрого старта не нужно писать HTTP-сервер с нуля на сокетах. Есть три популярных варианта:
1. Crow (легковесный, header-only)
Идеален для микросервисов до 5-10 эндпоинтов. Просто подключите один заголовочный файл — и готово. Минус: не поддерживает HTTP/2, слабая маршрутизация.
2. Drogon (полнофункциональный)
Лучший выбор для серьёзного проекта: HTTP/1.1 и HTTP/2, WebSocket, AOP, работа с базами данных, ORM. Drogon вдохновлён ASP.NET и Django — умеет даже автоматически генерировать JSON из моделей.
3. Pistache (современный, но сыроват)
Интересная альтернатива, но ещё не стабильна для продакшена.
Я рекомендую начинать с Crow — он минималистичен и позволяет за 10 минут получить работающий REST API. А для серьёзных проектов смотреть в сторону Drogon.
Практика: пишем микросервис на C++ с Crow
Создадим простой сервис, который принимает JSON с именем пользователя и возвращает приветствие. Это классический «Hello World», но в микросервисном стиле.
Шаг 1. Установка зависимостей
Вам понадобится CMake и компилятор с поддержкой C++17 (gcc 9+, clang 10+). Crow — header-only, поэтому просто копируем файл crow_all.h из репозитория.
# Скачиваем Crow
wget https://github.com/CrowCpp/Crow/releases/download/v1.1.0/crow_all.h
Шаг 2. Код сервиса
// main.cpp
#include "crow_all.h"
#include <iostream>
#include <string>
int main() {
crow::SimpleApp app;
// GET /hello — проверка здоровья
CROW_ROUTE(app, "/hello")
([](){
return crow::response(200, "Hello, World!");
});
// POST /greet — принимает JSON {"name": "Alice"}
CROW_ROUTE(app, "/greet").methods(crow::HTTPMethod::POST)
([](const crow::request& req){
auto body = crow::json::load(req.body);
if (!body || !body.has("name")) {
return crow::response(400, "Bad Request: missing 'name'");
}
std::string name = body["name"].s();
crow::json::wvalue result;
result["message"] = "Hello, " + name + "!";
result["from_service"] = "cpp-microservice";
return crow::response(200, result);
});
// Запускаем на порту 8080
app.port(8080).multithreaded().run();
}
Шаг 3. Сборка и запуск
# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(greeter_service)
set(CMAKE_CXX_STANDARD 17)
add_executable(greeter_service main.cpp)
mkdir build && cd build
cmake ..
make
./greeter_service
Проверяем:
curl http://localhost:8080/hello
# Ответ: Hello, World!
curl -X POST http://localhost:8080/greet -H "Content-Type: application/json" -d '{"name":"Alice"}'
# Ответ: {"message":"Hello, Alice!","from_service":"cpp-microservice"}
Вуаля! У вас есть работающий микросервис на C++. Занимает около 2 МБ в памяти и обрабатывает тысячи запросов в секунду.
Добавляем gRPC для внутреннего общения
HTTP REST хорош для внешних API, но между микросервисами часто используют gRPC — он быстрее, строже типизирован и поддерживает стриминг. C++ отлично дружит с gRPC через protobuf.
Пример proto-файла
// greeter.proto
syntax = "proto3";
package greeter;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Серверная часть на C++ (фрагмент)
#include <grpcpp/grpcpp.h>
#include "greeter.grpc.pb.h"
class GreeterServiceImpl final : public greeter::Greeter::Service {
grpc::Status SayHello(grpc::ServerContext* context,
const greeter::HelloRequest* request,
greeter::HelloReply* reply) override {
std::string message = "Hello " + request->name();
reply->set_message(message);
return grpc::Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<grpc::Server>