Django性能的继续优化
背景
前一篇《Django的认证性能优化》讲到对Django认证性能进行优化,优化之后发现还不够,还是比较慢。于是进一步测试,找出慢的根源究竟在哪里。经过测试发现,Django Rest framework在鉴权那里也是比较慢的。
理解设置与APIView的关系
在django项目的设置里面,也就是如下所示:
1 | # 以下代码取自官网示例: |
以上这几个地方的设置都要小心,因为一个是认证的设置,一个是鉴权的设置,一个是速率的设置。并且这都是全局的设置,也就是说如果在某个APIView里面,没有特殊指定,那么这个API就会按照全局的方式提供服务。
因为一般自定义的view代码采用的是class-based-view,也就是说继承至APIView类,如下图所示:
1 | # 以下代码取自官网 |
接着看官网的APIView类定义如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 以下代码取自官网
class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
def as_view(cls, **initkwargs):
return csrf_exempt(view)
上面的这段代码就决定了一般的APIView会按照全局设置进行服务。
理解速率限制与后端数据库之间的关系
在开源的redis-django项目中,有如下的设置:1
2
3
4
5
6
7
8
9
10# 代码取自官网
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
...
"OPTIONS": {
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
}
}
}
同样,这段代码应该被配置在django的设置文件中,它指定的是Django采用redis作为cache数据库,同时配置连接池的最大连接数为100。
当进行了如上两项配置之后,即配置了速率限制与后端数据库之后,当请求并发量增大的时候(大于100),会报redis连接错误,这是由于我们的连接池中配置的最大连接数为100,这100个连接已经被用完了,但是还有请求过来,发现没有可用的连接可用,因此会稳定复现redis连接的错误。
这说明什么?说明我们的速率限制是基于或者依赖我们配置的后端数据库的,也就是说只要当我们设置了cache,来一条请求,会有与redis的交互。
继续优化
基于以上的理解,当我们需要高性能的Saas服务的时候,需要关掉这个速率限制的设置,同时自定义我们自己的认证和鉴权类。下面是定义自己鉴权类的代码简化示例:
1 | # 代码简化示例 |
使用的时候,如下示例所示:
1 | # 以下代码仅为示例 |
结束
综合这两篇,一共做了如下三方面的工作之后:
- 自定义认证类
- 自定义鉴权类
- 取消速率限制
基于Django的Saas化服务,性能至少会提高三倍以上。
【版权声明】
本文首发于戚名钰的博客,欢迎转载,但是必须保留本文的署名戚名钰(包含链接)。如您有任何商业合作或者授权方面的协商,请给我留言:qimingyu.security@foxmail.com
欢迎关注我的微信公众号:科技锐新