Open-source project
Wizzercn/MqttWk avatar
Wizzercn/MqttWk

MqttWk, a Netty MQTT broker where Redis and Kafka do the heavy lifting

Java + Netty 实现的高并发高可用MQTT服务broker,轻松支持10万并发(有群友实现了130万在线)

735 stars247 forksJavaApache-2.0

At a glance

What is it?
MqttWk is a Java MQTT 3.1.1 broker built on Netty, NutzBoot, Redis and Kafka, aimed at teams that want an embedded broker with clustering, Websocket access and topic filtering without writing one. Its documentation is Chinese-first and its last push was on 2026-04-02, so read it as a working reference implementation rather than a fast moving product.
Who is it for?
MqttWk fits teams that already run Redis and want an MQTT broker they can read, configure through YAML and extend at the module level, and it is a reasonable choice for internal platforms rather than a public managed service. It is the wrong tool if you need a maintained distribution, a documented broker API, or English documentation.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An MQTT 3.1.1 broker built on Netty and NutzBoot

MqttWk is a Java implementation of an MQTT broker, and its name splits into the two halves of its design. Netty handles the socket layer and the protocol parsing, while NutzBoot, the framework by the same author behind NutzMqtt, provides dependency injection and property configuration. Redis stores session information and, in cluster mode, distributes it. Kafka is an optional path for forwarding messages rather than the transport itself.

The feature list is specific about scope. The implementation follows the MQTT 3.1.1 specification, implements the full set of QoS levels, supports will messages, retained messages and redelivery of undelivered messages, and has a heartbeat mechanism. Connection authentication and SSL are switches rather than defaults. Websocket support, clustering and Kafka forwarding are all optional and off by default.

That is an unusual combination for a broker: most packaged brokers treat Redis and Kafka as add-ons at the edge, while here Redis is part of the session model. The trade-off is that a running broker is really a running Redis as well.

Six modules and where the broker actually lives

The repository is a multi-module Maven project, and the module split maps closely onto the runtime responsibilities.

The core is mqtt-broker, which holds the server implementation, and mqtt-common holds shared classes plus the service interfaces other modules use. mqtt-auth handles username and password authentication at connection time. mqtt-store is the piece that keeps session information, using Redis for caching and Kafka for loading. mqtt-client is a sample client, and the README notes that its configuration file needs a database connection before it starts. mqtt-zoo is where the tutorials and test files live, including a Kafka consumer that receives messages and a Websocket communication test.

The important consequence for an adopter is that the extension point is a module boundary. The README states that connecting against a database, or using some other method of authentication, only requires rewriting the relevant methods inside the mqtt-auth module. That is a small, well-defined surface to work against, provided you are comfortable in Java and with the NutzBoot conventions the rest of the project follows.

Building the broker and starting it with a YAML profile

The documented path is Maven based and expects JDK 1.8. From the project root you install the modules into your local repository:

bash
mvn install

Then you build the broker as a shaded jar, which bundles its dependencies so the artifact can be copied around:

bash
mvn clean package nutzboot:shade

Run the jar and it loads the YAML configuration packaged inside it. Passing the NutzBoot profile switch selects the prod variant, so application-prod.yaml is the file that gets read:

bash
java -jar mqtt-broker-xxx.jar -Dnutz.profiles.active=prod

For a deployment where the configuration lives on disk rather than inside the jar, point NutzBoot at a directory with the boot configuration flag. The documentation gives this as a nohup launch into the background with output discarded:

bash
nohup java -Dnutz.boot.configure.yaml.dir=/data -jar mqtt-broker-xxx.jar >/dev/null 2>&1 &

Either way you get a single jar plus a YAML file. Nothing in the documented flow requires a database, a message queue, or a container image.

Ports, demo credentials and a statistics endpoint

Once the broker is up, the README points you at mqtt-spy as the client to try it with, and lists the values you need. The MQTT port is 8885 and the Websocket port is 9995. The demo username is demo, and the matching password is a long hex string that the README prints in full; it is the RSA encrypted form the broker decrypts before matching it against the username.

There is also a statistics URL to check after startup:

bash
http://127.0.0.1:8922/open/api/mqttwk/info

That endpoint is the quickest way to confirm the broker actually started and accepted the configuration you expected, which matters because the shaded jar starts quietly and its log output is redirected to nowhere in the background launch shown above.

One detail worth flagging for anyone wiring up TLS clients: the connection certificate referenced by the README sits at mqtt-zoo\keystore\server.cer. That path is inside the zoo module rather than the broker module, which tells you the shipped certificate is a sample for local testing, not a credential you would hand to clients in production.

Topic filters reject a trailing slash and put # only at the end

The topic filtering rules are spelled out in the README with concrete examples, and they are stricter than the MQTT specification requires. A single topic subscription such as test_topic or /mqtt/test cannot end with a slash. A wildcard subscription uses # or a path ending in #, for example /mqtt/#, and the # has to be the last character.

The README presents this as supported syntax rather than a restriction, but the effect on a client is real: subscribing to /mqtt/# works while subscribing to /mqtt/#/stats does not, and a topic literal with a trailing slash will not match the single-topic form. If your device fleet derives topics from a path template, that derivation has to agree with these rules.

This is also a good example of a documentation-driven trade-off. The filter implementation is narrow, which keeps the matching path cheap, and the cost lands on whoever writes the subscription side of the application.

Redis carries the session state, so a cluster needs a Redis cluster

Clustering is switched on with a flag in the broker configuration, and the Redis settings that go with it decide whether the deployment is one machine or several. The multi-machine form points at Redis nodes in cluster mode:

yaml
redis:
  mode: cluster
  nodes: 192.168.1.103:16379,192.168.1.104:26379,192.168.1.103:36379

The single-machine form keeps the broker clustering switched on but uses one ordinary Redis instance:

yaml
redis:
  mode: normal
  host: 127.0.0.1
  port: 6379

The cluster flag itself sits under the broker key as cluster-on: true, and the Kafka section below it carries broker-enabled, which the README shows as false, meaning message forwarding stays off unless you turn it on. The Kafka bootstrap servers are listed in the same structure, so the two dependencies are configured side by side even though only one is mandatory.

The practical reading of this layout: single node deployment is a broker plus one Redis. Anything larger is a broker tier, a Redis cluster, and a Kafka cluster that carries forwarded messages between nodes.

Connection auth defaults to an RSA encrypted password, and SSL needs your own certificate

Two pieces of configuration are worth understanding before you expose this broker to anything.

The first is authentication. The default scheme encrypts the password with an RSA key pair and matches it against the username when a client connects. If that does not fit your setup, you replace it by rewriting the corresponding methods in the mqtt-auth module, which is where the database backed variant would live. Authentication is optional in the first place, since the README lists it as a switch that can be left off.

The second is the server certificate. It lives at resources/keystore/server.pfx inside mqtt-broker. The README is unusually firm about this: you may create your own certificate, but the storage location and file name must stay exactly as described. The rule exists because the broker loads that path directly, so a renamed file silently disables the feature you thought you had configured. Getting a broker with SSL enabled and a certificate you control therefore means replacing one file in one known location, and nothing more.

A project description claim, a 2023 release and a push from April 2026

Two dates frame the maintenance picture. The last push to the default branch, named netty, was on 2026-04-02. The most recent listed release is 1.4.0-netty, published on 2023-08-14, with earlier releases in 2022 and 2020 following the same version pattern. So the source tree has seen work in 2026 while the released artifact dates from 2023, and anyone taking a dependency should check which of the two they are actually running.

The project description on the repository advertises support for 100,000 concurrent connections and mentions that someone in the community reached 1.3 million online clients. Those are claims from the project's own summary, not measurements you can verify from the documentation, and the description itself does not explain the hardware, the topic mix, or the QoS levels behind them. The README, by contrast, is mostly a development guide: modules, configuration keys and startup commands.

The licence is Apache 2.0, and the README links to the Apache licence text. That is a permissive licence for commercial use and for embedding, with the usual requirement to preserve notices and the licence itself when redistributing.

Editorial conclusion

MqttWk fits teams that already run Redis and want an MQTT broker they can read, configure through YAML and extend at the module level, and it is a reasonable choice for internal platforms rather than a public managed service. It is the wrong tool if you need a maintained distribution, a documented broker API, or English documentation. Before adopting it, check three things: that the last push on 2026-04-02 and the 1.4.0-netty release of 2023-08-14 match your upgrade expectations, that you can live with the topic filter rules (no trailing slash on a single topic, # only at the end of a wildcard subscription), and that you are willing to replace the certificate at resources/keystore/server.pfx yourself if you turn SSL on.

Frequently asked questions

How do I build and run the MqttWk MQTT broker?

With JDK 1.8 installed, run mvn install at the project root, then mvn clean package nutzboot:shade inside mqtt-broker. Start it with java -jar mqtt-broker-xxx.jar -Dnutz.profiles.active=prod to load application-prod.yaml from inside the jar.

Which ports does MqttWk listen on and how do I connect a test client?

The MQTT port is 8885 and the Websocket port is 9995, with the demo username demo and the password printed in the README. The README suggests using mqtt-spy as the test client, and broker statistics are served at http://127.0.0.1:8922/open/api/mqttwk/info.

Does MqttWk require Redis and Kafka to run?

Redis stores session information and is part of the deployment, while Kafka is optional and the broker-enabled flag is shown as false in the sample configuration. Single node deployment uses Redis in normal mode on one host, and cluster mode uses several Redis nodes.

How do I use my own TLS certificate with MqttWk?

The server certificate is stored at resources/keystore/server.pfx inside mqtt-broker, and the README states that your own certificate must use that same location and file name. SSL itself is a switch that can be turned on.

How do I connect MqttWk authentication to a database?

The default scheme encrypts the password with an RSA key pair and matches it against the username. To use a database or another method, rewrite the corresponding methods in the mqtt-auth module.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. Releases
  5. Wizzercn/MqttWk on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/wizzercn-mqttwk.svg)](https://hysenlabs.com/projects/wizzercn-mqttwk)

Was this useful?