Acknowledgement Modes

本文详细介绍了Java消息服务(JMS)的基本概念和技术细节,包括点对点和发布/订阅两种消息传递模型的特点、消息的消费方式、消息的确认机制、消息的生产和消费过程以及消息选择器等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/geloin/article/details/7967059

注:JMS&MQ系统是我在学习ActiveMQ过程中的一些积累和总结,其中的知识大部分来源于网络和《ActiveMQ in Action》,理论上并不能算是原创,此处予以说明,后文不再赘述。

        JMS定义了两种消息传递域:点对点消息传递域和发布/订阅消息传递域。


        点Q对点消息传递域的特点:
        1. 每个消息只能有一个消费者;
        2. 消息的生产者和消费者之间没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,它都可以提取消息。

        发布/订阅消息传递域的特点:
        1. 每个消息可以有多个消费者;
        2. 生产者和消费者之间有时间上的关联性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。JMS规范允许客户创建持久阅读,这在一定程度上放松了时间上的相关性要求。持久订阅允许消费者消费它在未处于激活状态时发送的消息。

        在点对点消息传递域中,目的地为队列(Queue);在发布/订阅消息传递域中,目的地为主题(Topic)。

        消息的消费可以采用以下两种方法之一:
        1. 同步消费。通过调用消费者的receive方法从目的地中显式地提取消息。receive方法可以一直阻塞到消息到达;
        2. 异步消费。客户可以为消费者注册一个消息监听器,以定义在消息到达时所采取的动作。

        JMS消息由以下三部分组成:
        1. 消息头。每个消息头字段都有相应的getter和setter方法;
        2. 消息属性。如果需要除消息头字段以外的值,那么可以使用消息属性;
        3. 消息体。JMS定义的消息类型有TextMessage、MapMessage、BytesMessage、StreamMessage和ObjectMessage。

        JMS消息只有在被确认之后,才认为已经被成功消费。消息的成功消费通常包含三个阶段:客户接收消息、客户处理消息和消息被确认。

        在事务性会话中,当一个事务被提交时,确认自动发生。在非事务性会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement mode)。该参数有以下三个可选值:
        1. Session.Auto_ACKNOWLEDGE。当客户成功地从receive方法返回的时候,或者从MessageListener.onMessage方法成功返回的时候,会话自动确认客户收到的消息。
        2. Session.CLIENT_ACKNOWLEDGE。客户通过消息的acknowledge方法确认消息。需要注意的是,在这种模式中,确认是在会话层进行:确认一个被消费的消息将自动确认所有已被会话消费的消息。例如,如果一个消息消费者消费了10个消息,然后确认第5个消息,那个所有10个消息都被确认。
        3. Session.DUPS_ACKNOWLEDGE。在会话迟钝等情况下确认消息。如果JMS provider失败,那么可能会导致一些重复的消息。如果是重复的消息,那么JMS provider必须把消息头的JMSRecelivered字段设置为true。

        JMS支持以下两种消息提交模式:
        1. PERSISTENT。指示JMS provider持久保存消息,以保证消息不会因为JMS provider的失败而丢失。
        2. NON_PERSISTENT。不要求JMS provider持久保存消息。

 

====================

http://blog.youkuaiyun.com/woohooli/article/details/6589301

 

JMS Details

This section provides a more detailed description of JMS. In particular, we explore the acknowledgement modes, which are fundamental to understanding the reliability aspects of a JMS provider. Also, this section covers message producers and consumers, as well as the details of exception listeners and message selectors.

As described previously, the Pub/Sub and P2P models have a lot in common, and unless otherwise noted, the information described in this section applies to both models. The only major differences between the two models in terms of the JMS API's is that the P2P model supports a queue browser and the Pub/Sub models support durable subscribers.

Acknowledgement Modes

Message acknowledgement is purely a consumer side concept, which relates to how a consumer tells the JMS provider that is has received a messages. On the producer side, the only notion of acknowledgement consists of a successful invocation of either the topic publisher's publish method or the queue sender's send method.

Acknowledgment of a message means that the JMS provider must never deliver the message to the consumer in question again. This also means that the JMS provider can release any resources it is occupying on behalf of said message. To minimize resource consumption, consumer applications should therefore acknowledge messages as quickly as possible.

JMS support a number of message acknowledgement modes:

Duplicates Allowed

Consumer applications specify this acknowledge mode using the DUPS_OK_ACKNOWLEDGE constant defined in the Session interface. Using this mode, the session acknowledges message lazily, which provides faster message processing, with the penalty that some duplicate messages may be delivered multiple times if JMS fails. Only applications that are tolerant to message duplicates should use this acknowledge mode.

Auto acknowledge

This is the default acknowledge mode, which is specified using the AUTO_ACKNOWLEDGE constant defined in the Session interface. For each message, the session automatically acknowledges that a client has received a message either:

  • Just before the call to a message consumer's receive or receiveNoWait return a message.

  • Right after the onMessage method returns successfully after invoking the consumer's MessageListener

If a JMS provider or the message consumer crashes while it is processing a message, this message is subject to either re-delivery or loss when using the automatic acknowledgement mode.

With synchronous receive, the message will be lost of JMS acknowledges it but crashes before receive returns the message to the consumer. With an asynchronous message listener, a duplicate will happen if JMS crashes after onMessage completed but before the acknowledgement was recorded.

Note that these situations are not limitations of a JMS implementation but the nature of doing automatic acknowledgements in a distributed system. The only way to prevent this is by maintaining persistent state in the client, or by using a distributed transaction.

Client acknowledge

Consumer applications specify this acknowledge mode using the CLIENT_ACKNOWLEDGE constant defined in the Session interface. This acknowledgement mode gives consumer more control over when messages are acknowledged. A consumer can group a number of messages and then invoke the acknowledge method of the Message to instruct the JMS provider that the message (and all other messages received up until this point) have been consumed.

When a consumer uses client acknowledge, it can use the recover method of the session to revert back to its last check point. This causes the session to re-deliver all messages that have not yet been acknowledged by the consumer. Note that if a client crashes and later re-connects to its queue or topic, the session will effectively be recovered and the consumer will receive all un-acknowledged messages.

Transactional Acknowledge

The session finally supports a different kinds of acknowledgement mode, which is referred to as a transacted session. A transacted session is a related group of consumed and produced messages that are treated as a single work unit. A transaction can be either committed or rolled back.

When the session's commit method is called, the consumed messages are acknowledged, and the associated produced messages are sent. When a session's rollback method is called, the produced messages are destroyed, and the consumed messages are recovered.

A transacted session always has a "current" transaction and applications do not explicitly start one. As soon as either the commit or rollback method is called, the current transaction ends and a new transaction is immediately started. These method can only be called on a transacted session.

The graph below illustrates a transacted session as using a "bucket" for holding on to messages and acknowledgements. The MSG's and ACK's are flushed when the commit orrollback method is called.

A typical use of transacted sessions is to consume and produce a message atomically. If an application moves messages from one destination to another, it should use a transacted session to ensure that the message is either successfully transferred, or not transferred at all. In this case, the commit method should be called after each message.

Message Producers

Message producers send or publish messages to a destination. The QueueSender and TopicPublisher interfaces support several variations of either a send or publish method for sending messages.

The producer application creates the message and is required to set the various properties of the message. If these properties are not specified in the send or publish method, JMS will assign what has been set as the default value for the queue sender or topic publisher:

  • The destination of the message. In P2P this is a queue and in Pub/Sub it's a topic.

  • The message delivery mode. JMS support persistent and non-persistent message delivery modes, with persistent being the default.

  • The message priority. JMS guarantees FIFO order for messages of the same priority but will attempt to expedite messages of higher priority.

  • The expiry of the message. This is also referred to a time-to-live (TTL) for the message. Expired messages are not delivered to consumers.

Once the invocation of the send or publish method returns successfully, JMS has received the message. For persistent messages this means that the message has successfully been written into some persistent store and is guaranteed not to be lost until the recipient has acknowledged it.

Message Consumers

A message consumer receives messages from a destination. The QueueReceiver and TopicSubscriber interfaces both extends the MessageConsumer, which support two way of receiving messages:

Synchronously

The client calls one of the receive methods defined in the MessageConsumer interface:

  • receive - This method can be called with out without a timeout. The consumer block either indefinitely or for the specified amount of time to retrieve a message. If a message was not available on the destination before the timeout expired, null is returned.

  • receiveNoWait - This method checks for a message and returns immediately with either null or a message if one is available on the destination to which to consumer is registered.

Note that before a consumer application can start to receive messages, it must call the start method on the Connection object. The start method is a signal to the JMS provider to start the flow on messages to all sessions created by the connection in question.

Asynchronously

The client registers a MessageListener with the MessageConsumer using its setMessageListener method. Note that the asynchronous and synchronous models can not be mixed and it is not allowed to call the receive methods on a consumer with a message listener.

A message listener is simply an object, which implements the onMessage method. This method has a single argument, which is a JMS message. A message listener is not allowed to raise any exceptions and a consumer application should always try to catch any exceptions and deal with them.

Ordinarily, the JMS provider will resolve connection problems. If an error occurs, the provider normally raises an exception when an application tries to send or receive a message. However, when using a message listener this is not possible because the consumer waits for the provider to invoke it.

Therefore, JMS support an interface called an ExceptionListener which is used to communicate exceptions to clients. The exception listener is primarily available to support asynchronous communication, but is is in general recommended that client application use it.

The exception listener is set using the setExceptionListener method on the Connection object. As opposed to a regular message listener, the exception listener is set once per connection instead of once per consumer. By default a connection does not have an exception listener.

So far, the discussion has covered both the P2P and Pub/Sub messaging models. However, both P2P and Pub/Sub support special kinds of message receivers. The P2P model support a queue browser and Pub/Sub support a durable subscriber.

Queue Browser

A queue browser is a special consumer that can retrieve but not consume messages. A queue browser supports the QueueBrowser interface, which has methods for looking at queue messages without actually removing them from the queue.

The QueueBrowser interface provides a familiar Enumeration which elements are messages. The order of messages in the enumeration corresponds to the order in which a regular queue receiver would receive them (subject to message expiry and arrival of new, high-priority messages).

Durable Subscriber

A durable subscriber is used to receive persistent topic messages. Since regular, transient topic subscribers do not survive crashes of either the JMS provider or the subscriber itself, the JMS provider will typically not persist topic messages when the topic only has transient subscribers.

The above is a consequence of the fact that a topic does not retain messages when there are no subscribers. In Pub/Sub messaging, subscribers will only get messages that were received by the topic after the subscription was made. Therefore, there can be no concept of persistent messages if connections can not survive a crash.

A durable subscriber can survive crashes, and the subscription is not lost until it is explicitly un-subscribed. If a durable subscriber is temporarily unavailable, the JMS provider will buffer messages on it behalf. When the subscriber comes back and re-connects, it will receive all buffered messages.

Durable subscribers require a connection client identifier. This identifier is part of the subscription name and must be set using the setClientID method on the Connection. As with an exception listener, this is set once per connection and the client identifier will apply to all durable subscribers within said connection.

Message Selectors

A message selector is an object invoked by the JMS provider to restrict messages from being delivered unless they meet certain specified criteria. Message selectors examine the message header fields and properties and then compare them to a context string that has been specified by the consumer.

The context string used by the message selector is built from syntax based on a subset of SQL92 conditional expression syntax. If you are familiar with JDBC, you essentially query as if the message properties where column names. The following table describes some common values. For a complete list, please refer to the JMS specification.

ValueExamples
Comparison operatorsAmount <= 5
Month = 'January'
Logical operatorsJMSPriority > 3 AND Value = 42
Width = 2 OR Height > 3
Level < 4 AND NOT Error
Arithmetic operatorsAmount * 22.3 + Tax / 1.45 < 4220.12
-Value * 9 < 12
SQL operatorsAmount BETWEEN 12 AND 22
Quote IN ('SSSW','CSCO','MSFT')
Property IS NULL
Number LIKE '12%3'
Word LIKE 'hel_o'

Un-selected message in the P2P model are retained on the queue so that if one consumer does not select a message, the JMS provider will attempt to re-assign it to another consumer (or keep it on the queue for some future consumer).

In the Pub/Sub model, un-selected message are discarded and from a subscriber's point of view, it will be as if the messages was never sent to the topic. The message may be selected by other subscribers of the topic.

 

<div align="center"> <h2>AFNet: Adaptive Fusion of Single-View and Multi-View Depth for Autonomous Driving</h2> <h2>**CVPR 2024**<h2> [Paper](https://arxiv.org/pdf/2403.07535.pdf) </div> This work presents AFNet, a new multi-view and singleview depth fusion network AFNet for alleviating the defects of the existing multi-view methods, which will fail under noisy poses in real-world autonomous driving scenarios. ![teaser](assets/pointcloud2.png) ## ✏️ Changelog ### Mar. 20 2024 * Initial release. Due to the confidentiality agreement, the accuracy of the current reproduced model on KITTI is very slightly different from that in the paper. We release an initial version first, and the final version will be released soon. * In addition, the models trained under noise pose will soon be released. ## ⚙️ Installation The code is tested with CUDA11.7. Please use the following commands to install dependencies: ``` conda create --name AFNet python=3.7 conda activate AFNet pip install -r requirements.txt ``` ## 🎬 Demo ![teaser](assets/visual_compare.png) ## ⏳ Training & Testing We use 4 Nvidia 3090 GPU for training. You may need to modify 'CUDA_VISIBLE_DEVICES' and batch size to accommodate your GPU resources. #### Training First download and extract DDAD and KITTI data and split. You should download and process DDAD dataset follow [DDAD🔗](https://github.com/TRI-ML/DDAD). #### Download [__split__ 🔗](https://1drv.ms/u/s!AtFfCZ2Ckf3DghYrBvQ-DWCQR1Nd?e=Q6qz8d) (You need to move this json file in split to the data_split path) [ models 🔗](https://1drv.ms/u/s!AtFfCZ2Ckf3DghVXXZY611mqxa8B?e=nZ7taR) (models for testing) Then run the following command to train our model. ``` bash scripts/train.sh ``` #### Testing First download and extract data, split and pretrained models. ### DDAD: run: ``` python eval_ddad.py --cfg "./configs/DDAD.conf" ``` You should get something like these: | abs_rel | sq_rel | log10 | rmse | rmse_log | a1 | a2 | a3 | abs_diff | |---------|--------|-------|-------|----------|-------|-------|-------|----------| | 0.088 | 0.979 | 0.035 | 4.60 | 0.154 | 0.917 | 0.972 | 0.987 | 2.042 | ### KITTI: run: ``` python eval_kitti.py --cfg "./configs/kitti.conf" ``` You should get something like these: | abs_rel | sq_rel | log10 | rmse | rmse_log | a1 | a2 | a3 | abs_diff | |---------|--------|-------|-------|----------|-------|-------|-------|----------| | 0.044 | 0.132 | 0.019 | 1.712 | 0.069 | 0.980 | 0.997 | 0.999 | 0.804 | #### Acknowledgement Thanks to Zhenpei Yang for opening source of his excellent works [MVS2D](https://github.com/zhenpeiyang/MVS2D?tab=readme-ov-file#nov-27-2021) ## Citation If you find this project useful, please consider citing: ```bibtex @misc{cheng2024adaptive, title={Adaptive Fusion of Single-View and Multi-View Depth for Autonomous Driving}, author={JunDa Cheng and Wei Yin and Kaixuan Wang and Xiaozhi Chen and Shijie Wang and Xin Yang}, year={2024}, eprint={2403.07535}, archivePrefix={arXiv}, primaryClass={cs.CV} } ``` PS E:\AFNet-main> pip install -r requirements.txt Defaulting to user installation because normal site-packages is not writeable Collecting imageio==2.9.0 (from -r requirements.txt (line 1)) Downloading imageio-2.9.0-py3-none-any.whl.metadata (2.6 kB) Collecting ipdb==0.12.3 (from -r requirements.txt (line 2)) Downloading ipdb-0.12.3.tar.gz (10 kB) Preparing metadata (setup.py) ... done Collecting joblib==1.0.1 (from -r requirements.txt (line 3)) Downloading joblib-1.0.1-py3-none-any.whl.metadata (6.8 kB) Collecting lz4==3.1.3 (from -r requirements.txt (line 4)) Downloading lz4-3.1.3.tar.gz (159 kB) Preparing metadata (setup.py) ... done Collecting matplotlib==3.1.3 (from -r requirements.txt (line 5)) Downloading matplotlib-3.1.3.tar.gz (40.9 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.9/40.9 MB 6.2 MB/s eta 0:00:00 Preparing metadata (setup.py) ... error error: subprocess-exited-with-error × python setup.py egg_info did not run successfully. │ exit code: 1 ╰─> [28 lines of output] C:\Users\HP\AppData\Local\Temp\pip-install-xl7u4dpy\matplotlib_e71ff03b933d48d99aa6e0525941cb19\setup.py:32: SetuptoolsDeprecationWarning: The test command is disabled and references to it are deprecated. !! ******************************************************************************** Please remove any references to `setuptools.command.test` in all supported versions of the affected package. This deprecation is overdue, please update your project and remove deprecated calls to avoid build errors in the future. ******************************************************************************** !! from setuptools.command.test import test as TestCommand Traceback (most recent call last): File "<string>", line 2, in <module> File "<pip-setuptools-caller>", line 34, in <module> File "C:\Users\HP\AppData\Local\Temp\pip-install-xl7u4dpy\matplotlib_e71ff03b933d48d99aa6e0525941cb19\setup.py", line 52, in <module> __version__ = versioneer.get_version() ^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\HP\AppData\Local\Temp\pip-install-xl7u4dpy\matplotlib_e71ff03b933d48d99aa6e0525941cb19\versioneer.py", line 1410, in get_version return get_versions()["version"] ^^^^^^^^^^^^^^ File "C:\Users\HP\AppData\Local\Temp\pip-install-xl7u4dpy\matplotlib_e71ff03b933d48d99aa6e0525941cb19\versioneer.py", line 1344, in get_versions cfg = get_config_from_root(root) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\HP\AppData\Local\Temp\pip-install-xl7u4dpy\matplotlib_e71ff03b933d48d99aa6e0525941cb19\versioneer.py", line 401, in get_config_from_root parser = configparser.SafeConfigParser() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: module 'configparser' has no attribute 'SafeConfigParser'. Did you mean: 'RawConfigParser'? [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. error: metadata-generation-failed × Encountered error while generating package metadata. ╰─> See above for output. note: This is an issue with the package mentioned above, not pip. hint: See above for details.
最新发布
06-04
<think>好的,用户遇到了在安装AFNet依赖时matplotlib安装失败的问题,具体错误是'SafeConfigParser'属性错误。我需要先理解这个错误的根本原因。根据用户提供的引用[^1],这个错误是因为在Python3中,SafeConfigParser已经被重命名为ConfigParser,而旧版本的matplotlib可能还在使用旧的名称。首先,用户提到的matplotlib版本是3.3.3,安装时出现versioneer.py中的错误。这说明问题可能出在matplotlib的版本与当前Python环境不兼容。接下来,我需要考虑可能的解决方案。常见的解决方法包括升级matplotlib到兼容Python3的版本,或者降级Python版本,但降级可能不实际。所以更可行的是升级matplotlib。但用户可能在安装AFNet时需要特定版本的matplotlib,比如依赖要求3.3.3。这时候可能需要检查AFNet的依赖是否必须使用该版本,或者是否有更新的版本可用。 另外,用户可能没有使用虚拟环境,导致环境冲突。建议使用虚拟环境来管理依赖,避免版本冲突。此外,安装时可能需要指定正确的版本,或者从源码安装并手动修改错误文件中的SafeConfigParser为ConfigParser。还需要检查Python版本是否过高,比如Python3.10以上可能导致某些旧包不兼容。如果用户Python版本较新,可能需要寻找支持新版本的matplotlib版本,或者应用补丁。 总结可能的解决步骤:1.升级matplotlib到更高版本,如3.5.0以上,这些版本已经修复了Python3的兼容性问题。2.如果必须使用3.3.3,可以手动修改versioneer.py中的代码,将SafeConfigParser替换为ConfigParser。3.使用虚拟环境确保环境隔离。4.检查Python版本,可能需要使用稍旧的Python版本,如3.7或3.8,以兼容旧库。 5.安装时使用--no-cache-dir选项避免缓存问题。同时,需要验证这些步骤是否有效,比如手动修改文件后重新安装。另外,用户可能需要更新pip和setuptools,确保安装工具本身没有问题。 最后,生成相关问题帮助用户深入理解类似问题,比如其他库的兼容性问题处理,或者如何维护依赖环境。</think>### 解决方法 出现`SafeConfigParser`属性错误的原因是matplotlib旧版本与Python 3的兼容性问题。以下是具体解决步骤: 1. **升级matplotlib版本** 直接安装支持Python 3的新版本(如$3.5.0+$),新版本已修复此问题: ```bash pip install matplotlib>=3.5.0 --upgrade ``` 2. **手动修改旧版本源码(适用于必须使用$3.3.3$的情况)** - 下载源码并解压: ```bash wget https://github.com/matplotlib/matplotlib/archive/refs/tags/v3.3.3.tar.gz tar -xzf v3.3.3.tar.gz ``` - 修改`versioneer.py`文件中的`SafeConfigParser`为`ConfigParser`[^1] - 重新安装: ```bash cd matplotlib-3.3.3 python setup.py install ``` 3. **使用虚拟环境隔离依赖** 通过`venv`创建纯净环境,避免依赖冲突: ```bash python -m venv myenv source myenv/bin/activate # Linux/Mac pip install matplotlib==3.5.0 ``` 4. **检查Python版本兼容性** 确保Python版本在$3.7$至$3.9$之间(部分旧库对$3.10+$支持不足)。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值