当前位置: 首页 > 网络应用技术

如何测量Django并发量(Django太大,量异常)

时间:2023-03-08 11:55:35 网络应用技术

  指南:本文的首席执行官注释将介绍如何衡量Django并发金额的相关内容。我希望这对每个人都会有所帮助。让我们来看看。

  最近,在Django模型中,通过首页上的表单提交了小小的需求

  (帖子),分析背景中帖子的参数,通过模型查询mysql,处理数据结构,然后返回前台页面以示出。

  QuerySet功能不熟悉,在测试过程中发现了许多问题。

  一开始我没有遇到任何问题。让我们举个例子。模型中有一只员工手表

  员工,在相应的表结构中,邮列列代表员工职位,前台帖子的参数被赋予姿势,加上进入时间,出发时间,查询操作通过了通过查询操作的通行

  Models.Filter(posity = params)已完成,并且获得的员工信息内容简单地由QuerySet和当前显示页面计算,以及每个页面显示的记录数量。

  忘记它,返回首页进行渲染显示。编码如下:

  1 def get_employees(位置,开始,结束):

  2返回员工。过滤器(posity__in =姿势)

  3

  4

  5 @login_required

  6 def show(请求):

  7如果没有价值(请求):

  8返回render_to_response('none.html',

  9 Context_Instance = requestContext(请求,'msg':'params error')

  10)

  11

  12位置= request.request.get('posity')

  13 time_range = request.request.get.get('time')

  14开始,end = time_range [0],time_range [1]

  15

  16 num_per_page,page_num = get_num(请求)

  17 all_empoloyees = get_employees(姿势,开始,结束)

  18#根据当前页面和每个页面显示的记录数量,获取正确的记录

  19员工=员工_events [(page_num-1)*num_per_page:page_num*num_per_page]

  20

  21返回render_to_response('show_employees.html',

  22 context_instance = requestContext(

  23请求,

  24个“员工”:员工,

  25'num_per_page':num_per_page,

  26'page_num':page_num,

  27“ page_options”:[50,100,200]

  28)

  29)

  运行后,您可以正确显示查询的员工信息,并且查询速度很快。

  员工表在员工表中有不同的工作信息,并且不同类型的细节不同。假设员工有一个名为Infomation的专栏,该专栏存储更详细的员工的详细员工

  详细信息,信息= {'age':33,'gene':'男性','normantity':'dermanity',

  '学位':'医生',“座右铭”:'只是做

  '}当前的需求是显示更详细的员工信息。除了发布位置和邮政验证时间外,前台还将在信息中筛选内容。

  例如,需要根据以前的代码来修改中国国籍的设计师。Employee员工存储在MySQL中,MySQL是一个ORM数据库。它不提供课程

  像MongoDB更强大的聚合功能一样,因此您无法使用此处提供的对象制作过滤器的方法,并且您需要一次获取所需的数据。那么您需要输入类型

  过滤数据后,执行第二个遍历,并确定当前记录以确定是否需要返回当前记录。在显示过程中,您需要关注num_per_page和

  page_num计算出需要显示数据的启动和终止位置。

  1 def get_employees(位置,开始,结束):

  2返回员工。过滤器(posity__in =姿势)

  3

  4

  5 def filter_wination(all_employees,normantity,num_per_page,page_num):

  6结果= []

  7

  8 pos =(page_num-)*num_per_page

  9 CNT = 0

  10 start = false

  11对于all_employes中的员工:

  12 info = json.loads(员工。信息)

  13如果info.Nationality!=国籍:

  14继续

  15

  16#获得的数据可能不是主页,因此您需要跳过上一页

  17如果cnt == pos:

  18如果开始:

  19 Bream

  20 cnt = 0

  21 pos = num_per_page

  22开始= true

  23

  24如果开始:

  25结果。申请(员工)

  26

  27退货员工

  28

  29

  30 @login_required

  31 def show(请求):

  32如果没有价值(请求):

  33返回render_to_response('none.html',,

  34 Context_Instance = requestContext(请求,'msg':'params error')

  35)

  36

  37 position = request.request.get.get('posity')

  38 time_range = request.request.get.get('time')

  39开始,end = time_range [0],time_range [1]

  40

  41 num_per_page,page_num = get_num(请求)

  42 all_employees = get_employees(姿势,开始,结束)

  43

  44国籍= request.request.get.get('nationality')

  45

  46名员工= filter_with_nation(all_employees,num_per_page,page_num)

  47

  48返回render_to_response('show_employees.html',

  49 context_instance = requestContext(

  50请求,

  51“员工”:员工,

  52'num_per_page':num_per_page,

  53'page_num':page_num,

  54'page_options':[50,100,200]

  55)

  56)

  编码完成后,在数据员工表数据很小的情况下找不到测试

  问题,当数据量非常大并且查询数据很小时,代码非常耗时。我们想象这是一家大型跨国公司,与此同时,交通量也是很大,所以员工

  表格的数据量很大,而且小国的员工不多。例如,当需要查询国籍的员工为梵蒂冈时,前台页面已进入无尽的等待状态。同时,监视过程的内存信息,

  该过程的记忆一直在增加。毫无疑问,该问题出现在filter_with_nation函数中,该功能逐一遍历员工中的数据,每件

  数据分析不是一种有效的方法。

  我在线检查了相关信息,并学到了:

  1 django的QuerySet是惰性的。使用过滤器语句进行查询。实际上,它不会运行数据库中的任何数据。

  2只要您查询,您就可以真正操作数据库。引起查询的操作是:遍历QuerySet,切片,序列化和list(),QuerySet的Len()方法,以及IF语句

  3当第一次输入循环并通过QuerySet时,Django从数据库中获取数据。在返回任何经过的数据之前,它将为内存中的每个数据创建一个实例,这可能会导致内存溢出

  以上解释了代码引起的现象。因此如何优化是一个问题,存在在线

  当涉及到巨大的QuerySet时,为了避免一次将它们加载到内存中,可以使用迭代器迭代器()处理,但是可以修改上述代码。

  雇员.iterator(),结果与以前相同,内存继续增长,前台页面正在等待。这样的解释是:user()

  通过不存储缓存的结果,可以为您节省一些内存

  Internet(不一定在PostgreSql上进行思考!);但仍然会

  从数据库中检索WHO对象。

  在这里,我们知道您不能一次穿越QuerySet中的所有记录,因此您只能做

  QuerySet切成薄片,采用块尺寸的大小,穿越该部分数据,然后累积。当达到所需数量时,请返回细致对象的列表,然后在此处修改。

  filter_with_nation函数:

  1 def filter_wination(all_employees,normantity,num_per_page,page_num):

  2结果= []

  3

  4 pos =(page_num-)*num_per_page

  5 cnt = 0

  6 start_pos = 0

  7 start = false

  8虽然是真的:

  9员工= all_employees [start_pos:start_pos+num_per_page]

  10 start_pos += num_per_page

  11

  30ee的员工12:

  13 info = json.loads(员工。infomation)

  14如果info.nationality!=国籍:

  15继续

  16

  17如果cnt == pos:

  18如果开始:

  19 Bream

  20 cnt = 0

  21 pos = num_per_page

  22开始= true

  23

  24如果开始:

  25结果。申请(OPT)

  26

  27 CNT += 1

  28

  29如果cnt == num_per_page或不事件:

  30休息

  31

  32返回结果

  运行上述代码时,查询速度更快,并且内存不会显着增加。

  更改。本文的最初意图是记录我对Django中QuerySet的理解和使用,对于本文中的示例,实际上,在正常业务中,如果您需要记录员工的详细信息,最好是正确

  员工表扩展或构建表以存储详细信息,而不是将所有信息放入字段中,以避免查询期间的辅助分析。

  Django的模块通常不能单独执行。如果是命令行,请使用python manage.py shell而不是直接使用python

  通过nginx部署Django(基于Ubuntu)

  部署Django有很多方法。NGINX+UWSGI的方法是一种更常见的方法。

  这样,我们通常的方法是将NGINX用作服务器的前端,它将接收Web的所有请求并均匀地管理请求。NGINX请求所有静态请求以处理自身(这是NGINX的优势)。

  可以看出,UWSGI的作用类似于桥梁。它扮演了桥梁的角色。

  Linux的强度用于用作服务器,因此我们选择完成以下整个部署过程。

  1.安装nginx

  NGINX是一款轻巧的Web服务器/反向代理服务器和电子邮件(IMAP/POP3)代理服务器,并根据BSD样协议发行。它的特征是拥有较少的内存和强大的并发症。实际上,NGINX的并发能力确实在同一类型的Web服务器中表现良好。

  Nginx也是一家非常受欢迎的Web服务器。在其部署Django的情况下,我们还在这里简要介绍。

  NGINX官方网站:

  打开Ubuntu控制台(CTRL+ALT+T),以使用Ubuntu的仓库安装。

  fnngj@ubuntu:?$ sudo apt-get安装nginx #installation

  启动nginx:

  fnngj@ubuntu:?$ /etc/init.d/nginx开始#startup

  fnngj@ubuntu:?$ /etc/init.d/nginx stop #close

  fnngj@ubuntu:?$ /etc/init.d/nginx restart #restart

  修改nginx的默认端口号,打开/etc/nginx/nginx.conf文件,然后修改端口号。

  复制代码

  服务器 {

  听8088;#修改端口号

  server_name localhost;

  #Charset KOI8-R;

  #access_log logs/host.access.log main;

  地点 / {

  根HTML;

  索引index.html index.htm;

  }

  复制代码

  关于文件36的位置,默认的80端号更改为其他端口号,例如8088。由于其他应用程序很容易占用默认的80 -port号码。

  然后,通过上面的命令重新启动nginx。访问:http // 127.0.0.1:8088/

  如果图片出现在上方,则NGINX启动成功。

  第二,安装UWSGI

  通过PIP安装UWSGI。

  root@ubuntu:/etc#python3 -m pip安装uwsgi

  测试UWSGI并创建一个test.py文件:

  def应用程序(env,start_response):

  start_response('200 ok',[('content-type','text/html')]))))))

  返回[B“ Hello World”]]

  通过UWSGI运行文件。

  fnngj@ubuntu:?/pydj $ uwsgi-http:8001-wsgi-file test.py

  下一个配置Django连接到UWSGI。

  fnngj@ubuntu:?/pydj $ uwsgi-http:8001-chdir/home/fnngj/pydj/myweb/-wsgi-file myweb/wsgi.py-master-master-master-master-master-processers 4-threads 2-stats127.0.0.0.0.0.0.0.0.1:9191919191:919191:919191

  共同选择:

  HTTP:协议类型和端口号

  过程:启动过程的数量

  工人:启动过程的数量等同于流程

  CHDIR:指定操作目录

  WSGI文件:已加载的WSGI文件(load.wsgi文件)

  统计:在指定的地址上,开始状态服务

  线程:运行threads.due to gil的存在,我认为这确实没有用。

  主:允许主进程(启用主过程)

  DAEMONIZE:使该过程在后台运行,并将日志击中指定的日志文件或UDP服务器(DAEMONIZE UWSGI)。实际上,最常用的是在本地文件上输出操作记录。

  PIDFILE:指定PID文件的位置并记录主过程的PID号。

  真空:当服务器退出时,自动清理环境,删除UNIX套接字文件和PID文件(尝试删除所有生成的文件/插座)

  3. nginx+uwsgi+django

  接下来,我们必须结合三个。第一个列表项目的必需文件:

  myweb/

  e- manage.py

  b - ├myweb/

  │_ _- __init__.py

  │e ─—设置.py

  │u - urURLS.PY

  │s-wsgi.py

  b - ─myweb_uwsgi.ini

  当我们通过django创建MyWeb项目时,由sub -directory myweb生成的wsgi.py文件。因此,我们只需要创建myweb_uwsgi.ini配置文件即可。当然,UWSGI支持多种类型的配置文件,例如XML,INI等。

  复制代码

  #myweb_uwsgi.ini文件

  [UWSGI]

  #与Django相关的设置

  插座=:8000

  #基本目录(完整路径)

  chdir =/home/fnngj/pydj/myweb

  #django s wsgi文件

  模块= myweb.wsgi

  #与过程相关的设置

  # 掌握

  主= true

  #最大工程数量

  过程= 4

  #...有适当的权限 - 可能需要

  #chmod-socket = 664

  #出口清除环境

  真空= true

  复制代码

  这种配置实际上等同于上一节中的WSGI命令,以及用一堆参数归档的方法。

  套接字指定项目执行的端口号。

  CHDIR指定项目目录。

  模块myweb.wsgi,您可以这样理解。对于myweb_uwsgi.ini文件,有一个具有级别的myWeb目录。此目录中有一个wsgi.py文件。

  几个参数可以参考上一节中的参数引入。

  接下来,切换到MyWeb项目目录,然后读取myweb_uwsgi.ini文件以通过UWSGI命令启动项目。

  复制代码

  fnngj@ubuntu:?cd/home/fnngj/pydj/myweb/

  fnngj@ubuntu:?/pydj/myweb $ uwsgi -ini myweb_uwsgi.ini

  [uwsgi]从myweb_uwsgi.ini获取INI配置

  ***开始UWSGI 2.0.12(32bit)[星期六3月12日13:05:06 2016] ***

  编译版本:4.8.4,2016年1月26日06:14:41

  操作系统:Linux-3.19.0-25代#26?14.04.1-ubuntu SMP星期五24:18:00 UTC 2015

  Nodename:Ubuntu

  机器:I686

  时钟来源:UNIX

  检测到的CPU核心数:2

  当前的工作目录:/home/fnngj/pydj/myweb

  检测到的二进制路径:/usr/local/bin/uwsgi

  !!!没有Interzal路由支持,可以通过PCRE支持重建!!!

  chdir()to/home/fnngj/pydj/myweb

  您的过程编号限制为15962

  您的内存页面大小为4096字节

  检测到的最大文件描述符编号:1024

  锁发动机:Pthread robust Mutexes

  雷霆锁:禁用(您可以使用锁定锁)启用它)

  UWSGI插座0绑定到TCP地址:8000 FD 3

  Python版本:3.4.3(默认,2015年10月14日,20:37:06)[GCC 4.8.4]

  *** Python线程支持被禁用。您可以使用-nable-threads ***启用它

  Python主解释器在0x8B52DC0初始化

  您的服务器插座收听积压限制为100个连接

  您对工人的优雅运营的怜悯是60秒

  映射4核的319920字节(312 kb)

  ***操作模式:预叉***

  WSGI应用程序0(MountPoint ='')在解释器0x8b52dc0 pid:7158(默认应用程序)上准备就绪。

  *** UWSGI以多解释器模式运行***

  产卵的UWSGI主处理(PID:7158)

  产卵的UWSGI工人1(PID:7160,核心:1)

  产卵的UWSGI工人2(PID:7161,核心:1)

  产卵的UWSGI工人3(PID:7162,核心:1)

  产卵的UWSGI工人4(PID:7163,核心:1)

  复制代码

  注意UWSGI的启动信息。如果有任何错误,请检查是否设置了配置文件的参数。

  我需要做的下一步是修改nginx.conf配置文件。open/etc/nginx/nginx.conf文件并添加以下内容。

  复制代码

  本国的

  服务器 {

  听8099;

  server_name 127.0.0.1

  charset UTF-8;

  access_log/var/log/nginx/myweb_access.log;

  error_log/var/log/nginx/myweb_error.log;

  client_max_body_size 75m;

  地点 / {

  包括uwsgi_params;

  UWSGI_PASS 127.0.0.1:8000;

  uwsgi_read_timeout 2;

  }

  位置 /静态{

  到期30d;

  自动索引;

  add_header缓存控制prive;

  别名/home/fnngj/pydj/myweb/static/;

  }

  }

  本国的

  复制代码

  侦听指定NGINX代理UWSGI的外部端口号。

  server_name Internet上的大多数信息是URL集(例如,wwwexamplecom)。如果我将其设置在此处,则无法访问它,因此指定了指定的默认IP。

  配置后,我有一个问题,我一直在考虑它。nginx如何与UWSGI关联。现在看来,最重要的是这两行配置。

  包括uwsgi_params;

  UWSGI_PASS 127.0.0.1:8000;

  必须指定包含为uwsgi_params;以及uwsgi_pass和myweb_uwsgi.ini配置文件的IP端口。

  现在重新启动nginx并查看上面的nginx的命令。然后,请访问:http // 127.0.0.1:8099/

  通过此IP和端口号的方向,请求首先为nginx。如果您在页面上执行一些请求,则将看到这些请求最终将转移到UWSGI以处理它。

  该要求使用会话来个人认为选择表或拿起缓存或去cookie是不合理的。

  -1。配置settings.py

  开始工人:芹菜-A项目名称工作者-L信息-P Eventlet

  开始节拍:芹菜-A项目名称BEAT -L信息

  启动克莱里背景(需要在开始之前查看):芹菜花

  启动MQ:自我抑制的百度

  Django后台还可以查看正时任务

  结论:以上是如何在首席执行官指出中测试Django并发的所有内容。我希望这对每个人都会有所帮助。如果您仍然想了解有关此信息的更多信息,请记住收集并关注此网站。