Search code examples
javaarchitecturesystemsoftware-design

How do you design a dorne delivery sytem from the software architecture point of view?


For my master's degree final project I decided to design a drone delivery system. The main purpose is to learn to design complex systems.

The basic use case is this:

  1. User goes to merchant online shop, selects the products, selects the delivery method as "Drone delivery" and selects his delivery location.
  2. Merchant website, makes an API call to our drone delivery system (DDS) application to register the new delivery order.(The order will contain all information that we need: parcel pick up location, and destination location...)
  3. The DDS application based on drones positions, and based on an algorithm will calculate and mark which drone can deliver this order in the shortest time.
  4. The selected drone when is free will deliver the order.

So far so good. My questions are related to the software architecture of this system. I have some general questions and some specific questions.

General questions:

  • How do you design a system like this in order to be scalable? I mean: The system may be used by may merchants, if they hit my API in the same time with 100 orders, the system must be able to handle it.
  • What are some good design principles or patterns when designing an system like this?

Specific questions:
So far i have came up with this architecture:

System Components:

  1. Java(Spring) application
    • Rest web servce
    • web interface managing dorens and parces
    • bussines logic and algorithms for routing drones
    • producer/consumer for RabbitMQ
  2. Mysql Server
  3. RabbitMq

System flow:

  1. Merchant hits REST API to register the order
  2. The Java Application saves the order to Mysql database.
  3. After saving the order to the database, an Producer puts the order in a queue in RabbitMQ
  4. An Consumer consumes the RabbitMQ order queue. It takes each order and calculates based on an algorithm the drone that offers the best time for the delivery. Each drone has a separate queue in RabbitMQ. After finding the best drone, the consumer inserts the order in the drone queue in RabbitMQ. The consumer also interrogates the mysql database during this process.
  5. Whenever a drone is free, it will communicate with the system to ask for the next order. The system will look in the drone RabbitMQ queue and will take from there the next order.

My questions are related to the consumer and producer:

  1. Is OK that the consumer to have logic in it, in my example it will have the algorithm that will determine the best drone, to do this it needs to talk to mysql also, for retrieving drone positions? Is this a good practice? If not how can i do different?

  2. Is best practice for the consumer to stay in the application? Right now consumers are running in the same server as the web service and the code is not separated from web service code. I am thinking maybe in the future you may need to move the consumers in a separate server? How do you think the consumers so they can easily be separated from the application?

  3. I think that the producer must stay in the application, i mean is coupled with the web service app. Is that OK?

Sorry for the long post, and for my poor English. Thank you very much :)


Solution

  • Yes, the consumer should have logic in it. This is a standard EIP routing pattern.

    If you properly separate your business logic layers from your data access layers (your queue access is a data access layer), then it probably isn't a problem to have them all share a common project. You ultimately probably want to separate your business logic/domain model from the web service and the router/consumer, but those are much more deployment and packaging concerns.

    As long as you keep your web service code out of your business logic (and vice versa) you will probably be ok, you will just have to deploy the whole thing multiple times, and only expose the endpoints that are relevant for any given deployment. You ultimately might be happier though if you separate your layers via libraries, as it will actually enforce not mixing the concerns.

    And yes, the producer must be deployed with the web service, just make sure you are aware that as a Data Access Layer, that it's in a separate package/class. It will make your testing much easier.