We encountered publish Guaranteed Message Publish error, it reports:
[ERR] {"message":"Guaranteed Message Window Closed","name":"OperationError","subcode":22,"level":"error","stack":"OperationError: Guaranteed Message Window Closed\n
at PublisherFSM.prepareAdMessageAndSend (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:21530:13)\n
at MessagePublisher.prepareAdMessageAndSend (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:20866:22)\n
at SessionFSM.prepareAndSendMessage (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:26483:49)\n
at Session.validateAndSendMessage (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:29161:22)\n
at Session.send (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:28463:10)\n
Known that is due to client side pended many unacknowledged messages (default window size is 50) https://solace.com/blog/understanding-guaranteed-message-publish-window-sizes-and-acknowledgement/. Per check the log, application side can receive acknowledge notification after it publish to solace more than 1 sec.
So what's the root cause introduced solace server can't acknowledge so many messages at client side? we checked the client application log, and just find below solace related error:
at PublisherFSM.process (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:17780:11)
at PublisherFSM.processEvent (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:17841:15)
at State.onEntry (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:2201:17)
at BufferSMFClient.rxDataBuffer (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:33020:10)
at CorrelatedRequest.respRecvdCallback (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:21257:77)
at SessionFSM.handleADCtrlMessage (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:25872:26)
ERROR solclientjs: Uncaught exception in {PublisherFSM: PublisherFSM} while processing {PublisherFSMEvent: MessagePublisherFailed}: TypeError: Cannot read property 'nextCorrelationTag' of null
at PublisherFSM.<anonymous> (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:17847:49)
at State.handleOpenFlowResponse (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:21120:22)
at TcpRawTransport.onData (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:34168:20)
at SessionFSM.getCorrelationTag (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:25777:28)
at SessionFSM.handleSMFMessage (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:26116:23)
at BufferSMFClient._rxSmfCB (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:26352:41)
at BufferSMFClient._rxDataCB (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:33074:16)
at State.sendOpenFlow (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:21244:47)
at State.onEntry (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:21262:14)
at State.processReactionResult (/home/vcap/deps/0/node_modules/solclientjs/lib/solclientjs-debug.js:9001:18)
We used solclientjs 10.2.1, and Solace VMR 9.0.0.17.
We can only restart the client application, but those unacknowledged messages are lost.
Related
I have published a message in the solace interface and got the messageId generated for that.
From SolAdmin, When I inspect the queue, I can able to see one new messages received, but the message id which generated is not same.
TextMessage txtMsg = jmsSession.createTextMessage();
messageID = txtMsg.getJMSMessageID();
The above messageID generated the output as
ID:2eaaf46d-b9ff-4aeb-a385-fbc2e6cced0a:1:1:1-1
But in SolAdmin, the message shows as 5985824677
The "Message ID" that is shown in the endpoints tab of SolAdmin is internal to the Solace Message Broker and is not equivalent to the "JMS Message ID".
You can use it for operations such as deleting some messages via the CLI or SEMP.
For example:
solace(admin/message-spool)# delete-messages queue my_sample_queue message 123456789 to 123456790
There's no way to display the JMS Message ID in SolAdmin.
Instead, you will need to make use of a queue browser to browse messages in the queue.
This can be a custom application that you write, sdkperf (use the -qb and -md flags), or a third party graphical JMS queue browser such as HermesJMS.
I am looking to retrieve some Solace queue stats e.g. the current messages spooled count out of the maximum limit for us to set a threshold to stop publishing more messages to the queue.
Also, to subscribe to vpn events to track message discard rates.
By the time we receive errors e.g. MaxMsgUsageExceeded/SpoolOverQuota, it will be too late.
I can't seem to find any of these on SolaceSystems.Solclient.Messaging API
https://docs.solace.com/API-Developer-Online-Ref-Documentation/net/html/7f10bcf6-19f4-beff-0768-ced843e35168.htm
Would be great if someone could help
(using C# for this)
To poll for Solace queue stats from your C# application, you could use legacy SEMP over the message bus to make a SEMP request for the details that you want. Semp (Solace Element Management Protocol) is a request/reply protocol that uses an XML schema to identify all managed objects available in a message broker. Applications can use SEMP to manage and monitor a message broker.
To allow for legacy SEMP to be used over the message bus, as opposed to the management interface, it first needs to be enabled on the Solace PubSub+ message broker at the VPN level.
To publish a SEMP request with the Solace .Net Messaging API, perform the following steps:
Create a Session.
Create the message topic. “#SEMP//SHOW”
ITopic topic = ContextFactory.Instance.CreateTopic( “#SEMP/<router name>/SHOW”);
Create a request message and set its Destination to the topic in Step 2:
IMessage requestMsg = ContextFactory.Instance.CreateMessage();
requestMsg.Destination = topic;
Set the SEMP request string as the binary attachment.
string SOLTR_VERSION = "8_4_0" //change to the message-broker's version
string SEMP_SHOW_QUEUE = "<rpc semp-version=\"soltr/" + SOLTR_VERSION +
"<show><queue><name>queueName</name><detail></detail></queue></show></rpc>";
requestMsg.BinaryAttachment = Encoding.UTF8.GetBytes(SEMP_SHOW_QUEUE);
Call the SendRequest(…) method on Session.
IMessage replyMsg;
ReturnCode rc = session.SendRequest(requestMsg, out replyMsg, timeout);
The SEMP response is returned in replyMsg.
Obtain the binary attachment data from the reply message:
replyMsg.BinaryAttachment
The binary attachment contains the SEMP reply for the command topic in the publish request.
The Solace PubSub+ message broker does raise an event when an egress message is discarded. However, it is only sent out approximately once every 60 seconds for the specified client so it is not possible to get these exact rates.
It is possible for your .NET application to subscribe to VPN-level events over the message-bus. To do this, you must first enable the Solace PubSub+ message broker to publish the events. You can then subscribe to the special topic and receive the events as messages.
The topic to subscribe to is:
#LOG/<level>/VPN/<routerName>/<eventName>/<vpnName>
The different levels can use the * wildcard. For example, if you wish to subscribe to all VPN events of all levels for the VPN apple on router QA-NY1, the topic string would be:
#LOG/*/VPN/QA-NY1/*/apple
SEMP (starting in v2) is a RESTful API for configuring, monitoring, and administering a Solace PubSub+ broker.
1-The swapper page link is SEMP V2 API
2-The Swagger metadata definitions URL is located # http://{solace-sever-url}/SEMP/v2/config/spec
3- From Visual studio, add REST API Client
4-In the configuration dialog pass swagger metadata URL (defined at step 2), for code purpose I choose SolaceSemp as input value parameter for client namespace input.
4 Once you click ok, VS will create the client along with the models under SolaceSemp namespace
5 Start using the client as per following
using SolaceSemp;
using Microsoft.Rest;
var credentials = new BasicAuthenticationCredentials();
credentials.UserName = "place user name";
credentials.Password = "place password";
using (var client = new SolaceSempClient(credentials))
{
var model = client.GetAboutApi();
}
In .NET Framework Microsoft.ServiceBus.Messaging had a class used to receive messages from Service Bus, BrokeredMessage. However, in .NET Standard 2.0, in order to receive messages from a Service Bus, class Message is used, from Microsoft.Azure.ServiceBus.Core.
BrokeredMessage has a method, CompleteAsync(), used to complete the receive operation of a message and indicates that the message should be marked as processed and deleted. I can't find a method for the Message class that does the same thing. Do you guys know any solution in order to mark a message as processed and deleted for the Message class?
To complete the message in the Queue using Microsoft.Azure.ServiceBus.Core, there is a method CompleteAsync available in the QueueClient, through which the messages will be received.
The lock token of the message should be passed as the parameter for the CompleteAsync method.
Example: queueClient.CompleteAsync(message.SystemProperties.LockToken)
Our application is using org.springframework.cloud, spring-cloud-starter-stream-rabbit framework and we are trying to avoid sending specific messages to DLQ and also retrying them, this behaviour should be somehow dynamically, because, for the default messages, retries and DLQ should work.
According to this documentation:
Putting it All Together
And this useful post:
DLX in rabbitmq and spring-rabbitmq - some considerations of rejecting messages
It seems that ImmediateAcknowledgeAmqpException could be used in spring AMQP to mark a message as acknowledged and no further process it. However, when we use this code:
#StreamListener(LogSink.INPUT)
public void handle(Message<Map<String, Object>> message) {
if (message.getPayload().get("condition1").equals("abort")) {
throw new ImmediateAcknowledgeAmqpException("error, we don't want to send this message to DLQ");
}
...
}
The message is always send to DLQ
Our current configuration:
spring.cloud.stream:
bindings:
log:
consumer.concurrency: 10
destination: log
group: myGroup
content-type: application/json
rabbit.bindings:
log:
consumer:
autoBindDlq: true
republishToDlq: true
transacted: true
Are we missing something? Is there any other alternative to avoid publishing to DLQ and requeuing?
republishToDlq does not look at that exception; it only applies when the exception is thrown to the container (method causeChainHasImmediateAcknowledgeAmqpException()).
Republishing subverts that logic since no exception is thrown to the container.
Please open an issue against the Rabbit binder, republishToDlq should honor that exception and discard the failed message.
I have two confusions.
1.If RuntimeException thrown from message listener, does SimpleMessageListenrContainer stop?
2.If SimpleMessageListenerContainer not stop, what is behavior about the auto acknowledgement?
Currently, I want that if the message listener handle message failed, i just log the error and don't stop the container meanwhile notify the broker have received message.
Now I just catch the throwable in message listener method, is it the right way?
No, the container won't stop.
If the listener throws an exception, the message is rejected (and requeued by default). You can change the default behavior to discard the message by setting defaultRequeueRejected to false (it's true by default). Or throw an AmqpRejectAndDontRequeueException which instructs the container to reject (and not requeue) the message - the ack is sent as if the listener had thrown no exception.
When a message is rejected without requeuing, it is either discarded or sent to the dead letter exchange, if the queue is so configured.