Django设置全局对象,仅在启动时初始化⼀次.
2018.10.23
github上的项⽬可以实现Django中的单例模式.
通过:
1. 维护该模型的表中只有⼀⾏,保证对象全局⼀致;
2. 配合实现cache机制,让对象常驻内存.
结合这两点实现我们要的全局对象的效果, 并且在django-models之内,便于管理.
2018.10.10
部署到uwsgi时默认配置也不会有问题, 多进程各请求可以访问共享数据.
只需考虑并发锁.
与uwsgi的⼯程加载模式有关.
lazy选项默认为false.
uwsgi将django项⽬读取⼀次之后,在master进程完成初始化, 包括我们设置的全局变量的代码块. 之后获取request直接在master中进⾏fork().这也是所谓preforking模式, 可以保证运⾏过程当中不需要再从磁盘读取代码⽂件.
lazy设置为true就会导致共享变量在各个进程当中存在多个独⽴副本的问题. 经过测试, 当请求频率变⾼, uwsgi将请求分配到其他进程时, 访问的共享变量就开始不⼀致.
2018.09.28
单进程的本地测试时没有问题,部署到uwsgi时,当uwsgi使⽤master-worker的⽅式启动多个Django Application,各进程之间互相隔离,将全局变量写在view当中会导致各进程间不⼀致。
解决⽅法:
依赖进程外的持久化⽅案,即数据库或内存数据库。
最佳的实践是使⽤Redis作为Django的cache,再利⽤django对cache的接⼝实现便利的redis操作。
但同时要注意,多进程并发操作redis会带来⼀致性问题。
解决⽅法:
1. 尽可能使⽤Redis⾃带原⼦操作,如incr,decr等实现值的⾃增;
2. 各个进程在操作之前使⽤SETNX加锁。
原⽂
解决问题:
HTTP是⽆状态的,但是我们希望记录⼀些前后多次requests中有关联的数据, ⼜或许在计算密集的模块有些只读模型数据只需要保存⼀份,供多次请求读取,⽽不需要每次请求都重新读取⼀遍.
实现⽅法:
将共享python变量写在views函数之外,view函数内通过global访问.
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
num =0
print("loading once")
python单例模式def check(request):
global num
num +=1
return HttpResponse("complete with "+str(num))
效果
从输出可以看到"loading once",num变量仅加载了⼀次,之后处理多次请求.
响应输出:
⽣产环境
使⽤python pickle完成object的序列化, 再⽤memcached和redis保存⼤⽂件数据更可靠, 每次请求从memcached或redis当中获取.实际⽤途
⽬标:
服务器加载pyltp⾃然语⾔处理框架, 暴露REST API给客户端, 客户端发送要查询的⽂本,响应给出处理结果.
问题:
ltp处理依赖模型, 如分词器需要加载对应分词模型数据, 数据只读, 只需⼀次加载,不需要多次为每次请求重复加载.全局变量实践:
在view函数以外,服务器启动时完成分词器的初始化,每个视图当中使⽤global获取全局对象.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论