Last updated
Last updated
中间件可以理解为是介于 HttpRequest 与 HttpResponse 处理之间的一道处理过程。
中间件一般对全局有效的,可以在全局范围内改变输入和输出结果,因此需要谨慎使用,否则不仅会造成难以定位的错误,而且可能会影响整体性能。
如果想要修改 HttpRequest 或者 HttpResponse,就可以通过中间件来实现。
登陆认证:在中间件中加入登陆认证,所有请求就自动拥有登陆认证,如果需要放开部分路由,只需要特殊处理就可以了。
流量统计:可以针对一些渲染页面统计访问流量。
恶意请求拦截:统计 IP 请求次数,可以进行频次限制或者封禁 IP。
需求分析重点是需求
2.3.1.1 Bottle 插件说明
bottle 是通过插件丰富装饰器,进而增加 Handler 的功能
2.3.1.2 Bottle 内置插件
bottle 中每个路由规则都会创建一个 Route 对象,主要包括了 path,method 和 callback 三个部分。
2.3.2.1 Django 中间件使用
当 Django 处理一个 Request 的过程是首先通过中间件,然后再通过默认的 URL 方式进行的
在 django 项目的 settings 模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件
中间件中可以定义五个方法
Request 预处理函数:process_request(self, request)
View 预处理函数:process_view(self, request, callback, callback_args,callback_kwargs)
Template 模版渲染函数:process_template_response() (不常用)
Exception 后处理函数:process_exception(self, request, exception)(不常用)
Response 后处理函数:process_response(self, request, response)
以上方法的返回值可以是 None 或一个 HttpResponse 对象,如果是 None,则继续按照 django 定义的规则向后继续执行,如果是 HttpResponse 对象,则直接将该对象返回给用户。
前二个方法是从前往后执行的,后三个方法是从后往前执行的,具体流程如下:
2.3.2.2 Django 中间件请求流程
2.3.2.2.1 Django WSGI 入口
2.3.2.2.2 Django middleware 执行顺序
从 django1.10 版本起,middleware 是继承自 django/utils/deprecation.py 中的 MiddlewareMixin 类,这是一个可调用的对象,其代码如下:
process_request(request)
process_response(request,response)
process_exception(request,response)
2.3.2.3 Django 的中间件与 Python 的装饰器
装饰器是 Python 的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,再执行该函数
联系:中间件是利用装饰器原理实现的,具体通过两个函数嵌套、或通过改写类中的__ call __方法实现一个装饰器功能。使之过来的 Request 的请求,先到 call 方法中进行处理。配置中间件,实现过程干预。 区别:一个是 Python 的语法功能,一个是 Django 框架自带的轻量级插件系统。
2.3.2.4 Django middleware 例子
https://flask.palletsprojects.com/en/2.0.x/quickstart/?highlight=middle#hooking-in-wsgi-middleware
2.3.3.1 例子
middleware.py
server.py
2.3.3.2 源码解读
厂内大部分使用 Gin 框架
2.3.4.1 全局中间件
2.3.4.2 Next() 方法
2.3.4.3 局部中间件
2.3.4.4 中间件推荐
https://github.com/gin-gonic/contrib/blob/master/README.md
RestGate - REST API 端点的安全身份验证
staticbin - 用于从二进制数据提供静态文件的中间件 / 处理程序
gin-cors - CORS 杜松子酒的官方中间件
gin-csrf - CSRF 保护
gin-health - 通过 gocraft/health 报告的中间件
gin-merry - 带有上下文的漂亮 打印 错误的中间件
gin-revision - 用于 Gin 框架的修订中间件
gin-jwt - 用于 Gin 框架的 JWT 中间件
gin-sessions - 基于 mongodb 和 mysql 的会话中间件
gin-location - 用于公开服务器的主机名和方案的中间件
gin-nice-recovery - 紧急恢复中间件,可让您构建更好的用户体验
gin-limit - 限制同时请求;可以帮助增加交通流量
gin-limit-by-key - 一种内存中的中间件,用于通过自定义键和速率限制访问速率。
ez-gin-template - gin 简单模板包装
gin-hydra - gin 中间件 Hydra
gin-glog - 旨在替代 Gin 的默认日志
gin-gomonitor - 用于通过 Go-Monitor 公开指标
gin-oauth2 - 用于 OAuth2
static gin 框架的替代静态资产处理程序。
xss-mw - XssMw 是一种中间件,旨在从用户提交的输入中“自动删除 XSS”
gin-helmet - 简单的安全中间件集合。
gin-jwt-session - 提供 JWT / Session / Flash 的中间件,易于使用,同时还提供必要的调整选项。也提供样品。
gin-template - 用于 gin 框架的 html / template 易于使用。
gin-redis-ip-limiter - 基于 IP 地址的请求限制器。它可以与 redis 和滑动窗口机制一起使用。
gin-method-override -
_method
受 Ruby 的同名机架启发而被 POST 形式参数覆盖的方法gin-access-limit - limit- 通过指定允许的源 CIDR 表示法的访问控制中间件。
gin-session - 用于 Gin 的 Session 中间件
gin-stats - 轻量级和有用的请求指标中间件
gin-statsd - 向 statsd 守护进程报告的 Gin 中间件
gin-health-check - check- 用于 Gin 的健康检查中间件
gin-session-middleware - 一个有效,安全且易于使用的 Go Session 库。
ginception - 漂亮的例外页面
gin-inspector - 用于调查 http 请求的 Gin 中间件。
gin-dump - Gin 中间件 / 处理程序,用于转储请求和响应的标头 / 正文。对调试应用程序非常有帮助。
go-gin-prometheus - Gin Prometheus metrics exporter
ginprom - Gin 的 Prometheus 指标导出器
gin-go-metrics - Gin middleware to gather and store metrics using rcrowley/go-metrics
ginrpc - Gin 中间件 / 处理器自动绑定工具。通过像 beego 这样的注释路线来支持对象注册
st2/st2common/st2common/middleware/request_id.py
总体设计重点是设计与折衷
一般来说会有个简单的架构图,并配以文字对架构进行简要说明;
架构图中如果有很多模块,需要对各个模块的功能进行简要介绍;
设计与折衷是总体设计中最重要的部分;
方案一:wsgi application(flask)
Butterfly 不仅需要支持 Http 请求,还需要支持异步处理 MQ 的请求,故仅在 wsgi application 处做过滤不可行
方案二:protocol_json
折衷考虑放到 protocol_json 处, 即方案二
方案一:创建 protocol_json 时,通过参数进行传入 middleware
方案二:protocol_json 改造, 通过类 flask 方式进行加载
app.wsgi_app = middleware(app.wsgi_app)
方案二对代码侵入性较小,故使用方案二
详细设计重点在“详细”
butterfly/wsgiapp.py
启动时 route 从 handlers
目录中加载 middleware 模块, 若加载成功则自动添加 middleware
无
/handlers/middleware.py
(有了数据库 + 接口 + 流程,别的同学拿到详设文档,基本也能够搞定了)
简要的交互可用文字说明,复杂的交互建议使用流程图,交互图或其他图形进行说明
4.2.4.1 wrapt
使用装饰器时 functools.wraps() 可以帮我们解决__name__和__doc__ 的问题,但对于获取函数的参数(argument)或源代码(source code)则束手无策
butterfly 在自动生成路由时,需要使用到 __name__
和获取函数参数 (argument), 所以需要用到如下 wrapt
4.2.4.1.1 不带参数的装饰器
wrapt 使用
4.2.4.1.2 带参数的装饰器
4.2.4.2 示例
4.2.4.2.1 关闭 db 连接 -- (使用数据库时,建议使用自动重连配置,则无需再添加关闭 db 连接配置)
4.2.4.2.2 检查是否已登录 -- (使用『火眼』组件,无需通过装饰器再实现)