re_path(r'ceshi_uwsgi',view=views.test),
re_path(r'ceshi_uwsgi2',view=views.test),
def test(request):
time.sleep(5)
return HttpResponse('ok')
def test2(request):
time.sleep(5)
return HttpResponse('ok')
启动方式
python manage.py runserver 0:8002
http://localhost:8002/publisher/ceshi_uwsgi
http://localhost:8002/publisher/ceshi_uwsgi
给我的反应是一个窗口请求 5 秒执行完后再执行另外一个窗口请求,总共 10 秒
http://localhost:8002/publisher/ceshi_uwsgi
http://127.0.0.1:8002/publisher/ceshi_uwsgi
给我的反应是基本上是同时执行 请求总共 5 秒中
有个朋友的回答,我觉得回答的挺好的,就是那个11111111的朋友..
我查了一下官方文档
(django==2.1)
--nothreading
Disables use of threading in the development server. The server is multithreaded by default.
django默认是多线程的,应该是支持并发,只不过没有uwsgi+nginx支持的好而已
还有google浏览器第一个访问没进去,第二个是不会响应的(我没仔细测试,但是应该是对的..)
非常感谢
1
lanqing OP 我希望在两个请求基本上同时发生的情况下,同时结束(能够并发),怎么实现它
|
2
Acebiu 2018-11-21 14:54:48 +08:00 via Android
请使用专业的工具测试,比如 ab,Chrome 访问两个相同的地址,会在一个加载完毕后再加载另外一个。
|
3
scriptB0y 2018-11-21 14:55:20 +08:00
你 uwsgi 配置多个进程多个线程,就支持并发了,默认单进程单线程跑应该还是没并发的。
|
4
Neojoke 2018-11-21 15:42:00 +08:00
Python 是有个全局锁,所以 Python 的应用一般是多进程部署,要想彻底搞明白这个问题,先搞定 Python 的全局锁,是什么,然后在研究一下 Django 的 python 启动模式,去官方文档里找 uwsgi 服务器的配置说明,启动完成以后,检查一下进程中是否有多个 uwsgi 进程,如果有,则是多进程启动
|
5
SmartKeyerror 2018-11-21 19:25:28 +08:00
首先要分清 Web Server 和 Web Application 之间的区别:Web Server 可以使用多线程多线程或者是 Reactor 模型来支持并发, 前者可以支持并行, 后者因为 GIL 的原因, 只能支持并发。 而 Web Application 仅仅只是一个应用而已, 当你使用 runserver 来启动 Django 时, 其实是启动了 Django 为开发者所提供的测试 Server 而已, 并不支持并发, 请求为串行执行。 至于在配置了 uwsgi Web Server 之后还是不支持并发, 尝试将 process 配置为 CPU 核心数
|
6
Nick2VIPUser 2018-11-21 21:19:59 +08:00 1
生产上可以用 uwsgi+nginx
|
7
lfzyx 2018-11-21 21:26:27 +08:00 4
上面动不动就说 GIL 全局锁的是不是有毛病?你家网站是 CPU 密集型的?
|
8
FullBridgeRect 2018-11-21 21:53:45 +08:00 via Android
django 自带那个是调试用的,虽然是串行,但正常人是不会将他放到生产环境的。你要并行的 uwsgi 非阻塞模式 /gunicorn 异步引擎了解一下
|
10
ltoddy 2018-11-21 21:57:17 +08:00
网络请求本身就是异步的.
|
11
111111111111 2018-11-21 22:00:22 +08:00 via Android
楼上的不观察细节吗。两次请求的域名不一样就并发…一样就串行
Chrome 有这个毛病,同样的 URL 并发请求,如果第一无响应第二个根本不发出去 另外建议楼主在视图函数的开始和结束时分别打带时间的 Log,这才是 debug 应有的态度 |
12
111111111111 2018-11-21 22:01:24 +08:00 via Android
@FullBridgeRect django 的 runserver 是多线程的
|
13
111111111111 2018-11-21 22:13:14 +08:00 via Android
django 文档里明确说明了 runserver 是多线程,如果想要单线程需要加参数--nothreading 为啥各位大佬都说串行……
|
14
ericls 2018-11-22 00:10:49 +08:00
wsgi 并发要借助 thread 和 multi-process
|
15
FullBridgeRect 2018-11-22 01:24:26 +08:00 via Android
@111111111111 是吗😂平时都没留意,很多 wsgi 服务器都说要特定的引擎才能实现非阻塞,就把他套在了 runserver 上面了🙈
|
16
Trim21 2018-11-22 01:53:34 +08:00 via Android
这个是 chrome 的问题,对同一个 url 只会在第一个请求结束之后才开始第二个请求。
|
17
Neojoke 2018-11-22 09:02:35 +08:00
@111111111111 Python 的多线程基本上是伪并行,可以了解一下 GIL 全局锁,就明白了,Python 的应用即便是使用了多线程,但基本上没办法处理高并发,所以一般高并发配合的必须是多进程,或者采用协程,但协程是开弓没有回头箭,一开始是协程,就要任何代码都是协程,否则性能很难保证
|
18
petelin 2018-11-22 09:29:53 +08:00 via iPhone
@Neojoke 没法高并发是因为 python 慢,可不是因为什么全局锁。你在学习一下并发和并行的区别就明白了
|
19
hljjhb 2018-11-22 09:51:07 +08:00 via Android
既视感 两三年前有个如出一辙的帖子
|
20
111111111111 2018-11-22 11:00:06 +08:00 via Android
@Neojoke
In CPython, due to the Global Interpreter Lock,..... However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously. |
21
petelin 2018-11-22 17:40:33 +08:00
@Neojoke 另外 Python 的多线程是真的多线程, 只是有一把锁而已, 执行 Python 代码的时候要先拿到这把锁. 但是调用系统库那可是真的并行在跑
|
22
Neojoke 2018-11-22 18:11:24 +08:00
@petelin
我觉得吧,您让我学习一下的建议,我会接受的,但您是否考虑一下我的建议? 1. 翻翻 Python 解释器的源码,找找 CPython 的全局锁的实现代码。 这里给您奉上: https://github.com/python/cpython/blob/e62a694fee53ba7fc16d6afbaa53b373c878f300/Python/ceval.c#L238 2. 考虑一下解释器作为共享资源,被全局锁保护以后,多线程代码在执行的时候,是否会被同步,在临界代码执行以后,才会被释放 3. 再思考一下,在什么特殊的情况下,会主动让出全局锁 4. PyThread_type_lock 这个看一下结构体,然后呢,自己做个试验,在多线程的情况下,模拟并发耗时操作,不断调高线程数,看一下总耗时是否和线程数的增加成正相关 5. 人家说的 Django,里面基本上是 Python 代码,几乎没有 C 的扩展调用,系统库也不都是用 C 实现的,C 实现的 io 操作是使用操作系统本身的线程、进程以及信号量来处理的。 |
23
Neojoke 2018-11-22 18:32:20 +08:00
楼主,没有人会使用 Django 默认的 runserver 进行生产部署的,并且官方文档也非常不推荐在生产环境使用 runserver 进行部署,原因就是 Python 虽然可以多线程,但是因为 CIL 的存在,导致其并发效率非常低,至于为什么很低,我前面已经把关键点罗列了一下。
生产环境部署 Python 的 Web 应用,有两种方式,一种是 uwsgi 使用多进程,多开 work,进行部署,一种是使用 gevent 协程实现非阻塞异步 I/O,但是我前面说了,这种要求,其他的代码也必须是非阻塞的编程模型。跟 nodejs 一样。 @111111111111 说的 runserver 是多线程的没有什么问题,能解决您的测试疑惑,但这里面最本质的还是要考虑,CIL 到底对并发有多大影响,GIL 一直起作用的时候,线程需要不断等待获取 GIL,线程被同步,但 I/O 操作的时候,Python 代码是会让出全局锁的,所以,多线程是有效的,可以考虑使用,但前提这是非阻塞的 I/O,也就说,C 底层提供的 I/O 功能,或者用 C 实现的非阻塞 I/O 功能,uwsgi 虽然是 C 写的,但不是非阻塞的,可以查看一下 C 的源码,如果不设置多个 work,就不能处理高并发,可以压测一下。试试 |
24
petelin 2018-11-22 18:58:42 +08:00 via iPhone
@Neojoke 你这不也承认多线程是有用的吗,还有什么好抬杠的。网站就是一个网络数据的处理,c 单线程估计也能完爆多线程的 python,python 的协程估计比多线程还强,这里面的思想不就是让 CPU 一直跑着去 handle 数据?数据流动比 CPU 处理速度慢多了
|
25
Neojoke 2018-11-22 21:18:36 +08:00 via iPhone
@petelin
前提都看不懂么?在非阻塞的情况下多线程能处理并发,阻塞代码基本上多线程没用 什么 C 单线程完爆 Python 多线程,还估计,说的是 C 的非阻塞 IO 代码能交还 GIL,不会引起 Python 多线程的同步等待,这也是 Python 伪并发的原因 这里的思想是 CPU 跑着 handle 数据?想表达什么? 数据流动比 CPU 处理速度快?数据流动是什么? |
26
YuanGu333 2018-12-05 14:43:30 +08:00
有大佬开多一个贴再说明说明吗?
|