Jetty(嵌入式)的使用及测试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fd_mas/article/details/53241143

使用9.2.x。因为这个版本是JDK7的,9.3对应的JDK8。
嵌入模式中运行Jetty意味着放一个HTTP模块到你的应用中,而不是放你的应用到一个HTTP server中。

1 开发一个嵌入式SERVER的步骤

1)创建一个Server实例;
2)添加/配置连接器;
3)添加/配置Handlers和/或Contexts和/或Servlets;
4)启动Server;
5)在server上等待或者使用你的线程做其它事。
这里写图片描述
Connector负责接收客户端的HTTP请求,请求的处理是由Handler来完成的。

2 主要代码所在地:Handler

处理逻辑在Handler中完成,这也是你的主要代码所在地。
为了对一个请求产生一个响应,Jetty要求你在server上设置一个handler。一个handler可以:
1)测试/修改HTTP请求;
2)产生完整的HTTP响应;
3)调用另一个Handler(看HandlerWrapper);
4)选择一个或多个Handlers调用(看HandlerCollection)。

其核心代码示例:

public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException  
{  
        //response.setContentType("text/plain;charset=utf-8");
        //response.getWriter().println(new JSONObject(params));
        response.setContentType("text/html;charset=utf-8");  
        response.setStatus(HttpServletResponse.SC_OK);  
        baseRequest.setHandled(true); //本Handler将请求标记为已处理。

        response.getWriter().println("<h1>"+_greeting+"</h1>");  
}  

  在自定义Handler的时候,必须要实现这个方法,可以直接输出响应,也可以对Request做一些包装再把它交给下一个Handler。
  Handler的强大的地方是可以为Jetty Server设置若干Handler,每个Handler完成自己的功能。
  
传递给handle方法的参数是:
1)target:请求的目标,一个URI或者一个来自指定的分发器的名称;
2)baseRequest:Jetty易变的请求对象,总是被拆开;
3)request:不变的请求对象,可以被一个filter或者servlet包装;
4)response:响应,可以被一个filter或者servlet包装。

  handler设置响应状态、content-type、并在使用writer产生响应的body前将请求设置为handled(表示处理完成,不再传递到下一个handler处理)。

Handler集合和包装器
1)HandlerCollection
包含其它多个handler的集合,按顺序调用每一个handler(即使某个Handler将请求标记为已处理,即setHandled(true));。
2)HandlerList
一个handler集合,依次调用每一个handler,直到或者一个异常产生,或者响应被提交,或者request.isHandled()返回true。
3)HandlerWrapper
一个Handler基类,你能以面向方面编程的风格使用链接在一起的Handler。例如,一个标准web应用通过一个context、session、security和servlet handlers的链实现。
4)ContextHandlerCollection
一个特殊的HandlerCollection,使用请求URI(contextPath)的最长前缀选择一个包含的ContextHandler处理这个请求。

多个handler的处理:

    public static void main(String[] args) throws Exception  
    {  
        Server server = new Server(8081);  
        HandlerCollection hc =new HandlerCollection();  
        hc.setHandlers(new Handler[]{new HelloHandler(),new HelloHandlerScond()});  
        server.setHandler(hc);  
        server.start();  
        server.join();  
    }  

3 连接器

上面的代码,Server内部会创建一个默认的连接器实例,监听该端口的请求。然而,我们经常希望能够直接为Server实例初始化和配置一个或者多个连接器。

public static void main(String[] args) throws Exception  
    {  
        // The Server  
        Server server = new Server();  

        // HTTP connector  
        ServerConnector http = new ServerConnector(server);  
        http.setHost("localhost");  
        http.setPort(8080);  
        http.setIdleTimeout(30000);  

        // Set the connector  
        server.addConnector(http);  

        // Set a handler  
        server.setHandler(new HelloHandler());  

        // Start the server  
        server.start();  
        server.join();  
    }  

也可以根据需要,设置多个连接器,比如一个处理HTTP,一个处理HTTPS。

4 嵌入Servlets

Servlet可看成是类似于Jetty Handler,除了请求对象是不可变的。
Servlet在Jetty中被一个ServletHandler处理。
它使用标准路径匹配方法来匹配一个Servlet到一个请求。

public static void main(String[] args) throws Exception  
    {  
        Server server = new Server(8080);  

        ServletHandler handler = new ServletHandler();  
        server.setHandler(handler);  

// HelloServlet就是你按照Servlet的语法写的程序。   handler.addServletWithMapping(HelloServlet.class, "/*");  

        server.start();  
        server.join();  
    }  

5 验证程序的响应能力

写一个最简单的程序,做高并发访问的压力测试。
程序如下:

public class RestServer
{
    public static void main(String[] args ) throws Exception
    {
        Server server = new Server();

        ServerConnector connector = new ServerConnector(server);
        //http.setHost("localhost");
        connector.setPort(8080);
        //connector.setIdleTimeout(30000);
        server.setConnectors(new Connector[] { connector });

        server.setHandler(new HelloHandler());

        server.start();
        server.join();
    }
}
// ------- HelloHandler ---------
public class HelloHandler extends AbstractHandler {

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException
    {
        System.out.print("target=" + target + ", baseRequest=" + baseRequest.getQueryString());
        response.setContentType("text/plain; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);

        String xxx = request.getParameter("xxx");
        System.out.println(", xxx=" + xxx);

        PrintWriter out = response.getWriter();
        out.println("Hello, Jetty. 我来啦!");
        baseRequest.setHandled(true);
    }

}
  • 使用Apache ab做压力测试:
    就是httpd里面自带的一个执行文件。
ab -n 100000 -c 100 http://localhost:8080/ab?xxx=a1

ab的常用参数:
-n:总共的请求执行数,缺省是1;
-c:并发数,缺省是1;
-t:测试所进行的总时间,秒为单位,缺省50000s
-p:POST时的数据文件
-w: 以HTML表的格式输出结果

如果要用POST提交数据,增加以下内容:
-p d:/tmp/postfile.txt -T “application/x-www-form-urlencoded”
postfile.txt的内容就是标准的POST数据格式,例如:name=xxx&age=123。

压测结束后,看其结果报告,注意几个数据:
1)Failed requests。失败了多少
2)Requests per second。响应能力
3)Time per request。一个请求的响应时间

  因为apache不提供windows版的运行程序下载,所以,需要到ApacheHaus或XAMPP等第三方软件中找。这在Apache http的官网上可以找到他们的链接。在httpd下载页面上,”For Microsoft Windows”这个链接页面上有。
  到ApacheHaus中,下载对应版的文件即可,比如对应WIN10的包: Apache 2.4 VC14。下载解压后,到bin目录即可找到ab.exe。
  
- 使用jstat监测性能(GC等)、jmap监测内存

jps  // 找到Jetty程序的pid
jstat -gcutil PID 5000 //开始监测。每5秒(5000毫秒)显示一次
jmap -histo PID | less // 打印每个class的实例数目,内存占用,类全名信息

jstat,一般使用 -gcutil 查看gc情况:
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时

展开阅读全文

没有更多推荐了,返回首页