Python + Sanic框架

Sanic 是一个基于 Python 的异步 Web 框架,设计目标是 高性能、异步非阻塞,类似于 Flask,但原生支持 async/await。它常用于需要高并发、低延迟的 Web 服务或 API 后端。


1. 安装

1
pip install sanic

2. 基础示例

1
2
3
4
5
6
7
8
9
10
11
from sanic import Sanic
from sanic.response import json

app = Sanic("MyApp") # 创建应用实例

@app.route("/")
async def index(request):
return json({"message": "Hello, Sanic!"})

if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
  • async def 支持异步请求处理
  • json() 快速返回 JSON 数据
  • app.run() 内部使用 uvloop + asyncio 提升性能

3. 路由与请求

1
2
3
4
5
6
7
8
@app.route("/hello/<name>")
async def hello(request, name):
return json({"hello": name})

@app.post("/data")
async def data_handler(request):
data = request.json
return json({"received": data})
  • 路由支持动态参数 <name>
  • 支持 GETPOST 等 HTTP 方法
  • 可以直接通过 request.json 获取 JSON body

4. 中间件(Middleware)

中间件用于请求和响应的统一处理,例如日志、认证等:

1
2
3
4
5
6
7
@app.middleware("request")
async def print_request(request):
print(f"Request path: {request.path}")

@app.middleware("response")
async def add_custom_header(request, response):
response.headers["X-Custom-Header"] = "Sanic"

5. 静态文件

1
app.static("/static", "./static")  # URL /static 映射到 ./static 文件夹

6. 异步任务和后台任务

1
2
3
4
5
6
7
8
@app.listener("after_server_start")
async def setup_background_tasks(app, loop):
app.add_task(background_task())

async def background_task():
while True:
print("Running background task")
await asyncio.sleep(5)

7. 配置和优化

  • Keep-Alive 超时(你的关注点):
1
2
3
4
app.run(host="0.0.0.0", port=8000, 
access_log=True,
backlog=100,
keep_alive=5) # keep-alive 超时,单位秒

keep_alive 控制 HTTP 持久连接的空闲超时,默认值通常是 5 秒。它是 HTTP 层检测,不是 TCP 层的 tcp_keepalive,TCP 层的连接可能更久。

  • Worker & Concurrency
1
app.run(workers=4)  # 多进程模式
  • Max Request Size
1
app.config.REQUEST_MAX_SIZE = 10 * 1024 * 1024  # 10MB

8. 注意点

  1. 异步优先:Sanic 推荐使用 async/await,阻塞操作需用线程池或异步库。
  2. 性能优化:在生产环境推荐配合 Gunicorn + uvloop
  3. 中间件顺序requestroute handlerresponse
  4. Keep-Alive vs TCP KeepAlive
    • keep_alive 是 HTTP 层空闲连接检测
    • TCP KeepAlive 是内核层,配置 net.ipv4.tcp_keepalive_* 参数

说明:

  1. Sanic Keep-Alive
    • 单位秒(默认 5 秒)
    • HTTP 层主动关闭空闲连接
  2. TCP KeepAlive
    • 单位秒(默认 2 小时开始探测)
    • 内核层检测死连接,不影响活跃 HTTP 请求
  3. 两者互相独立,但 TCP KeepAlive 可以作为额外保险,清理异常死连接。

9.修改默认KEEP_ALIVE_TIMEOUT

Sanic 有定义空闲连接超时(keep-alive 超时),默认是 60 秒

  • 参数名字:KEEP_ALIVE_TIMEOUT
  • 默认值:5/60 秒(不通版本默认值不一样)
  • 表示:在客户端和服务端建立连接后,如果空闲(无请求)超过该时间,Sanic 会主动关闭连接。
  1. 环境变量
1
SANIC_KEEP_ALIVE_TIMEOUT=30
  1. 代码设置(启动 app 时传入参数):
1
2
app = Sanic("semantic_search_engine")
app.config.KEEP_ALIVE_TIMEOUT = 30 # 单位秒

延伸:

  • KEEP_ALIVE:是否启用 HTTP keep-alive(默认 True)
  • KEEP_ALIVE_TIMEOUT:空闲连接多久关闭(默认 60s)
  • GRACEFUL_SHUTDOWN_TIMEOUT:优雅关停时的超时(默认 15s)

1.Sanic 默认值

Sanic 的 KEEP_ALIVE_TIMEOUT 默认值其实是 **5 秒**,不是 60 秒。我前面提到 60 秒是我在旧版本里看到的配置,现代 Sanic(>=21.x)实际是 5 秒。

  • 对应源码位置:sanic/server/protocols/http.py
  • 默认常量:DEFAULT_KEEP_ALIVE_TIMEOUT = 5

所以,如果你没有显式设置,空闲的 HTTP 连接会在 5 秒 后被关闭。


2.是 HTTP 层还是 TCP 层?

✅ 这是 HTTP 层的超时,而不是 TCP 层的。

  • Sanic 会在 HTTP Keep-Alive 队列里检查连接是否空闲超过 KEEP_ALIVE_TIMEOUT,如果超过就主动关闭 TCP 连接。
  • TCP 本身也有类似 tcp_keepalive_timetcp_fin_timeout 的参数,但 Sanic 不直接受它控制;Sanic 是应用层逻辑来主动关闭 socket。

3.举例

1
2
app = Sanic("semantic_search_engine")
app.config.KEEP_ALIVE_TIMEOUT = 10 # HTTP 空闲连接 10 秒后关闭
  • 客户端在请求结束后,如果 10 秒内不再发送新的请求,Sanic 就会关闭这个 TCP 连接。
  • 如果 TCP 层设置了更短或更长的 tcp_keepalive,可能会影响 FIN/ACK 行为,但 Sanic 的主动关闭在应用层优先执行。