Git Product home page Git Product logo

flashmq's Introduction

FlashMQ

building testing linting docker

FlashMQ is a high-performance, light-weight MQTT broker/server, designed to take good advantage of multi-CPU environments.

Builds (AppImage and a Debian/Ubuntu apt server) are provided on www.flashmq.org.

Building from source

Building from source should be done with build.sh. It's best to checkout a tagged release first. See git tag.

If you build manually with cmake with default options, you won't have -DCMAKE_BUILD_TYPE=Release and you will have debug code enabled and no compiler optimizations (-O3). In other words, it's essentially a debug build, but without debugging symbols.

Docker

Official Docker images aren't available yet, but building your own Docker image can be done with the provided Dockerfile.

# It's best to checkout a tagged release. See 'git tag'.
git checkout <tag name>

# build flashmq docker image
docker build . -t halfgaar/flashmq

# run using docker (with, as an example, a place for a config file (default
# name flashmq.conf). Create extra volumes as you need, for the persistence DB
# file, logs, password files, auth plugin, etc.
docker run -p 1883:1883 -v /srv/flashmq/etc/:/etc/flashmq halfgaar/flashmq

# for development you can target the build stage to get an image you can use for development
docker build . --target=build

Plugins

A plugin interface is defined and documented in flashmq_plugin.h. It allows custom authentication and other behavior.

See the examples directory for example implementations of this interface.

Commercial services

If your company requires commercial FlashMQ services, go to www.flashmq.com. Services include:

  • the development of custom FlashMQ plugins;
  • MQTT integration advice; and
  • managed FlashMQ (coming Q1 2023).

flashmq's People

Contributors

bigsmoke avatar halfgaar avatar jeroendekker82 avatar quinox avatar thiemovanengelen avatar truebrain avatar wiebeytec avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flashmq's Issues

keepalive interval vs paho-mqtt

I have been faced with a very odd situation where clients seem to be keeping reconnecting. Could not put my finger behind it. I might have reduced it to paho doing a default keep alive interval of 60s, and flashmq setting 5 seconds(?)

When updated the paho connect keepalive interval to 15, the client stayed connected.

I noticed that the situation is observed by a subscribe only process, have low amounts of traffic. I don't know if this is the exclusive case.

support mosquitto style plugins

I was trying to use some sample plugins from mosquitto with flashmq but it failed to load.

There are two issues here i think:

  1. the plugin failed to load
  2. flashmq shutdown instead of just rejecting the plugin, logging the error and loading up. It probably is by design to make sure user understand the plugin did not load, but seemed something worth mentioning in the documentation.

plugin in question : https://github.com/eclipse/mosquitto/tree/master/plugins/payload-modification

feel free to close if above is expected and by design

error log:

[2022-12-01 17:43:29] [NOTICE] Loading auth plugin /home/ubuntu/mosquitto/mosquitto/plugins/payload-modification/mosquitto_payload_modification.so
[2022-12-01 17:43:29] [ERROR] Error initializing auth back-end: /home/ubuntu/mosquitto/mosquitto/plugins/payload-modification/mosquitto_payload_modification.so: undefined symbol: mosquitto_callback_register
[2022-12-01 17:43:29] [NOTICE] Quitting FlashMQ

Question

Do you have any comparison on features as compared to other brokers such as clustering etc... I see from the videos that performance is not an issue but If I decide to go with flashmq will I suffer from lack of features and then end up going back to a lesser performing broker ? I am not looking to push 1M messages per second but I have noticed with lower hardware specs other brokers such EMQ and VernMQ have had issues with large volumes of messages so your broker seems to fit well in this area.

Thank you,

Gary

FlashMQ randomly dropping incoming SSL connections

Flashmq randomly drops incoming SSL connections.

Besides the inline logs I share down bellow, I attach the related flasmq.log report.

The test is done with the latest tag (v1.10.0) on a Fedora 39 (Linux 6.7.7-200.fc39.x86_64) but I am facing similar issues after building docker image.

Just in case it helps, I'm using same environment to run similar tests against other MQTT brokers (emqx, hivemq, vernemq, mosquitto) and they seem to run smoothly at this point so I wonder if I am missing any fundamental config setting ? (see flashmq.conf bellow).

FlashMQ running instance

./FlashMQBuildRelease/flashmq -c flashmq.conf
[2024-03-13 10:00:11.311] [NOTICE] Loading config. Reload: false.
[2024-03-13 10:00:11.318] [NOTICE] Creating IPv4 SSL TCP listener on [0.0.0.0]:8883
[2024-03-13 10:00:11.319] [NOTICE] Creating IPv6 SSL TCP listener on [::0]:8883
[2024-03-13 10:00:11.319] [NOTICE] Creating IPv4 SSL TCP listener on [0.0.0.0]:8883
[2024-03-13 10:00:11.319] [NOTICE] Creating IPv6 SSL TCP listener on [::]:8883
[2024-03-13 10:00:11.319] [NOTICE] Creating IPv4 non-SSL TCP listener on [0.0.0.0]:1883
[2024-03-13 10:00:11.319] [INFO] Loading './str/bridgenames.db'
[2024-03-13 10:00:11.320] [INFO] Setting rlimit nofile to 1000000.
[2024-03-13 10:00:11.320] [NOTICE] 8 CPUs are detected, making as many threads. Use 'thread_count' setting to override.
[2024-03-13 10:00:11.320] [INFO] Loading './str/retained.db'
[2024-03-13 10:00:11.320] [INFO] Loading './str/sessions.db'
[2024-03-13 10:00:11.321] [NOTICE] Starting FlashMQ version 1.10.0, release build with SSE4.2 support.
[2024-03-13 10:00:11.321] [INFO] Switching logging from stdout to logfile './flashmq.log'

MqttLoadSimulator already reports dropped connections

./MqttLoadSimulator --hostname localhost --port 8883 --client-certificate ./new2/client.crt --client-private-key ./new2/client.key --ssl --delay 10
Version: 1.5.0.
Clients: 2 on 8 threads. Sent: 175 (25/s). Recv: 175 (25/s). Recv-Sent: 0. Connects: 2 (0/s). Disconnects: 2 (0/s). Errors: 4 (0/s).
Message latency (min/avg/max): 0.4 ms / 0.7 ms / 1.1 ms.
Thread loop drift: Avg: 1.00 ms, max: 1 ms (OK)

Similar behavior with other benchmark tools like "mqtt-bechmark"

mqtt-benchmark --broker tls://localhost:8883 --count 10 --size 100 --clients 10 --qos 1 --format text -broker-ca-cert ./new2/ca.crt -client-cert ./new2/client.crt -client-key ./new2/client.key
2024/03/13 10:01:10 Starting client  0
2024/03/13 10:01:10 Starting client  1
2024/03/13 10:01:10 Starting client  2
2024/03/13 10:01:10 Starting client  3
2024/03/13 10:01:10 Starting client  4
2024/03/13 10:01:10 Starting client  5
2024/03/13 10:01:10 Starting client  6
2024/03/13 10:01:10 Starting client  7
2024/03/13 10:01:10 Starting client  8
2024/03/13 10:01:10 Starting client  9
2024/03/13 10:01:10 CLIENT 4 had error connecting to the broker: not Authorized
2024/03/13 10:01:10 CLIENT 8 had error connecting to the broker: not Authorized
2024/03/13 10:01:10 CLIENT 0 had error connecting to the broker: not Authorized
2024/03/13 10:01:10 CLIENT 9 had error connecting to the broker: not Authorized
2024/03/13 10:01:10 CLIENT 6 had error connecting to the broker: not Authorized
2024/03/13 10:01:10 CLIENT 1 had error connecting to the broker: not Authorized
2024/03/13 10:01:10 CLIENT 3 is connected to the broker tls://localhost:8883
2024/03/13 10:01:10 CLIENT 7 is connected to the broker tls://localhost:8883
2024/03/13 10:01:10 CLIENT 5 is connected to the broker tls://localhost:8883
2024/03/13 10:01:10 CLIENT 2 is connected to the broker tls://localhost:8883

flashmq.conf

log_file    ./flashmq.log
storage_dir ./str

listen {
  protocol mqtt
  inet_protocol ip4_ip6
  inet4_bind_address 0.0.0.0
  inet6_bind_address ::0
  fullchain ./new2/server.crt
  privkey ./new2/server.key

  # default = 8883
  port 8883
}

listen {
  protocol mqtt
  fullchain ./new2/server.crt
  privkey ./new2/server.key
  client_verification_ca_file ./new2/ca.crt
  client_verification_still_do_authn false
}

listen {
  protocol mqtt
  inet_protocol ip4

  # default = 1883
  port 1883
}

flashmq.log

Support lua scripting

Lots of MQTT broker support lua scripting, such as vernemq and emqtt.
Lua can make it easier to develop plugins.

make install after build gets cmake error

All,
Building for deployment on bare metal (so don't want docker image).
Steps:
git clone https://github.com/halfgaar/FlashMQ.git
cd FlashMQ
git checkout v1.1.0
mkdir build
cd build
cmake ..
make
sudo make install

Consolidate compiler generated dependencies of target flashmq
[100%] Built target flashmq
Install the project...
-- Install configuration: ""
-- Installing: /usr/bin/flashmq
-- Up-to-date: /var/lib/flashmq
-- Up-to-date: /var/log/flashmq
-- Installing: /etc/flashmq/flashmq.conf
-- Installing: /lib/systemd/system/flashmq.service
CMake Error at cmake_install.cmake:126 (file):
file INSTALL cannot find "/home/myusername/FlashMQ/man/flashmq.conf.5":
No such file or directory.

It seems that I didn't have docbook2x installed. Would be nice if the README.md included the dependencies for those of us that don't intend to deploy in docker. If I missed it somehow in the documentation then I apologize.

Looks like an awesome broker.

Build with musl

I tried to compile with musl, but got errors:

flashmq> [ 18%] Building CXX object CMakeFiles/flashmq.dir/types.cpp.o
flashmq> In file included from /build/source/utils.h:34,
flashmq>                  from /build/source/utils.cpp:20:
flashmq> /build/source/cirbuf.h:55:21: error: ‘uint’ has not been declared
flashmq>    55 |     void doubleSize(uint factor = 2);
flashmq>       |                     ^~~~
flashmq> In file included from /build/source/utils.h:34,
flashmq>                  from /build/source/mainapp.h:35,
flashmq>                  from /build/source/mainapp.cpp:18:
flashmq> /build/source/cirbuf.h:55:21: error: ‘uint’ has not been declared
flashmq>    55 |     void doubleSize(uint factor = 2);
flashmq>       |                     ^~~~
flashmq> In file included from /build/source/session.cpp:20:
flashmq> /build/source/session.h:95:38: error: ‘u_int16_t’ has not been declared
flashmq>    95 |     bool removeIncomingQoS2MessageId(u_int16_t packet_id);
flashmq>       |                                      ^~~~~~~~~
flashmq> /build/source/session.h:98:38: error: ‘u_int16_t’ has not been declared
flashmq>    98 |     void removeOutgoingQoS2MessageId(u_int16_t packet_id);
flashmq>       |                                      ^~~~~~~~~
flashmq> In file included from /build/source/variablebyteint.h:4,
flashmq>                  from /build/source/mqtt5properties.h:7,
flashmq>                  from /build/source/types.cpp:21:
flashmq> /build/source/cirbuf.h:55:21: error: ‘uint’ has not been declared
flashmq>    55 |     void doubleSize(uint factor = 2);
flashmq>       |                     ^~~~
flashmq> /build/source/session.cpp:330:6: error: no declaration matches ‘bool Session::removeIncomingQoS2MessageId(u_int16_t)’
flashmq>   330 | bool Session::removeIncomingQoS2MessageId(u_int16_t packet_id)
flashmq>       |      ^~~~~~~
flashmq> /build/source/session.h:95:10: note: candidate is: ‘bool Session::removeIncomingQoS2MessageId(int)’
flashmq>    95 |     bool removeIncomingQoS2MessageId(u_int16_t packet_id);
flashmq>       |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
flashmq> /build/source/session.h:33:7: note: ‘class Session’ defined here
flashmq>    33 | class Session
flashmq>       |       ^~~~~~~
flashmq> /build/source/session.cpp:358:6: error: no declaration matches ‘void Session::removeOutgoingQoS2MessageId(u_int16_t)’
flashmq>   358 | void Session::removeOutgoingQoS2MessageId(u_int16_t packet_id)
flashmq>       |      ^~~~~~~
flashmq> /build/source/session.h:98:10: note: candidate is: ‘void Session::removeOutgoingQoS2MessageId(int)’
flashmq>    98 |     void removeOutgoingQoS2MessageId(u_int16_t packet_id);
flashmq>       |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
flashmq> /build/source/session.h:33:7: note: ‘class Session’ defined here
flashmq>    33 | class Session
flashmq>       |       ^~~~~~~

Topic specific statistics

In threaddata.cpp some "$SYS" topics are currently defined. In your opinion:

  1. Should the server be able to provide throughput per topic so monitoring it becomes possible?
  2. Should a client aggregate these statistics, at the cost of receiving all information?

Multi-level wildcard out of spec

The non-normative comment in the MQTT v5 standard, point 4.7.1.2 says:

Client subscribes to “sport/tennis/player1/#”, it would receive messages published using these Topic Names:
· “sport/tennis/player1”
· “sport/tennis/player1/ranking
· “sport/tennis/player1/score/wimbledon”

When I subscribe with a mosquitto client:
mosquitto_sub -t "sport/tennis/player1/#" -v

and publish:
mosquitto_pub -t "sport/tennis/player1" -m "hello"

I don't get the message. Publishing the other two of the examples is OK.

A potential fix may be to add the following after the while loop in topicsMatch

    if (subscribe_itr != subscribe_itr.end() && *subscribe_itr == "#")
    {
        return true;
    }

Shared subscription load balancing strategies?

Hi,
FlashMQ seems like a fantastic broker :)
I was wondering if load balancing strategies have been considered for FlashMQ.
Specifically, I'm interested in emqx's 'hash' strategy, which effectively pairs publishers with subscribers.

Fail to run as image

I've cloned repository to build the most recent image :
docker build . -t xxxx/flashmq:v230226.2208
and pushed it.
When I restart my container with this new image I get the following error 👍
flashmq | /bin/flashmq: error while loading shared libraries: libresolv.so.2: cannot open shared object file: No such file or directory
several times
It's the same result if I try with the v1.2.1 code source

Deal with empty user names some way

FlashMQ currently doesn't except MQTT connect packets that flag a username as present, but is empty. It says:

Username flagged as present, but it's 0 bytes.

The MQTT spec says:

If the User Name Flag is set to 1, a user name MUST be present in the payload

But, there is some ambiguity if a zero byte username means 'present'. FlashMQ has the current behavior to not have two ways of having an anonymous login.

But, because other servers do accept this situation, we should deal with it. Perhaps with a config option.

SSL listener

Does ssl cert reload the listener when changed ?

Thank you

Install on Raspberry Pi

Can you create a tutorial how to install FlasMQ on RaspberryPi ?
I tried but failed:
N: Skipping loading the configured file "main/binary-armhf/Packages" because the depot "http://repo.flashmq.org/apt bullseye InRelease" does not support the "armhf" architecture.

If I didn't know for sure that it would run on another RaspberryPi (Victron Venus) - I would not ask for.

Huge amount of rentained messages and restarting

The last action upon a restart is saving retained messages to /var/lib/flashmq/retained.db, would it be possible to do this in a different way, since it takes quite long to write it. In addition to it, it looks that flashmq needs a whopping 6GB of RAM, and my expectation is that this is mostly due to these retained messages, any chance to offload this?

Support Mosquitto's sha512-pbkdf2 password file format

TODO:

  • Implement.
  • Add warning in man page that with thousands or millions of clients, purposefully slow hashing algorithms can be a problem, because it may require hours for all clients to connect.

Example:

wiebe:$7$101$oW4vum9VREb/0aH6K3ge7kY9u26JboPDpF+9SKjd0fdz6SXidJ9n+TtBbg5n0ImfM/LkIEn6BZxT78Wn6Uzgvw==$Sc31amckhadG9Sd7/qTR8L+ROxljBLCMTrFj/Isb0rikvolsWnucdfDDY3bcIk03Nm/ymzfenE7LuTtgbz3wkA==

Errors while loading config should be handled

This unexpectedly passes:

$ FlashMQ --test-config -c /dev/null
Config OK

$ ulimit -m 12345678
$ FlashMQ --test-config -c /dev/zero
Config OK

When I modify the code and call infile.exceptions(std::ifstream::failbit | std::ifstream::badbit); after opening infile they fail as expected:

$ FlashMQ --test-config -c /dev/null
basic_ios::clear: iostream error

$ FlashMQ --test-config -c /dev/zero
std::bad_alloc

Request haproxy example configuration for SSL termination

I am trying to get haproxy support to work as SSL terminator for port 8883. My expectation was the setup below would be in the right direction. I have tested it with mode tcp and mode http.

frontend mqtt
    bind :::8883 ssl crt /etc/haproxy/ssl
    tcp-request content reject unless { req.payload(0,0),mqtt_is_valid }
    use_backend flashmq
    mode tcp
    maxconn 1000

backend flashmq
    mode tcp

    # Create a stick table for session persistence
    stick-table type string len 32 size 100k expire 30m

    # Use ClientID / client_identifier as persistence key
    stick on req.payload(0,0),mqtt_field_value(connect,client_identifier)
    server flashmq 127.0.0.1:2883
listen {
  protocol mqtt
  port 2883
  haproxy on
}

FlashMQ Version 1.4.5 with SSE4.2 support
HAProxy version 2.4.18-0ubuntu1 2022/08/25 - https://haproxy.org/

A little bit more elaboration;

The client succesfully gets the SSL handshake done. The log of FlashMQ raises:

[2023-05-24 17:09:53] [NOTICE] Accepting connection from: address='127.0.0.1', transport='TCP/HAProxy/Non-SSL', fd=18
[2023-05-24 17:09:53] [NOTICE] Removing client '[ClientID='', username='', fd=18, keepalive=0s, transport='TCP/HAProxy/Non-SSL', address='127.0.0.1', prot=none, clean=0]'. Reason(s): HAProxy health check, epoll says socket is in ERR or HUP state.

Last Will not working correctly?

I think LWT is not working as it should in FlashMQ. I had some alerts in my uptime monitor that are not working after I changed my Server to FlashMQ.

I try to compare Mosquitto and FlashMQ with two shell windows.
First I connect to my Mosquitto Server:
On the 1st I do:
mosquitto_sub --will-topic foobar_topic --will-payload crashed --will-retain -i foobar -t foobar_topic -v -h localhost --disable-clean-session
no output yet. 👍

On the 2nd I do:
mosquitto_pub --will-topic foobar_topic --will-payload crashed --will-retain -i foobar -t foobar_topic -m online -h localhost -r --disable-clean-session
now the 1st outputs: foobar_topic online 👍

I only get the crashed LWT once I kill -9 the mosquitto_sub process.

Now I try my FlashMQ Server:
On the 1st I do:
mosquitto_sub --will-topic foobar_topic --will-payload crashed --will-retain -i foobar -t foobar_topic -v -h localhost --disable-clean-session
instant output foobar_topic crashed👎

On the 2nd I do:
mosquitto_pub --will-topic foobar_topic --will-payload crashed --will-retain -i foobar -t foobar_topic -m online -h localhost -r --disable-clean-session
now the 1st outputs: foobar_topic crashed 👎

Also I watch the topic with MQTT Explorer and once I pub, I get both topics, crashed and online afterwards. This is different from Mosquitto.

Question for DB archive

what would be the best approach to archive all the messages received in a DB ? would it be to tap into AlterPublish path for the plugin and pipe to DB or you would suggest to instead create a dumb subscriber whose sole purpose is to subscribe to all topics and keep writing to a DB ?

Build of 1.7.2 fails with gcc 13.1.1

Building 1.7.2 fails with gcc (GCC) 13.1.1 20230511 (Red Hat 13.1.1-2). The error is that std::string is used in globalstats.h but the <string> header is not included.

Simply including <string> fixes the issue

Plugin interface: call a plugin main_init function from main thread before other threads are created

Currently all plugin functions are called for each thread but it will be good to have one which is called only once from the main thread before the other threads are created.
To minimise the impact on the current design its signature may look like this:
typedef void(*F_flashmq_plugin_main_init_v2)(std::unordered_map<std::string, std::string> &auth_opts);
No global data pointer is added to keep the multi-core design of FlashMQ unchanged and in case needed, a static variable can be used as suggested in the documentation for flashmq_plugin_allocate_thread_memory.

One use case for this function would be to check which OS user is running the process.

The best place to call this function would be here:

    GlobalStats *globalStats = GlobalStats::getInstance();
->
    for (int i = 0; i < num_threads; i++)
    {
        std::shared_ptr<ThreadData> t = std::make_shared<ThreadData>(i, settings);

But the main problem is Authentication, which is a member of ThreadData is instantiated a few lines after this location.

Topic prefix stripping in server-to-server connections

Hi,

While FlashMQ supports prefixing topics on messages it sends and receives, it doesn't seem to be able to remove a prefix from incoming or outgoing topics, at least as far as flashmq.conf manpage is concerned.

This would afford transparently tunneling arbitrary messages through a shared server.

Mosquitto can do it ;-)

[simple question] how to give access for log dir ?

Hello,

when i try to give access for flashmq user i didn't gain the access with chown flashmq:flashmq & chmod..

File '/var/log/flashmq/flashmq.log' is not there and can't be created, because '/var/log/flashmq' is also not writable

I'm not a linux expert so..

#Edit (not for this case)
For mTLS i also add SSL_CTX_use_certificate_chain_file in listener.cpp

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.