设为首页 收藏本站
查看: 927|回复: 0

[经验分享] Jetty 服务器的知识

[复制链接]

尚未签到

发表于 2017-2-27 11:52:55 | 显示全部楼层 |阅读模式
  Jetty 服务器的知识
  也许你还没有听说过这个Jetty服务器,不过它确实是一种比较轻量级的Java服务器,和Tomcat一样,专门解释JavaWeb程序的服务器。因为在之前学习Java Web 的时候总是遇到Tomcat配置出错,什么WebRoot目录之类的,不知道你有没有遇到过。偶然的一个机会接触到了Jetty服务器,因为我们可以直接在Java项目中使用这个服务器,需要的就只是简单地把相关的JAR包导入即可,也可以像普通的服务器那样使用。
  1.直接当做服务器使用
  Jetty和Tomcat一样,可以直接当做服务器使用。我这里下载的是最新的Jetty9,直接解压就可以了。插一句话,其实学习这些框架知识,最好的资源就是官方网站的说明文档。虽然是英文的,但是使用的都是简单地句子,应该不是很大的问题。我学习这些基本都是参考的说明文档,做一下笔记,方便自己将来使用的时候查阅。
  官方文档中开始的时候这样写道:
  Jetty is an open-source project providing an HTTP server, HTTP client, and javax.servlet container.
  This guide is in two parts.
  The first part emphasizes beginning to use Jetty. It provides information about downloading Jetty, changing things like the port Jetty runs on, adjusting logging levels, and configuring many of the most common servlet container features such as JNDI, JMX, and session management.
  The second part describes advanced uses of Jetty, providing in depth coverage of specific features like our highly scalable async client, proxy servlet configuration, the Jetty Maven plugin, and using Jetty as an embedded server. The advanced section includes tutorials, howtos, videos, and reference materials.”
  应该不是很难看懂吧,主要说了Jetty入门使用,Jetty作为容器特性比如JNDI, JMX, Session Management等等,然后继续深入的讲解Jetty的一些知识,比如Jetty的高度可扩展性的异步客户端实现机制,代理服务器的配置,Maven的配置和使用Jetty作为嵌入式服务器的应用等等。
  先启动服务器:
  直接解压之后,便可以运行,不过之前需要我们在环境变量中PATH添加JDK的路径,之后还需要新建JAVA_HOME,Value是JDK的安装路径,因为在Tomcat的时候,没有添加这一个变量,就无法启动,不知道这个会不会,还是添加上比较好。
  启动命令:java –jar start.jar jetty.port=8001(可以写到一个bat批处理文件,或者是Shell脚本)
  我们会发现Jetty的主页是没有任何东西的,因为根目录中是没有任何东西的,所以需要我们新建一个HTML文件,便可以看到。打开浏览器便可以看到响应的结果。
  可能遇到的问题:
  直接双击了start.jar, 但是无法关掉服务器。
  开始的时候我直接双击的start.jar,也是可以运行的,但是问题就出来了,我不确定是否运行,便打开浏览器运行,发现服务器已经在运行,但是如何终止呢,我找了半天也没找到,最后在进程控制中强制咔掉了JAVA的所有服务,才终止了服务器的运行。这个时候服务器的根目录在jetty\demo-base\webapps\ROOT中,建议还是不要这样运行,
  JDK环境配置问题
  上面知识一个简单地服务器,但是只能够运行HTML文件,所以我们小心点测试一下JSP页面怎样,会发现虽然可以启动服务器,但是运行代码的时候报错:
  HTTP ERROR 500
  Problem accessing /. Reason:
  Server Error
  Caused by:
  org.apache.jasper.JasperException: PWC6345: There is an error in invoking javac.  A full JDK (not just JRE) is required
  at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:92)
  at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:378)
  我找了一下资料,说是什么使用的是系统的JDK,所以在运行的时候找不到我们安装的JDK目录,因为在安装JDK的时候,会网C盘系统中复制Java.exe, 这样系统运行的时候优先使用系统的,而导致找不到我们安装的完整版的JDK,所以就无法运行了,出现了A full (not just jre) is required. 的系统错误。
  其实Jetty中有关于系统运行之前的配置信息,保存在同目录下面的start.ini文件中,里面有关于开启JSP服务的知识,将最后面一句前面的#删除即可
  #
  # Initialize module jsp
  #
  --module=jsp
  # JSP Configuration
  # To use an non-jdk compiler for JSP compilation uncomment next line
  #-Dorg.apache.jasper.compiler.disablejsr199=true
  改成: -Dorg.apache.jasper.compiler.disablejsr199=true
  这样便可以直接运行JSP文件了,终止程序的话,退出当前的窗口即可。我们可以讲系统的日志输入到文件中 java –jar start.jar jetty.port=8001 > server.log
  2.关于Jetty的一些参数设置
  jetty.home: The property that defines the location of the jetty distribution, its libs, default modules and default XML files (typically start.jar, lib, etc)
  jetty.base: The property that defines thelocation of a specific instance of a jetty server, its configuration, logs and web applications (typically start.ini, start.d, logs and webapps)
  jetty.port: jetty start port, 这一个配置在start.d/http.ini文件中,可以修改
  java –jar start.jar –add-to-startd=httpd
  3.使用Maven配置
<dependency>

  <groupId>org.eclipse.jetty</groupId>

  <artifactId>jetty-project</artifactId>

  <version>9.1.3-SNAPSHOT</version>

</dependency>

  也许你还不知道Maven,其实我也是半瓶水,一般在里linux上比较好用,他会根据依赖的包的关系,自动下载相应的包,我们只需要dependency配置文件。
  4.Jetty的嵌入式服务器
  在Java应用中使用Jetty作为嵌入式服务器,我们可下载一个完整版的JAR包,地址是http://central.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/.
  此外还要添加servlet.jar
  源代码:
  //TestMain.java
package jetty_test;


import org.eclipse.jetty.server.Server;

import org.eclipse.jetty.server.ServerConnector;

import org.eclipse.jetty.server.handler.DefaultHandler;


public class TestMain {


    public static void main(String[] args) throws Throwable {

        // TODO Auto-generated method stub

        Server serverJetty = new Server();

        ServerConnector connector_one = new ServerConnector(serverJetty);

        ServerConnector connector_two = new ServerConnector(serverJetty);

        connector_one.setPort(8000);

        connector_two.setPort(8001);

        serverJetty.setConnectors(new ServerConnector[]{connector_one, connector_two});

        serverJetty.setHandler(new MyHandler());

        serverJetty.start();

        serverJetty.join();   

    }

  }
/*

* author yang

* MyHandler.java

*/

package jetty_test;


import java.io.IOException;

import java.util.Date;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.eclipse.jetty.server.Handler;

import org.eclipse.jetty.server.Request;

import org.eclipse.jetty.server.Server;


public class MyHandler implements Handler {

    @Override

    public void handle(String target, Request baseRequest, HttpServletRequest request,

            HttpServletResponse response) throws IOException, ServletException {

        // TODO Auto-generated method stub

        System.out.println("target:" + target);

        System.out.println(request.getRequestURL().toString());

      

        response.setCharacterEncoding("utf-8");

        response.setContentType("text/html;charset=utf-8");

        response.setStatus(HttpServletResponse.SC_OK);

        response.getWriter().write("<b>yangtengfei</b>"+ (new Date()).toLocaleString());

        response.flushBuffer();


    }

    /*

    省略自动生成的代码

    */

}

  测试可以哎,这就是将WebServer嵌入到应用程序中,其中最为关键的就是Handle,也就是分发处理请求,传入的主要参数HttpServletRequest & HttpServletResponse,将结果传入到response即可。
  对于一些比较特殊的情况,在嵌入式应用程序,可能需要配置Jetty服务器的参数,我们可以使用jetty.xml加载配置信息到XmlConfiguration中,然后配置到Server,我还是没有配置成功,建议使用Java语言进行配置,不适用XML文件了。
  5.理论性的介绍
  因为我们已经学会简单地使用Jetty服务器了,那么为什么还要去了解Jetty的理论知识。其实学习一部分知识,不仅仅要学会如何使用,还要知道这个框架知识的优缺点,什么情况下使用这部分的知识应用于实际。这里的Jetty服务器有什么好的地方?
  Jetty是一个使用Java实现的、开元的基于标准的,并且具有丰富功能的HTTP服务器和 Web 容器。Jetty的用途:传统的Web服务器、动态的内容服务器、嵌入到Java应用。
  特征
  易用性:使用API 或者是XML配置即可,默认配置可以满足绝大部分需求,将Jetty可嵌入到应用程序中,切代码量非常的少。
  可扩展性:在Ajax的Web 2.0应用程序中,每一个连接需要保持很长的时间,这样的线程和内存消耗会急剧增加,从而导致整个系统因为单一组件陷入瓶颈而影响程序的整体性能。Jetty非常轻松的解决了这个问题:
  即使有大量服务请求的情况支架,系统的性能也可以保持在一个可以接受的状态;利用Configuration机制来处理大量的用户请求以及时间比较长的连接。同时Jetty设计了非常良好的接口,所以我们可以根据自己的而需要进行修改。
  易嵌入型:就是将Jetty嵌入到Java应用程序中,也就是嵌入式Web服务器。
  6.Jetty 的Configuration机制
  在Web 2.0时代中的Ajax技术中,一个核心对象就是XMLHttpRequest对象,这个对象支持异步请求(异步请求:当客户端发送一个请求到服务器端的时候,客户端不必一直等待服务器的响应。这样就不会造成真个页面的刷新,给用户带来更好的用户体验,当服务器返回响应的时候,客户端利用一个JavaScript函数对返回值进行处理,更新页面上的部分元素的值)这种请求只是在很小的一部分情况下才会发生。如果实现这一种服务器有了响应之后客户端会立马知道的功能呢?有两种方式:轮询,也就是让浏览器每隔一段时间就请求服务器;Comet,维持服务器和客户端的长连接机制。
  轮询的方式最大的缺点就是产生大量的传输浪费。因为很多的请求时无效的请求,占用大量的带宽资源,加剧了服务器端的负载,尤其是针对邮件系统,需要个很长的时间才会更新。如果设置的时间间隔很长的话,客户端就不能得到及时的响应。
  使用Comet技术的话,客户端就必须保证一个长连接。一般情况下,服务器的每一个Servlet都会独自占用一个线程,这样就会导致服务器端有大量的线程同时存在,当客户端非常多的时候,就会对服务器的处理能力造成极大的挑战。
  在Java中使用Java语言的非阻塞IO技术处理并发的大量连接。Jetty处理长连接机制:一个被称为Configuration的特性,Jetty可以使用一个线程同时处理多个客户端发送的异步请求:
  public class ChatContinuation extends HttpServlet{
  public void doPost(HttpServletRequest request, HttpServletResponse response){
  postMessage(request, response);
  }
  private void postMessage(HttpServletRequest, HttpServletResponse response){
  HttpSession session  = request.getSession(true);
  People people = (People)session.getConfiguration(request,this);
  If(!people.hasEvent()){
  Continuation continuation = Continuation.getContinuation(request,this);
  people.setContinuation(continuation);
  continuation.suspend(1000);//这个时候,线程是挂起,是可以处理其他的请求的,大大提高了程序的并发性能,使长连接获得很好的扩展性。
  }
  people.setContinuation(null);
  people.sendEvent(response);
  }
  }
  如果不使用Continuation机制的话,只能够使用线程挂起进行等待,参考代码如下:
  public class Chat extends HttpServlet{
  public void doPost(HttpServletRequest request, HttpServletResponse response){
  postMessage(request,response);
  }
  private void postMessage(HttpServletRequest request, HttpServletResponse response){
  HttpSession session = request.getSession(true);
  People people = (People)session.getAttribute(session.getId());
  while(!people.hasEvent()){
  try{
  Thread.sleep(1000);
  }catch(InterruptException e){
  e.printStack();
  }
  }
  }
  }
  Jetty的Continuation机制:
  使用Continuations机制,Jetty必须配置为使用它的SelectChannelConnector处理请求,这个Connector构建在java.nio.API之上,允许它维持每个连接而不用小号一个县城。当使用SelectChannelConnector时, ContinuationSupport.getContinuation()提供一个SelectChannelConnector.RetryContinuation实例。在RetryContinuation上调用suspend函数的时候,会抛出运行时的异常。该异常传递到filter链,最后被SelectChannelConnector捕获。但是不会发送异常到客户端,而是将请求维持在未决Continuation队列里面,则HTTP连接保持开放。这样用来服务请求的线程返回给ThreadPool,然后又可以用来服务其他的请求。暂停的请求停留在未决Continuation队列里直到指定的过期时间,或者是在他的Continuation上调用resume()。当其中的任何一个条件被触发的时候,请求就会被重新提交给Servlet(通过Filter链),整个请求过程被重播,知道RetryRequest异常不在抛出,然后按照正常的情况执行。
  追寻梦的飞飞
  2014.03.24 于广州

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-347955-1-1.html 上篇帖子: EClipse + Jdk + ApacheAnt + jetty + GWT + MySQL(Navicat) 下篇帖子: maven+jetty.自动集成运行环境
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表