定制 magetips/module-azure 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

magetips/module-azure

Composer 安装命令:

composer require magetips/module-azure

包简介

Azure Service Bus integration for Magento's MessageQueue framework, built for Dynamics 365 connectivity.

README 文档

README

title README

MageTips_Azure

Connects Magento's native MessageQueue framework to Azure Service Bus, so publishers, consumers, and topology declared via the standard communication.xml / queue_topology.xml / queue_publisher.xml / queue_consumer.xml config work against an Azure Service Bus namespace exactly the way they would against RabbitMQ — same XML, same PublisherInterface/consumer handler signatures, same bin/magento queue:consumers:start.

Built on magetips/windowsazure, a maintained fork of the archived Azure PHP SDK, trimmed to only the Service Bus REST client this module needs.

Table of contents

Installation

composer require magetips/module-azure
bin/magento module:enable MageTips_Azure
bin/magento setup:upgrade

magetips/module-azure requires magetips/windowsazure (the underlying Service Bus REST client) as a normal Composer dependency, so it's pulled in automatically by the command above — no separate install step.

If Composer can't resolve magetips/windowsazure (for example, it isn't registered on Packagist yet), add it as a VCS repository in your project's root composer.json and re-run composer require:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/mage-tips/windowsazure"
        }
    ]
}

Core concept: how Magento's MQ abstractions map to Azure

Magento's MessageQueue framework was designed around AMQP (RabbitMQ), so its vocabulary is exchanges, queues, and bindings. Azure Service Bus has its own model — topics and subscriptions. This module bridges the two:

Magento concept (XML) Azure Service Bus concept Notes
communication.xml <topic> Azure Topic The thing you publish to.
queue_topology.xml <exchange> Azure Topic (again) In this module's convention, exchange name == topic name.
queue_topology.xml <binding destination="…"> Azure Subscription Each binding under an exchange becomes one Azure subscription on that topic. One binding = the common case; more than one = fan-out.
queue_consumer.xml <consumer queue="…"> A consumer reading one Subscription The queue attribute must match a binding's destination.
Admin Service Bus Configurations grid row Namespace host + SAS credentials + default subscription name, keyed by topic See Configuration reference.

The practical upshot: one topic can have several independent subscriptions, each getting its own full copy of every message (Azure's native fan-out) — this module supports that directly, see Multi-subscription fan-out.

Quick start

  1. Install the module — see Installation.
  2. Declare a topic across communication.xml, queue_topology.xml, queue_publisher.xml, and queue_consumer.xml in your own module — see Declaring a topic below for the exact shape each file needs.
  3. Go to Stores > Configuration > MageTips > Azure Service Bus > Service Bus Configurations and add a row for your topic with your Azure Service Bus namespace host, a SAS Access Key name/secret, and a subscription name.
  4. Either enable Topology > Automatically Create Topics on setup:upgrade and re-run setup:upgrade, or create the topic/subscription yourself in the Azure Portal.
  5. Publish via the standard PublisherInterface::publish($topicName, $data) and consume with bin/magento queue:consumers:start <consumer_name>.
  6. Check Azure Service Bus > Message Log in the admin, or var/log/azure_service_bus.log.

Declaring a topic: the four files you need

Every topic touches four config files, each answering a different question. This is the part new developers usually trip over, so here's a complete example — a fictional vendor_module.order_export topic — file by file, in the order Magento actually needs them.

1. communication.xml — "what does this topic carry, and who handles it?"

<topic name="vendor_module.order_export" request="string">
    <handler name="vendor_module_order_export.handler"
             type="Vendor\Module\Queue\Consumer\OrderExportConsumer"
             method="process"/>
</topic>
  • name — the topic name. This is the string every other file below references.
  • request — the PHP type of the message payload (string, int, a DTO/API interface, etc.).
  • response + is_synchronous="true" — only needed for RPC topics.
  • <handler> — which class/method actually processes a decoded message. You can register more than one handler per topic; Magento calls all of them.

2. queue_topology.xml — "what does this topic look like on the transport?"

<exchange name="vendor_module.order_export" type="topic" connection="azure-servicebus">
    <binding id="vendorModuleOrderExportTopology"
             topic="vendor_module.order_export"
             destinationType="queue"
             destination="vendor_module.order_export"/>
</exchange>
  • <exchange name="…"> — becomes the Azure Topic. Must equal the communication.xml topic name.
  • connection="azure-servicebus" — always this literal value for anything this module should handle (it's how MageTips\Azure\MessageQueue\ConnectionTypeResolver claims the connection).
  • <binding destination="…"> — becomes an Azure Subscription name (unless it differs from the topic name, see fan-out). In the common case, destination equals the topic name, exactly like above.

3. queue_publisher.xml — "which connection/exchange does publishing this topic use?"

<publisher topic="vendor_module.order_export">
    <connection name="azure-servicebus" exchange="vendor_module.order_export" disabled="false"/>
</publisher>
  • topic — again, must match. exchange — must match the <exchange name="…"> from queue_topology.xml. This file is what Magento\Framework\MessageQueue\PublisherInterface::publish() reads to route a topic to the right transport.

4. queue_consumer.xml — "who reads which subscription, and how?"

<consumer name="vendorModuleOrderExportConsumer"
          queue="vendor_module.order_export"
          connection="azure-servicebus"
          consumerInstance="MageTips\Azure\Queue\MessageQueueConsumer"
          handler="Vendor\Module\Queue\Consumer\OrderExportConsumer::process"/>
  • name — the consumer name you pass to bin/magento queue:consumers:start <name>.
  • queue — must match a binding's destination from queue_topology.xml (not necessarily the topic name — see fan-out below).
  • consumerInstance — always MageTips\Azure\Queue\MessageQueueConsumer for this module. Don't write your own; it's what wires Azure-specific logging, dead-lettering, and lock-renewal into the generic consumer contract.
  • handlerClass::method, invoked with the decoded message.

Optional per-consumer tuning attributes (same as any Magento consumer, nothing Azure-specific): maxMessages, sleep (seconds between polls when idle), maxIdleTime, onlySpawnWhenMessageAvailable.

The naming rule that ties it all together

File Attribute Must equal
communication.xml <topic name> the topic name everywhere else
queue_topology.xml <exchange name> the topic name
queue_topology.xml <binding topic> the topic name
queue_topology.xml <binding destination> the Azure subscription (see fan-out for when this differs from the topic name)
queue_publisher.xml <publisher topic> the topic name
queue_publisher.xml <connection exchange> the <exchange name> above
queue_consumer.xml <consumer queue> a <binding destination> above

Get any of these out of sync and Magento's own config validation (or TopologyInstaller) will fail loudly at setup:upgrade time, not silently at runtime.

Publishing and consuming

Publishing uses the plain Magento API — nothing Azure-specific in your calling code:

/** @var \Magento\Framework\MessageQueue\PublisherInterface $publisher */
$publisher->publish('vendor_module.order_export', json_encode(['orderId' => 12345]));

A consumer handler is a plain class/method, also nothing Azure-specific:

namespace Vendor\Module\Queue\Consumer;

class OrderExportConsumer
{
    public function process(string $message): void
    {
        $data = json_decode($message, true);
        // ... do the work ...
    }
}

Everything Azure-specific — connecting, encoding, peek-lock receive, ack/reject, dead-lettering, logging — happens inside MageTips\Azure\Queue\MessageQueueConsumer and MessageQueue\Queue/Exchange, which consumerInstance="MageTips\Azure\Queue\MessageQueueConsumer" wires in for you.

Extending topology

Multi-subscription fan-out

Azure Service Bus topics natively support more than one independent subscription — each subscription gets its own copy of every message published to the topic, the same way a RabbitMQ topic exchange can bind to multiple queues. Add a second <binding> with a different destination and a matching <consumer>:

<!-- queue_topology.xml -->
<exchange name="my_topic" type="topic" connection="azure-servicebus">
    <binding id="myTopicPrimary" topic="my_topic" destinationType="queue" destination="my_topic"/>
    <binding id="myTopicSecondConsumer" topic="my_topic" destinationType="queue" destination="my_topic.consumer_b"/>
</exchange>
<!-- queue_consumer.xml -->
<consumer name="myTopicConsumerB" queue="my_topic.consumer_b" connection="azure-servicebus"
          consumerInstance="MageTips\Azure\Queue\MessageQueueConsumer"
          handler="Vendor\Module\Queue\Consumer\SecondConsumer::process"/>

TopologyInstaller creates one Azure subscription per binding under the topic. The subscription name for each binding is resolved as follows:

  • If the binding's destination matches the topic name (the single-binding case every topic starts as), the subscription name comes from the admin-configured Subscription field for that topic — existing single-binding topics are completely unaffected by this feature.
  • Otherwise (an additional fan-out binding), the subscription name is the binding's own destination — there's no separate admin config for it, the same way AMQP has no separate "friendly queue name" either.

The Dead Letters admin page and CLI automatically iterate every subscription on a topic, so fan-out topics don't need any special handling there either.

Synchronous / RPC topics

communication.xml's is_synchronous="true" topics are fully supported: MessageQueue\Exchange::enqueue() publishes the request, then polls the reply queue (Azure has no blocking wait like AMQP's channel->wait(), but ReceiveMessageOptions::setTimeout() maps to Azure's own server-side long-poll, so this isn't a client busy-loop) matching on correlation_id, and returns the reply body — or throws a LocalizedException after 30 seconds if nothing matching arrives (mirrors Magento\Framework\Amqp\Exchange::RPC_CONNECTION_TIMEOUT).

Two extra declarations are required, since Azure has no "raw queue" concept outside topic+subscription:

  1. A reply topic. Magento\Framework\MessageQueue\Rpc\ResponseQueueNameBuilder builds the reply queue name as responseQueue.<topic_name>, shared by every RPC call to that topic. It needs its own <exchange>/<binding> in queue_topology.xml (same pattern as any other topic) and its own <topic> in communication.xml (no handler needed — nothing consumes it via queue_consumer.xml, it's read directly by Exchange::enqueue()'s wait loop; Magento's own topology config reader validates every binding's topic against communication.xml regardless of whether anything consumes it).
  2. Its own admin config row under Service Bus Configurations, same as the request topic — it has no fallback to another topic's credentials.
<!-- communication.xml -->
<topic name="my.rpc.topic" request="string" response="string" is_synchronous="true">
    <handler name="my_rpc.handler" type="Vendor\Module\Queue\Consumer\MyRpcHandler" method="process"/>
</topic>
<topic name="responseQueue.my.rpc.topic" request="string"/>
<!-- queue_topology.xml -->
<exchange name="my.rpc.topic" type="topic" connection="azure-servicebus">
    <binding id="myRpcTopology" topic="my.rpc.topic" destinationType="queue" destination="my.rpc.topic"/>
</exchange>
<exchange name="responseQueue.my.rpc.topic" type="topic" connection="azure-servicebus">
    <binding id="myRpcReplyTopology" topic="responseQueue.my.rpc.topic"
             destinationType="queue" destination="responseQueue.my.rpc.topic"/>
</exchange>

Publishing is the same PublisherInterface::publish() call — for a synchronous topic it blocks and returns the reply:

$reply = $publisher->publish('my.rpc.topic', $requestPayload); // blocks until reply or 30s timeout

This also requires Magento\Framework\MessageQueue\Rpc\Publisher wired under PublisherPool's sync mode for the azure-servicebus connection type — already done in this module's etc/di.xml, nothing to add yourself:

<type name="Magento\Framework\MessageQueue\PublisherPool">
    <arguments>
        <argument name="publishers" xsi:type="array">
            <item name="sync" xsi:type="array">
                <item name="azure-servicebus" xsi:type="object">Magento\Framework\MessageQueue\Rpc\Publisher</item>
            </item>
        </argument>
    </arguments>
</type>

The publishing process is the one waiting for the reply, not the one producing it, so a consumer for the topic must already be running (bin/magento queue:consumers:start <consumer_name>) before you publish.

Topology installation (setup:upgrade)

Declaring a topic in the four files above doesn't create anything on Azure by itself — something has to call TopologyInstaller::install().

This is controlled by a single admin setting: Stores > Configuration > MageTips > Azure Service Bus > Topology > Automatically Create Topics on setup:upgrade (disabled by default). It's the sole authority over this behavior — there's no separate deployment-mode check baked into the module.

  • Enabled: MageTips\Azure\Setup\Recurring runs TopologyInstaller::install() automatically on every bin/magento setup:upgrade, creating any topic/subscription/rule declared in queue_topology.xml that doesn't already exist. Convenient for local/sandbox development — declare a topic, run setup:upgrade, it's on Azure. If installation fails (e.g. credentials without "Manage" rights), the failure is written to var/log/azure_service_bus.log and never blocks setup:upgrade.
  • Disabled (default): automatic installation is a no-op. Topology is expected to be provisioned out-of-band by whoever owns Azure infrastructure (DevOps/IaC — Terraform, ARM templates, or the Portal), typically issuing scoped, least-privilege, per-topic SAS credentials (e.g. Send-only or Listen-only on one specific topic) rather than a namespace-wide RootManageSharedAccessKey.

There is deliberately no separate CLI command to trigger this manually — Magento_Amqp doesn't have one either, so setup:upgrade (with the setting enabled) is the one and only way topology gets installed, matching RabbitMQ's own behavior exactly.

If you want topology installation restricted by Magento's deployment mode (e.g. never even attempt it in production regardless of the admin setting), that's deliberately not built into this module — add a plugin or di.xml preference around MageTips\Azure\System\TopologyConfig::isAutoInstallEnabled() in your own module instead, rather than relying on logic buried in this one.

Limitation: with the setting left at its default (disabled), a fresh deployment against a brand-new Azure namespace will not work out of the box purely by running setup:upgrade — someone has to either enable the setting and run setup:upgrade (with sufficiently-privileged credentials), or provision the topics out-of-band (DevOps/IaC).

Running consumers

This module doesn't ship its own cron or consumer-scheduling config — consumers declared in queue_consumer.xml are picked up and run automatically by Magento's own built-in Magento\MessageQueue\Model\Cron\ConsumersRunner (the consumers_runner cron job in Magento_MessageQueue), exactly the same way RabbitMQ consumers are. That runner already handles connection resolution (via ConnectionTypeResolver, which this module implements so it's only claimed for azure-servicebus connections), lock-based de-duplication, and message-availability checks before spawning a process.

Configure it the standard Magento way, in app/etc/env.php:

'cron_consumers_runner' => [
    'cron_run' => true,
    'max_messages' => 10000,
    'consumers' => [], // empty = run every declared consumer; or list specific consumer names
    'multiple_processes' => [], // consumer name => number of parallel processes
],

multiple_processes spawns several concurrent OS processes against the same consumer/subscription. This is safe: Azure's own peek-lock semantics guarantee a message is only ever handed to one receiver at a time, and Magento's own DB-level queue_lock table (keyed by message_id) adds a second, transport-independent safety net.

If you'd rather not have cron spawn short-lived processes, run consumers as long-lived processes under supervisord instead (bin/magento queue:consumers:start <name>) and set cron_run to false — again, identical to how this is done for RabbitMQ.

Configuration reference

All settings live under Stores > Configuration > MageTips > Azure Service Bus.

Service Bus Configurations

A repeatable grid, one row per topic:

Column Description
Topic Must exactly match a communication.xml/queue_topology.xml topic name.
Host Namespace endpoint, e.g. https://your-namespace.servicebus.windows.net/.
Access Key SAS policy name, e.g. RootManageSharedAccessKey.
Access Secret The SAS key itself — encrypted at rest (EncryptedArraySerialized backend model).
Subscription Default subscription name for this topic's primary binding (see fan-out for how additional bindings resolve their own).

There's no fallback between rows for most call sites (AsbTopicConfigMapper) — every topic your topology declares needs its own row, including reply topics for RPC.

Each row is keyed by topic name, and a consumer process runs from the CLI with no storefront/website context, so it can't resolve a per-website scope at runtime. If you need separate configuration per business line (e.g. a B2C and a B2B website on the same Magento instance, each with its own Azure namespace or credentials), give each one its own topic name (e.g. b2c_sales_order_export / b2b_sales_order_export), each with its own queue_consumer.xml entry and its own row in this grid — rather than relying on store-scoped config against a shared topic name.

Topology

Field Default Description
Automatically Create Topics on setup:upgrade Disabled See Topology installation.
Max Delivery Count 10 (Azure's own default) Delivery attempts before Azure auto-dead-letters a message. Applied when a subscription is created; existing subscriptions aren't retroactively updated.

Message Log Cleanup

Field Default Description
Enable Message Log Cleanup Disabled Turns the cleanup cron on/off.
Archive Before Delete Enabled (once cleanup is on) Copy expired rows to the archive table before deleting, vs. deleting outright.
Retention (Days) 30 How old a message must be (by created_at) before cleanup.
Cleanup Frequency Nightly or Weekly, always runs at 02:00. Controls when, not how far back — that's Retention (Days).

See Message log, archiving, and cleanup for the full picture.

Dead-lettering

There are two distinct dead-letter mechanisms, covering two different kinds of failure:

  • Local/application-levelQueue::reject($envelope, false, $reason) is used for permanent failures (e.g. a message that fails to decode). The message is completed off the live queue immediately and recorded via MageTips\Azure\Api\DeadLetterQueueInterface, so it shows up right away in the Message Log grid (dead-letter flag, reason, delivery count) with no round-trip to Azure needed to see it.
  • Azure-nativeQueue::reject($envelope, true) is used for transient failures: the peek-lock is released and Azure's own server-side delivery-count tracking takes over, automatically moving the message to that subscription's native $DeadLetterQueue sub-queue once Max Delivery Count is exceeded. This lives entirely in Azure and is invisible to the Message Log grid.

For the Azure-native case, this module provides both a CLI and an admin page to see and act on what's sitting in a topic's dead-letter sub-queue(s) — if a topic has more than one subscription (fan-out), every subscription's dead-letter sub-queue is reported/acted on, labeled by subscription:

  • bin/magento magetips:azure:deadletter:list <topic> [--limit=50] — read-only listing, per subscription.
  • bin/magento magetips:azure:deadletter:requeue <topic> [--count=1] — re-publishes the oldest N dead-lettered messages back onto the live topic, per subscription.
  • bin/magento magetips:azure:deadletter:purge <topic> [--count=1] — permanently removes the oldest N, per subscription.
  • Azure Service Bus > Dead Letters (admin) — a live snapshot across every configured topic and subscription (up to 20 messages per subscription), refreshed on every page load. All messages are shown in a single unified table with Topic/Subscription columns, so the page stays usable as the number of topics/subscriptions/messages grows — client-side sorting, a search box, and pagination are handled by DataTables (MIT licensed, vendored locally under view/adminhtml/web rather than loaded from a CDN). This is deliberately client-side only: the server-side fetch stays capped per subscription regardless of what's shown/sorted/filtered in the browser, since Azure's classic REST API has no server-side offset-based pagination to page through in the first place — a "Requeue Oldest" / "Purge" action pair per subscription sits above the table for the actual per-subscription actions.

Both the CLI and the admin page act on the oldest N messages, not "the specific row you're looking at" — the classic Service Bus REST API has no addressable per-message access (only sequential receive from the front of the sub-queue), and peek-locks expire in 30-60 seconds, so there's no reliable way to act on a specific message referenced from an earlier list/page-load. Each requeue/purge receives-with-lock and acts immediately in the same call, with no gap a lock could expire across.

Message log, archiving, and cleanup

Every message MessageQueueConsumer processes is logged to the magetips_azure_consumer table, visible in the admin under the Azure Service Bus menu:

  • Azure Service Bus > Message Log — every consumed message: topic, consumer, event ID, delivery count, dead-letter status, and processing status (Success/Pending). Click a row for full detail, including the message body (pretty-printed if it's JSON) and, for dead letters, the exception/reason. Delete individual rows or select several and use the "Delete" mass action — there's no export button on this grid, since these rows are meant to get cleaned up, not archived via download.
  • Azure Service Bus > Archived Messages — same columns as the live log plus "Original ID" and "Archived At". Delete individual or bulk rows; no requeue/restore action, since archived messages are kept for reference (and CSV/XML export) rather than re-processing — re-publish via the topic's publisher if you need something back in the live queue.

Both grids support standard Magento UI-component filtering and sorting.

The magetips_azure_consumer table grows with every processed message, so any long-running installation needs a retention policy — see the Message Log Cleanup fields in Configuration reference. When enabled, a nightly/weekly cron (magetips_azure_message_log_cleanup) batches through rows older than the retention window (200 at a time, so a large backlog doesn't attempt one huge delete), archiving each one first if configured to. A failure on one row is logged and skipped rather than aborting the rest of the batch — failures go to var/log/azure_service_bus.log.

Admin UI reference

All under a top-level Azure Service Bus menu (MageTips_Azure::azure_top, sort order 65):

Menu item Controller route ACL resource
Message Log magetips_azure/messagelog/index MageTips_Azure::message_log
Archived Messages magetips_azure/messagelogarchive/index MageTips_Azure::message_log_archive
Dead Letters magetips_azure/deadletter/index MageTips_Azure::dead_letter

Config section itself lives under Stores > Configuration > MageTips > Azure Service Bus, gated by MageTips_Azure::system_config.

CLI command reference

Command Purpose
magetips:azure:deadletter:list <topic> [--limit=50] List dead-lettered messages, every subscription on the topic.
magetips:azure:deadletter:requeue <topic> [--count=1] Re-publish the oldest N dead-lettered messages per subscription.
magetips:azure:deadletter:purge <topic> [--count=1] Permanently remove the oldest N dead-lettered messages per subscription.

bin/magento queue:consumers:start <name> and bin/magento queue:consumers:list are plain Magento core commands, not Azure-specific — every consumer declared in your queue_consumer.xml shows up there automatically.

Logging

Everything this module logs goes to its own dedicated channel/file, not Magento's general system.log/exception.log:

  • File: var/log/azure_service_bus.log
  • Monolog channel name: magetips_azure
  • Wired via di.xml virtual types (MageTips\Azure\Logger\Handler / MageTips\Azure\Logger\AzureLogger), the documented Magento pattern for a module-specific log file — not custom PHP classes.

Covers: topology installation results (including harmless "already exists" 409s), setup:upgrade failures, message log cleanup runs, dead-letter subscription read errors, and anything else logged by classes that inject a generic Psr\Log\LoggerInterface (they get this channel via DI preference, not Magento's default).

Cron jobs

Job Group Schedule Class Purpose
magetips_azure_message_log_cleanup default 0 2 * * * by default, overridden by the Cleanup Frequency admin field (writes to crontab/default/jobs/magetips_azure_message_log_cleanup/schedule/cron_expr, same mechanism Magento_Cron's Config\Backend\Product\Alert/Sitemap use) MageTips\Azure\Cron\PurgeConsumerLog Archives/deletes expired message log rows. No-op unless Enable Message Log Cleanup is on.

Consumer scheduling is not a cron this module owns — see Running consumers for why that's deliberately left to Magento's own Magento_MessageQueue::consumers_runner job.

Key classes

Class Role
MessageQueue\Queue One consumer's binding: resolves its Azure topic + subscription via QueueTopicResolver, implements dequeue/ack/reject/renewLock/push.
MessageQueue\Exchange Publish side: sends to a topic, and for synchronous topics, waits for and returns the reply.
System\QueueTopicResolver Resolves a Magento queue name (binding destination) to its Azure topic and subscription — the piece that makes fan-out and RPC reply queues work.
System\Config / System\AzureTopicsConfig Read the per-topic admin config grid (host/credentials/subscription).
Service\TopologyInstaller Creates topics/subscriptions/rules on Azure from queue_topology.xml, one subscription per binding.
Service\ServiceBusClientProxy Caches one Azure REST client connection per topic for 120 seconds, to avoid reconnecting on every call.
Service\DeadLetterReader Reads/requeues/purges Azure's native per-subscription dead-letter sub-queue.
Queue\MessageQueueConsumer The consumerInstance every queue_consumer.xml entry uses — adapted from Magento\Framework\MessageQueue\Consumer with plain constructor DI, Azure-specific audit logging, and dead-letter recording.
Model\DeadLetterQueue Local/application-level dead-letter recording (see Dead-lettering).

Known limitations

  • No offline provisioning by default. With Automatically Create Topics left at its default (disabled), a fresh deployment against a brand-new Azure namespace needs either that setting enabled with sufficiently-privileged credentials, or topics provisioned out-of-band.
  • No addressable per-message actions. Dead-letter requeue/purge and admin actions always target the oldest N messages — the classic Service Bus REST API has no "act on this specific message I saw earlier" capability, and peek-locks expire in 30-60 seconds.
  • Reply topics for RPC must be declared and configured manually — Azure has no concept of an ad-hoc reply queue the way AMQP does.
  • AsbTopicConfigMapper has no cross-topic credential fallback — every topic (including RPC reply topics) needs its own admin config row.

License

GNU General Public License v3.0 or later. See LICENSE.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-3.0-or-later
  • 更新时间: 2026-07-03

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固