We use RabbitMQ to transmit messages between applications. When they are within a single LAN, transmission is very fast. Unfortunately, when the applications are on different machines, connected by WAN (in VPN), there is a significant large delay.
Is it possible to reduce it by setting options in RabbitMQ server or client (e.g. buffer sizes)? Does anyone have some experience in this field?
We use one connection with multiple channels, queues are durable and messages persistent. We set prefetch count setting to 50. There is only one consumer per queue. We wonder whether Windows firewall may have some significance.
EDIT: We're running RabbitMQ 2.8.4 on Erlang R15B01
and on client's side:
> RabbitMQ version 3.4.0.0 platform .NET copyright Copyright (C)
> 2007-2014 GoPivotal, Inc. information Licensed under the MPL. See
> http://www.rabbitmq.com/ capabilities publisher_confirms: true
> exchange_exchange_bindings: true basic.nack: true
> consumer_cancel_notify: true connection.blocked: true
> authentication_failure_close: true
Deliver: 4.8/s Acknowledge 4.8/s We are not making a big transfers.
http://i.stack.imgur.com/v7BEs.png
http://i.stack.imgur.com/n8P05.png
Furthermore we are communicating PHP application with .NET app via
RabbitMQ at this strategy: 1. .NET application has persistent queues
waiting for requests from PHP 2. when PHP makes a request it makes
also a non-durable uniqe queue for listening for response from server.
This strategy makes a lot of uniq queues for sending response to the
PHP app which are deleted after connsuming the message.
Anyway this works very fast on same machine, and very slow on WAN
Related
I develop an application where we need to handle 160k concurrent users which are connected to the backend via a websocket connection.
We decided to use the spring websocket implementation and RabbitMQ as the message broker.
In our application every user needs to subscribe to its user queue /exchange/amq.direct/update as well as to another queue where also other users can potential subscribe to /topic/someUniqueName.
In our first performance test we did the naive approach where every user subscribes to two new queues.
When running the test RabbitMQ dies silently when around 800 users are connected at the same time, so around 1600 queues are active (See the graph of all RabbitMQ objects here).
I read though that you should be careful opening many connections to RabbitMQ.
Now I wonder if the approach that is anticipated by Spring Websocket with opening one queue per user is a conceptional problem for systems with high load or if there is another error in my system.
Limiting factors for RabbitMQ are usually:
memory (can be checked in dashboard) that needs to grow with number of messages and number of queues (if you don't use lazy queues that go directly to disk).
maximum number of file descriptors (at least 1 per connection) that often defaults to too low values on many distributions (ref: https://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2012-April/019615.html)
CPU for routing the messages
I did find the issue. I actually misconfigured the RabbitMQ service and just gave it a 1024 file descriptor limit. Increasing it solved the issue.
Amqp brokers have persistence settings that allow guaranteed delivery - but that only works if the message actually reaches the broker. If there is a network failure and a subsequent client crash/reboot messages could be lost. Is there some way in rabbitmq or activemq or some other messaging framework for the client (producer) to persist messages to disk so that in the event the client crashes or is rebooted any unsent messages will not be lost?
I have seen people run a broker locally in order to get around this issue. That seems like an unnecessary amount of work, especially if you don't have much control over the deployment of your client.
In reality you've answered your own question pretty well. Many people looking for client side persistence turn to embedded brokers because it's actually a very good solution. Having a local broker that can store and forward gives you a lot more flexibility than just an built in persistence layer in each client, all local clients can share one broker instance which can allow you to move storage as needed in cases where you find that your stored local messages are building up due to unforeseen remote downtime.
There are of course some client implementations that do offer storage but finding one depends on your chosen broker / protocol and of course your willingness to shell out the money to buy support or licensing if that client happens to not be from say an open source implementation. The MQTT Paho client does I think have a local storage option as do some others.
I want to support around 100K mqtt connections using activemq. The activemq server is rejecting connections beyond 30K. How to tune activemq to support more number of connections.
I have tried the following
transportConnector name="mqtt" allowLinkStealing="true"
uri="mqtt+nio://0.0.0.0:1883?maximumConnections=100000&wireFormat.maxFrameSize=104857600&transport.defaultKeepAlive=60000&transport.closeAsync=false&useQueueForAccept=false
in activemq.xml but of no use.
I did some unix kernel tuning for number of open file fds to 100000.
Any one solved this problem ?
If you are going to handle > 100k connections I'd recommend looking into a dedicated MQTT broker instead of a multi-protocol message broker. You can see a list of MQTT brokers at the MQTT Github wiki.
ActiveMQ is afaik not designed for handling that much MQTT connections and is not optimized for MQTT because it's a multi-purpose Message Queue. If you want to stick with Apache software, perhaps using Apache Apollo can help although I don't know of any MQTT Apollo deployments with that size, but probably wort a try if you need a multi-protocol broker. Again, I'd recommend a dedicated MQTT broker for large amounts of MQTT connections.
You should definitely look into reactive and multi-threaded MQTT brokers if you want to handle that amount of connections and you should make sure that the MQTT broker you choose is known to work with your desired connection amount and load. HiveMQ for example is capable of handling >100k connections.
Full disclosure: I work for the company behind HiveMQ.
May I suggest you use Apache Apollo for MQTT connections when you have that number of concurrent sessions?
Apache Apollo is a sub project of ActiveMQ with the intent to make the broker scalable to a large number of connected clients. While ActiveMQ supports MQTT, it's not really optimized for this scenario.
JoramMQ (http://jorammq.com) is based on the Joram (http://joram.ow2.org) multi-protocol message broker and it supports more than 500K concurrent MQTT connections.
For anyone still trying to find a fitting MQTT broker for many connections here are my tests of multiple brokers (I should actually add ActiveMQ to the comparison). Performance is not the only thing to compare, but also clustering, monitoring, support, price. Final pick depeneds on your own needs.
Tests were conducted on a 32GB RAM, AMD 5800X, Ubuntu 18 PC.
50 000 MQTT clients connected with no ssl.
Clients subscribed to 4 channels & no messages were published.
Tests above 50k need multiple machines involved or some other tricks because of the 65k limit of outgoing sockets in the system.
Test results
RabbitMQ: 21GB of RAM and ~4 cores.
Mosquitto: 200Mb of RAM and ~0.05 core.
HiveMQ: 2.1GB of RAM and ~0.05 core.
EMQX: 1.4GB of RAM and ~1
core.
VerneMQ: 1.7GB of RAM and ~0.5 core.
If pricing is OK for you - HiveMQ lookes to me like the best broker.
If you are looking for something for free - check VerneMQ.
I have the following situation that is affecting our ActiveMQ 5.8 broker.
Several Perl scripts on a Windows workstation connected to ActiveMQ using STOMP and subscribed (nondurable) to various topics. The power failed on the Workstation.
Using the Web console, I can see that ActiveMQ still thinks these subscribers are connected, based on the number of consumers shown and on the high temp message store being used. I had set for no producer flow control and set memory limits, so what I believe I am seeing is that ActiveMQ is spooling all messages to disk because it thinks the long dead subscribers are still connected and might eventually read them. It's been 30 days, and ActiveMQ still doesn't realize that these subscribers are no longer connected.
It there a way to configure ActiveMQ so that "undead" subscriber connections like these are eventually cleared automatically?
While the previous answer is basically correct, ActiveMQ does provide solutions for STOMP transports on the Broker to heart-beat connections, even if the client connects with STOMP v1.0. I blogged about this some time ago when ActiveMQ v5.6 was released, see the section on STOMP 1.0 default heartbeat configuration. Another option is to set tcp keepAlive on for the transport and tune your OS to use a shorter default check interval, the default is usually around two hours.
Though Stomp 1.1+ supports Heartbeating, Active MQ currently doesnt support inactive consumer detection for Stomp. (usually achieved with wireFormat.maxInactivityDuration).
Be Careful:
These values are currently not supported but are planned for a later release
ActiveMQ supports it for Openwire though. i,e after the configured duration the consumer would be considered DEAD !
I am confused about the function of Apache ActiveMQ.
I downloaded ActiveMQ from this link.
So I use it this way (environment: Windows 7): I start the bin/activemq.bat, then it works.
My question is: Does this mean I start a server on my machine? When I initialize the ActiveMQConnectionFactory, the broker URL is tcp://localhost:61616. But what if I want my machine to serve as a server and another machine to connect to my server?
Yes, you can use the primary box as a server and have consumers/subscribers running on other boxes (which will need to connect to the server - you will need to specify the server hostname & port for the connection to be established) - once in place, the messages on the server (topic or queue) can be consumed by the clients.
If you one have one producer and one consumer, you can look into using queues - if you have more than one consumer/subscriber, you can look into setting up a topic to which the consumers will subscribe to. Messages need to be inserted to the topic/queue as needed.
You can specify the server information in your code or preferably in the config file.
For reference to topologies:
http://activemq.apache.org/topologies.html
Also, you can choose to persist your messages or not based on your use case. Kaha DB is the preferred route (specially if performance is of concern).
Useful examples:
http://sujitpal.blogspot.com/2007/12/jms-patterns-with-activemq.html
http://vvratha.blogspot.com/2012/05/java-client-to-sendreceive-messages-for.html
Hope it helps.
Apache ActiveMQ ™ is the most popular and powerful open source messaging and Integration Patterns server
& it act like a third party server.
Apache ActiveMQ is fast, supports many Cross Language Clients and Protocols, comes with easy to use Enterprise Integration Patterns and many advanced features while fully supporting JMS 1.1 and J2EE 1.4. Apache ActiveMQ is released under the Apache 2.0 License.
ActiveMQ have the capabilities to send 100 MB single message framework and maintain 1000 concurrent connection simultaneously , for the further information you can check activemq.xml in your documentation.
Further Info at here about the ActiveMQ