用FastAPI实现微服务API网关
创作时间:
作者:
@小白创作中心
用FastAPI实现微服务API网关
引用
1
来源
1.
https://www.cnblogs.com/liupras/articles/18545802
本文将介绍如何使用FastAPI实现一个简单的API网关。通过本文,读者将学习到如何使用同步和异步两种方式实现HTTP请求转发,并了解如何测试网关功能。
本文阐述了基于FastAPI实现一个API网关的详细步骤。这样未来可以不断的在服务端像搭积木一样添加各种服务。 我们即将实现下面的简单的微服务架构,目前它只实现了请求转发功能。
代码实现
下面使用FastAPI的同步和异步两种方式实现http请求转发。
其中services是在本网关中定义的服务名称,path是服务的路径,网关将把这个路径转发到后端服务。
例如:前端使用URL:http://127.0.0.1:8000/translation/trans/v1访问本网关时,@api_route将会把server的值填充为translation,将path的值填充为trans/v1,这样API网关调用的后端服务的API地址为:http://127.0.0.1:5001/trans/v1。
同步转发
from fastapi import FastAPI, Request,HTTPException
import requests
# 创建一个FastAPI实例
app = FastAPI()
# 定义服务
services = {
"translation": "http://127.0.0.1:5001",
# 可以在这里添加其它服务地址
}
'''
services的key是服务名称,客户端在请求时传入服务名称,本网关再根据服务名称找到对应的服务地址
'''
# 接收客户端请求并转发到后端服务
@app.api_route("/{service}/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"])
async def gateway(service: str, path: str, request: Request):
'''
!注意:网关并未将header转发给后端服务,这样比较简单。
'''
if service not in services:
raise HTTPException(status_code=401, detail="未找到该服务")
# 根据服务名称找到对应的服务地址
service_url = services[service]
body = await request.json() if request.method in ["POST", "PUT", "PATCH"] else None
url = f"{service_url}/{path}"
# 同步调用,这里会阻塞
response = requests.post(url, json = body)
return response.json()
# 启动网关
if __name__ == "__main__":
import uvicorn
# 交互式API文档地址:
# http://127.0.0.1:8000/docs/
# http://127.0.0.1:8000/redoc/
uvicorn.run(app, host="0.0.0.0", port=8000)
异步转发
from fastapi import FastAPI, Request,HTTPException
import httpx
# 定义超时时间,单位:秒
time_out = 30
# 创建一个FastAPI实例
app = FastAPI()
# 定义服务
services = {
"translation": "http://127.0.0.1:5001",
# 可以在这里添加其它服务地址
}
'''
services的key是服务名称,客户端在请求时传入服务名称,本网关再根据服务名称找到对应的服务地址
'''
# 接收客户端请求并转发到后端服务
@app.api_route("/{service}/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"])
async def gateway(service: str, path: str, request: Request):
'''
!注意:网关并未将header转发给后端服务,这样比较简单。
'''
if service not in services:
raise HTTPException(status_code=401, detail="未找到该服务")
#headers = dict(request.headers)
# 从客户端请求中获取数据
client_request_data = await request.json()
service_url = services[service]
url = f"{service_url}/{path}"
# 使用 httpx 将请求转发到后端服务,非阻塞,不过在我的配置一般的开发机上没有发现和阻塞式调用在性能上有多少区别。
async with httpx.AsyncClient() as client:
'''
!注意:httpx.AsyncClient默认的timeout为5秒,在调用基于大模型的后端服务时经常超时,所以这里设置超时时间为30秒
'''
response = await client.post(url=url, json=client_request_data,timeout=time_out)
#print(response)
return response.json()
# 启动网关
if __name__ == "__main__":
import uvicorn
# 交互式API文档地址:
# http://127.0.0.1:8000/docs/
# http://127.0.0.1:8000/redoc/
uvicorn.run(app, host="0.0.0.0", port=8000)
测试网关
1. 启动翻译服务
在开发环境中,可以用以下命令启动翻译服务:
# 激活虚拟环境
.venv\Scripts\activate
# 启动翻译服务
python "06-2.langchain api with fastapi.py"
2. 启动网关
# 激活虚拟环境
.venv\Scripts\activate
# 启动网关服务
python "07-1.fastapi gateway.py"
3. 测试网关
可以使用Apifox或其他API测试工具发送请求进行测试。
热门推荐
错误代码1-错误代码101
非遗传承人王学勤的年画“生意经”
西辽的历史:从耶律大石到蒙古帝国的崛起
古韵新声:中国传统音乐研究的新发现、跨学科与世界性
朱元璋可称为千古大帝,但是你知道朱元璋的功绩有哪些吗?
用力过猛只会适得其反?掌握人生的正确打开方式
如何拍摄一部车和自然的大片
欧冠附加赛:皇马、拜仁、巴黎等豪强客场告捷,仅一冷门出现
桑螵蛸的药用价值
Nature和Science的多种获取途径
冲锋衣如何正确清洗与维护:步骤详解及注意事项总结
Excel成绩等级考核计算方法详解
霍金名言语录(中英文对照)
怎么看自己五行属什么
关于徽州古牌坊的建筑故事
百川智能最新医学大模型论文:用先进患者模拟器探索医疗"问诊-诊疗"关系
从传奇到传奇,最独特JDM之RX-7,20年后依旧超前
合同迟延履行的法律责任及违约条款撰写指南
经济日报:理性看待富士康的出与进
电动车最长能骑多少年?多久换一次最划算?
"主升浪"启动前,成交量必然有此盘面特征,万次交易从不例外
本田雅阁行人保护装置详解:工作原理与局限性
揭秘黄瓜命名之谜:为何绿色的瓜却叫“黄”瓜?
广州全力打造美丽全运 6个场馆完成绿色低碳技术设计,开展“无废全运”行动
股票融资的双刃剑:资本流动、风险评估与市场前景深入解析
踮脚尖的坏处是什么
Web3时代的数字身份认证:安全性与隐私保护探讨
生物识别技术:数字身份认证的前沿
我国游戏行业分析:销售收入与用户规模创新高 3A、AI游戏、小游戏、多端布局
智慧养鸡场:鸡舍环境监测与智慧化控制系统