uwsgi基础——最佳实践和问题
需要知道的内容(最佳实践和问题)
--http 和 --http-socket 完全不一样。 第一个产生一个附加的进程(一个代理),将请求路由(routing) 到uwsgi实例上。第二个,设置uwsgi为原生的http。如果web服务器不支持uwsgi协议,你需要使用http(像webfaction 或者 heroku)--http-socket.如果你打算发布你的app(从1.3-dev版开始支持https)使用 http转发、路由、代理、负载会很可靠。
默认的发送 SIGTERM(终止信号)的意思是“brutally-reload-it”,普通的apps在遇到SIGTERM会关闭。关闭uwsgi使用SIGINT or SIGQUIT.如果你不想这样设置,你可以使用--die-on-term 选项。
如果打算托管多个应用,使用Emperor
使用uwsgitop或者相似的东西来监控你的apps
uWSGI可以从代码和插件中引入新功能。通常你发行版uwsgi包是模块化的。这种情况下要记得加载需要的插件。如果看到'unavailable modifier requested'这样的信息,意味着插件没有加载上。如果使用distro-supplied包,双击来安装。
配置文件支持,变量,if逻辑和简单循环。检查ConfigLogic 和ParsingOrder
为了转发请求到指定的插件,web服务器需要床底一个魔法数,默认数字是0(对应python)。举个栗子,转发一个请求到psgi (perl)要设置modifier为5,或者加载psgi插件为‘0’。 规则没有定义线程或进程数目。这取决于应用和系统以来。不要以为只是简单的2*cpucores就够了。你需要尝试不同的设置,同时不断的监控你的app。uwsgitop是一个非常好的工具来找到这个最佳值。
如果http请求有一个body(像post一个表单)你不读取,那么socket和web服务器的通讯会被拖垮。如果你不想手动读取,使用 --post-buffering选项,这样会自动为你读取这些数据。
常常检查你的内存使用。--memory-report 选项非常有用。
如果你打算使用unux sockets,记住它们是标准的文件对象。这意味着它们有权限,所以web服务器要可以写。
不要用root运行uwsgi。它们明显可以用root运行,但是确保它们降权使用 --uid 和--gid选项。
uwsgi 只要可能的情况下都用 fork() 来复制。默认,他会在加载应用后执行 fork 。如果你不想使用 --lazy选项。开启它,会知道uwsgi来加载应用。lazy模式优雅的重启works:代替重载的是,每个worker轮流着reload。如果你使用'lazy app loading',但你想维持标准的uwsgi重载行为,在1.3之后你可以使用 --lazy-apps 选项。
默认的python插件不会初始化GIL,意味着你的app线程不会运行。如果需要线程,记得开启 --enable-threads .运行uwsgi在多线程模式(--threads)会自动开启线程支持。这是由于性能所引起的奇怪行为,并不可耻。
如果为一个请求开启一个进程,它会继承一个worker的文件描述,包括socket连接web服务器或路由器。如果不想使用这个特性,设置--close-on-exec 选项。
Ruby的垃圾回收默认实在每个请求后。这是一个拖慢你的apps的危险策略(消耗CPU成本要低于内存成本)。改变这个频率使用 --ruby-gc <freq> option
在OpenBSD,NetBSD和FreeBSD(<9v版本)ipc信号使用的锁子系统。这次操作系统分贝的信号量优先。应该提高默认限制。如果你要运行多个uwsgi实例就提高这些限制。freebsd 9以后都不需要设置。
不要在不同的uwsgi库中编译构建插件(至少要确切的知道你要做什么)
默认的uwsgi分配一个小的buffer(4k)来接收每个请求的头信息。如果在日志中看见"invalid request block size",它意味着你需要一个大一点的buffer。使用--buffer-size增长(到60K):如果接收'21573' 作为你接收的块大小,这意味着你使用htpp实例覆盖了uwsgi协议!!!