zoukankan      html  css  js  c++  java
  • 【Django】runserver 0.0.0.0:0 后,究竟发生了什么

    WSGI协议

    Django是遵循WSGI协议设计的

    WSGI协议主要包括server和application两个部分:

    1. WSGI server:负责从客户端接收请求,将request转发给application,将application返回的response返回给客户端
    2. WSGI application:接收由server转发的request,处理请求,并将处理结果返回给server。application中可以包含多个栈式的中间件,这些中间件需要同时实现server与application:对server来说,中间件扮演应用程序;对应用程序来说,中间件扮演服务器

    可以选择任意的server和application组合实现自己的web应用。

    runserver后到底发生了什么

    通过runserver运行的Django主进程会创建一个WSGIServer的实例,WSGIServer父类是操作socket的TCPServer。

    WSGIServer将打开一个socket,并将此socket绑定到runserver参数中指定的ip和端口,然后调用socket.listen()开始监听请求。

    当请求来临,WSGIServer会调用WSGIHandler这个application,在application中执行Django框架对请求数据的一系列处理。

    runserver 0.0.0.0:8000

    runserver 0.0.0.0:8000表示将django进程使用的socket绑定ip设置为INADDR_ANY(0),因此socket会在8000端口监听从本机所有网卡发来的数据,相当于绑定了本机的所有ip地址。

    比如你的机器有三个ip

      192.168.1.1   
      202.202.202.202   
      61.1.2.3   
    

    使用runserver 0.0.0.0:8000启动的django进程可以通过服务器的所有ip访问到,而使用runserver 192.168.1.1:8000,只有通过192.168.1.1:8000才能够访问

    如果本机有唯一的ip地址192.168.1.1,那么runserver 0.0.0.0:8000 就等同于 runserver 192.168.1.1:8000

    runserver 127.0.0.1

    表示将socket绑定到本机回环地址,只能监听本机对此服务的请求

    runserver 0.0.0.0:0

    如果不为socket指定绑定任何端口,或者将绑定的端口设置为0时,系统会在本机可选的端口中为socket随机绑定一个

    下面来实验一下:

    $ python manage.py runserver 0.0.0.0:0       
    Performing system checks...
    
    System check identified no issues (0 silenced).
    April 29, 2020 - 19:53:25
    Django version 2.0.13, using settings 'qaboard.settings'
    Starting development server at http://0.0.0.0:0/
    Quit the server with CONTROL-C.
    

    尝试找到这个服务绑定的端口:

    $ ps -ef|grep 0.0.0.0:0
    luozx   896 19075  0 19:53 pts/28   00:00:00 python manage.py runserver 0.0.0.0:0
    luozx   901   896  4 19:53 pts/28   00:00:04 /home/luozixi/myserver/venv/bin/python manage.py runserver 0.0.0.0:0
    luozx  1070 28816  0 19:54 pts/37   00:00:00 grep 0.0.0.0:0
    

    发现有两个进程,这是因为runserver默认启动两个进程,一个进程是提供服务的django应用,一个进程用于检测项目代码修改,如果有修改则自动重启主进程

    如果在runserver时使用 "--noreload" 参数则不会启动检测进程

    $ python manage.py runserver 0.0.0.0:0 --noreload
    $ ps -ef|grep 0.0.0.0:0 
    luozx  1429 19075 38 19:56 pts/28   00:00:01 python manage.py runserver 0.0.0.0:0 --noreload
    luozx  1447 28816  0 19:56 pts/37   00:00:00 grep 0.0.0.0:0
    

    查看进程标识符为1429的进程使用的socket绑定了哪个端口

    $ netstat -nltp|grep 1429
    Proto Recv-Q Send-Q Local Address           Foreign Address         State        PID/Program name
    tcp        0      0 0.0.0.0:48381           0.0.0.0:*               LISTEN      1429/python    
    

    从服务器的48381端口就可以访问我们的django服务了

    参考资料

    Python Web开发最难懂的WSGI协议,到底包含哪些内容?
    python从小白到入门:10分钟搞懂WSGI协议
    About IP 0.0.0.0 in Django
    Socket.Bind(EndPoint) 方法
    socket INADDR_ANY 监听0.0.0.0地址 socket只绑定端口让路由表决定传到哪个ip

  • 相关阅读:
    k8s-[排查记录]解决节点无法查看pod日志
    k8s kube-proxy模式
    容器网络
    k8s-使用kubeadm安装集群
    k8s-Deployment重启方案
    k8s-NetworkPolicy-网络策略
    nodejs 解析终端特殊字符
    fluentd 日志自定义字段解析
    题目笔记 CF 1494b
    CF1225D Power Products(分解质因子 哈希)
  • 原文地址:https://www.cnblogs.com/luozx207/p/12808007.html
Copyright © 2011-2022 走看看