A simple RabbitMQ sample with Java to implement the Stock Trading API.
This project uses RabbitMQ as:
- A RPC system: the method of communication between services (APIService and StockService).
- A Pub/sub system: send order update messages to all subcribers.
- A task queue: Limit update DB request/second with queue.
In this project, we use RabbitMQ to set up RPC as a method of communication between APIService and StockService.
Our RPC will work like this:
- We will setup a new
DirectExchange
- The
APIService
will leverage theconvertSendAndReceive
method, passing theexchange name
, theroutingKey
, and themessage
. - The request is sent to an
Request Queue
. - The
StockService
is waiting for requests on that queue. When a request appears, it performs the task and sends a message with the result back to theAPIService
, using the queue from thereplyTo
field. - The
APIService
waits for data on theCallback Queue
. When a message appears, it checks thecorrelationId
property. If it matches the value from the request it returns the response to the application.
In this project, we use RabbitMQ to set up Pub/Sub system to broadcast all order updates to all clients.
Once any Order updated, StockService
send message to an exchange
. An exchange
is a very simple thing. On one side it receives messages from producers and the other side it pushes them to queues
.
The main idea behind Task Queue
is to avoid doing a resource-intensive task immediately and having to wait for it to complete. Instead we schedule the task to be done later. We encapsulate a task as a message and send it to a queue. A worker process running in the background will pop the tasks and eventually execute the job.
In this project, assuming our DB only suffered around 200 request at the same time, that means if more than 200 request at the same time, our DB will die.
Official RabbitMQ docker image at https://hub.docker.com/_/rabbitmq
$ cd ./rabbitmq && docker-compose up -d
RabbitMQ Server listens on port 5672
as default.
Below are mutual properties between APIService and StockService:
mq.rabbitmq.queue=stocktrading.queue
mq.rabbitmq.exchange=stocktrading.exchange
mq.rabbitmq.routingkey=stocktrading.routing
mq.rabbitmq.queue.json=stocktrading.queue.json
mq.rabbitmq.routingkey.json=stocktrading.routing.json
mq.rabbitmq.db.task.queue=db.task.queue
mq.rabbitmq.pubsub.queue=pubsub.queue
mq.rabbitmq.pubsub.exchange=fanout.exchange
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=user
spring.rabbitmq.password=passw0rd
Project dir: ./Utils. Run $ mvn install
to build project.
$ mvn spring-boot:run
$ mvn spring-boot:run
RESTful server
listens on port 8081
(see application.properties
-> server.port
for more detail).
Available apis:
curl --request POST \
--url http://localhost:8081/api/enterOrder \
--header 'Content-Type: application/json' \
--data '{
"clientID": "C123456",
"stockID": "AAPL",
"marketID": "NASDAQ",
"price": "100.4",
"qty": "10000"
}'
curl --request POST \
--url http://localhost:8081/api/orderEnquiry \
--header 'Content-Type: application/json' \
--data '{
"clientID": "C123456"
}'
curl --request POST \
--url http://localhost:8081/api/cancelOrder \
--header 'Content-Type: application/json' \
--data '{
"clientID": "C123456",
"orders": [
{
"orderID": "1"
},
{
"orderID": "2"
}
]
}'