5 Replies Latest reply on Sep 25, 2012 11:44 PM by ybxiang.china

    Remote EJB is 3x slower than WebService in 7.1 latest from git

    willreichert

      We are testing with the Specj application where the same bean is exposed as both an EJB and a Web Service. The benchmark results were showing the remote EJB calls took 3x longer than calls to the same bean via the web service. I created a sample application that returns the same object (to minimize gc overhead) and exposed it as both a Web Service and Remote EJB. The sample also demonstrates a 3x increase in response time when using the EJB interface. I am running on the latest build from git master and use a single threaded app to drive load so I doubt concurrency is part of the problem. I ran the test with OProfile and the highest sampled Java method was Ljava/io/DataOutputStream.write(). I unfortunately cannot get the full callstack because attaching byteman to that method results in an infinite loop (unless someone has a more sophisticated way to attach without capturing the logging for log files).

       

      Sample Applicaiton

       

      The payload for the test

      public class CalendarPayload implements Serializable{
                private static final long serialVersionUID = 696756365558432253L;
                private int int1;
                private int int2;
                private Calendar calendar;
      
                public CalendarPayload(){
                          int1 = 1; int2 = 2; calendar = new GregorianCalendar());
                }
              public int getFirst(){return int1;}
              public int getSecond(){return int2;}
              public Calendar getCalendar(){return calendar;}
      }
      

       

      The service

       

      @Stateless
      @WebService
      public class SimpleBean implements Simple {
                private CalendarPayload payload = new CalendarPayload();
      
                @Override @WebMethod
                public int getInt() {return 0;}
      
                @Override @WebMethod
                public Integer getInteger() {return new Integer(1);}
      
                @Override @WebMethod
                public Calendar getCalendar() {return new GregorianCalendar();}
      
                @Override @WebMethod
                public CalendarPayload getPayload() {return new CalendarPayload();}
      
                @Override
                public CalendarPayload getStaticPayload() {return payload;}
      }
      
        • 1. Re: Remote EJB is 3x slower than WebService in 7.1 latest from git
          jaikiran

          We'll need some more details. What kind of application is the client? Running in a separate JVM? What does the client code look like (both for webservice and EJB).

          • 2. Re: Remote EJB is 3x slower than WebService in 7.1 latest from git
            jaikiran

            I did not notice that you had attached a sample application. I'll take a look, but it will also help if you attach the client application too.

            • 3. Re: Remote EJB is 3x slower than WebService in 7.1 latest from git
              willreichert

              The original problem is observed when using Faban load harness with the specJ load driver but I created a slimmed down client that I run from eclipse to simulate the load from a user perspective. The client is a single threaded process that I just run from eclipse and use to drive load against JBoss running on the same computer (I know, violates SUT rules but this is just a small p.o.c. test).  Here is the code I use for the client:

               

               

              public static void main(String...args){
                try {
                  System.out.println(System.getProperty("java.version"));
                  System.setSecurityManager(new RMISecurityManager());
                  final Hashtable<String,String> prop = new Hashtable<String,String>();
                  prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.as.naming.InitialContextFactory");
                  prop.put(Context.PROVIDER_URL, "w520:1099");
                  prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
                  prop.put("com.sun.appserv.iiop.endpoints", "w520:1099");
                  prop.put("org.omg.CORBA.ORBInitialHost", "w520");
                  prop.put("org.omg.CORBA.ORBInitialPort", "1099");
                  prop.put("networkaddress.cache.ttl", "0");
                  prop.put("sun.net.inetaddr.ttl", "0");
              
                  final InitialContext context = new InitialContext(prop);
                  Simple simpleEjb = (Simple) context.lookup("ejb:StatelessCalendarEAR/StatelessCalendarEJB/SimpleBean!org.perf.test.Simple");
                  String wsdlLocation = "http://localhost:8080/StatelessCalendarEJB/SimpleBean?wsdl";
                  String qName = "http://test.perf.org/";
              
              
                  URL wsdlDocumentLocation = new URL(wsdlLocation);
                  QName serviceName = new QName(qName, "SimpleBeanService");
                  Service s = Service.create(wsdlDocumentLocation, serviceName);
              
              
                  Simple simpleWs = s.getPort(Simple.class);
              
                  int count = 1000000;
                  int buckets= 25;
                  histogramStaticPayload(simpleWs, count, buckets,"./ws.payload.hist.txt");
                  histogramStaticPayload(simpleEjb, count, buckets, "./ejb.payload.hist.txt");
                } catch (NamingException e) {
                  e.printStackTrace();
                } catch (MalformedURLException e) {
                  e.printStackTrace();
                }
              }
              public static void histogramStaticPayload(Simple simple, int count,int buckets,String file){
                int times[] = new int[count];
                int hist[] = new int[buckets];
                int div = count/10;
                long start = 0;
                for(int i=1; i<=count; i++){
                  if(div>0 && i%div==0)
                    System.out.println(i);
                  start = System.nanoTime();
                  simple.getPayload();
                  int time = (int)(System.nanoTime()-start);
                  times[i-1]= time;
                  int bucket = time/1000000;
                  if(bucket > buckets-1)
                    bucket = buckets-1;
                  ++hist[bucket];
                }
                try {
                  FileWriter writer = new FileWriter(file);
                  PrintWriter out = new PrintWriter(writer);
                  out.print("[");
                  for(int i=0; i<hist.length;i++){
                    if(i>0){
                      out.print(",");
                      System.out.print(",");
                    }
                    out.print(""+hist[i]);
                    System.out.print(hist[i]);
                  }
                  System.out.print("\n");
                  out.print("]\n");
              
                  for(int i=0; i<count; i++){
                    if(i>0)
                      out.print("\n");
                    out.print(""+times[i]/1000);
                  }
                  out.flush();
                  out.close();
                } catch (IOException e) {
                  e.printStackTrace();
                }
              }
              
              • 4. Re: Remote EJB is 3x slower than WebService in 7.1 latest from git
                jaikiran

                It turns out the unmarshalling of the return value from the method invocation is expensive for EJB calls as compared to WS. We use jboss-marshalling for EJB invocations. I'm not sure how the WS implementation deals with respect to unmarshalling. I'll have to take a look at that part to understand better.

                • 5. Re: Remote EJB is 3x slower than WebService in 7.1 latest from git
                  ybxiang.china

                  Dear pai,

                   

                           I has the same issue. I post it here: https://community.jboss.org/thread/198059.

                           I really can NOT endure the slow EJB calling.