• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

jetty-yarn: Jetty-On-Yarn 目的是让 WebServer 运行在 Hadoop Yarn上, 实现动态部署, ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

jetty-yarn

开源软件地址:

https://gitee.com/zhzhenqin/jetty-yarn

开源软件介绍:

Jetty On Yarn

##开发背景

在如今大公司都在实践弹性部署的大背景下, 笔者在了解 Mesos 和 Yarn 的一些功能后, 对 Yarn 的运行原理有些启发, 创建此项目. 目的是让 WebServer 运行在 Hadoop Yarn上, 实现动态部署, 一个命令即可批量实现批量部署或者批量关闭部署, 实现Web 运行环境的动态管理.

使用场景: 在某些不充分了解系统压力的 Web 项目, 或者访客具有群体效应的业务环境. 如: 在少量时间有大量访问, 访问具有突发性. 当然, 如果把 Hadoop Yarn 当做云操作系统, 也完全可以把任何 Web 应用部署在其上, 可以减少硬件投入.

##部署环境

  • JDK: jdk 1.6 或者 jdk1.7. 在 jdk1.8上没有测试
  • Jetty: jetty-8.1.17
  • Hadoop: 2.2.0
  • 操作系统: Lunix, Mac 系统上, JettyAppMaster 不能杀掉 Web Instance, 这个 Linux 和 Mac 系统的 PID 生成规则有关.

##部署

  1. 解压 jetty-on-yarn-0.1.0.tar.gz, 到 Linux 系统任意位置
  2. jetty-8.1.17.zip 需要上传到 HDFS 的 /lib/jetty/ 目录下
  3. 把相关的 war 放置到 HDFS 的任意目录. 案例中是放到 /lib/jetty 目录下.

###Jetty-On-Yarn 支持的命令

可使用 jetty-on-yarn help 查看支持的命令.

命令行如果有任何异常, 可加 '-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

./jetty-on-yarn yarn 时只需要输入 Y 即可启动 Jetty-On-Yarn.

弹性部署, 增加 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

配置:

  1. hadoop 配置请参考Hadoop 的 core-site.xml, hdfs-site.xml, yarn-site.xml
  2. Jetty 需要默认的 jetty.xml, webdefault.xml.
  3. jetty.yarn.properties, 控制 JettyAppMaster 的行为

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需为: /conf/webdefault.xml

<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 包基本都能部署. ./jetty-on-yarn yarn-add -appid application_1449726747657_0010 -wars /lib/jetty/hellp.war 即可部署一份, 如果没有 jetty context 的 xml 描述文件, 该 WebServer 的 ContextPath 会自动映射为: http://host:port/hellp.war. 这是因为 Jetty 遇到没有 xml 描述的 war 包自动部署的结果,当然 Jetty 也支持 xml 描述. JettyOnYarn 在不是应用时, 会自动扫描/lib/jetty/hellp.war的同目录下是否存在同名的 xml 文件/lib/jetty/hellp.xml. 如果存在该 xml, 则应用该 xml 的描述部署.

<?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>

的配置, 可以写任意的 path, 也可以是 "/". 同时,注意: /conf/webdefault.xml

##注册到 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


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
EasyQueue: 简单易用的PHP-Reids延迟队列发布时间:2022-03-25
下一篇:
vagrant_linux_shell: 自己用的安装hhvm和nginx的vagrant脚本发布时间:2022-03-25
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap