{"id":24837055,"url":"https://github.com/itechub/seckill-sanic","last_synced_at":"2025-10-14T11:31:51.309Z","repository":{"id":53530127,"uuid":"209044495","full_name":"itechub/seckill-sanic","owner":"itechub","description":"⏱Sanic seckill demo, a barebone microservice project structure.","archived":false,"fork":false,"pushed_at":"2021-03-25T23:30:38.000Z","size":363,"stargazers_count":7,"open_issues_count":9,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-07T05:29:42.939Z","etag":null,"topics":["microservice","microservices-demo","opentracing","python37","restful","sanic","sanic-framework","seckill-service","service-discovery"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itechub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-17T12:12:39.000Z","updated_at":"2024-11-03T22:48:28.000Z","dependencies_parsed_at":"2022-09-09T07:01:50.275Z","dependency_job_id":null,"html_url":"https://github.com/itechub/seckill-sanic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/itechub/seckill-sanic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itechub%2Fseckill-sanic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itechub%2Fseckill-sanic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itechub%2Fseckill-sanic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itechub%2Fseckill-sanic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itechub","download_url":"https://codeload.github.com/itechub/seckill-sanic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itechub%2Fseckill-sanic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279019089,"owners_count":26086516,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["microservice","microservices-demo","opentracing","python37","restful","sanic","sanic-framework","seckill-service","service-discovery"],"created_at":"2025-01-31T05:53:17.958Z","updated_at":"2025-10-14T11:31:50.958Z","avatar_url":"https://github.com/itechub.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Seckill-Sanic\n\n![MIT][MIT]\n\n`English` | [简体中文][简体中文]\n\n[English]: README.md\n[简体中文]: README.zh-Hans.md\n[Sanic]: https://sanicframework.org/\n[MIT]: https://img.shields.io/github/license/itechub/PROnunciation.svg\n\nA simple seckill scenario implemented by [`Sanic`][Sanic] web framework, using microservices style.\nThis project simulate a simple seckill scenario, which is consist of three microservices as follow:\n\n* Product Service\n  * any user can query products and product details\n  * any user can add/delete/edit product instance\n* Activity Service\n  * any user can query activities and activity details\n  * any user can add/delete/edit activity instance\n  * any user can participate seckill activity to place an order with unique user id.\n* Order Service\n  * user can query their orders, identify by unique user id\n  * user can view/delete order details\n\n## Original Requirements Description\n\n\u003e Write an web api service to simulate users' participation of a seckill activity:\n\u003e\n\u003e * Provide a web API, based on HTTP or TCP, which users can place their order for specific activity\n\u003e * 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)\n\u003e * The orders info should be persistent even when the service or machine is being restarted\n\u003e * Each activity only related to one product, user can only place order when activity's product inventory \u003e 0\n\u003e * The final products sum up within orders should be equivalent to inventory of the products\n\u003e * The service should be able to handle large amount concurrent requests from multiple users (etc. 100 TPS)\n\n## Features\n\n* **Using [Sanic][sanic] , Async Python 3.6+ web server/framework | Build fast. Run fast**\n* **Using [aiomysql][aiomysql] as database driver, to execute sql statement asynchronously**\n* **Using [aiohttp][aiohttp] as client to issue async http requst, interacting with other microservices.**\n* **Using [peewee][peewee] as ORM，Only for modeling and data model migrations**\n* **Using [sanic-opentracing][sanic-opentracing] as distributed tracing system implementation**\n* **Using [sanic-openapi][sanic-openapi] to auto generate Swagger API documentation**\n\n[sanic]: https://github.com/huge-success/sanic\n[aiomysql]: https://github.com/aio-libs/aiomysql\n[aiohttp]:https://github.com/aio-libs/aiohttp\n[peewee]: https://github.com/coleifer/peewee\n[sanic-opentracing]: https://github.com/shady-robot/sanic-opentracing\n[sanic-openapi]: https://github.com/huge-success/sanic-openapi\n\n## Screenshots\n\n### Swagger API\n\n![Swagger](assets/images/swagger_sanic.jpg)\n\n### Jaeger Server\n\n![Jaeger](assets/images/jaeger_sanic.jpg)\n\n## Environment\n\n### Docker-Compose Environment\n\n#### Configure environment variables via `.env`\n\nCreate your local `.env` file, you can use the `.env_template` as a starting point.\n\n```conf\nDOCKER_DIR=~/you/project/patch/sanic_seckill/seckill/deployment\nMYSQL_ROOT_PASSWORD=sanicroot\n```\n\n![Docker-Compose](assets/images/docker-compose.jpg)\n\n#### Start all services\n\nBuild 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.\n\n```shell\ndocker-compose build\ndocker-compose up\n```\n\n#### Access services\n\nBy default, docker-compose will bind services port to local host machine. Change any port mapping as you like by editing `docker-compose.yml` file.\n\n* Consul UI:  `http://localhost:8501`\n* Jaeger UI:  `http://localhost:8502`\n* Product Service:  `http://localhost:8503`\n* Activity Service:  `http://localhost:8504`\n* Order Service:  `http://localhost:8505`\n\nIf everything works as expected, you can see all three microservices are registered with healthy check status in `Consul` web GUI.\n\nBy 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.\n\n![Consul](assets/images/consul.jpg)\n\n### Local environment setup\n\n#### docker volume\n\n#### Python virtualenv\n\n## Technical implementation\n\n### Server\n\n#### Before server starts\n\n* Create DB connection pool\n* Create client connection session，to interact with other services\n* Create `jaeger.tracer` to implement distributed tracing over requests\n\n#### Middlewares\n\n* Implement request middleware to add specific HTTP headers, handle CORS request\n* Add an envelop to response, uniform all response data format\n\n#### Exceptions\n\nIntercept with exception, and response with uniform format.\n\n#### Service Registration\n\nCreate ServiceWatcher Task, for service discovery and service healthy status check, all services are maintained to `app.services` list.\n\n### Data Model\n\n\u003e Using peewee as ORM backend, only for data model design and data migration, using `aiomysql` for async SQL operation.\n\n* All DB connection configurations are configured by environment variables\n* If you are using `docker-compose`, you don't have to create DB table manually\n* Otherwise you need to run `python migrations.py` to migrate DB table\n\n### Database Operation\n\nUsing `aiomysql` as database connector, all sql related operation are capsulated by `DBConnection`, to execute raw sql asynchronously,\n\n* `acquire()` returns a non-transaction SQL connection. Used for query which is optimized for efficiency.\n* `tansaction()` as transaction function, all delete/insert related SQL should use transaction when needed.\n* If `trace` is set to `true`, all DB operation will being traced.\n\n### HTTP Async Request Client\n\nUsing `client` within `aiohttp` package, capsulating to provide common utilities for accessing other microservices asyncronously.\n\n### Logging\n\nUsing `Python logging` module, `logging,yml` as configuration file, `JsonFormatter` will transform logs into json format.\n\n### Distributed Tracing System\n\n* OpenTracing is built around by Dapper, Zipkin, which bring us a standard for distributed tracing system\n* Opentracing will trace every request within your service, and every related service, which plays an critical part for analysis of microservice performance\n* Implementing opentracing standard, and use Jaeger as tracer\n* Tracing behaviors(DB, Client) can be configured by environment variables\n\n### Handling Exceptions\n\nUsing `app.error_handler = CustomHander()` to handle exceptions.\n\n* `code`: status code, `0` for success, and other for exceptions.\n* `message`: error message\n* `status_code`: standard HTTP status code\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitechub%2Fseckill-sanic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitechub%2Fseckill-sanic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitechub%2Fseckill-sanic/lists"}