【发布时间】:2016-03-10 12:22:46
【问题描述】:
我正在考虑制作一个 django 应用程序,该应用程序将动态添加新的 django 网站和静态网站。
我可以完成所有步骤,但问题是如果我有很多用户正在尝试添加网站,如果每次添加网站我都必须服务 uwsgi 启动/停止和服务 nginx 重启 .. 网站将有当用户尝试访问它时出现问题。
关于如何在不重新启动服务的情况下更新更改有什么解决方案?
任何帮助或建议将不胜感激。
谢谢!
【问题讨论】:
我正在考虑制作一个 django 应用程序,该应用程序将动态添加新的 django 网站和静态网站。
我可以完成所有步骤,但问题是如果我有很多用户正在尝试添加网站,如果每次添加网站我都必须服务 uwsgi 启动/停止和服务 nginx 重启 .. 网站将有当用户尝试访问它时出现问题。
关于如何在不重新启动服务的情况下更新更改有什么解决方案?
任何帮助或建议将不胜感激。
谢谢!
【问题讨论】:
如果您尝试在一个 uWSGI 服务器上启动所有应用程序,那么您做错了。每个 django 应用都需要单独的 uWSGI 服务器...
... uWSGI 内置了解决方案:emperor and vassals。只需将 Emperor 配置为主要的 uWSGI 服务,并将其配置为可以动态启动和停止 vassal 而无需重新启动自身。这样,如果有人更改 django 应用程序的配置,则只会启动/停止或重新加载一个 vassal(必须发生某些事情,您无法避免)。
不幸的是,nginx 很难实现。首先,您不必重新启动 nginx,您可以使用 service nginx reload 优雅地重新加载它的配置。但是,如果您对此不满意,还有另一种解决方案。
要使该解决方案正常工作,您所有的 django 项目都必须具有完全相同的 nginx 配置(如果您想在它们之间创建一些差异,请检查它是否可以在 uWSGI 中实现,通过巧妙的 nginx 配置,您将能够使用任何uWSGI 功能)。如果可以满足此要求,请执行以下操作:
创建配置文件以捕获所有可能的 django 网站(每个网站必须位于不同的域),它可以如下所示:
server {
server_name ~^(www\.)?(?<domain>.+)$;
# server_name can contain any regular expression. Just remember that it should start with `~` and contain `^` and `$`
# as you can see, we can use named capture group as an variable later
# you can add any named capture group for later use
root /sites/$domain/public;
location @default {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
include /etc/nginx/uwsgi_params;
uwsgi_pass unix:/run/uwsgi/${domain}.sock;
break;
}
location /static/ {
try_files $uri @default;
}
location /media/ {
try_files $uri @default;
}
location ~* ^/(android-(?:chrome|icon)[-0-9x]*\.png|ms(?:tile|-icon)[-0-9x]*\.png|browserconfig.xml|apple-(?:touch-)?icon[-0-9x]*\.png|favicon[-0-9x]*.png|favicon\.ico|manifest.json|apple-touch-icon-precomposed\.png)$ {
try_files $uri /static/favicon$uri @default;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
try_files /500.html /error.html /error500.html;
}
location / {
try_files /maintenance.html @default;
}
}
将每个项目存储在修补到它们的目录中会以某种方式匹配域名。如果要将每个项目存储在它所属的用户目录中,则该目录名称必须包含在 URL 中。
换句话说,您必须能够按其域构造目录到项目。
您可以通过创建一些包含指向实际项目目录的符号链接的全局目录来破解该限制。
注意!!可能存在安全漏洞!如果有人将创建目录,哪个路径将匹配主机名,nginx 将在该主机名上提供该目录。即使域不会指向您的服务器,也有人可以访问它。因此,您应该更好地使用带有符号链接到实际项目的全局目录的方法。
确保到 uWSGI 服务器的套接字也可以从域名创建。您也可以在此处使用符号链接。
【讨论】: