This project is an implementation of a distributed message queue using the Raft consensus algorithm in Go. It is heavily inspired by the following projects / talks / resources:
- GopherCon 2023: Philip O'Toole - Build Your Own Distributed System Using Go
- Raft Consensus Algorithm
- Golang Implementation of the Raft Consensus Protocol
- Raft backend implementation using BoltDB
- A reference use of Hashicorp's Raft implementation
Full walkthrouh of the project can be found here.
These instructions will get you up and running on your local machine for development and testing purposes.
git clone https://github.com/kavinaravind/go-raft-message-queue.git
cd go-raft-message-queue
make clean && make build- The
-leaderflag is used to specify that the node is the leader node. - The
-idflag is used to specify a unique string identifying the server. - The
-raddrflag is used to specify the Raft address of the server. - The
-dirflag is used to specify the directory where the server's data will be stored. - The
-paddrflag is used to specify the host and port of the leader node to join the cluster. - The
-haddrflag is used to specify the host and port of the server for the client to interact with.
The following commands will run a leader node and two follower nodes on your local machine. The leader node will be running on port 3000, and the follower nodes will be running on ports 3002 and 3004. The Raft addresses will be 3001, 3003, and 3005 respectively. The data for each node will be stored in the tmp directory of the current working directory. These ports can be any available ports on your machine.
./queue -leader -id=node01 -raddr=localhost:3001 -dir=./tmp/node01 -haddr=localhost:3000./queue -id=node02 -raddr=localhost:3003 -dir=./tmp/node02 -paddr=localhost:3000 -haddr=localhost:3002
./queue -id=node03 -raddr=localhost:3005 -dir=./tmp/node03 -paddr=localhost:3000 -haddr=localhost:3004POST /send- Push a message to the queueGET /recieve- Pop a message from the queueGET /stats- Get the status of the raft nodePOST /join- Join a node to the cluster
The model of the message is as follows:
type Comment struct {
Timestamp *time.Time `json:"timestamp,omitempty"`
Author string `json:"author,omitempty"`
Content string `json:"content,omitempty"`
}This can be pushed to the queue using the following command:
curl -X POST -d '{"timestamp": "2022-05-15T17:19:09Z", "author": "John Doe", "content": "This is a sample comment."}' http://localhost:3000/sendThis can be done using the following command:
curl -X GET http://localhost:3000/recieveWill return the following response:
{
"Data": {
"timestamp": "2022-05-15T17:19:09Z",
"author": "John Doe",
"content": "This is a sample comment."
}
}If the queue is empty, the following response will be returned:
{
"Data": {}
}Can be used for debugging purposes. Will return the following Raft.Stats map.
curl -X GET http://localhost:3000/stats