2

我有一个测试 EE7 应用程序,其中一个 servlet 调用一个 EJB,该 EJB 使用 ExecutorService 运行一组线程化的任务。与运行相同任务集的沼泽标准 Java 控制台应用程序相比,性能(每秒事务数)相差甚远 - 控制台应用程序中的 2.5k tps 与 EE 应用程序中的 50 tps(均使用 256 个线程调用重复代码 60 秒,EE 应用程序通过 SoapUI 完成)。

这些任务只是休眠 100 毫秒的虚拟实现。测试中,提交了5个并行任务;时序显示所有这些都按预期在 100-101 毫秒内完成 - Glassfish+Servlet+EJB 似乎根本不会增加太多开销。

我在 Windows 和 Linux 下都做了同样的测试,结果是一样的。在这两种情况下,我都使用带有默认 ManagedExecutorService 的 Glassfish 4.0。我已将最大连接数/缓存/bean/线程/等设置增加到 256。

注意:如果我只是调用 EJB 但不向 ExecutorService 提交任何内容,我会得到 9k tps。如果我从任务中等待,我会得到 5k tps。我的机器似乎永远不会耗尽资源(cpu 核心平均在 10-25% 之间,系统内存可用(尚未调整 jvm))。

我很欣赏这有点含糊,但您认为这更多是 Glassfish 的配置问题,还是在 Java EE7 中运行托管线程?我希望 Glassfish 至少有 1k tps,并希望有 2k。

更新:我已经尝试过 JBoss 的 Wildfly 8 beta,我得到了大约 5k tps - 一个巨大的差异。

从下面的代码重新创建:在 Netbeans 7.4 中创建一个针对 Glassfish 4/EE7 的 EE 应用程序,然后添加 Servlet 和 EJB。

EJB + 任务类:

package ejb;

import java.util.*;
import java.util.concurrent.*;
import java.util.logging.*;
import javax.annotation.Resource;
import javax.ejb.*;
import javax.enterprise.concurrent.ManagedExecutorService;

@Stateless
@LocalBean
public class NewSessionBean {
    @Resource(name="concurrent/__defaultManagedExecutorService")
    ManagedExecutorService executor;    

    public String businessMethod() {
        long start = System.currentTimeMillis();
        String message = "<p>starting businessMethod()</p>";

        List<MyTask> tasks = new ArrayList<MyTask>();
        for(int i = 0; i < 5; i++) {
            MyTask task = new MyTask(String.format("Task %d \r\n", i));
            tasks.add(task);
        }

        List<Future<String>> futures = new ArrayList<Future<String>>();
        int taskCount = tasks.size();
        for(int i = 0; i < taskCount; i++) {
            MyTask task = tasks.get(i);
            if(task != null) {
                 futures.add(executor.submit(task));
            }
        }

        int futureCount = futures.size();
        for(int i = 0; i < futureCount; i++) {
            Future<String> future = futures.get(i);
            if(future != null) {
                try {
                    message += future.get();
                } catch (InterruptedException ex) {
                    message += ex.getMessage();
                    Logger.getLogger(NewSessionBean.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ExecutionException ex) {
                    message += ex.getMessage();
                    Logger.getLogger(NewSessionBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

        long end = System.currentTimeMillis();

        message += String.format("<p>took %d ms (started at %d)</p>", end-start, start);

        return message;
    }
}

class MyTask implements Callable<String> {
    String message;

    public MyTask(String message) {
        this.message = message;
    }

    @Override
    public String call() throws Exception {
        if(message == null) message = "";

        long start = System.currentTimeMillis();
        message += String.format("<p>thread %s</p>", Thread.currentThread().getName());
        message += String.format("<p>started at %d</p>", start);

        Thread.sleep(100);

        long end = System.currentTimeMillis();
        message += String.format("<p>ended at %d (duration = %d ms)</p>", end, end-start);

        return message;
    }    
}

小服务程序:

package servlet;

import java.io.*;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.*;

public class NewServlet extends HttpServlet {
    @EJB
    ejb.NewSessionBean nsb;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet NewServlet</title>");            
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet NewServlet at " + request.getContextPath() + "</h1>");
            out.println(nsb.businessMethod());
            out.println("</body>");
            out.println("</html>");
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
}
4

0 回答 0