当前位置:首页 > 随笔 > 正文内容

基于Flask与MySQL的微服务城市数据查询系统

访客 随笔 2026年7月5日 1

服务模块实现

1. 数据存储服务(端口 5001)

该服务负责与 MySQL 数据库交互,提供城市相关数据的读写功能。使用 SQLAlchemy 进行数据库操作,Flask 框架处理 HTTP 请求。

from flask import Flask, request, jsonify
from sqlalchemy import create_engine, text

server = Flask(__name__)
# 请替换为实际的数据库连接信息:用户名:密码@主机地址:端口/数据库名称
db_engine = create_engine("mysql+pymysql://root:your_password@localhost:3306/your_database")

@server.post("/fetch_value")
def fetch_value():
    city_name = request.json.get("city")
    with db_engine.connect() as conn:
        result = conn.execute(
            text("SELECT value FROM city_data WHERE city = :city"),
            {"city": city_name}
        ).fetchone()
    return jsonify({"value": result[0]}) if result else ("", 404)

@server.post("/update_value")
def update_value():
    data = request.json
    with db_engine.connect() as conn:
        conn.execute(
            text("REPLACE INTO city_data (city, value) VALUES (:city, :value)"),
            data
        )
        conn.commit()
    return "", 201

if __name__ == "__main__":
    server.run(port=5001, debug=False)

2. 业务逻辑服务(端口 5002)

此服务作为中间层,首先尝试从本地数据库获取城市高程数据;若未命中,则调用外部地理编码 API 获取,并将结果缓存至数据库。

from flask import Flask, request, jsonify
import requests

app = Flask(__name__)
database_url = "http://127.0.0.1:5001"
geocode_api = "https://geocoding-api.open-meteo.com/v1/search"

@app.post("/query_city_info")
def query_city_info():
    payload = request.json
    city = payload["city"]

    # 尝试从数据库读取缓存
    cache_response = requests.post(f"{database_url}/fetch_value", json={"city": city})
    if cache_response.status_code == 200:
        return jsonify(cache_response.json())

    # 缓存未命中,请求第三方接口
    api_response = requests.get(geocode_api, params={"name": city, "count": 1})
    results = api_response.json().get("results", [])
    if not results:
        return "", 404

    elevation_value = str(results[0]["elevation"])

    # 写入数据库以供后续使用
    requests.post(f"{database_url}/update_value", json={"city": city, "value": elevation_value})

    return jsonify({"value": elevation_value})

if __name__ == "__main__":
    app.run(port=5002, debug=False)

3. 网关接口服务(端口 5003)

对外暴露的统一入口,接收路径参数形式的城市名,转发请求至逻辑服务并格式化响应内容。

from flask import Flask
import requests

gateway = Flask(__name__)
logic_service = "http://127.0.0.1:5002"
output_field = "elevation"

@gateway.get("/gateway/<city_name>")
def handle_request(city_name):
    response = requests.post(
        f"{logic_service}/query_city_info",
        json={"city": city_name}
    )
    if response.status_code == 200:
        return f"The {output_field} of {city_name} is {response.json()['value']}.\n"
    return f"Error: {city_name} not found.\n", 404

if __name__ == "__main__":
    gateway.run(port=5003, debug=False)

部署流程说明

环境准备

  1. 在 PyCharm 中创建新项目。
  2. 通过终端安装所需依赖:
pip install flask sqlalchemy pymysql requests
  1. 在 MySQL 客户端执行建表语句(仅需一次):
CREATE TABLE city_data (
    city VARCHAR(50) PRIMARY KEY,
    value VARCHAR(50)
);

文件配置步骤

  1. database.py:新建文件并粘贴数据服务代码,修改连接字符串中的用户名、密码和数据库名。
  2. logic.py:新建文件并插入业务逻辑代码,无需额外修改。
  3. gateway.py:新建文件并填入网关代码,保持默认设置即可。

启动顺序要求

必须按照以下顺序依次启动服务,确保依赖关系正确:

  1. 启动数据库服务
    打开终端运行:python database.py
    确认输出包含 * Running on http://127.0.0.1:5001
  2. 启动逻辑处理服务
    另开终端执行:python logic.py
    等待服务监听在 5002 端口。
  3. 启动网关服务
    再开启一个终端窗口运行:python gateway.py
    验证其已在 5003 端口就绪。

功能测试方法

服务全部启动后,在终端中执行以下命令进行验证:

curl http://127.0.0.1:5003/gateway/Shanghai

预期返回示例:

The elevation of Shanghai is 4.

再次请求相同城市时,应能从数据库快速响应,体现缓存机制生效。

相关文章

可以按小时收费的VPS

很多 VPS 提供商都支持 按小时计费(hourly billing),想短期试用 / 临时搭建节点、测试网络、短期项目等场景非常合适。下面是当前最主流且靠谱的按小时 VPS 选项,分别按不同需求场景整理: 1. Vultr(全球节点,包括日本) 按小时计费 可选机房:东京 / 大阪 / 洛杉矶 / 法兰克福 / 伦敦 … 支持 PayPal(部分情况),但更常用信用卡/PayPal+卡价格参考$...

在 iPhone 上下载国外App

地区/国家限制App Store 会根据 Apple ID 的国家或地区限制应用下载。如果你的 Apple ID 绑定的是中国大陆,就可能无法下载 OpenAI 官方的 ChatGPT 应用,因为它在大陆 App Store 不上架。解决办法:换成美国、加拿大、香港等地区的 Apple ID。或者在现有 Apple ID 上更改地区。注册一个国外 Apple ID(推荐)比如注册 美国区 Appl...

Node.js 中的异步编程:回调与 Promise

Node.js 是一个基于 JavaScript 构建的单线程、非阻塞运行环境,它通过异步编程机制来高效处理多个操作。在执行如文件读取、API 请求或数据库查询等任务时,Node.js 不会等待这些操作完成,而是使用回调函数和 Promise 来避免阻塞主线程。 回调方式实现异步 那么当异步操作完成后,Node.js 如何知道接下来要做什么呢?这就要用到 回调函数(callback)。 回调本质上...

Selenium自动化测试入门指南

Selenium自动化测试入门指南

什么是自动化测试? 自动化测试是指利用软件工具自动执行测试用例,模拟用户操作,如打开网页、点击链接、输入文本等,并验证结果是否符合预期。 其主要优点包括: 大幅减少人工成本 测试速度快 可以在非工作时间运行 支持持续集成和交付 然而,它也存在一些局限性,例如开发成本较高、不适合快速变化的项目、依赖稳定的UI界面等。 自动化测试的应用条件 适合引入自动化测试的情况包括: 手动测试耗时且需要大量...

MariaDB Galera集群故障快速恢复指南

OpenStack控制节点采用三节点MariaDB Galera集群架构。当数据库集群因故障重启时,有时会出现Galera集群无法正常启动的问题。虽然有多种方法可以恢复数据库服务,但如何实现快速启动同时确保数据完整性呢? 通过分析日志发现,MariaDB Galera集群节点宕机时会在日志中输出以下信息: [Note] WSREP: 新集群视图:全局状态: 874d8e7e-5980-11e8-8...

Android 中 EventBus 的通信机制与实现原理深度解析

EventBus 核心设计思想 EventBus 是一个基于观察者模式的事件总线框架,广泛应用于 Android 平台以实现组件解耦。它通过中心化的消息分发机制,使不同层级、不同线程的对象能够以"发布-订阅"方式通信,避免了传统接口回调或广播带来的强依赖问题。 核心角色说明 事件(Event):任意 Java 对象,作为数据载体,如网络状态变更通知、用户登录信息等。 发布者(Publi...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。