A powerful, lightweight microservices framework using PHP and Unix sockets for ultra-fast inter-service communication. This architecture provides a robust foundation for building modular, scalable applications with minimal overhead.
- Core Features
- Architecture Overview
- Directory Structure
- Core Components
- Application Demos
- Communication Flow
- Security
- Performance Considerations
- Installation & Setup
- Usage Examples
- Extending the Framework
- Deployment with Docker
- Troubleshooting
- High-Performance Socket Communication: Achieve microsecond-level latency between services
- Process-based Isolation: Each service runs in its own protected process environment
- Robust Error Handling: Comprehensive exception hierarchy with detailed logging
- Clean Domain-Driven Design: Separation of concerns with repository pattern
- Dependency Injection: PHP-DI integration for flexible service management
- Signal Handling: Graceful service shutdown and reload capabilities
- Resource Monitoring: Built-in metrics for performance analysis
- Automatic Service Discovery: Services locate and communicate with each other seamlessly
- Dual Application Support: Run as Unix Socket service or REST API
The architecture follows clean hexagonal design principles with a focus on decoupling and testability:
graph TB
subgraph "Application Layer"
Unix["Unix Orchestrator"]
Micro["Micro App"]
Router["Router"]
end
subgraph "Domain Layer"
UseCase["HandleMessageUseCase"]
Repository["RouterRepositoryInterface"]
end
subgraph "Infrastructure Layer"
RouterRepo["RouterRepository"]
subgraph "Datasources"
LibDatasource["Library\nRouterDatasource"]
UnixDatasource["Unix\nRouterDatasource"]
end
end
subgraph "Socket Layer"
AbstractRequest["AbstractRequest"]
SocketRequest["SocketRequest"]
HttpRequest["HttpRequest"]
Security["Security"]
Config["Config"]
end
subgraph "Demo Applications"
UnixApp["Unix Socket App"]
RestApp["REST API App"]
end
%% Connections
Unix --> AbstractRequest
Unix --> Config
Micro --> HttpRequest
UnixApp --> Unix
RestApp --> Micro
SocketRequest --> AbstractRequest
HttpRequest --> AbstractRequest
UseCase --> Repository
RouterRepo --> Repository
RouterRepo --> LibDatasource
RouterRepo --> UnixDatasource
SocketRequest --> Security
SocketRequest --> Config
HttpRequest --> UseCase
Router --> UseCase
%% Styles
classDef core fill:#f96,stroke:#333,stroke-width:2px;
classDef domain fill:#bbf,stroke:#333,stroke-width:2px;
classDef infra fill:#bfb,stroke:#333,stroke-width:2px;
classDef socket fill:#fcf,stroke:#333,stroke-width:2px;
classDef app fill:#ff9,stroke:#333,stroke-width:2px;
class Unix,Micro,Router core;
class UseCase,Repository domain;
class RouterRepo,LibDatasource,UnixDatasource infra;
class AbstractRequest,SocketRequest,HttpRequest,Security,Config socket;
class UnixApp,RestApp app;
library/unix/
βββ client.php # Test client for socket connections
βββ composer.json # Dependency management
βββ Dockerfile # Container configuration
βββ rest-app/ # HTTP API implementation
β βββ Controllers/ # API controllers
β βββ config/ # Application configuration
β βββ public/ # Application entry point
βββ src/ # Core framework code
β βββ Application/ # Application layer
β β βββ Exception/ # Application exceptions
β β βββ Micro.php # HTTP application core
β β βββ Router.php # Request router
β β βββ Unix.php # Unix socket orchestrator
β βββ Domain/ # Business logic
β β βββ Datasource/ # Data access interfaces
β β βββ Entity/ # Domain entities
β β βββ Repository/ # Repository interfaces
β β βββ UseCase/ # Application use cases
β βββ Infrastructure/ # Implementation details
β β βββ Datasource/ # Data source implementations
β β βββ Repository/ # Repository implementations
β βββ Socket/ # Socket communication
β βββ Request/ # Request handling
β βββ Config.php # Socket configuration
β βββ Security.php # Authentication and security
βββ unix-app/ # Unix socket microservice
βββ Controllers/ # Service controllers
βββ config/ # Service configuration
βββ public/ # Service entry point
The orchestrator manages the lifecycle of all services:
- Service Registration: Adds new services to the orchestration pool
- Process Forking: Creates isolated processes for each service
- Signal Handling: Manages graceful shutdown and reload
- Resource Monitoring: Tracks service status and performance
Key methods:
registerSocket()
: Registers a new service with process isolationrun()
: Main orchestration loopshutdown()
: Graceful service terminationhandleSignal()
: Process OS signals (SIGTERM, SIGINT, SIGHUP)
Handles all socket-based communication with two main implementations:
-
SocketRequest: Unix socket communication for service-to-service interaction
- Creates and manages Unix domain sockets
- Handles client connections asynchronously
- Processes incoming JSON messages
- Provides resource cleanup and error handling
-
HttpRequest: HTTP-based interface for external clients
- Accepts HTTP requests and translates to internal format
- Routes requests to appropriate handler
- Returns HTTP responses
FastRoute-based request router:
- Maps URI paths to controller actions
- Supports middleware-like validation
- Handles authentication requirements
- Manages error responses
Clean, testable business logic:
- Use Cases: Single-responsibility actions
- Repositories: Data access abstractions
- Entities: Core business objects
- Interfaces: Dependency inversion
Token-based authentication system:
- Generates and validates authentication tokens
- Secures inter-service communication
- Single shared secret across services
A microservices implementation that communicates via Unix sockets:
sequenceDiagram
participant C as Client
participant S as SocketRequest
participant R as Router
participant Ctrl as Controller
C->>S: Connect to socket
C->>S: Send JSON message
S->>S: Authentication check
S->>R: Route request
R->>Ctrl: Execute controller action
Ctrl-->>R: Return response
R-->>S: Format response
S-->>C: Send JSON response
How to run:
php unix-app/public/index.php
Key files:
unix-app/public/index.php
: Entry pointunix-app/config/container.php
: DI configurationunix-app/config/routers.php
: Route definitionsunix-app/Controllers/
: Request handlers
A RESTful HTTP API implementation that shares the same core architecture:
sequenceDiagram
participant C as HTTP Client
participant H as HttpRequest
participant R as Router
participant Ctrl as Controller
C->>H: HTTP Request
H->>R: Route request
R->>Ctrl: Execute controller action
Ctrl-->>R: Return response
R-->>H: Format response
H-->>C: HTTP Response
How to run:
php rest-app/public/index.php
Key files:
rest-app/public/index.php
: Entry pointrest-app/config/container.php
: DI configurationrest-app/config/routers.php
: Route definitionsrest-app/Controllers/
: Request handlers
The full request lifecycle:
sequenceDiagram
participant CL as Client
participant SR as SocketRequest
participant SC as Security
participant RT as Router
participant UC as UseCase
participant RP as Repository
participant DS as Datasource
participant CT as Controller
CL->>+SR: Connect to socket
CL->>SR: Send request {path, method, data}
SR->>SC: authenticateMessage()
alt Authentication Failed
SC-->>SR: false
SR-->>CL: 401 Unauthorized
else Authentication Successful
SC-->>SR: true
SR->>+UC: execute(message)
UC->>+RP: handlerMessage(message)
RP->>+DS: handleMessage(message)
DS->>+RT: dispatch(method, uri, data)
RT->>+CT: call action(params)
CT-->>-RT: response
RT-->>-DS: formatted response
DS-->>-RP: response
RP-->>-UC: response
UC-->>-SR: response
SR-->>-CL: JSON response
end
Security is implemented through several layers:
- Token Authentication: Shared secret between services
- Socket Permissions: Filesystem-level access control
- Process Isolation: Services run in separate processes
- Timeout Protection: Guards against hanging connections
- Error Handling: Prevents information leakage
The security token is generated at first startup and stored in .auth_token
. This token must be included in all inter-service communications.
The Unix socket architecture provides significant performance advantages:
Communication Method | Average Latency | Throughput | Resource Usage |
---|---|---|---|
Unix Sockets | ~0.1ms | ~100,000 req/s | Very Low |
HTTP REST | ~1-10ms | ~10,000 req/s | Low |
HTTP with DB | ~10-100ms | ~1,000 req/s | Medium |
Performance optimizations:
- Non-blocking socket I/O
- Process-based concurrency
- Message buffering
- Resource pooling
- Micro sleep intervals
- PHP 8.4+
- Required PHP extensions:
sockets
pcntl
posix
- Composer
-
Clone the repository:
git clone https://github.com/yourname/unix-socket-microservices.git
-
Install dependencies:
composer install
-
Configure socket directory permissions:
mkdir -p /tmp/service chmod 0770 /tmp/service
-
Run the application:
# For Unix socket app php unix-app/public/index.php # For REST API php rest-app/public/index.php
docker build -t unix-socket-microservices .
docker run -p 8080:80 -v /tmp/service:/tmp/service unix-socket-microservices
<?php
// Connect to service
$client = socket_create(AF_UNIX, SOCK_STREAM, 0);
$socketPath = "/tmp/service/service_home.sock";
if (socket_connect($client, $socketPath)) {
// Prepare request
$request = json_encode([
'path' => '/user',
'method' => 'GET',
'auth_token' => file_get_contents('.auth_token'),
'data' => ['id' => 123]
]);
// Send request
socket_write($client, $request, strlen($request));
// Read response
$response = '';
while ($buffer = socket_read($client, 4096)) {
$response .= $buffer;
if (strlen($buffer) < 4096) break;
}
// Process response
$data = json_decode($response, true);
var_dump($data);
}
socket_close($client);
- Create controller:
namespace UnixApp\Controllers;
class ProductController extends BaseController
{
public function list(): array
{
return [
'products' => [
['id' => 1, 'name' => 'Product 1'],
['id' => 2, 'name' => 'Product 2']
]
];
}
}
- Add to router configuration:
// In unix-app/config/routers.php
return [
'/products' => [
[
'controller' => ProductController::class,
'action' => 'list',
'method' => 'GET',
'uri' => '',
'is_public' => true
]
]
];
- Register service:
// In unix-app/public/index.php
$application->registerSocket(\Nexus\Socket\Request\SocketRequest::class, 'products');
- Create interface (if needed):
namespace Nexus\Domain\Datasource;
interface NewDatasourceInterface
{
public function fetchData(array $params): array;
}
- Implement the datasource:
namespace Nexus\Infrastructure\Datasource;
class NewDatasource implements NewDatasourceInterface
{
public function fetchData(array $params): array
{
// Implementation here
return ['result' => 'data'];
}
}
- Register in container:
// In config/container.php
NewDatasourceInterface::class => function (ContainerInterface $c) {
return new NewDatasource();
}
Extend the AbstractRequest class:
namespace MyApp\Request;
use Nexus\Socket\Request\AbstractRequest;
class CustomRequest extends AbstractRequest
{
public function listen($routers): void
{
// Custom implementation
}
protected function receiveMessage($client): array
{
// Custom implementation
}
protected function handleMessage(array $routes, array $message): array
{
// Custom implementation
}
protected function sendMessage($client, array $data): void
{
// Custom implementation
}
}
The included Dockerfile provides a production-ready container:
FROM alpine:3.21.3
RUN apk add --update \
&& apk cache clean \
&& rm -rf /var/cache/apk/* \
&& apk del --purge \
&& rm -rf /tmp/* /var/tmp/* \
&& find /var/log -type f -delete
RUN apk add --no-cache curl php84-fpm php84 php84-json php84-pdo php84-pdo_mysql php84-sockets php84-pcntl php84-posix
RUN ln -s /usr/bin/php84 /usr/bin/php
WORKDIR '/var/www/html'
CMD ["php-fpm", "-F"]
RUN apk cache clean \
&& rm -rf /var/cache/apk/* \
&& apk del --purge \
&& rm -rf /tmp/* /var/tmp/* \
&& find /var/log -type f -delete
For a complete environment with multiple services:
version: '3'
services:
unix-orchestrator:
build: .
volumes:
- ./:/var/www/html
- socket-volume:/tmp/service
command: php unix-app/public/index.php
restart: unless-stopped
rest-api:
build: .
volumes:
- ./:/var/www/html
- socket-volume:/tmp/service
ports:
- "8080:80"
command: php rest-app/public/index.php
restart: unless-stopped
depends_on:
- unix-orchestrator
volumes:
socket-volume:
-
Socket permissions:
- Error: "Permission denied"
- Solution: Check socket directory permissions (
chmod 0770 /tmp/service
)
-
Missing extensions:
- Error: "Function socket_create undefined"
- Solution: Install required extensions (
sockets
,pcntl
,posix
)
-
Stale socket files:
- Symptom: Connection refused
- Solution: Delete old socket files (
rm /tmp/service/*.sock
)
-
Authentication failures:
- Symptom: 401 Unauthorized responses
- Solution: Verify .auth_token file exists and is accessible
Enable debug logging for detailed information:
// In src/Socket/Config.php
$this->config = [
// ...
'debug' => true,
];
View logs:
tail -f /var/log/microservices/app.log
Monitor service health with built-in metrics:
// Get service metrics
$metrics = $application->getStatus();
echo json_encode($metrics, JSON_PRETTY_PRINT);
Example output:
{
"home": {
"pid": 12345,
"uptime": 3600,
"status": "running",
"class": "Nexus\\Socket\\Request\\SocketRequest",
"requests": 15000,
"errors": 2,
"avgResponseTime": 0.0023
}
}
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.