itechub / seckill-sanic

⏱Sanic seckill demo, a barebone microservice project structure.
MIT License
6 stars 5 forks source link
microservice microservices-demo opentracing python37 restful sanic sanic-framework seckill-service service-discovery

Seckill-Sanic

MIT

English | 简体中文

A simple seckill scenario implemented by Sanic web framework, using microservices style. This project simulate a simple seckill scenario, which is consist of three microservices as follow:

Original Requirements Description

Write an web api service to simulate users' participation of a seckill activity:

  • Provide a web API, based on HTTP or TCP, which users can place their order for specific activity
  • User can send request over once to the same activity, and the server side should ensure that only one order is being placed when conditions are met. (only when there are products left)
  • The orders info should be persistent even when the service or machine is being restarted
  • Each activity only related to one product, user can only place order when activity's product inventory > 0
  • The final products sum up within orders should be equivalent to inventory of the products
  • The service should be able to handle large amount concurrent requests from multiple users (etc. 100 TPS)

Features

Screenshots

Swagger API

Swagger

Jaeger Server

Jaeger

Environment

Docker-Compose Environment

Configure environment variables via .env

Create your local .env file, you can use the .env_template as a starting point.

DOCKER_DIR=~/you/project/patch/sanic_seckill/seckill/deployment
MYSQL_ROOT_PASSWORD=sanicroot

Docker-Compose

Start all services

Build and start all services with the following command using docker-compose. You can adjust the port mapping or other setting by editing the docker-compose.yml file.

docker-compose build
docker-compose up

Access services

By default, docker-compose will bind services port to local host machine. Change any port mapping as you like by editing docker-compose.yml file.

If everything works as expected, you can see all three microservices are registered with healthy check status in Consul web GUI.

By default, TRACE_ALL is set to true within the activity service, which is configured in docker-compose.yml, so when you make request to activity service, you can view all request trace in Jaeger web GUI.

Consul

Local environment setup

docker volume

Python virtualenv

Technical implementation

Server

Before server starts

Middlewares

Exceptions

Intercept with exception, and response with uniform format.

Service Registration

Create ServiceWatcher Task, for service discovery and service healthy status check, all services are maintained to app.services list.

Data Model

Using peewee as ORM backend, only for data model design and data migration, using aiomysql for async SQL operation.

Database Operation

Using aiomysql as database connector, all sql related operation are capsulated by DBConnection, to execute raw sql asynchronously,

HTTP Async Request Client

Using client within aiohttp package, capsulating to provide common utilities for accessing other microservices asyncronously.

Logging

Using Python logging module, logging,yml as configuration file, JsonFormatter will transform logs into json format.

Distributed Tracing System

Handling Exceptions

Using app.error_handler = CustomHander() to handle exceptions.