Микросервисы на C++: архитектура и практика для высоконагруженных систем

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: почему C++ для микросервисов?

Микросервисная архитектура прочно вошла в мир разработки, но традиционно ассоциируется с языками вроде Go, Java или Python. Однако C++ остается незаменимым там, где критичны производительность, низкая задержка и эффективное использование памяти. В этой статье мы разберем, как строить микросервисы на C++, какие библиотеки использовать и как организовать инфраструктуру.

Основные преимущества C++ в микросервисах:

  • Максимальная производительность (нативно компилируемый код)
  • Минимальное потребление памяти
  • Полный контроль над ресурсами
  • Отсутствие сборщика мусора (предсказуемые задержки)

Мы рассмотрим архитектуру, реализацию REST API, gRPC, работу с очередями и контейнеризацию на практических примерах.

Архитектура микросервиса на C++

Базовые принципы

Микросервис на C++ должен быть:

  • Автономным — каждый сервис работает независимо
  • Слабо связанным — минимальные зависимости между сервисами
  • Ориентированным на бизнес-функции — один сервис решает одну задачу
  • Устойчивым к сбоям — graceful degradation

Типовая структура проекта

my_microservice/
├── CMakeLists.txt
├── src/
│   ├── main.cpp
│   ├── server/
│   │   ├── http_server.cpp
│   │   └── http_server.h
│   ├── service/
│   │   ├── order_service.cpp
│   │   └── order_service.h
│   ├── repository/
│   │   ├── order_repository.cpp
│   │   └── order_repository.h
│   └── config/
│       ├── config.cpp
│       └── config.h
├── include/
│   └── (публичные заголовки)
├── tests/
│   └── test_order_service.cpp
└── Dockerfile

Практическая реализация: REST API микросервис

Выбор HTTP-библиотеки

Для C++ лучшие варианты — cpp-httplib (легковесная, header-only) и Drogon (полнофункциональный фреймворк). Рассмотрим пример с cpp-httplib.

Пример: сервис управления заказами

// main.cpp
#include <httplib.h>
#include <nlohmann/json.hpp>
#include <iostream>
#include <memory>
#include "order_service.h"

using json = nlohmann::json;

int main() {
    httplib::Server svr;
    auto orderService = std::make_shared<OrderService>();

    // POST /orders — создание заказа
    svr.Post("/orders", [orderService](const httplib::Request& req, httplib::Response& res) {
        try {
            auto data = json::parse(req.body);
            auto order = orderService->createOrder(data);
            res.set_content(order.dump(), "application/json");
            res.status = 201;
        } catch (const std::exception& e) {
            res.set_content(json{{"error", e.what()}}.dump(), "application/json");
            res.status = 400;
        }
    });

    // GET /orders/{id} — получение заказа
    svr.Get(R"(/orders/(\d+))", [orderService](const httplib::Request& req, httplib::Response& res) {
        int orderId = std::stoi(req.matches[1]);
        auto order = orderService->getOrder(orderId);
        if (order) {
            res.set_content(order->dump(), "application/json");
        } else {
            res.status = 404;
            res.set_content(json{{"error", "Order not found"}}.dump(), "application/json");
        }
    });

    std::cout << "Server started on port 8080" << std::endl;
    svr.listen("0.0.0.0", 8080);
    return 0;
}
// order_service.cpp
#include "order_service.h"
#include <stdexcept>

using json = nlohmann::json;

json OrderService::createOrder(const json& data) {
    if (!data.contains("product_id") || !data.contains("quantity")) {
        throw std::invalid_argument("Missing required fields");
    }

    Order order;
    order.id = nextId_++;
    order.productId = data["product_id"];
    order.quantity = data["quantity"];
    order.status = "created";
    orders_[order.id] = order;

    json result;
    result["id"] = order.id;
    result["product_id"] = order.productId;
    result["quantity"] = order.quantity;
    result["status"] = order.status;
    return result;
}

std::optional<json> OrderService::getOrder(int id) {
    auto it = orders_.find(id);
    if (it == orders_.end()) {
        return std::nullopt;
    }

    json result;
    result["id"] = it->second.id;
    result["product_id"] = it->second.productId;
    result["quantity"] = it->second.quantity;
    result["status"] = it->second.status;
    return result;
}

Сборка с CMake

# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(order_service)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Зависимости
include(FetchContent)
FetchContent_Declare(
    cpp-httplib
    GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
    GIT_TAG v0.12.0
)
FetchContent_MakeAvailable(cpp-httplib)

FetchContent_Declare(
    nlohmann_json
    GIT_REPOSITORY https://github.com/nlohmann/json.git
    GIT_TAG v3.11.2
)
FetchContent_MakeAvailable(nlohmann_json)

add_executable(order_service
    src/main.cpp
    src/service/order_service.cpp
)

target_include_directories(order_service PRIVATE include)
target_link_libraries(order_service PRIVATE httplib::httplib nlohmann_json::nlohmann_json)

Межсервисное взаимодействие: gRPC и очереди

gRPC на C++

Для высоконагруженных систем gRPC предпочтительнее REST. Используем библиотеку gRPC C++.

// proto/order.proto
syntax = "proto3";

package order;

service OrderService {
    rpc CreateOrder (CreateOrderRequest) returns (OrderResponse);
    rpc GetOrder (GetOrderRequest) returns (OrderResponse);
}

message CreateOrderRequest {
    string product_id = 1;
    int32 quantity =                

Блоги

Рекомендаций по книгам