Design and Thinking Around PHP Architecture (Part 1)

A microservices architecture design for PHP, covering a complete walkthrough and implementation plan for the core modules: service registry, service scheduling, service degradation, service gateway, service configuration, service bus and so on:

graph TD
    A[服务网关] --> B[服务注册中心]
    A --> C[服务配置中心]
    D[服务提供者] --> B
    E[服务消费者] --> B
    F[服务总线] --> D
    F --> E
    G[服务调度器] --> F
    H[降级管理器] --> C

1. Core architecture modules and technology choices

Module Recommended tech PHP integration Characteristics
Service registry Consul, Nacos HTTP API / PHP client library Supports health checks and service discovery
Service gateway Kong, APISIX Nginx proxy / PHP plugin Dynamic routing, rate limiting, auth
Service config center Apollo, Nacos HTTP long polling / PHP SDK Hot config reload, version management
Service bus RabbitMQ, Kafka PHP extension (php-amqplib/rdkafka) Async decoupling, reliable messaging
Service scheduling Workerman/Swoole Native PHP support Coroutine scheduling, high performance
Service degradation ResiliencePHP Composer library Circuit breaking, rate limiting, fallback
Distributed tracing Jaeger, Zipkin OpenTracing-PHP Full-link monitoring

2. Concrete implementation plan for each module

  1. Service registry (Consul + PHP)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // Install the Consul PHP client: composer require sensiolabs/consul-php-sdk
    use SensioLabs\Consul\ServiceFactory;
    use SensioLabs\Consul\Services\AgentInterface;

    $consul = new ServiceFactory([
    'base_uri' => 'http://consul-server:8500',
    ]);

    // Service registration
    $consul->get(AgentInterface::class)->registerService([
    'ID' => 'order-service-001',
    'Name' => 'order-service',
    'Address' => '192.168.1.101',
    'Port' => 8000,
    'Check' => [
    'HTTP' => 'http://192.168.1.101:8000/health',
    'Interval' => '10s'
    ]
    ]);

    // Service discovery
    $services = $consul->getCatalog()->service('order-service')->json();
    $instances = array_map(fn($s) => "{$s['ServiceAddress']}:{$s['ServicePort']}", $services);
  2. API gateway (Kong + PHP)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # Kong configuration example
    location /api/ {
    access_by_lua_block {
    -- PHP auth plugin
    local res = ngx.location.capture("/auth.php?token="..ngx.var.arg_token)
    if res.status ~= 200 then
    ngx.exit(401)
    end
    }

    proxy_pass http://php-upstream;
    proxy_set_header X-Service-Name $route_name;
    }
  3. Config center (Apollo + PHP)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // Using apollo-client-php
    $client = new \ApolloClient\Client([
    'config_server' => 'http://apollo-config:8080',
    'app_id' => 'user-service',
    'cluster' => 'default',
    ]);

    // Get the config
    $mysqlConfig = $client->get('mysql.connection');

    // Listen for config changes
    $client->listen(function($key, $value) {
    if ($key === 'feature_toggle') {
    FeatureToggle::update($value);
    }
    });
  4. Service bus (RabbitMQ + PHP)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // Producer
    $connection = new AMQPStreamConnection('rabbitmq', 5672, 'guest', 'guest');
    $channel = $connection->channel();
    $channel->queue_declare('order_events', false, true, false, false);

    $msg = new AMQPMessage(json_encode([
    'event' => 'ORDER_CREATED',
    'data' => ['id' => 123]
    ]), ['delivery_mode' => 2]);

    $channel->basic_publish($msg, '', 'order_events');

    // Consumer
    $channel->basic_consume('order_events', '', false, false, false, false,
    function($msg) {
    $event = json_decode($msg->body, true);
    EventDispatcher::dispatch($event);
    $msg->ack();
    }
    );
  5. Service degradation (ResiliencePHP)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    use Resilience\Retry;
    use Resilience\CircuitBreaker;

    // Circuit breaker configuration
    $circuitBreaker = CircuitBreaker::builder()
    ->withFailureRateThreshold(50)
    ->withWaitDuration(10000)
    ->build();

    // Retry mechanism with circuit breaking
    $result = Retry::with(Retry::maxAttempts(3))
    ->decorate($circuitBreaker)
    ->run(function() use ($service) {
    return $service->callApi();
    }, function($e) {
    // Fallback handling
    return ['status' => 'degraded', 'data' => cached_data()];
    });
  6. Distributed scheduling (Swoole coroutines)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    use Swoole\Coroutine;

    // Call multiple services concurrently
    Coroutine\run(function() {
    $results = [];
    $wg = new Coroutine\WaitGroup();

    $services = ['inventory', 'payment', 'notification'];

    foreach ($services as $service) {
    $wg->add();
    go(function() use ($service, &$results, $wg) {
    $results[$service] = callService($service);
    $wg->done();
    });
    }

    $wg->wait();

    // Process the aggregated result
    processResults($results);
    });

3. The complete architecture deployment plan

graph LR
    A[客户端] --> B[Kong网关]
    B --> C[认证服务]
    B --> D[用户服务]
    B --> E[订单服务]
    B --> F[支付服务]

    subgraph 微服务集群
        C -->|注册| H[Consul]
        D -->|注册| H
        E -->|注册| H
        F -->|注册| H

        C -->|配置| I[Apollo]
        D -->|配置| I
        E -->|配置| I
        F -->|配置| I

        E -->|消息| J[RabbitMQ]
        J --> F
        J --> K[通知服务]
    end

    H --> L[Prometheus监控]
    I --> L
    J --> L
    L --> M[Grafana]

4. Installing and configuring the key components

  1. Infrastructure deployment (Docker example)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # docker-compose.yml
    version: '3'

    services:
    consul:
    image: consul:latest
    ports:
    - "8500:8500"

    kong:
    image: kong:latest
    depends_on:
    - postgres
    ports:
    - "8000:8000"
    - "8001:8001"

    apollo:
    image: apolloconfig/apollo-portal
    ports:
    - "8070:8070"

    rabbitmq:
    image: rabbitmq:management
    ports:
    - "5672:5672"
    - "15672:15672"
  2. Dockerfile for the PHP service

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    FROM php:8.2-fpm

    # Install the required extensions
    RUN apt-get update && apt-get install -y \
    libzip-dev \
    librabbitmq-dev \
    && docker-php-ext-install zip pdo_mysql \
    && pecl install amqp \
    && docker-php-ext-enable amqp

    # Install Composer
    COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

    WORKDIR /var/www
    COPY . .
    RUN composer install --no-dev --optimize-autoloader

5. Production environment recommendations

  1. Service registry:

    • Use a Consul cluster (at least 3 nodes)

    • Turn on ACL security controls

    • Integrate Prometheus monitoring

  • Gateway layer:

    • Kong cluster + Nginx load balancing

    • Enable the JWT auth plugin

    • Configure rate limiting (1000rps/service)

  • Configuration management:

    • Apollo multi-environment config (DEV/TEST/PROD)

    • Encrypted storage for sensitive configuration

    • Audit logs for config changes

  • Service communication:

    • Synchronous calls: HTTP/2 + Protobuf

    • Asynchronous messaging: RabbitMQ mirrored queues

    • Service mesh: Istio (optional)

  • Observability:

    • Logs: ELK collects Nginx/PHP logs

    • Metrics: Prometheus collects service metrics

    • Tracing: Jaeger for full-link tracing

6. PHP microservices development toolkit

1
2
3
4
5
6
7
composer require:
sensiolabs/consul-php-sdk # Consul client
guzzlehttp/guzzle # HTTP client
php-amqplib/php-amqplib # RabbitMQ
kwn/php-jaeger-client # Jaeger tracing
resilience-php/resilience-php # circuit breaking and fallback
ext-swoole # coroutine scheduling