Python-Nacos电商订单分布微服系统开发

在Windows环境下,利用Python构建一个包含订单、支付、库存服务的电商微服务系统,采用Nacos作为服务注册与发现中心,MongoDB作为数据存储,并设计统一网关服务以托管前端页面并聚合后端API,HTML/CSS/JS页面设计。

1 IMA-GLM助力

咨询提示词:给出Windows下使用Python开发的电商订单分布微服务系统:订单服务、支付服务、库存服务,NACOS服务注册发现,MongoDB数据存储,统一网关服务并托管兼作页面web服务器,HTML/CSS/JS页面设计[相互关联的订单、支付、库存]。

2 系统架构设计概览

本系统旨在解决传统单体架构中"烟囱式系统"带来的信息孤岛、维护成本高及响应速度慢等问题。通过微服务架构,将核心业务拆分为独立的服务单元,实现高内聚低耦合。

核心架构组件:

  1. 微服务应用层:包含订单服务、支付服务、库存服务,均使用Python(如Flask或FastAPI)开发。
  2. 服务治理层:使用Nacos实现服务的注册、发现与配置管理。
  3. 数据存储层:采用MongoDB存储业务数据,利用其文档模型灵活处理商品规格与订单详情。
  4. 统一接入层:API网关负责路由转发、认证鉴权,并托管前端静态资源。

3 核心微服务开发

使用Flask框架完成核心服务的实现,每个服务独立运行,拥有自己的数据库连接。

3.1 库存服务

库存服务管理商品库存,是防止"超卖"问题的关键。在高并发场景下,通常需要结合Redis分布式锁或数据库乐观锁,这里仅实现基础逻辑。

设计思路:库存服务独立管理商品数据,体现了" 每个服务拥有独立数据库" 的设计原则,避免共享数据库带来的耦合。

以下inventorySvc.py 完整代码实现,包含了商品列表查询、库存检查及初始化数据的逻辑。

python 复制代码
from flask import Flask, jsonify, request; from pymongo import MongoClient
from bson.objectid import ObjectId     # 用于处理MongoDB的_id字段
app = Flask(__name__)
# 1. 配置MongoDB连接
client = MongoClient('mongodb://localhost:27017/')
db = client['ecommerce_db']          # 连接本地MongoDB实例,数据库名为'ecommerce_db'
products_collection = db['products']
# 2. 辅助函数:将MongoDB的ObjectId转换为字符串
def product_serializer(product):
    """将MongoDB文档序列化为JSON友好的字典"""
    return { "id": str(product['_id']), "name": product.get('name'),
        "price": product.get('price'), "stock": product.get('stock'), "specs": product.get('specs', {}) }
# 3. API接口:获取商品列表
@app.route('/products', methods=['GET'])
def get_products():   # 获取商品列表接口,支持简单的查询参数过滤,如?name=手机
    try:       
        query_name = request.args.get('name')       # 获取查询参数
        query = {}                             # 构建查询条件
        if query_name:
            # 使用正则表达式进行模糊查询,类似于SQL的 LIKE
            query['name'] = {"$regex": query_name, "$options": "i"}       
        # 从数据库查询数据,参考:使用find()方法查询集合中的所有文档
        products_cursor = products_collection.find(query)       
        # 使用列表推导式处理数据,将游标转换为列表并序列化
        products_list = [product_serializer(product) for product in products_cursor]       
        return jsonify({ "code": 200, "message": "查询成功", "data": products_list }), 200
    except Exception as e:
        return jsonify({"code": 500, "message": f"服务器错误: {str(e)}"}), 500
# 4. API接口:检查并扣减库存 (供订单服务调用)
@app.route('/inventory/check', methods=['POST'])
def check_and_reduce_stock():
    data = request.json; product_id = data.get('product_id'); quantity = data.get('quantity')   
    if not product_id or quantity is None:
        return jsonify({"error": "参数缺失"}), 400
    try:       
        product = products_collection.find_one({"_id": ObjectId(product_id)}) # 查询商品       
        if product and product.get('stock', 0) >= quantity:                   # 执行库存扣减
            new_stock = product['stock'] - quantity
            products_collection.update_one( {"_id": ObjectId(product_id)}, {"$set": {"stock": new_stock}} )
            return jsonify({"available": True, "price": product.get('price', 0)}), 200       
        return jsonify({"available": False, "message": "库存不足"}), 200
    except Exception as e:
        return jsonify({"error": str(e)}), 500
# 5. 初始化数据功能(便于测试)
def init_db_data():
    """如果集合为空,插入示例数据"""
    if products_collection.count_documents({}) == 0:
        sample_products = [
            {"name": "华为手机", "price": 2999.00, "stock": 100, "specs": {"color": "黑色", "ram": "8GB"}},
            {"name": "vivo手机", "price": 2599.00, "stock": 50, "specs": {"color": "白色", "ram": "12GB"}},
            {"name": "Apple", "price": 1.2, "stock": 100} # 示例数据
        ]
        products_collection.insert_many(sample_products)
        print("数据库初始化完成,已插入示例商品。")
if __name__ == '__main__':   
    init_db_data()                     # 启动时初始化数据   
    app.run(port=5002, debug=True)     # 运行服务,端口设为5002

3.2 订单服务

订单服务是电商系统的核心,负责处理用户下单逻辑。在微服务架构中,它需协调库存与支付服务。

设计思路:订单服务作为协调者,通过HTTP 请求同步调用库存服务进行预扣减,遵循微服务间同步通信机制。

代码实现 (orderSvc.py):

python 复制代码
from flask import Flask, jsonify, request; import requests; from pymongo import MongoClient
app = Flask(__name__)
client = MongoClient('mongodb://localhost:27017/')  # 连接MongoDB
db = client['ecommerce_db']; orders_collection = db['orders']
@app.route('/orders', methods=['POST'])
def create_order():
    data = request.json; user_id = data.get('user_id')
    product_id = data.get('product_id'); quantity = data.get('quantity', 1)
    # 1. 调用库存服务检查库存,此处简化为直接调用,实际生产中应通过Nacos发现服务地址
    inventory_url = "http://localhost:5002/inventory/check" 
    inv_response = requests.post(inventory_url, json={"product_id": product_id, "quantity": quantity})    
    if inv_response.status_code != 200 or not inv_response.json().get('available'):
        return jsonify({"error": "库存不足或服务不可用"}), 400
    # 2. 创建订单 (简化逻辑,未包含支付调用)
    order_doc = { "user_id": user_id, "product_id": product_id,
        "quantity": quantity, "status": "CREATED",
        "total_price": inv_response.json().get('price', 0) * quantity
    }
    result = orders_collection.insert_one(order_doc)    
    return jsonify({"message": "订单创建成功", "order_id": str(result.inserted_id)}), 201
if __name__ == '__main__':
    app.run(port=5001)

3.3 支付服务

支付服务处理交易流程,通常涉及第三方支付接口对接。

设计思路:支付服务与订单服务解耦,通过API 交互。在复杂场景下,可使用RabbitMQ 或Kafka 实现异步通信,确保系统高可用。

代码实现 (paymentSvc.py):

python 复制代码
from flask import Flask, jsonify, request; from pymongo import MongoClient; from bson.objectid import ObjectId
app = Flask(__name__)
client = MongoClient('mongodb://localhost:27017/')
db = client['ecommerce_db']
payments_collection = db['payments']
@app.route('/pay', methods=['POST'])
def process_payment():
    data = request.json; order_id = data.get('order_id'); amount = data.get('amount')   
    payment_doc = {             # 模拟支付处理
        "order_id": order_id, "amount": amount,
        "status": "SUCCESS",           # 模拟支付成功
        "transaction_id": "TRANS123456"
    }
    payments_collection.insert_one(payment_doc)    
    # 实际场景中,支付成功后可能通过消息队列异步通知订单服务更新状态
    return jsonify({"message": "支付成功", "status": "SUCCESS"}), 200
if __name__ == '__main__':
    app.run(port=5003)

4 Nacos服务注册与发现集成

Nacos作为服务注册中心,能够动态管理服务实例地址,解决硬编码问题。虽然Nacos原生对Java生态支持最完善,但Python服务可通过其HTTP API进行注册。

设计思路:通过Nacos 的Open API ,Python 微服务可以实现服务注册与心跳保活,实现与Spring Cloud 生态的互联互通。

Python服务注册示例 (registerNacosAll.py):

python 复制代码
import requests, time, threading
NACOS_SERVER = "http://localhost:8848"; SERVICE_IP = "192.168.0.102"  # 本机IP
def register_service(svrNm, svrPt):
    url = f"{NACOS_SERVER}/nacos/v1/ns/instance"
    params = { "serviceName": svrNm, "ip": SERVICE_IP, "port": svrPt, "weight": 1.0, "enable": True,
        "healthy": True, "metadata": '{"preserved.register.source":"PYTHON"}' }
    try:
        response = requests.post(url, params=params)
        if response.status_code == 200:
            print(f"服务 {svrNm} 注册成功")
        else:
            print(f"注册失败: {response.text}")
    except Exception as e:
        print(f"连接Nacos失败: {e}")
def start_heartbeat(svrNm, svrPt):   # 启动发送心跳
    url = f"{NACOS_SERVER}/nacos/v1/ns/instance/beat"
    params = { "serviceName": svrNm, "ip": SERVICE_IP, "port": svrPt,
        "beat": f'{{"ip":"{SERVICE_IP}","port":{svrPt},"serviceName":"{svrNm}"}}' }
    try:
        requests.put(url, params=params)
    except:
        pass
def send_heartbeat():            # 发送心跳维持注册状态
    while True:
        start_heartbeat("orderSvc", "5001"); start_heartbeat("inventorySvc", "5002")
        start_heartbeat("paymentSvc", "5003"); start_heartbeat("gateway", "8080")
        time.sleep(5)
if __name__ == '__main__':
    register_service("orderSvc", "5001");  register_service("inventorySvc", "5002")
    register_service("paymentSvc", "5003");  register_service("gateway", "8080")    
    threading.Thread(target=send_heartbeat, daemon=True).start() # 启动心跳线程

5 MongoDB数据存储设计

MongoDB的文档模型非常适合电商场景,能够灵活存储商品的多变属性和订单的嵌套信息。

数据模型设计示例:

商品文档:

javascript 复制代码
{ "_id": ObjectId("..."), "name": "智能手机", "price": 2999.00, "stock": 100,
  "specs": { "color": "黑色", "ram": "8GB" }, // 动态属性
  "category": "电子产品"
}

订单文档:

javascript 复制代码
{ "_id": ObjectId("..."), "user_id": "user_123",
  "items": [ { "product_id": "prod_456", "quantity": 1, "price": 2999.00 } ],
  "total_amount": 2999.00, "status": "PAID", "create_time": ISODate("2026-04-09T10:00:00Z")
}

设计思路:MongoDB 支持嵌入式文档,避免了关系型数据库中多表关联查询的性能损耗,特别适合商品详情页等高频读取场景。

6 统一网关与前端页面设计

统一网关不仅作为系统的流量入口,还承担着静态资源服务器的角色,简化部署架构。

6.1 网关服务实现

使用Flask构建一个简单的API网关,负责路由转发和静态文件托管。

代码实现(gateway.py):

python 复制代码
from flask import Flask, request, jsonify, send_from_directory
import requests
app = Flask(__name__, static_folder='static')
SERVICE_MAP = {     # 简单的路由映射表(生产环境应从Nacos动态获取)
    "orderSvc": "http://localhost:5001", "paymentSvc": "http://localhost:5003",
    "inventorySvc": http://localhost:5002 }
@app.route('/api/<service_name>/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def proxy(service_name, path):
    target_url = SERVICE_MAP.get(service_name)
    if not target_url:
        return jsonify({"error": "Service not found"}), 404    
    url = f"{target_url}/{path}"
    resp = requests.request( method=request.method, url=url,
        headers={k: v for k, v in request.headers if k != 'Host'},
        data=request.get_data(), params=request.args )
    return (resp.content, resp.status_code, resp.headers.items())
# 托管前端页面
@app.route('/')
def index():
    return send_from_directory('static', 'index.html')
@app.route('/<path:filename>')
def static_files(filename):
    return send_from_directory('static', filename)
if __name__ == '__main__':
    app.run(port=8080)

6.2 前端页面设计

前端页面通过AJAX调用网关API,实现订单、支付、库存的交互。

HTML结构 (static/index.html):

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>电商微服务系统</title>
    <!--link rel="stylesheet" href="style.css"-->
    <script src="script.js"></script>
</head>
<body>
    <div class="container">
        <h1>电商订单系统</h1>
        <div class="section">
            <h2>商品列表 (库存服务)</h2>
            <div id="product-list"></div>
        </div>        
        <div class="section">
            <h2>创建订单</h2>
            <input type="text" id="user-id" placeholder="用户ID">
            <input type="text" id="product-id" placeholder="商品ID">
            <button onclick="createOrder()">下单</button>
        </div>        
        <div class="section">
            <h2>支付订单</h2>
            <input type="text" id="order-id" placeholder="订单ID">
            <button onclick="payOrder()">支付</button>
        </div>
    </div>
</body>
</html>

JavaScript交互 (static/script.js):

javascript 复制代码
const API_GATEWAY = 'http://localhost:8080/api'
async function loadProducts() {    // 加载商品列表
    const response = await fetch(`${API_GATEWAY}/inventorySvc/products`)
    const products = await response.json(); const listDiv = document.getElementById('product-list')
    listDiv.innerHTML = products.data.map(p => 
        `<div class="product">
            <span>${p.name} - 库存: ${p.stock}</span>
            <button onclick="document.getElementById('product-id').value='${p.id}'">选择</button>
        </div>`
    ).join('')
}
async function createOrder() {     // 创建订单
    const userId = document.getElementById('user-id').value
    const productId = document.getElementById('product-id').value    
    const response = await fetch(`${API_GATEWAY}/orderSvc/orders`, {
        method: 'POST', headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({user_id: userId, product_id: productId, quantity: 1})
    })
    const result = await response.json(); alert(result.message || result.error)
async function payOrder() {        // 支付订单
    const orderId = document.getElementById('order-id').value
    // 简化:假设支付金额固定
    const response = await fetch(`${API_GATEWAY}/paymentSvc/pay`, {
        method: 'POST', headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({order_id: orderId, amount: 100}) })
    const result = await response.json()
    alert(result.message)
}
window.onload = loadProducts       // 页面加载时初始化

7 部署运行测调试

7.1 前提准备

安装Python

安装MongoDB及其Navicat管理器

安装JDK1.8以上版本

安装并运行Nacos

7.2 核心依赖库清单

针对该电商微服务系统(订单、支付、库存、网关),需要在 requirements.txt 中声明以下核心依赖库。这些库覆盖了Web服务构建、数据库连接、服务注册发现及HTTP请求处理。

javascript 复制代码
# Web框架与网关基础
Flask==3.0.0          # 轻量级Web框架,用于构建各个微服务及网关
Werkzeug==3.0.1       # WSGI工具库,Flask的依赖
# 数据库连接
pymongo==4.6.0        # MongoDB的Python驱动,用于连接MongoDB数据库
# 服务注册与发现
nacos-sdk-python==0.1.12  # Nacos的Python客户端,用于服务注册与配置管理
# HTTP请求与服务间调用
requests==2.31.0      # 用于服务间(如订单调用库存)的HTTP请求
# 生产环境运行服务器 (可选,用于部署)
# gunicorn==21.2.0      # Linux/macOS下的WSGI HTTP服务器
# waitress==2.1.2       # Windows下的WSGI HTTP服务器,纯Python实现

Flask: 作为微服务的核心框架,负责路由分发与业务逻辑承载。

pymongo: 实现Python与MongoDB的交互,支持电商数据的文档存储。

nacos-sdk-python: 实现微服务向Nacos的注册、心跳发送及配置获取。

requests: 微服务架构中,服务间通信(如订单服务调用库存服务)的基石。

7.3 虚拟环境操作指南

在Windows环境下,为每个微服务创建独立的虚拟环境是避免依赖冲突的最佳实践。

1. 创建虚拟环境

Python 3.3+ 内置了 venv 模块,推荐在项目根目录下执行以下命令创建名为 venv 的虚拟环境:python -m venv venv。该命令会在当前目录下创建一个包含独立Python解释器和pip工具的文件夹。

2. 激活虚拟环境

创建完成后,必须激活环境才能在其中安装依赖。在Windows命令提示符(CMD)或PowerShell中,执行:

在CMD中,venv\Scripts\activate.bat。

在PowerShell中 (可能需要先执行 Set-ExecutionPolicy RemoteSigned),venv\Scripts\Activate.ps1。

激活成功后,终端提示符前会出现 (venv) 前缀,表明已进入隔离环境。

3. 安装依赖

在激活的虚拟环境中,使用pip安装 requirements.txt 中列出的依赖:pip install -r requirements.txt

此操作会将所有依赖安装到 venv\Lib\site-packages 目录下,与系统全局环境完全隔离。

4. 依赖管理与导出

在开发过程中,如果新增了依赖库,应及时更新 requirements.txt 文件,以便团队协作和部署:

pip freeze > requirements.txt。该命令会将当前环境所有包及其精确版本号写入文件,确保环境可复现。

7.4 部署运行与调试

1. 本地开发调试

在开发阶段,可以直接使用Flask内置服务器进行调试。

运行服务:确保虚拟环境已激活,运行服务脚本(如 orderSvc.py):python orderSvc.py

调试模式:在代码中设置 app.run(debug=True),开启调试模式后,代码修改会自动重载,便于快速迭代。

Nacos连接测试:启动服务后,观察控制台日志,确认服务是否成功注册到Nacos。若连接失败,请检查Nacos服务器地址是否包含完整协议与端口(如 http://127.0.0.1:8848)。

浏览器交互测试:

数据库管护:

2. 生产环境部署

Flask内置服务器仅适用于开发,生产环境需使用WSGI服务器。

Windows环境部署:推荐使用 waitress,它是纯Python实现,兼容性好。

javascript 复制代码
# 安装
pip install waitress
# 运行 (示例代码)
waitress-serve --port=5001 order_service:app

Docker容器化部署:为了进一步解决环境差异,推荐使用Docker进行部署。在构建镜像时,利用多阶段构建可以显著减小镜像体积。

javascript 复制代码
# 第一阶段:构建依赖
FROM python:3.9-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 第二阶段:运行环境
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "order_service.py"]

通过这种方式,镜像中仅包含运行必需的文件,避免了编译工具等临时文件的冗余。

8 总结

本文构建了一个基于Windows和Python的电商微服务原型系统。该系统利用Flask实现了业务逻辑的拆分,通过Nacos实现了服务的动态注册与发现,使用MongoDB灵活存储了电商复杂数据,并设计了统一网关来聚合API与托管前端。

系统核心优势:

  1. 解耦与独立扩展:订单、支付、库存服务可独立开发、部署和扩展,互不影响。
  2. 数据模型灵活:MongoDB完美适配商品规格多变、订单结构嵌套的电商特性,提升了开发效率。
  3. 统一接入与简化部署:网关层统一了流量入口,整合了前端静态资源服务,简化了运维复杂度。

在实际生产环境中,还需进一步完善服务间通信的容错机制(如熔断器)、分布式事务解决方案(如Saga模式)以及全面的监控体系(如Prometheus+Grafana)。

参考

腾迅云,通过 Python+Nacos实现微服务,细解微服务架构,https://cloud.tencent.com/developer/article/2426423,2024.6.10

阿里云,Python 高级编程与实战:构建微服务架构,https://developer.aliyun.com/article/1655626,2025.3.5

百度智能云,Python Web微服务架构:从理论到实战的全链路指南,https://cloud.baidu.com/article/3667660,2025.9.19

阿里云,Python进行微服务架构的设计与实现,https://developer.aliyun.com/article/1532877,2024.6.8

脚本之家,Python中微服务架构设计与实现详解,https://www.jb51.net/python/353876sre.htm,2025.11.28

相关推荐
kishu_iOS&AI2 小时前
机器学习 —— 线性回归(实例)
人工智能·python·机器学习·线性回归
架构师老Y2 小时前
007、微服务架构设计与服务拆分策略
python·微服务·架构
skilllite作者3 小时前
SkillLite 多入口架构实战:CLI / Python SDK / MCP / Desktop / Swarm 一页理清
开发语言·人工智能·python·安全·架构·rust·agentskills
ZC跨境爬虫3 小时前
批量爬取小说章节并优化排版(附完整可运行脚本)
前端·爬虫·python·自动化
ths5123 小时前
Python 正则表达式实战指南:从入门到精通(12 个高频案例)(三)
python·正则表达式
ZC跨境爬虫3 小时前
海南大学交友平台登录页开发实战day4(解决python传输并读取登录信息的问题)
开发语言·前端·python·flask·html
Wyawsl3 小时前
Python操作MySQL数据库
数据库·python·mysql
SuperEugene3 小时前
Python 异步 async/await:为什么 AI 框架大量使用?| 基础篇
开发语言·人工智能·python
SMF19193 小时前
【uv】Python包管理器uv安装和应用
开发语言·python·uv