# 服务应用部署 # Laravel 微服务架构的 GitHub 最佳实践项目 以下是 Laravel 微服务架构的 **GitHub 最佳实践项目** 和关键实现方案,涵盖服务拆分、通信、部署和监控等核心环节: --- ### 一、微服务核心架构模式 #### 1. **服务拆分原则** - **按业务域划分**(如用户服务、订单服务、支付服务) - **独立数据库**(每个服务拥有自己的数据库) - **API 网关**(统一入口,路由到不同服务) #### 2. **技术栈组合**
组件推荐方案
通信协议HTTP/REST、gRPC、消息队列(RabbitMQ)
服务发现Consul、Nacos、Eureka
部署Docker + Kubernetes
监控Prometheus + Grafana
--- ### 二、GitHub 最佳实践项目案例 #### 1. [Laravel Microservice Boilerplate](https://github.com/mateusjunges/laravel-microservices) - **Stars**: 800+ - **特点**: - 使用 **API 网关**(Kong)统一路由 - 服务间通过 **gRPC** 通信 - 集成 **JWT 认证** - Docker Compose 本地开发环境 - **目录结构**: ```markdown /api-gateway # 网关服务 /user-service # 用户微服务 /order-service # 订单微服务 /docker # 容器化配置 ``` #### 2. [Laravel + DDD + CQRS 微服务示例](https://github.com/renoki-co/laravel-microservices) - **Stars**: 1k+ - **亮点**: - 领域驱动设计(DDD)分层 - CQRS 模式(命令与查询分离) - 事件溯源(Event Sourcing) - 使用 **Laravel Octane** 提升性能 #### 3. [Lumen 微服务框架示例](https://github.com/liyu001989/lumen-api-demo) - **Stars**: 500+ - **适用场景**: - 轻量级 API 服务(基于 Lumen) - 集成 **Swagger 文档** - JWT + OAuth2 认证 --- ### 三、关键实现方案 #### 1. **服务间通信** - **同步通信(HTTP/gRPC)**: ```php // 使用 Guzzle 调用其他服务 $response = Http::post('http://user-service/api/users', [ 'name' => 'John Doe' ]); ``` - **异步通信(消息队列)**: ```php // 在订单服务中发布事件 event(new OrderCreated($order)); // 在支付服务中监听事件 class ProcessPayment implements ShouldQueue { public function handle(OrderCreated $event) { // 处理支付逻辑 } } ``` #### 2. **API 网关实现** - **Kong 配置示例**: ```yaml # 路由规则 routes: - name: user-service paths: /users/* service: user-service - name: order-service paths: /orders/* service: order-service ``` #### 3. **数据一致性** - **Saga 模式**(分布式事务): ```php // 使用 Saga 协调多个服务 $saga = new CreateOrderSaga(); $saga->addStep(new ReserveProductStep()); $saga->addStep(new ProcessPaymentStep()); $saga->execute(); ``` #### 4. **服务发现与负载均衡** - **Consul 集成**: ```php // 注册服务 Consul::agent()->service()->register([ 'Name' => 'user-service', 'Address' => '192.168.1.100', 'Port' => 8000 ]); // 发现服务 $services = Consul::catalog()->services(); ``` --- ### 四、部署与 DevOps #### 1. **容器化(Docker)** - **docker-compose.yml 示例**: ```yaml version: '3' services: user-service: build: ./user-service ports: ["8001:80"] order-service: build: ./order-service ports: ["8002:80"] api-gateway: image: kong:latest ports: ["8000:8000"] ``` #### 2. **Kubernetes 部署** - **Deployment 示例**: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: user-service spec: replicas: 3 selector: matchLabels: app: user-service template: containers: - name: user-service image: user-service:latest ports: - containerPort: 80 ``` #### 3. **监控与日志** - **Prometheus 指标收集**: ```php // 在 Laravel 中暴露指标 Route::get('/metrics', function () { return response(Prometheus::export()); }); ``` - **集中式日志(ELK Stack)**: ```bash # Logstash 配置 input { beats { port => 5044 } } ``` --- ### 五、安全实践 1. **服务间认证**: - 使用 **JWT** 或 **mTLS(双向 TLS)** 2. **API 网关防护**: - 限流、IP 白名单、请求签名 3. **数据库隔离**: - 每个服务使用独立数据库用户 --- ### 六、学习资源 1. **官方文档**: - [Laravel Queue](https://laravel.com/docs/queues) - [Lumen 微服务框架](https://lumen.laravel.com/) 2. **书籍**: - 《微服务架构设计模式》(Chris Richardson) 3. **视频课程**: - [Udemy: Laravel Microservices](https://www.udemy.com/course/laravel-microservices/) --- ### 总结对比
方案适用场景技术栈
**Lumen 轻量级**简单 API 服务Lumen + JWT + Swagger
**DDD + CQRS**复杂业务系统Laravel + Event Sourcing
**Kubernetes 集群**高可用生产环境Docker + K8s + Istio
选择时需权衡团队技能和业务复杂度。建议从简单 HTTP 通信开始,逐步引入消息队列和复杂事务模式。 # 使用 Docker 搭建 Laravel 集群指南 本指南将介绍如何使用 Docker 和 Docker Compose 搭建一个 Laravel 应用集群,包含 Web 服务器、MySQL 数据库、Redis 缓存和负载均衡。 (通过GitHub和DockerHub的集成实现自动化构建流程。包括设置GitHub组织、配置DockerHub访问权限、创建仓库及使用webhook触发构建过程。) ## 1. 准备工作 确保已安装: - Docker (>= 20.10) - Docker Compose (>= 2.0) - Git ## 2. 项目结构 ``` laravel-cluster/ ├── docker/ │ ├── nginx/ │ │ ├── Dockerfile │ │ └── default.conf │ ├── php/ │ │ └── Dockerfile │ └── haproxy/ │ └── haproxy.cfg ├── src/ (Laravel 项目) ├── docker-compose.yml └── .env ``` ## 3. 配置 Docker 环境 ### docker-compose.yml ```yaml version: '3.8' services: # MySQL 数据库 mysql: image: mysql:8.0 container_name: mysql environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: ${DB_DATABASE} MYSQL_USER: ${DB_USERNAME} MYSQL_PASSWORD: ${DB_PASSWORD} volumes: - mysql_data:/var/lib/mysql networks: - laravel-network # Redis 缓存 redis: image: redis:alpine container_name: redis ports: - "6379:6379" networks: - laravel-network # PHP-FPM 服务 (多个实例) php1: build: context: ./docker/php container_name: php1 volumes: - ./src:/var/www/html environment: - DB_HOST=mysql - REDIS_HOST=redis networks: - laravel-network depends_on: - mysql - redis php2: build: context: ./docker/php container_name: php2 volumes: - ./src:/var/www/html environment: - DB_HOST=mysql - REDIS_HOST=redis networks: - laravel-network depends_on: - mysql - redis # Nginx Web 服务器 (多个实例) nginx1: build: context: ./docker/nginx container_name: nginx1 ports: - "8081:80" volumes: - ./src:/var/www/html depends_on: - php1 networks: - laravel-network nginx2: build: context: ./docker/nginx container_name: nginx2 ports: - "8082:80" volumes: - ./src:/var/www/html depends_on: - php2 networks: - laravel-network # HAProxy 负载均衡 haproxy: image: haproxy:2.4 container_name: haproxy ports: - "80:80" - "8404:8404" # 统计页面 volumes: - ./docker/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg depends_on: - nginx1 - nginx2 networks: - laravel-network volumes: mysql_data: networks: laravel-network: driver: bridge ``` ### docker/php/Dockerfile ```dockerfile FROM php:8.1-fpm # 安装依赖 RUN apt-get update && apt-get install -y \ libzip-dev \ zip \ unzip \ libpq-dev \ libonig-dev \ libxml2-dev # 安装 PHP 扩展 RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath zip # 安装 Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # 设置工作目录 WORKDIR /var/www/html ``` ### docker/nginx/default.conf ```nginx server { listen 80; index index.php index.html; server_name localhost; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/html/public; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php1:9000; # 修改为对应的 PHP 容器名 fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } ``` ### docker/haproxy/haproxy.cfg ```cfg global stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners log stdout format raw local0 info defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms frontend http_front bind *:80 stats uri /stats default_backend http_back backend http_back balance roundrobin server nginx1 nginx1:80 check server nginx2 nginx2:80 check listen stats bind *:8404 stats enable stats uri / stats refresh 5s ``` ## 4. 部署步骤 1. 克隆 Laravel 项目到 `src` 目录: ```bash git clone https://github.com/laravel/laravel.git src ``` 2. 创建 `.env` 文件: ```bash cp src/.env.example src/.env ``` 3. 修改 `src/.env` 数据库配置: ```env DB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=laravel DB_PASSWORD=secret ``` 4. 创建项目 `.env` 文件: ```bash cat > .env < [ 'read' => [ 'host' => [ env('DB_READ_HOST_1', 'read1.db.cluster'), env('DB_READ_HOST_2', 'read2.db.cluster'), ], ], 'write' => [ 'host' => env('DB_WRITE_HOST', 'write.db.cluster'), ], 'sticky' => true, 'driver' => 'mysql', 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), // ... ], ``` ### 2. Redis 集群配置 ```php // config/database.php 'redis' => [ 'cluster' => env('REDIS_CLUSTER', true), 'default' => [ [ 'host' => env('REDIS_HOST_1', 'redis1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, ], [ 'host' => env('REDIS_HOST_2', 'redis2'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, ], ], 'cache' => [ // 单独配置缓存Redis ], ], ``` ## 四、性能优化 ### 1. 缓存策略 ```php // 使用多级缓存 $value = Cache::remember('key', $seconds, function () { return DB::table(...)->get(); }); // 标签缓存 Cache::tags(['people', 'authors'])->put('John', $john, $seconds); ``` ### 2. 队列优化 ```php // 配置多个队列连接 'connections' => [ 'default' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, 'block_for' => null, ], 'processing' => [ 'driver' => 'sqs', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'prefix' => env('SQS_PREFIX'), 'queue' => env('SQS_QUEUE'), 'region' => env('AWS_DEFAULT_REGION'), ], ], ``` ## 五、监控与日志 ### 1. Prometheus 监控配置 ```yaml # prometheus.yml scrape_configs: - job_name: 'laravel' metrics_path: '/metrics' static_configs: - targets: ['laravel-app:9000'] relabel_configs: - source_labels: [__meta_kubernetes_pod_name] target_label: pod ``` ### 2. 集中式日志 (ELK) ```php // config/logging.php 'stacks' => [ 'elastic' => [ 'driver' => 'custom', 'via' => \App\Logging\ElasticsearchLogger::class, 'level' => 'debug', 'hosts' => [ [ 'host' => env('ELASTICSEARCH_HOST', 'elasticsearch'), 'port' => env('ELASTICSEARCH_PORT', 9200), 'scheme' => env('ELASTICSEARCH_SCHEME', 'https'), ] ], ], ], ``` ## 六、CI/CD 流程 ### 1. GitLab CI 示例 ```yaml stages: - test - build - deploy unit_tests: stage: test image: php:8.1 script: - apt-get update && apt-get install -y git unzip - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts - vendor/bin/phpunit build_image: stage: build image: docker:latest services: - docker:dind script: - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:latest . - docker push $CI_REGISTRY_IMAGE:latest deploy_production: stage: deploy image: bitnami/kubectl:latest script: - kubectl apply -f kubernetes/deployment.yaml - kubectl rollout status deployment/laravel-app environment: name: production url: https://yourdomain.com when: manual ``` ## 七、安全最佳实践 1. **网络安全**: - 使用 WAF (Web Application Firewall) - 配置 VPC 网络隔离 - 启用 DDoS 防护 2. **应用安全**: ```php // 强制 HTTPS URL::forceScheme('https'); // CSP 头 header("Content-Security-Policy: default-src 'self'"); ``` 3. **密钥管理**: - 使用 Vault 或 KMS 管理密钥 - 定期轮换数据库凭证 ## 八、扩展策略 1. **水平扩展**: - 无状态应用层自动扩展 - 数据库读写分离 2. **垂直扩展**: - 数据库优化 (索引、分表) - 查询缓存 3. **功能解耦**: ```php // 使用事件驱动架构 event(new OrderShipped($order)); // 微服务通信 Http::post('inventory-service/api/update', [...]); ``` 这套架构可以支持日 PV 千万级的大型 Laravel 应用,根据实际业务需求可进一步调整优化。 # Nginx + PHP 8 + PHP-FPM 性能优化指南 ## 1. PHP-FPM 配置优化 ### 主配置文件优化 (`/etc/php/8.x/fpm/php-fpm.conf`) ```ini emergency_restart_threshold = 10 emergency_restart_interval = 1m process_control_timeout = 10s ``` ### 进程池优化 (`/etc/php/8.x/fpm/pool.d/www.conf`) ```ini [www] user = www-data group = www-data ; 动态进程管理 - 根据服务器内存调整 pm = dynamic pm.max_children = 100 ; 最大子进程数 = (总内存 - 其他服务内存) / 单个PHP进程内存 pm.start_servers = 20 ; 启动时的子进程数 = CPU核心数 × 2 pm.min_spare_servers = 10 ; 最小空闲进程数 ≈ CPU核心数 pm.max_spare_servers = 30 ; 最大空闲进程数 ≈ CPU核心数 × 2 pm.max_requests = 500 ; 每个子进程处理多少请求后重启 ; 提高进程优先级 process.priority = -10 ; 优化进程通信 listen = /run/php/php8.2-fpm.sock listen.owner = www-data listen.group = www-data listen.mode = 0660 ; 启用慢日志 slowlog = /var/log/php-fpm/slow.log request_slowlog_timeout = 5s ; 限制单个请求资源 request_terminate_timeout = 30s rlimit_files = 65535 rlimit_core = unlimited ``` ## 2. PHP 8 配置优化 (`/etc/php/8.x/fpm/php.ini`) ```ini ; 基础优化 max_execution_time = 30 ; 减少脚本执行时间 memory_limit = 128M ; 根据应用需求调整 upload_max_filesize = 16M post_max_size = 18M ; OPcache 配置 (PHP 8 内置) opcache.enable=1 opcache.memory_consumption=256 ; 根据应用大小调整 opcache.interned_strings_buffer=20 opcache.max_accelerated_files=20000 opcache.revalidate_freq=60 ; 检查文件更改间隔(秒) opcache.fast_shutdown=1 opcache.enable_cli=1 ; CLI也启用OPcache opcache.jit_buffer_size=256M ; PHP 8 JIT 缓冲区大小 opcache.jit=1235 ; JIT模式 (4级优化) ; 禁用不必要功能 disable_functions = exec,passthru,shell_exec,system,proc_open,popen expose_php = Off ``` ## 3. Nginx 配置优化 ### 主配置文件 (`/etc/nginx/nginx.conf`) ```nginx user www-data; worker_processes auto; # 自动设置为CPU核心数 worker_rlimit_nofile 65535; # 每个worker能打开的文件描述符数量 events { worker_connections 4096; # 每个worker最大连接数 multi_accept on; # 同时接受多个连接 use epoll; # Linux高性能事件模型 } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 15; keepalive_requests 1000; types_hash_max_size 2048; server_tokens off; # 缓冲区优化 client_body_buffer_size 16K; client_header_buffer_size 1k; client_max_body_size 18m; large_client_header_buffers 4 16k; # 文件缓存 open_file_cache max=200000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; # MIME类型 include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式 access_log off; # 生产环境可关闭或缓冲 error_log /var/log/nginx/error.log crit; # Gzip压缩 gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # 包含站点配置 include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } ``` ### PHP站点配置示例 ```nginx server { listen 80; server_name example.com; root /var/www/html; index index.php index.html; # 安全头 add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "strict-origin-when-cross-origin"; # 静态文件缓存 location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ { expires 365d; access_log off; add_header Cache-Control "public"; } # PHP处理 location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 优化FastCGI fastcgi_buffer_size 128k; fastcgi_buffers 256 16k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; fastcgi_read_timeout 60s; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } # 限制上传目录执行PHP location ~* /uploads/.*\.php$ { deny all; } } ``` ## 4. 系统级优化 ### 内核参数调整 (`/etc/sysctl.conf`) ```conf # 增加网络性能 net.core.somaxconn = 65535 net.core.netdev_max_backlog = 262144 net.ipv4.tcp_max_syn_backlog = 262144 # 减少TCP连接时间 net.ipv4.tcp_fin_timeout = 15 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 # 增加文件描述符限制 fs.file-max = 2097152 # 内存分配 vm.swappiness = 10 vm.vfs_cache_pressure = 50 ``` 应用修改: ```bash sysctl -p ``` ### 增加文件描述符限制 (`/etc/security/limits.conf`) ``` * soft nofile 65535 * hard nofile 65535 www-data soft nofile 65535 www-data hard nofile 65535 ``` ## 5. 监控与调优工具 ### 实时监控命令 ```bash # 查看PHP-FPM状态 sudo systemctl status php8.2-fpm sudo journalctl -u php8.2-fpm -f # 查看PHP-FPM进程 ps -ylC php-fpm8.2 --sort:rss # Nginx状态 sudo systemctl status nginx sudo tail -f /var/log/nginx/error.log # 系统资源监控 htop iftop -n iotop -o ``` ### 性能测试工具 ```bash # 安装基准测试工具 sudo apt install apache2-utils siege # 压力测试 ab -n 10000 -c 100 http://example.com/ siege -b -c100 -t60S http://example.com/ ``` ## 6. 高级优化技巧 ### 使用最新版本 ```bash # 升级到最新PHP 8.2/8.3 sudo apt install php8.3-fpm php8.3-opcache # 使用最新Nginx主线版 sudo add-apt-repository ppa:nginx/development sudo apt update sudo apt install nginx ``` ### 使用Unix Socket替代TCP ```nginx fastcgi_pass unix:/run/php/php8.2-fpm.sock; ``` ### 启用HTTP/2 ```nginx listen 443 ssl http2; ``` ### 使用 Brotli 压缩 ```nginx brotli on; brotli_comp_level 6; brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ``` ## 7. 优化效果验证 优化前后对比指标: 1. 请求响应时间 (使用 `ab` 或 `siege`) 2. 并发处理能力 3. 内存占用情况 4. CPU利用率 5. 吞吐量 (Requests/sec) 通过以上优化,Nginx + PHP 8 + PHP-FPM 的性能通常可以提高3-5倍,特别是在高并发场景下效果更为显著。建议每次修改配置后都进行压力测试,观察系统资源使用情况,逐步调整到最佳状态。 # PHP 微服务架构下的用户认证与权限系统设计 ## 1. 整体架构设计 ### 架构图 ``` ┌───────────────────────────────────────────────────────┐ │ 客户端层 (Client) │ │ (Web/App/API调用方) │ └───────────────┬───────────────────┬───────────────────┘ │ │ ┌───────────────▼───────┐ ┌────────▼───────────────────┐ │ API 网关 │ │ 认证服务 │ │ (身份验证/路由转发) │ │ (登录/注册/令牌签发) │ └───────────────┬───────┘ └────────┬───────────────────┘ │ │ ┌───────────────▼───────────────────▼───────────────┐ │ 微服务集群 │ │ (各业务服务通过JWT验证权限) │ └───────────────┬───────────────────┬───────────────┘ │ │ ┌───────────────▼───────┐ ┌────────▼───────────────────┐ │ 用户服务 │ │ 权限服务 │ │ (用户数据管理) │ │ (角色/权限分配/验证) │ └───────────────────────┘ └───────────────────────────┘ ``` ## 2. 核心组件实现 ### 2.1 JWT 认证服务 **安装依赖**: ```bash composer require firebase/php-jwt lcobucci/jwt ``` **JWT 服务类**: ```php secretKey = $secretKey; } public function generateToken(array $payload, int $expire = 3600): string { $issuedAt = time(); $payload += [ 'iat' => $issuedAt, 'exp' => $issuedAt + $expire, 'iss' => 'your-auth-service', 'aud' => 'your-microservices' ]; return JWT::encode($payload, $this->secretKey, $this->algorithm); } public function validateToken(string $token): ?array { try { $decoded = JWT::decode($token, new Key($this->secretKey, $this->algorithm)); return (array)$decoded; } catch (\Exception $e) { return null; } } } ``` ### 2.2 权限服务设计 **RBAC (基于角色的访问控制) 数据库结构**: ```sql CREATE TABLE `users` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `username` varchar(255) UNIQUE NOT NULL, `password_hash` varchar(255) NOT NULL ); CREATE TABLE `roles` ( `id` int PRIMARY KEY AUTO_INCREMENT, `name` varchar(255) UNIQUE NOT NULL, `description` varchar(255) ); CREATE TABLE `user_roles` ( `user_id` bigint, `role_id` int, PRIMARY KEY (`user_id`, `role_id`) ); CREATE TABLE `permissions` ( `id` int PRIMARY KEY AUTO_INCREMENT, `name` varchar(255) UNIQUE NOT NULL, `description` varchar(255) ); CREATE TABLE `role_permissions` ( `role_id` int, `permission_id` int, PRIMARY KEY (`role_id`, `permission_id`) ); ``` **权限检查服务**: ```php pdo = $pdo; } public function userHasPermission(int $userId, string $permission): bool { $stmt = $this->pdo->prepare(" SELECT COUNT(*) FROM user_roles ur JOIN role_permissions rp ON ur.role_id = rp.role_id JOIN permissions p ON rp.permission_id = p.id WHERE ur.user_id = :userId AND p.name = :permission "); $stmt->execute([ ':userId' => $userId, ':permission' => $permission ]); return $stmt->fetchColumn() > 0; } public function getUserPermissions(int $userId): array { $stmt = $this->pdo->prepare(" SELECT p.name FROM user_roles ur JOIN role_permissions rp ON ur.role_id = rp.role_id JOIN permissions p ON rp.permission_id = p.id WHERE ur.user_id = :userId "); $stmt->execute([':userId' => $userId]); return $stmt->fetchAll(\PDO::FETCH_COLUMN, 0); } } ``` ## 3. API 网关实现 ### 3.1 统一认证中间件 ```php jwtService = $jwtService; $this->permissionService = $permissionService; } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { // 1. 获取Token $token = $this->getTokenFromRequest($request); if (!$token) { return new JsonResponse(['error' => 'Token missing'], 401); } // 2. 验证Token $payload = $this->jwtService->validateToken($token); if (!$payload) { return new JsonResponse(['error' => 'Invalid token'], 401); } // 3. 检查权限 (从路由获取所需权限) $requiredPermission = $request->getAttribute('route')->getArgument('permission'); if ($requiredPermission && !$this->permissionService->userHasPermission($payload['user_id'], $requiredPermission)) { return new JsonResponse(['error' => 'Forbidden'], 403); } // 4. 将用户信息添加到请求属性 $request = $request->withAttribute('auth_user', $payload); return $handler->handle($request); } private function getTokenFromRequest(ServerRequestInterface $request): ?string { $header = $request->getHeaderLine('Authorization'); if (preg_match('/Bearer\s(\S+)/', $header, $matches)) { return $matches[1]; } return $request->getQueryParams()['token'] ?? null; } } ``` ## 4. 登录流程实现 ### 4.1 登录控制器 ```php userRepository = $userRepository; $this->jwtService = $jwtService; } public function login(ServerRequestInterface $request): ResponseInterface { $data = json_decode($request->getBody()->getContents(), true); // 1. 验证输入 if (empty($data['username']) || empty($data['password'])) { return new JsonResponse(['error' => 'Invalid credentials'], 400); } // 2. 查找用户 $user = $this->userRepository->findByUsername($data['username']); if (!$user || !password_verify($data['password'], $user['password_hash'])) { return new JsonResponse(['error' => 'Invalid credentials'], 401); } // 3. 生成JWT $token = $this->jwtService->generateToken([ 'user_id' => $user['id'], 'username' => $user['username'] ]); // 4. 返回响应 return new JsonResponse([ 'token' => $token, 'expires_in' => 3600, 'token_type' => 'Bearer' ]); } } ``` ## 5. 微服务集成方案 ### 5.1 服务间认证 **使用服务账户**: ```php // 在服务启动时获取服务令牌 $serviceToken = $jwtService->generateToken([ 'service_name' => 'order-service', 'scope' => ['internal'] ], 86400 * 365); // 长期有效的服务令牌 // 在服务间调用时携带 $response = $httpClient->request('GET', 'http://user-service/api/users', [ 'headers' => [ 'Authorization' => 'Bearer ' . $serviceToken, 'X-Service-Auth' => 'order-service' ] ]); ``` ### 5.2 权限缓存优化 **Redis缓存权限**: ```php class CachedPermissionService extends PermissionService { private $redis; private $ttl = 3600; public function __construct(\PDO $pdo, \Redis $redis) { parent::__construct($pdo); $this->redis = $redis; } public function getUserPermissions(int $userId): array { $cacheKey = "user_permissions:$userId"; if ($this->redis->exists($cacheKey)) { return json_decode($this->redis->get($cacheKey), true); } $permissions = parent::getUserPermissions($userId); $this->redis->setex($cacheKey, $this->ttl, json_encode($permissions)); return $permissions; } } ``` ## 6. 安全增强措施 ### 6.1 令牌黑名单 ```php class JwtServiceWithBlacklist extends JwtService { private $redis; public function __construct(string $secretKey, \Redis $redis) { parent::__construct($secretKey); $this->redis = $redis; } public function invalidateToken(string $token, int $expire): void { $payload = $this->validateToken($token); if ($payload) { $jti = $payload['jti'] ?? md5($token); $this->redis->setex("jwt_blacklist:$jti", $expire, '1'); } } public function validateToken(string $token): ?array { $payload = parent::validateToken($token); if ($payload) { $jti = $payload['jti'] ?? md5($token); if ($this->redis->exists("jwt_blacklist:$jti")) { return null; } } return $payload; } } ``` ### 6.2 速率限制 ```php class RateLimitMiddleware implements MiddlewareInterface { private $redis; public function __construct(\Redis $redis) { $this->redis = $redis; } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $ip = $request->getServerParams()['REMOTE_ADDR']; $key = "rate_limit:$ip"; $current = $this->redis->incr($key); if ($current === 1) { $this->redis->expire($key, 60); } if ($current > 100) { return new JsonResponse(['error' => 'Too many requests'], 429); } return $handler->handle($request); } } ``` ## 7. 部署建议 1. **认证服务独立部署**:将认证服务部署为独立微服务 2. **多区域部署**:在多个区域部署认证服务以减少延迟 3. **数据库分片**:用户数据按地区或ID范围分片 4. **监控**:监控认证服务的成功率、延迟和错误率 5. **灾备**:建立多活数据中心,确保认证服务高可用 ## 8. 性能优化 1. **使用OPcache**:PHP配置中启用OPcache 2. **连接池**:数据库和Redis使用连接池 3. **异步日志**:使用异步方式记录审计日志 4. **热点缓存**:缓存频繁访问的用户权限数据 5. **JWT预验证**:在API网关层先验证JWT有效性 这种架构设计提供了灵活的认证和授权机制,能够支持高并发的微服务系统,同时保持了良好的安全性和可扩展性。