Sanic 是一个基于 Python 的异步 Web 框架,设计目标是 高性能、异步非阻塞,类似于 Flask,但原生支持 async/await。它常用于需要高并发、低延迟的 Web 服务或 API 后端。
1. 安装
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>
- 支持
GET、POST 等 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")
|
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. 配置和优化
1 2 3 4
| app.run(host="0.0.0.0", port=8000, access_log=True, backlog=100, keep_alive=5)
|
keep_alive 控制 HTTP 持久连接的空闲超时,默认值通常是 5 秒。它是 HTTP 层检测,不是 TCP 层的 tcp_keepalive,TCP 层的连接可能更久。
1
| app.config.REQUEST_MAX_SIZE = 10 * 1024 * 1024
|
8. 注意点
- 异步优先:Sanic 推荐使用
async/await,阻塞操作需用线程池或异步库。
- 性能优化:在生产环境推荐配合 Gunicorn + uvloop。
- 中间件顺序:
request → route handler → response。
- Keep-Alive vs TCP KeepAlive:
keep_alive 是 HTTP 层空闲连接检测
- TCP KeepAlive 是内核层,配置
net.ipv4.tcp_keepalive_* 参数
说明:
- Sanic Keep-Alive:
- 单位秒(默认 5 秒)
- HTTP 层主动关闭空闲连接
- TCP KeepAlive:
- 单位秒(默认 2 小时开始探测)
- 内核层检测死连接,不影响活跃 HTTP 请求
- 两者互相独立,但 TCP KeepAlive 可以作为额外保险,清理异常死连接。
9.修改默认KEEP_ALIVE_TIMEOUT
✅ Sanic 有定义空闲连接超时(keep-alive 超时),默认是 60 秒。
- 参数名字:
KEEP_ALIVE_TIMEOUT
- 默认值:5/60 秒(不通版本默认值不一样)
- 表示:在客户端和服务端建立连接后,如果空闲(无请求)超过该时间,Sanic 会主动关闭连接。
- 环境变量
1
| SANIC_KEEP_ALIVE_TIMEOUT=30
|
- 代码设置(启动 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_time、tcp_fin_timeout 的参数,但 Sanic 不直接受它控制;Sanic 是应用层逻辑来主动关闭 socket。
3.举例
1 2
| app = Sanic("semantic_search_engine") app.config.KEEP_ALIVE_TIMEOUT = 10
|
- 客户端在请求结束后,如果 10 秒内不再发送新的请求,Sanic 就会关闭这个 TCP 连接。
- 如果 TCP 层设置了更短或更长的
tcp_keepalive,可能会影响 FIN/ACK 行为,但 Sanic 的主动关闭在应用层优先执行。