Messaging (ActiveMQ / RocketMQ)
Not every integration in xly is a synchronous HTTP call. The framework runs two message brokers, each with a different role:
| Broker | Used for | Producer | Consumer |
|---|---|---|---|
| ActiveMQ / JMS | In-cluster fan-out events: base-data merge jobs (consolidating per-tenant rows into flattened lookup tables) and document-update / document-delete notifications. Despite the historical naming of one queue, this channel is NOT used for Redis cache invalidation — see Cache invalidation on metadata change for the actual cache-evict path. | xlyErpJmsProductor |
xlyErpJmsConsumer |
| RocketMQ | Other integration flows where the ActiveMQ assumptions don't fit. |
RocketMQServiceImpl (in xlyBusinessService) |
(varies — service-specific) |
This page is a pointer rather than a deep dive — exact queue names and
payloads are documented at the consumer-thread level in
xlyErpJmsConsumer/src/main/java/com/xly/xlyerpjmsconsumer/.
ActiveMQ / JMS — base-data merge + fan-out channel
Producer-side queue declarations live in
xlyErpJmsProductor/src/main/java/com/xly/xlyerpjmsproductor/config/P2pQueue.java.
The full set is 24 destinations, grouped by intent:
Module / control (2)
| Constant | Purpose |
|---|---|
ERP_JMS_ACTIVEMQ_CHANGE_GDS_MODULE |
"Module metadata changed" — ConsumerChangeGdsModuleThread runs the stored proc PRO_ERPMERGEBASEGDSMODULE to merge per-tenant gdsmodule rows into a flattened base lookup table. Does not invalidate Redis caches despite the name — Redis cache eviction happens synchronously via @CacheEvict in BACK during save. See Cache invalidation on metadata change. |
ERP_JMS_ACTIVEMQ_CHANGE_WORK_ORDER_CONTROL |
Work-order control state changed (status/aggregate flags) — fan-out for downstream recalculation. |
Document operations (6)
| Constant | Purpose |
|---|---|
ERP_JMS_ACTIVEMQ_UPD_SALE_ORDER / _UPD_WORK_ORDER / _UPD_PRODUCTION_REPORT
|
"Document was updated" notifications consumed by background workers (totals recalculation, downstream invalidations). |
ERP_JMS_ACTIVEMQ_DEL_SALE_ORDER / _DEL_WORK_ORDER / _DEL_PRODUCTION_REPORT
|
Document-delete notifications. |
Element-master change fan-out (7) — CHANGE_ELE_*
| Constant | Purpose |
|---|---|
_CHANGE_ELE_CUSTOMER |
Customer-master change. |
_CHANGE_ELE_EMPLOYEE |
Employee-master change. |
_CHANGE_ELE_MACHINE |
Shop-floor machine-master change. |
_CHANGE_ELE_MATERIALS |
Materials-master change. |
_CHANGE_ELE_PRODUCT |
Product-master change. |
_CHANGE_ELE_PROCESS |
Process-master change. |
_CHANGE_ELE_TEAM |
Team-master change. |
System-info / lookup-table change fan-out (9) — CHANGE_SIS_*
| Constant | Purpose |
|---|---|
_CHANGE_SIS_CUSTOMER_CLASSIFY |
Customer-classification change. |
_CHANGE_SIS_DELIVER |
Delivery-method change. |
_CHANGE_SIS_FORMULA |
Calculation-formula change. |
_CHANGE_SIS_PAYMENT |
Payment-method change. |
_CHANGE_SIS_PROCESS_CLASSIFY |
Process-classification change. |
_CHANGE_SIS_PRODUCT_CLASSIFY |
Product-classification change. |
_CHANGE_SIS_SALES_MAN |
Sales-personnel change. |
_CHANGE_SIS_TAX |
Tax-rate change. |
_CHANGE_SIS_WORK_CENTER |
Work-centre change. |
(Constant prefixes elided to _… after the first table — the full literal is ERP_JMS_ACTIVEMQ_….)
Listener side
xlyErpJmsConsumer/.../consumer/Consumer.java is a single class that
hosts all 24 @JmsListener methods — one per destination. Each
method dispatches the payload to a corresponding Consumer*Thread
class under xlyErpJmsConsumer/.../thread/, which executes the
domain-specific work (typically calling a PRO_ERPMERGEBASE* stored
proc that consolidates per-tenant rows into a flattened base lookup
table) asynchronously. There is one listener class with 24 methods,
not 24 listener classes. None of the consumer threads invoke
@CacheEvict or cleanRedis* — Redis cache invalidation is
synchronous in BACK during save, see cache-invalidation.md.
RocketMQ — other flows
RocketMQServiceImpl and its companion RocketMQService interface
sit in xlyBusinessService/src/main/java/com/xly/service/. They cover
non-cache-invalidation flows (for example, MQCompensateServiceImpl
handles compensation/retry semantics that ActiveMQ's destinations don't
express well). RocketMQ topics are configured per environment.
Manual cache-invalidation poke
If a metadata change happens via raw SQL, the cache across nodes will not
bust automatically because no BACK save path calls @CacheEvict. The
supported override is to invoke the appropriate
BusinessCleanRedisDataImpl.delCleanRedisDataByTableName(...) cleaner
from inside the application once; it evicts the shared Redis-backed Spring
cache directly. See
cache invalidation on metadata change
for the broader troubleshooting path.
What this is not
- Not a public integration channel. External integrators do not publish or subscribe to these brokers. They are internal fan-out for the cluster.
-
Not a cache-invalidation channel. The HTTP write paths in
xlyEntryalready evict Redis synchronously when they should; the manual cleaner call is for raw-SQL or bypass paths.