用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测试工具发送请求进行测试。
热门推荐
77,640欧元!迈克尔·杰克逊标志性帽子再创拍卖新高
香煎秋刀鱼:这道“脑黄金”海鱼的美味烹饪指南
告别失眠!中医古法助你一夜好眠,睡到自然醒
小型观赏鱼的初级饲养指南
“小狮女”林熙悦的家乡揭阳古城旅游攻略:八大景点详解及实用信息
青狮跃动耀古城 揭阳非遗展风采
苹果ID注册避坑指南:资深顾问亲授秘籍!
感悟先哲智慧,照亮人生之路
一日三餐,怎么吃更健康?
早上喝白开水可以缓解便秘吗 早上喝白开水有什么好处
汤姆·费尔顿:舞台上的德拉科·马尔福
海南情侣旅游预算指南:如何合理规划旅行花销与开销明细
从原著到银幕:德拉科·马尔福的角色蜕变
德拉科的觉醒:从假性自我到真我认同
天堂鸟养殖全攻略,新手必看的养护秘籍!
客厅植物摆放:好看又好养
《姥姥的外孙》:一部打动人心的泰国亲情电影
云南山茶花:城市绿化的“花中娇子”
乾隆皇帝的秘密:普陀宗乘之庙的艺术设计
冬日山茶花摄影指南:捕捉最美瞬间!
冬日赏花指南:山茶花的诗意之美
冬日温暖:用山茶花装点你的家
普陀宗乘之庙:世界遗产背后的历史传奇
承德的小布达拉宫:普陀宗乘之庙探秘
Windows 11麦克风问题终极指南:从硬件检查到系统设置
专业歌手教你保养麦克风,这些小技巧你get了吗?
世界上最孤独的国家,1600公里内没有邻国,总人口的5%都是华人
7.7万村官被查背后:村支书权力滥用之谜
搬家时用绑带固定物品的小窍门
明天就搬过去?这份极简搬家指南请收好!