在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:jetty-yarn开源软件地址:https://gitee.com/zhzhenqin/jetty-yarn开源软件介绍:Jetty On Yarn##开发背景 在如今大公司都在实践弹性部署的大背景下, 笔者在了解 Mesos 和 Yarn 的一些功能后, 对 Yarn 的运行原理有些启发, 创建此项目. 目的是让 WebServer 运行在 Hadoop Yarn上, 实现动态部署, 一个命令即可批量实现批量部署或者批量关闭部署, 实现Web 运行环境的动态管理. 使用场景: 在某些不充分了解系统压力的 Web 项目, 或者访客具有群体效应的业务环境. 如: 在少量时间有大量访问, 访问具有突发性. 当然, 如果把 Hadoop Yarn 当做云操作系统, 也完全可以把任何 Web 应用部署在其上, 可以减少硬件投入. ##部署环境
##部署
###Jetty-On-Yarn 支持的命令 可使用 命令行如果有任何异常, 可加 '-s' 抛出完整异常堆栈. 启动或者停止 Jetty-Yarn. usage: yarnjetty on yarn, start/shutdown app master -appid,--appid <arg> App Id, JettyOnYarn ApplicationMaster ID -m,--memory ApplicationMaster Memory, default 512M //该 WebInstance 的内存, 默认512 -n,--appname App Name, JettyOnYarn //Jetty-On-Yarn 在 Yarn 上注册的 AppName -q,--queue Hadoop Yarn Queue, default //Jetty-On-Yarn 在 Yarn 上的任务队列名称, 默认 default -s print exception -shutdown,--shutdown App Name, shutdown JettyOnYarn //和appid 搭配使用, 用于停止 JettyAppMaster, 停止 AppMaster 会停止所有由他启动的 Jetty Instance. -z,--zip Jetty Zip Location, default /lib/jetty/jetty-{version}.zip
弹性部署, 增加 Web 运行实例. usage: yarn-addjetty on yarn, add jetty instance -appid,--appid <arg> App Id, JettyOnYarn ApplicationMaster ID. //必须参数 -c,--core Jetty Instance Cores, default 1 -m,--memory Jetty Instance Memory, default 512M -s print exception -wars,--wars <arg> JavaEE War Location, HDFS direction. //必须参数 -x,--xml Jetty XML, default conf/jetty.xml -z,--zip Jetty Zip Location, default /lib/jetty/jetty-{version}.zip 列举指定 yarn app 上已经启动的 Web Server 信息 usage: yarn-list jetty on yarn, list jetty instance -appid,--appid <arg> App Id, JettyOnYarn ApplicationMaster ID -s print exception 停止已经运行的 Jetty-Instance(Jetty-Instance 即是一个 Jetty WebServer 的运行实例, 运行的实例数越多, 理论上可以提高并发). usage: yarn-stopjetty on yarn, stop jetty instance -a,--all Stop All Jetty Instance, --all -appid,--appid <arg> App Id, JettyOnYarn ApplicationMaster ID -c,--containerid <arg> Jetty Container Id, JettyOnYarn yarn-list -n,--nodeid <arg> Jetty Instance NodeId, JettyOnYarn yarn-stop -s print exception 配置:
jetty.yarn.properties yarn.appmaster.avro.port=40880 #JettyAppMaster 开放给 Client 执行 command 的命令端口号master.heartbeat.interval.millis=10000 #JettyAppMaster 报告 Yarn 进度,心跳的频率#默认的 Jetty Instance 启动级别yarn.master.container.priority=0#Jetty Zip访问其别jetty.zip.visibility=PUBLICjetty.yarn.app.master.opts=-server #AppMaster 启动优化参数jetty.yarn.instance.jvm.opts=-server #Jetty Instance 启动优化参数#默认的注册器是 LoggerJettyPublisher, 可以把启动信息注册到 ZooKeeper, Socket, 数据库等多种方式jetty.yarn.publisher.class=com.ivyft.jetty.yarn.ZookeeperJettyPublisherjetty.yarn.zookeeper.root=/jettyjetty.yarn.publisher.zookeeper.server=192.168.102.10:2181jetty.yarn.publisher.zookeeper.connectionTimeout=60000jetty.yarn.publisher.zookeeper.sessionTimeout=6000 Jetty.xml 请注意, 这里的defaultsDescriptor需为: <Ref id="DeploymentManager"> <Call id="webappprovider" name="addAppProvider"> <Arg> <New class="org.eclipse.jetty.deploy.providers.WebAppProvider"> <Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps</Set> <Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/conf/webdefault.xml</Set> <Set name="scanInterval">1</Set> <Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set> <Set name="extractWars">true</Set> </New> </Arg> </Call></Ref> ###关于 WebServer 的 Context Path 问题 部署一个 Web Instance, 只需要一个 war 包. JavaEE 标准的 war 包基本都能部署. <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"><Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath"><SystemProperty name="hostContext" default="/solr"/></Set> <Set name="war"><SystemProperty name="jetty.home"/>/webapps/hellp.war</Set> <Set name="defaultsDescriptor"><SystemProperty name="jetty.home"/>/conf/webdefault.xml</Set> <Set name="tempDirectory"><Property name="jetty.home" default="."/>/tmp/hellp</Set></Configure> 如 ##注册到 ZooKeeper 及后期设想 ###JettyPublisher public interface JettyPublisher { public void init(JettyConfiguration jettyConf); public void publish(String host, int port);} ###ZookeeperJettyPublisher @Overridepublic void init(JettyConfiguration jettyConf) { String zookeeperServer = jettyConf.getString("jetty.yarn.publisher.zookeeper.server"); LOG.info("connect to " + zookeeperServer); zkClient = new ZkClient(zookeeperServer, jettyConf.getInt("jetty.yarn.publisher.zookeeper.sessionTimeout", 6000), jettyConf.getInt("jetty.yarn.publisher.zookeeper.connectionTimeout", 60000)); rootPath = jettyConf.getProperty("jetty.yarn.zookeeper.root", "/jetty"); LOG.info("register to zookeeper path " + rootPath); if(!zkClient.exists(rootPath)) { zkClient.createPersistent(rootPath); }}@Overridepublic void publish(String host, int port) { String path = rootPath + "/" + host + ":" + port; LOG.info("jetty server published zookeeper at: " + path); zkClient.createEphemeral(path); //创建一个ZooKeeper 临时节点, 这种节点在 Session 失效后就立即消失, 也就是说, 当 Web Instance 因故被 kill 或者其他原因宕机, ZooKeeper 在连接失效后会清理该节点.} 任何在yarn 启动的 WebInstance, 最后都把自己的 server host 和 port 注册到一个地址. 这个注册方式可以多种. 比如注册到 Zookeeper 中. 连续启动多个 Jetty Server: ./jetty-on-yarn yarn-add -appid application_1449726747657_0010 -wars /lib/jetty/hellp.war 注册到 ZooKeeper 的信息如下: [zk: localhost:2181(CONNECTED) 2] ls /jetty[nowledgedata-n9:8080, nowledgedata-n9:8082] 由此可以诞生出一个想法, 就是让 Nginx, Apache 等代理支持 ZooKeeper. 如 Nginx: upstream 192.168.1.105 { #weight 参数表示权值,权值越高被分配到的几率越大 server 192.168.1.105:8090 max_fails=2 fail_timeout=60s weight=2; server 192.168.1.105:8080 max_fails=2 fail_timeout=60s weight=1; } Nginx 目前支持的代理都是静态的, 被写到配置文件中. 如果能支持动态的代理方式, Web Server 等弹性部署将会提升很大空间. Nignx ZooKeeper 支持, github 上已经有实践, 但不知道是否可用. https://github.com/Timandes/nginx-zookeeper |
请发表评论