当你开始着手部署应用时,最简单的方式莫过于使用管理员身份重启my_app或者所有服务,使产品升级至当前版本。开始的时候一切都很好,但是最终你会发现一旦应用启动以后,在重启期间去尝试连接会得到众多HTTP 503 错误。
最后你可能发现Gunicorn和uWSGI可以在不关闭套接字的情况下重新加载你的应用,这样在你的应用启动时,网络请求仅仅是被延时了一点点。只要你的应用不会花费很长时间在启动上,它就会工作的很好。不幸的是,现有的许多应用可能会花费1分钟的时间在启动上,对于等待在套接字上的链接来说,这太长了。
Gunicorn使用kill -HUP $PID,通过关闭所有工作进程,然后再启动它们来重新加载。但是工作进程缓慢的初始化过程往往会导致问题的产生。uWSGI使用链式重载,它每次只会启动一个工作进程。我需要对Tornado的支持,它当前并不十分适合uWSGI。
使用负载均衡器
一种常见的技术是从负载均衡器中移除单个服务器,升级/重启应用,然后再把它加载回来。我们正在使用负载均衡器,但是为了调度整个过程,在配置节点的时候需要协调使用HAProxy来管理套接字。我们当前的部署方案是同时部署到所有节点,而不是一个接一个的来,一个相当大的变化。在等待LBs(译注:负载均衡器)将节点移出池期间,可以使用404'ing状态页来欺骗healthcheck。这比我想要的时间要多一点,对于每个服务器来说,两次healthcheck失败间隔5秒钟,这包括了升级完成后web进程恢复的时间。
Gunicorn 重载 ++
Gunicorn会自动重启失败的web进程,所以它可能会杀掉每个进程,在其间休眠,直到所有的子进程执行完毕。这很有效,不过如果应用启动的次数变动显著的话,我们要么会为重启等待过长时间,要么会等待不长的时间并承担一些故障宕机的风险。
因为Gunicorn包含了指向应用的Python钩子,所以完全可能写出一小段代码,在工作进程准备就绪的时候通知重启进程。Gunicorn并不包含需要的钩子,但做出改变非常简单。在新版本发布前它需要一些修改。
现在重启进程发挥了这样的事实优势,就是说单个的soket具有接受连接的多个进程。重启只会极微弱的减少服务能力(1/N),但我们因此可以继续处理流量而无需让连接等待过长时间。
这种进程一般是这样的
for child_pid of gunicorn-master: kill child_pid wait for app startup
我的第一个版本使用shell和nc来监听应用启动的UDP数据包。尽管将我们的进程管理器集成到shell环境比我预想的要麻烦一点,但它工作的很好。
重启脚本被调用的时候应该带上Gunicorn的PID,就是masterrestart.sh的 $PID
echo 'Killing children of ' $1; children=$(pgrep -P $1) for child in $children do echo 'Killing' $child kill $child response=$(timeout 60 nc -w 0 -ul 4012) if [ "$response" != '200 OK' ]; then echo 'BROKEN' exit 1; fi done
在串联上post_worker_init脚本,以便app运行的时候通知重启脚本。
import socket import time def post_worker_init(worker): _send_udp('200 OK\n') def _send_udp(message): udp_ip = "127.0.0.1" udp_port = 4012 sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP sock.sendto(message, (udp_ip, udp_port)) 如果我们有这样一个WSGI( Python Web Server Gateway Interface)应用: from werkzeug.wrappers import Request, Response @Request.application def application(request): resp = Response('Hello World!') if request.path == '/_status': resp.status = '200 OK' else: resp.status ='404 Not Found' return resp
我们甚至可以去做检查/_status页面之类的事情,以此来验证应用是否已运行。
def post_worker_init(worker): env = { 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/_status', } def start_response(*args, **kwargs): _send_udp(args[0]) worker.wsgi(env, start_response)
注意不要试图在这个健康检测中运行太多的应用,如果不管什么原因你的post_worker_init产生了一个错误,那么工作进程将会退出,并阻止应用的启动。在你检查可能失效的DB链接的时候这会是一个问题,即使你的应用可以工作,它也无法再次启动。
现在通过一分钟的应用启动,我们实现了滚动重启,而无需停止应用或者丢弃任何链接!
本文向大家介绍Java应用服务器之tomcat部署的详细教程,包括了Java应用服务器之tomcat部署的详细教程的使用技巧和注意事项,需要的朋友参考一下 一、相关术语简介 首先我们来了解下tomcat是什么,tomcat是apache软件基金会中的一个项目,由apache、Sun 和其他一些公司及个人共同开发而成。主要作用是提供servlet和jsp类库;tomcat是一个免费开源的we
我正在关注阿伦·古普塔的JavaEE7动手实验室。https://github.com/javaee-samples/javaee7-hol 我已经在JBoss Dev Studio wildfly 8服务器Windows7中部署了该应用程序。很好用。 但当我在Windows8 Eclipse Glassfish4服务器上部署相同的组件时,它引发了以下异常。有人能告诉我Windows 8的设置有什
我有一个使用tomcat服务器运行的java应用程序。现在我需要在jboss服务器上运行相同的应用程序。我是jboss新手,我尝试过在jboss中部署war文件,但没能做到。 我不知道应用程序要在jboss上运行需要做什么更改。任何人请引导我。 非常感谢。
服务端部署 1. 源码部署 CAT安装环境 Linux 2.6以及之上(2.6内核才可以支持epoll),线上服务端部署请使用Linux环境,Mac以及Windows环境可以作为开发环境,美团点评内部CentOS 6.5 Java 6,7,8,服务端推荐使用jdk7的版本,客户端jdk6、7、8都支持 Maven 3及以上 MySQL 5.6,5.7,更高版本MySQL都不建议使用,不清楚兼容性
部署模式 SOFARegistry 支持两种部署模式,分别是集成部署模式及独立部署模式,本文将介绍最简单的单节点集成部署模式,更多更详细的部署模式介绍可以查看 部署文档。 部署步骤 1. 下载源码或者安装包 下载源码方式 git clone https://github.com/sofastack/sofa-registry.git cd sofa-registry mvn clean packa
我正在尝试使用无服务器将lambda函数部署到AWS。执行时 无服务器部署--详细 我得到以下错误每次: 无服务器错误--------------------------------------- 出现错误:mainTable-无效的KeySchema:第一个 myserverless.yml如下所示: 你们中有人能帮忙吗? 干杯