We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

  Назад к списку статей

Микросервисная архитектура в Termux: запуск и оркестрация сервисов на основе gRPC и Protobuf в изолированных окружениях

Termux на Android давно перестал быть только инструментом для «попробовать команды». В руках инженера он становится полноценной средой для разработки и запуска распределённых компонентов: сервисов, контрактов API и транспорта данных. Микросервисная архитектура в Termux особенно полезна для:

  • локальной разработки и тестирования gRPC-контрактов (Protobuf);
  • отработки коммуникаций между сервисами без сложной инфраструктуры;
  • проверки изоляции окружений для воспроизводимых экспериментов;
  • обучения и прототипирования, где важны контроль зависимостей и наблюдаемость.

Важно: ниже речь идёт только о локальной инфраструктуре и безопасных практиках. Мы не используем VPN для обхода ограничений; при необходимости VPN применяется исключительно для создания локальной сети.

Концепция: сервисы, контракт и транспорт

Классический подход для микросервисов в мобильной/локальной среде:

  • Контракты задаются Protobuf (IDL);
  • Сервисная логика реализуется как gRPC-сервисы;
  • Оркестрация отвечает за запуск, параметры и жизненный цикл;
  • Изоляция обеспечивает управляемость зависимостей и снижает риск конфликтов.

На практике это превращается в «мини-кластер» на вашем устройстве: несколько процессов, работающих в изолированных окружениях, общающихся по сети через gRPC.

Требования и подготовка Termux

Перед началом убедитесь, что:

  • у вас установлен Termux;
  • доступна сеть (локальная или корпоративная);
  • ваша версия Android и права позволяют запуск нужных бинарей;
  • вы готовы работать в терминале и собирать зависимости.

Начнём с обновления и базовых инструментов:

pkg update && pkg upgrade -y
pkg install -y git wget clang make pkg-config python python-dev python-pip

Для gRPC/Protobuf в Termux чаще всего применяют Python-подход (grpcio + grpcio-tools), потому что он быстро даёт результат и хорошо подходит для обучения архитектуре.

Создание контрактов Protobuf

Представим сервис «user» с методом для получения профиля. Создадим структуру проекта:

mkdir -p ~/micro-termux/{proto,services/user,services/gateway,orchestrator}

В каталоге proto создадим файл контракта user.proto:

cat > ~/micro-termux/proto/user.proto << 'EOF'
syntax = "proto3";

package user.v1;

option go_package = "user/v1;userv1";

service UserService {
  rpc GetProfile (GetProfileRequest) returns (GetProfileResponse);
}

message GetProfileRequest {
  string user_id = 1;
}

message GetProfileResponse {
  string user_id = 1;
  string display_name = 2;
  string email = 3;
}
EOF

Дальше сгенерируем код клиента/сервера для Python. Сначала установим инструменты:

pip install --user grpcio grpcio-tools protobuf

Генерация:

python -m grpc_tools.protoc 
  -I ~/micro-termux/proto 
  --python_out ~/micro-termux/services/user 
  --grpc_python_out ~/micro-termux/services/user 
  user.proto

Альтернатива — генерировать один раз в отдельный каталог с последующим импортиванием. Важно закрепить единый подход для воспроизводимости.

Реализация gRPC сервиса UserService

Теперь добавим реализацию сервиса. Создадим файл server.py в каталоге services/user:

cat > ~/micro-termux/services/user/server.py << 'EOF'
import time
import grpc
from concurrent import futures

# Имя модулей зависит от результата генерации protoc.
# Обычно они будут user_pb2.py и user_pb2_grpc.py внутри папки services/user.
import user_pb2
import user_pb2_grpc

class UserService(user_pb2_grpc.UserServiceServicer):
    def GetProfile(self, request, context):
        user_id = request.user_id
        # В реальном мире здесь будет обращение к БД или другому сервису.
        return user_pb2.GetProfileResponse(
            user_id=user_id,
            display_name=f"User {user_id}",
            email=f"user{user_id}@example.local"
        )

def serve(host="127.0.0.1", port=50051):
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=8))
    user_pb2_grpc.add_UserServiceServicer_to_server(UserService(), server)
    server.add_insecure_port(f"{host}:{port}")
    server.start()
    print(f"[user] gRPC server started on {host}:{port}", flush=True)
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        server.stop(0)

if name == "main":
    serve()
EOF

Проверим запуск в текущем окружении:

cd ~/micro-termux/services/user
python server.py

Если сервис стартовал без ошибок — база готова.

Клиент (проверка API) и базовый end-to-end сценарий

Для проверки добавим простой клиент. Создадим client_test.py в том же каталоге:

cat > ~/micro-termux/services/user/client_test.py << 'EOF'
import grpc
import user_pb2
import user_pb2_grpc

def main():
    with grpc.insecure_channel("127.0.0.1:50051") as channel:
        stub = user_pb2_grpc.UserServiceStub(channel)
        resp = stub.GetProfile(user_pb2.GetProfileRequest(user_id="42"))
        print(resp)

if name == "main":
    main()
EOF

В другом окне терминала:

cd ~/micro-termux/services/user
python client_test.py

Так вы подтверждаете корректность контракта и транспорта.

Изоляция окружений: почему это важно

В микросервисной архитектуре на одном устройстве почти неизбежны конфликты зависимостей: версии библиотек, разные параметры Python, несовместимые зависимости. Чтобы избежать «эффекта домино», применяют изоляцию:

  • виртуальные окружения (venv) для каждого сервиса;
  • отдельные рабочие каталоги с фиксированными версиями зависимостей;
  • раздельные конфигурации и переменные окружения.

Это обеспечивает повторяемость и снижает риски при изменениях.

Один сервис — одно окружение (venv per service)

Создадим виртуальное окружение для user-сервиса и установим зависимости в него:

python -m venv ~/micro-termux/envs/user
source ~/micro-termux/envs/user/bin/activate
pip install --upgrade pip
pip install grpcio grpcio-tools protobuf
deactivate

Аналогично подготовим окружение для gateway (агрегатора), который будет вызывать user-сервис.

python -m venv ~/micro-termux/envs/gateway
source ~/micro-termux/envs/gateway/bin/activate
pip install --upgrade pip
pip install grpcio grpcio-tools protobuf
deactivate

В gateway нам понадобятся сгенерированные файлы protobuf-модулей. Проще всего импортировать их из общего каталога или разместить копию. Мы сделаем общий каталог с интерфейсами и подгрузим его через PYTHONPATH.

Gateway: оркестратор на уровне приложения

Рассмотрим сервис gateway, который предоставляет один метод клиенту (например, HTTP не требуется), но внутри вызывает gRPC user-сервис. Для простоты оставим gateway тоже gRPC.

Создадим контракт gateway.proto (или расширим существующий). Для краткости gateway может иметь отдельный сервис:

cat > ~/micro-termux/proto/gateway.proto << 'EOF'
syntax = "proto3";

package gateway.v1;

service GatewayService {
  rpc ProfileSummary (ProfileSummaryRequest) returns (ProfileSummaryResponse);
}

message ProfileSummaryRequest {
  string user_id = 1;
}

message ProfileSummaryResponse {
  string summary = 1;
}
EOF

Сгенерируем код gateway и оставим user-клиентовые модули в окружении импорта. Для корректного импорта удобно генерировать в один общий каталог интерфейсов:

mkdir -p ~/micro-termux/interfaces
python -m grpc_tools.protoc 
  -I ~/micro-termux/proto 
  --python_out ~/micro-termux/interfaces 
  --grpc_python_out ~/micro-termux/interfaces 
  user.proto gateway.proto

Теперь в services/gateway напишем сервер:

cat > ~/micro-termux/services/gateway/server.py << 'EOF'
import os
import time
import grpc
from concurrent import futures

# Добавляем интерфейсы в PYTHONPATH через env или sys.path
# В данном примере предполагаем, что PYTHONPATH будет установлен orchestrator'ом.
import gateway_pb2
import gateway_pb2_grpc
import user_pb2
import user_pb2_grpc

class GatewayService(gateway_pb2_grpc.GatewayServiceServicer):
    def init(self, user_target):
        self.user_target = user_target

    def ProfileSummary(self, request, context):
        with grpc.insecure_channel(self.user_target) as channel:
            stub = user_pb2_grpc.UserServiceStub(channel)
            prof = stub.GetProfile(user_pb2.GetProfileRequest(user_id=request.user_id))
            summary = f"{prof.display_name} <{prof.email}>"
            return gateway_pb2.ProfileSummaryResponse(summary=summary)

def serve(host="127.0.0.1", port=50052, user_target="127.0.0.1:50051"):
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=8))
    gateway_pb2_grpc.add_GatewayServiceServicer_to_server(
        GatewayService(user_target=user_target), server
    )
    server.add_insecure_port(f"{host}:{port}")
    server.start()
    print(f"[gateway] gRPC server started on {host}:{port} (user={user_target})", flush=True)
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        server.stop(0)

if name == "main":
    # host/port/user_target можно прокидывать через переменные окружения
    host = os.getenv("GATEWAY_HOST", "127.0.0.1")
    port = int(os.getenv("GATEWAY_PORT", "50052"))
    user_target = os.getenv("USER_TARGET", "127.0.0.1:50051")
    serve(host=host, port=port, user_target=user_target)
EOF

Запускаем gateway в его окружении:

cd ~/micro-termux/services/gateway
source ~/micro-termux/envs/gateway/bin/activate
export PYTHONPATH=~/micro-termux/interfaces
export USER_TARGET=127.0.0.1:50051
python server.py
deactivate

Если оба сервиса запущены, вы можете отдельно протестировать gateway аналогичным клиентом.

Оркестрация: скрипт запуска нескольких сервисов

В «ручном» режиме запуск нескольких процессов в разных окнах быстро превращается в хаос. Поэтому нужен оркестратор (пусть даже простой Bash-скрипт), который:

  • поднимает сервисы в правильных окружениях;
  • задаёт переменные (host/port/targets);
  • выводит логи с префиксами;
  • умеет завершать процессы при остановке.

Создадим orchestrator/start.sh:

cat > ~/micro-termux/orchestrator/start.sh << 'EOF'
#!/data/data/com.termux/files/usr/bin/env bash
set -euo pipefail

BASE_DIR="$HOME/micro-termux"
INTERFACES="$BASE_DIR/interfaces"

USER_ENV="$BASE_DIR/envs/user"
GATEWAY_ENV="$BASE_DIR/envs/gateway"

USER_HOST="${USER_HOST:-127.0.0.1}"
USER_PORT="${USER_PORT:-50051}"

GATEWAY_HOST="${GATEWAY_HOST:-127.0.0.1}"
GATEWAY_PORT="${GATEWAY_PORT:-50052}"

USER_TARGET="${USER_TARGET:-${USER_HOST}:${USER_PORT}}"

echo "[orchestrator] Starting services..."
echo "[orchestrator] Interfaces: $INTERFACES"

# Запуск user-сервиса
(
  cd "$BASE_DIR/services/user"
  source "$USER_ENV/bin/activate"
  export PYTHONPATH="$INTERFACES"
  export USER_HOST USER_PORT
  python server.py
) &
USER_PID=$!

# Запуск gateway-сервиса
(
  cd "$BASE_DIR/services/gateway"
  source "$GATEWAY_ENV/bin/activate"
  export PYTHONPATH="$INTERFACES"
  export USER_TARGET
  export GATEWAY_HOST GATEWAY_PORT
  python server.py
) &
GATEWAY_PID=$!

echo "[orchestrator] user pid=$USER_PID"
echo "[orchestrator] gateway pid=$GATEWAY_PID"

# Корректное завершение по Ctrl+C
trap 'echo "[orchestrator] Stopping..."; kill $USER_PID $GATEWAY_PID 2>/dev/null || true' INT TERM

wait $USER_PID
EOF

Сделаем исполняемым и запустим:

chmod +x ~/micro-termux/orchestrator/start.sh
~/micro-termux/orchestrator/start.sh

Так вы получаете базовую оркестрацию процессов в терминах «поднять стек сервисов».

Локальная сеть и взаимодействие сервисов

Если сервисы должны общаться не только через 127.0.0.1 (например, gateway и client на разных интерфейсах), используйте доступный IP в локальной сети. При необходимости можно развернуть локальную сеть средствами VPN-клиента, но только для создания маршрутизации внутри локальной инфраструктуры (без обхода блокировок).

Практический подход:

  • на серверной части gRPC указывайте host=0.0.0.0 или конкретный локальный IP;
  • на клиентской стороне используйте адрес сервера в локальной сети;
  • не забывайте о сетевых ограничениях Android (firewall/политики сети).

Наблюдаемость и логирование: минимальный набор

Для микросервисов в Termux крайне желательно фиксировать хотя бы базовую наблюдаемость:

  • время старта и адреса;
  • ошибки gRPC (исключения, коды);
  • корреляция запросов (request_id в metadata);
  • агрегация логов в единый файл (опционально).

В простом варианте можно прокидывать логи через перенаправления в orchestrator. Например, добавьте в start.sh:

python server.py >> "$BASE_DIR/logs/user.log" 2>&1

Это позволит анализировать поведение без множества окон.

Безопасность: что делать с TLS

Для локальной разработки обычно применяют insecure-канал. Однако для практики продакшен-ориентированного подхода полезно заранее заложить:

  • возможность использовать TLS;
  • хранение ключей в защищённых каталогах;
  • ограничение сетевого доступа.

Если вы переходите к TLS, ориентируйтесь на gRPC Python поддержку SSL/TLS и следите за тем, чтобы сертификаты и ключи не попадали в публичные репозитории.

Как масштабировать архитектуру дальше

Когда базовый стек работает, масштабирование обычно идёт в трёх направлениях:

  • Больше сервисов: добавляете новые контракты Protobuf и сервисные реализации;
  • Разделение ответственности: отдельные окружения, конфиги, зависимости;
  • Усложнение оркестрации: переход к более «системному» управлению (например, расширение scripts с health-check и перезапусками).

Даже в рамках Termux можно постепенно прийти к модели, похожей на контейнерные платформы, но с упором на «простоту и контроль».

Заключение

Микросервисная архитектура в Termux на практике реализуется довольно прагматично: вы описываете контракты через Protobuf, поднимаете gRPC-сервисы в изолированных окружениях (venv per service) и используете простой оркестратор для согласованного запуска и остановки процессов. Такой подход помогает учиться инженерной дисциплине, тестировать взаимодействие сервисов и снижать риски конфликтов зависимостей.

Если вы хотите ускорить внедрение этой архитектуры под ваши задачи (контракты, генерация кода, структура репозитория, оркестрация, настройка сетевого взаимодействия и наблюдаемости), обратитесь в РыбинскЛАБ — мы поможем спроектировать и развернуть рабочий стек на Termux.

* Текст статьи подготовлен и структурирован с использованием технологий искусственного интеллекта. Проверен и доработан перед публикацией.

Нужна помощь с настройкой Termux, Linux и серверов?

Я оказываю ИТ-услуги: настройка серверов, автоматизация, безопасность, помощь с Linux и инфраструктурой. Материалы сайта — только в ознакомительных и образовательных целях.

Связаться со мной
Поддержать проект