Laravel 12 集成 Kafka 消息队列完整指南
在 Laravel 12 中使用 Kafka 作为消息队列驱动需要安装特定的扩展包,以下是完整的实现方案:
1. 安装必要依赖
首先安装 PHP 的 Kafka 扩展和 Laravel 适配包:
# 安装 librdkafka 依赖
sudo apt-get install -y librdkafka-dev
# 安装 PHP 扩展
pecl install rdkafka
# 在 php.ini 中添加扩展
echo "extension=rdkafka.so" | sudo tee -a /etc/php/8.3/cli/php.ini
# 安装 Laravel 适配包
composer require enqueue/rdkafka enqueue/laravel-queue
2. 配置环境变量
在 .env
文件中添加 Kafka 配置:
QUEUE_CONNECTION=kafka
KAFKA_BROKERS=kafka1:9092,kafka2:9092
KAFKA_QUEUE=laravel_queue
KAFKA_GROUP_ID=laravel_group
KAFKA_AUTO_COMMIT=true
KAFKA_OFFSET_RESET=latest
KAFKA_SECURITY_PROTOCOL=PLAINTEXT
KAFKA_SASL_MECHANISM=PLAIN
KAFKA_SASL_USERNAME=
KAFKA_SASL_PASSWORD=
3. 队列服务配置
创建 config/queue.php
中的 Kafka 连接配置:
'kafka' => [
'driver' => 'kafka',
'connection' => 'default',
'queue' => env('KAFKA_QUEUE', 'default'),
'consumer_group_id' => env('KAFKA_GROUP_ID', 'laravel_group'),
'auto_commit' => env('KAFKA_AUTO_COMMIT', true),
'sleep_on_error' => env('KAFKA_ERROR_SLEEP', 5),
'max_retries' => env('KAFKA_MAX_RETRIES', 3),
'brokers' => env('KAFKA_BROKERS', 'localhost:9092'),
'options' => [
'security_protocol' => env('KAFKA_SECURITY_PROTOCOL', 'PLAINTEXT'),
'sasl_mechanism' => env('KAFKA_SASL_MECHANISM', 'PLAIN'),
'sasl_username' => env('KAFKA_SASL_USERNAME'),
'sasl_password' => env('KAFKA_SASL_PASSWORD'),
'offset_reset' => env('KAFKA_OFFSET_RESET', 'latest'),
'log_level' => env('KAFKA_LOG_LEVEL', LOG_DEBUG),
],
],
4. 创建 Kafka 任务
生成队列任务类:
php artisan make:job ProcessKafkaMessage
编辑 app/Jobs/ProcessKafkaMessage.php
:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessKafkaMessage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $message;
public function __construct($message)
{
$this->message = $message;
}
public function handle()
{
// 处理 Kafka 消息
\Log::info('Processing Kafka message: ', (array)$this->message);
// 业务逻辑处理
// ...
}
public function failed(\Throwable $exception)
{
\Log::error('Kafka message processing failed: ', [
'error' => $exception->getMessage(),
'message' => $this->message
]);
}
}
5. 生产消息到 Kafka
在控制器中分发消息:
use App\Jobs\ProcessKafkaMessage;
// 简单消息
ProcessKafkaMessage::dispatch([
'event' => 'user.created',
'data' => ['user_id' => 123, 'email' => 'test@example.com']
]);
// 带自定义属性的消息
ProcessKafkaMessage::dispatch([
'event' => 'order.paid',
'amount' => 99.99
])->onConnection('kafka')
->onTopic('orders')
->withKey('order_12345'); // Kafka 消息键
6. 启动 Kafka Consumer
# 基础消费者
php artisan queue:work kafka
# 高级选项
php artisan queue:work kafka \
--queue=high_priority \
--sleep=3 \
--tries=3 \
--max-jobs=1000 \
--timeout=60
7. Supervisor 配置
创建 /etc/supervisor/conf.d/laravel-kafka-worker.conf
:
[program:laravel-kafka-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/your-project/artisan queue:work kafka --sleep=3 --tries=3 --max-jobs=1000
autostart=true
autorestart=true
user=www-data
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/your-project/storage/logs/kafka-worker.log
stopwaitsecs=60
environment=KAFKA_BROKERS="kafka1:9092,kafka2:9092"
管理 Supervisor:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-kafka-worker:*
8. 高级配置
自定义 Kafka 主题
// 在任务类中添加
public function topic()
{
return 'custom_topic';
}
// 或者动态指定
ProcessKafkaMessage::dispatch($data)->onTopic('custom_topic');
消息分区策略
// 指定分区键
public function key()
{
return $this->message['user_id']; // 按用户ID分区
}
// 或直接指定分区号
public function partition()
{
return 2; // 固定分区2
}
事务支持
DB::transaction(function () {
$user = User::create([...]);
ProcessKafkaMessage::dispatch([
'event' => 'user.created',
'user_id' => $user->id
])->afterCommit(); // 事务提交后发送
});
9. 监控与调试
查看 Kafka 主题
kafka-topics --bootstrap-server kafka:9092 --list
kafka-console-consumer --bootstrap-server kafka:9092 --topic laravel_queue --from-beginning
集成 Prometheus 监控
安装监控包:
composer require superbalist/laravel-prometheus-exporter
配置 Kafka 指标:
// app/Providers/AppServiceProvider.php
public function boot()
{
$exporter = app('prometheus');
$exporter->registerGauge('kafka_messages_processed', 'Total processed messages', ['topic']);
}
在 Job 中记录指标:
public function handle()
{
$start = microtime(true);
// 处理消息...
app('prometheus')->inc('kafka_messages_processed', ['topic' => $this->topic()]);
app('prometheus')->observe('kafka_message_process_time', microtime(true) - $start);
}
10. 性能优化建议
-
批量消费:
php artisan queue:work kafka --batch-size=100
-
调整预取值:
// config/queue.php 'kafka' => [ 'options' => [ 'fetch.message.max.bytes' => 1048576, // 1MB 'queued.max.messages.kbytes' => 10240, // 10MB ], ],
-
并行处理:
; Supervisor 配置 numprocs = (CPU核心数 × 3)
-
内存管理:
php artisan queue:work kafka --memory=512 --max-jobs=500
常见问题解决
连接问题
# 测试连接
kafka-console-producer --broker-list kafka:9092 --topic test
> hello
> ^D
kafka-console-consumer --bootstrap-server kafka:9092 --topic test --from-beginning
性能瓶颈
// 在 Job 中禁用模型序列化
public $preserveModel = false;
消息顺序保证
// 使用相同分区键保证顺序
public function key()
{
return $this->message['order_id'];
}
通过以上配置,您的 Laravel 12 应用可以高效地使用 Kafka 作为消息队列驱动,实现高吞吐量的异步消息处理。Kafka 特别适合需要高并发、持久化和顺序保证的消息场景。