laravel/symfony-on-cloud
Composer 安装命令:
composer require laravel/symfony-on-cloud
包简介
Bring Laravel Cloud features to Symfony — a feature-based bundle whose first capability is Managed Queues on top of Symfony Messenger.
README 文档
README
Bring Laravel Cloud features to a Symfony application.
Managed queues is the first feature; more Laravel Cloud
capabilities will follow under the same laravel_cloud config key.
Installation
composer require laravel/symfony-on-cloud
Then register the bundle in config/bundles.php:
return [ // ... Laravel\Cloud\Symfony\LaravelCloudBundle::class => ['all' => true], ];
The package ships no Symfony Flex recipe, so the bundle has to be registered manually for now.
Managed queues
Run Laravel Cloud managed queues on top of Symfony Messenger.
The bundle ships a ready-made cloud transport that always points at your
managed queue — nothing to declare, no DSN to wire up. Just route to it:
# config/packages/messenger.yaml framework: messenger: routing: '*': cloud
On Cloud that's all you need: the injected config wires everything up, so it just works — no extra setup — and throughput, duration and failures show up in the Laravel Cloud dashboard automatically. To run it locally, see Local development.
Already running Messenger? Cloud injects
MESSENGER_TRANSPORT_DSN=laravel-cloud://managed-queue, so an app using the conventionalasynctransport (dsn: '%env(MESSENGER_TRANSPORT_DSN)%') runs on Cloud unchanged.
Multiple queues
A Laravel Cloud environment can have several managed queues (for example
default and critical), each backed by its own SQS queue and its own isolated
workers. You keep the single cloud transport and reference a queue by its
name on both sides, rather than Symfony's one-transport-per-queue convention.
Dispatch to a specific queue with CloudQueueStamp — the same pattern as
Symfony's own AmqpStamp:
use Laravel\Cloud\Symfony\Queue\Messenger\CloudQueueStamp; use Symfony\Component\Messenger\MessageBusInterface; $bus->dispatch(new ProcessReport($report), [new CloudQueueStamp('critical')]);
Without a stamp, a message goes to the environment's default queue. To route by message type, add a middleware that attaches the stamp based on the class.
On Cloud each managed queue gets its own isolated workers, run for you. A
CloudQueueStamp('critical') dispatch is handled by the critical workers and
reported against critical in the dashboard, so per-queue metrics line up with
where you sent the work.
FIFO queues
A managed queue whose name ends in .fifo is a FIFO queue:
messages are delivered in strict order and deduplicated. Target one exactly like
any other queue — by its .fifo name:
use Laravel\Cloud\Symfony\Queue\Messenger\CloudQueueStamp; $bus->dispatch(new ProcessOrder($order), [new CloudQueueStamp('orders.fifo')]);
SQS requires every FIFO message to carry a message group ID (messages sharing a group are ordered relative to each other) and a deduplication ID. By default the bundle sends SQS-safe values — the group ID is the queue name and the deduplication ID is unique per message — so this works with no extra setup.
To control ordering scope or deduplicate by a stable key, add a CloudFifoStamp
alongside the queue stamp (the field names match Symfony's AmazonSqsFifoStamp):
use Laravel\Cloud\Symfony\Queue\Messenger\CloudFifoStamp; use Laravel\Cloud\Symfony\Queue\Messenger\CloudQueueStamp; $bus->dispatch(new ProcessOrder($order), [ new CloudQueueStamp('orders.fifo'), // Order this customer's jobs together; dedupe re-dispatches of the same order. new CloudFifoStamp( messageGroupId: 'customer-'.$order->customerId, messageDeduplicationId: 'order-'.$order->id, ), ]);
A CloudFifoStamp is only valid on a .fifo queue; applying it to a standard
queue throws rather than being silently ignored. FIFO queues don't support a
per-message delivery delay at all, so a caller-set DelayStamp is rejected (see
Delays below).
Fair queues
SQS fair queues keep one noisy tenant from starving the others on a busy queue. On a standard queue, attaching a message group ID marks each message with the tenant it belongs to (a customer, client app, or request type); SQS then spreads consumer capacity fairly across groups when one tenant builds a backlog. Fairness is automatic and server-side — there's nothing to enable and no change to your consumers.
Unlike FIFO, the group ID here is only a tenant key: messages in the same
group still process in parallel at full throughput, and there is no ordering or
deduplication. Attach a CloudMessageGroupStamp:
use Laravel\Cloud\Symfony\Queue\Messenger\CloudMessageGroupStamp; use Laravel\Cloud\Symfony\Queue\Messenger\CloudQueueStamp; $bus->dispatch(new ProcessOrder($order), [ // A standard queue (no ".fifo"), so the group ID is a fair-queue tenant key. new CloudQueueStamp('orders'), new CloudMessageGroupStamp('customer-'.$order->customerId), ]);
To attach the tenant key everywhere without repeating it at each dispatch, add a
middleware that stamps CloudMessageGroupStamp from the message (the tenant on
the job, the authenticated user, etc.).
The two stamps mirror the two queue models and don't mix: CloudMessageGroupStamp
is for fair queues (standard) and is rejected on a .fifo queue, where the group
is an ordering scope set via CloudFifoStamp instead.
Delays
A DelayStamp on a standard queue maps to an SQS per-message delivery delay,
which SQS hard-caps at 15 minutes. Asking for a longer delay is unsatisfiable,
so the transport throws rather than silently delivering after 15 minutes — a
job that must run in an hour shouldn't quietly run in fifteen.
FIFO queues don't support a per-message delay at all, so a DelayStamp on a
.fifo queue is rejected outright — same principle, same loud failure.
(This is about dispatch delays only. Retry backoff is a separate path that isn't bound by the 15-minute cap — see Retries.)
Retries
When a handler fails, the transport releases the message back to SQS for native redelivery via the visibility timeout, rather than re-sending a fresh copy. The original message stays put and SQS redelivers it after the backoff — so retries are never re-dispatched, the backoff can run up to SQS's 12-hour visibility ceiling (not the 15-minute send cap), and it works unchanged on FIFO queues.
Retries use Symfony Messenger's own retry strategy — there's no separate config
to learn, and UnrecoverableExceptionInterface is honored (an unrecoverable error,
or a handler failure wrapping one, skips straight to failure). Tune it on the
cloud transport like any other Messenger transport:
# config/packages/messenger.yaml framework: messenger: transports: cloud: retry_strategy: max_retries: 3 # 3 retries → 4 total deliveries delay: 1000 # first backoff, in milliseconds multiplier: 2 # backoff multiplier per attempt max_delay: 0 # backoff ceiling in ms; 0 = none (SQS still caps at 12h)
(You only add the retry_strategy — the dsn comes from the ready-made cloud
transport. Omit the block entirely to use Messenger's defaults: 3 retries.)
A job that exhausts its retries (or throws an unrecoverable exception) is deleted and recorded as a failed job, surfacing in the Laravel Cloud dashboard.
Local development
The cloud transport is just a default, so an app-defined transport of the same
name wins. To process jobs inline locally without SQS, override it in dev:
# config/packages/messenger.yaml when@dev: framework: messenger: transports: cloud: 'sync://'
To turn the feature off entirely, set laravel_cloud.queue.enabled: false.
Testing
composer install vendor/bin/phpunit
统计信息
- 总下载量: 4
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-29