環境:Python 3.8.1 +?Django?2.2.12
項目目錄結構:
CellMiddle -- 項目根目錄
├─task --- 需求系統
│ ├─migrations
│ ├─static
│ └─templates
├─logs --- 日志目錄
├─doc --- 文檔系統
│ ├─data
│ ├─migrations
│ ├─static
│ └─templates
├─sso --- 單點登錄,權限控制系統
│ ├─migrations
│ ├─static
│ └─templates
├─upload ---文件資源上傳目錄
├─static --- 靜態資源
├─templates --- 公共模板
└─CellMiddle --- 項目主目錄
│ ├─config --- 公共配置
│ ├─helper --- 公共輔助類,ex:時間,日期,字符串,響應等
│ └─loader --- 第三方庫的實例化加載,ex:Redis,Memcached等
│ │ settings.py
│ │ urls.py
│ │ wsgi.py
│ │ __init__.py
├─manage.py
└─envConf -- 部署配置文件:requirement.txt, host.conf, supervisor, gunicorn 等
使用 nginx + gunicorn + supervisor 部署,使用域名?cell.hao456.com?解析指向服務器, nginx 監聽 gunicorn 綁定的端口,可以正常訪問:
http://cell.hao456.com/task
http://cell.hao456.com/doc
http://cell.hao456.com/sso
雖然同一個域名路由控制來訪問,也是可以的。但還是想像PHP一樣只要獨立入口文件,每個app獨立使用不同子域名,如:
http://task.hao456.com 指向task
http://doc.hao456.com 指向doc
http://sso.hao456.com 指向sso
嘗試了幾種辦法:
nginx 層轉發;
修改proxy指向,location 要加app,static 等。
每個app獨立一個 wsgi.py 文件,使用gunicorn單獨起服務;
增加 task_wsgi.py, doc_wsgi.py, sso_wsgi.py,使用 supervisor起三個gunicorn服務。
使用django-hosts;
添加MIDDLEWARE中間件,實現host與urls的namespace關聯。nginx的conf配置不用改動,只需要將 所有子域名的監聽,一起代理指向gunicorn端口
$ cat hosts.conf
server {listen 80;server_name task.hao456.com doc.hao456.com sso.hao456.com;location / {proxy_pass http://127.0.0.1:10888;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_read_timeout 120s;}... ...
}
django-hosts實現:
- pip 安裝 django-hosts, 這里用到的是 4.0版本:
$ pip install django-hosts==4.0 # root權限
- 修改settings.py:
- 將django-hosts添加到app:
INSTALLED_APPS = [...'django_hosts','sso','doc','task',]
- 添加Django的hosts配置:
ROOT_HOSTCONF = 'CellMiddle.hosts' # host配置DEFAULT_HOST = 'sso' # 默認的域名
-
- 將django_hosts添加到中間件MIDDLEWARE:
MIDDLEWARE = ['django_hosts.middleware.HostsRequestMiddleware', # 首要加...'django_hosts.middleware.HostsRequestMiddleware', # 尾要加
]
- 在項目主目錄下settings.py同級,添加?hosts.py(注意和 settings 里面配置的ROOT_HOSTCONF一致):
...
└─CellMiddle│ hosts.py --- 新增文件│ settings.py│ urls.py│ wsgi.py│ __init__.py
內容為:
# coding=utf8"""django-hosts"""from django.conf import settingsfrom django_hosts import patterns, hosthost_patterns = patterns('',host('sso', settings.ROOT_URLCONF, name='sso'),host('doc', 'doc.urls', name='doc'),host('task', 'task.urls', name='task'),)
- 路由配置urls.py,添加路由對應的appname(app名稱), namespace(域名):
urlpatterns = [path('admin/', admin.site.urls),path('', include(('sso.urls', 'sso'), namespace='sso')), # 默認ssopath('doc', include(('doc.urls', 'doc'), namespace='doc')), # 文檔path('task', include(('task.urls', 'task'), namespace='task')), # 需求]
- reload 重載服務:
- DNS 確認子域名的解析;
- 檢查nginx的配置有效性,重載nginx;
- 動態更新Web服務 或 在 supervisorctl重啟Web服務;
$ kill -HUP PID # root權限
$ supervisorctl restart program_name服務名 # root權限
- 檢查子域名的訪問,app對應的路由,靜態資源訪問等是否正常;