Scalability : the system should be able to handle increasing customer request
Availability : the system can be accessed at any time especially viewing status of delivery.
Reliability : the system should handle failures without losing critical data. Automatic retries for notification or order status updates can enhance reliability.
Monitoring and Logging : for detecting bottlenecks system need comprehensive monitoring and logging aiding in active system maintenance.
Latency : service should provide regular queries in response time less than 200ms, complex queries in time under 1 second.
DAU : 100M customers, 10K businesses
order placemnet in a day : 10M
size of order placement data : 1KB
data size in a day = 10M*1KB = 10G/day
notification per order = average 3
notification in a day = 10M * 3 = 30M
notification in a second = 30M/24*60*60 = 300K/864=340/sec
Asume that peak requests per second = 700/sec
POST /api/register
POST /api/login
get history of order placement
GET /api/orders/history
get status of order placement
GET /api/orders/{orderID}/status
update status of order
PATCH /api/orders/{orderID}/status
get order detail
GET /api/orders/{orderID}
get current location of delivery
GET /api/orders/{orderID}/location
notifyCustomer
POST /api/notify/customer
notifyWMS
POST /api/notification/wms
subscribe notification
POST /api/notification/subscribe
unsubscribe notification
POST /api/notification/unsubscribe
database tech choice
User
Order
Product
Since order and product relation is many to many, we have 2 choice.
There are 3 user : delivery man, customer, businesses
To scale each part of system independently, microservice is more suitable for this design. in order to find each service api gateway is needed and it route request to right service. and load balancer distribute the traffic evenly to replicated service.
To process asyncronously I introduce the kafka messaging where the worker make the notification message and notify to user sequantially.
There are 3 user : delivery man, customer, businesses
Delivery man update the status of order and current location. It should be stored in mongoDB and notified to customer and businesses through notification service.
after user receive the notification, user would access to this system to see datails of order.
sharding
To support increase user's demand on order tracking, order data should be stored in distributed shard. shard key can be user id or order id. but order id is more suitable for searching order data. and by adding shard we can store more big data.
caching
in tracking system, user will access to location and status data frequently. to avoid the bottleneck of this data, we can use cache like redis. since location changes in real time, we would use write-through caching strategy for reducing caching miss.
microservices vs. monolithic
while pros of monolithic architecture is easy to develop and deploy and test, the limitation of scalability we would choose the microservice architecture. this help we can scale indepentenly for each microservice as much as their own traffic.
Websockets or server-sent events
To update the real time location to users, we would choose server-sent event. even though websocket is good for send real time data, its connection cost is high and there's no need for 2-way communication. server-sent event is more efficient and meet our requirement properly.
kafka failure
If a worker fails, the request can be dequeued and retried by another worker.
redis failure
point-in-time recovery in redis will be conducted.
request fail
If the request fail then server return the reason for that to user.
mongoDB fail
secondary node become primary node. and service would be available with minimum downtime.