Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > EJB клиент


Автор: KostenkoSergey 21.4.2010, 16:14
Интерессует следующий момент:
Есть некое Swing-приложение, которое работает с EJB 3.0 через удалённые интерфейсы.
У меня стоит JBoss 4.2.3 - локально приемлемо, а на удалённом сервере - вроде как медлительно получается.

Отсюда вопросы:
1. Насколько оптимальна такая схема с точки зрения производительности ?
2. Насколько требователен к каналам связи rmi\iiop протокол?
3. Возможно есть ещё какие то более "быстрые" протоколы для вызова удалённых тырфейсов ?

зы. Может имеет смысл сделать в качестве точки входа сервлет, который будет дёргать бины локально и позаморачиваться с взаимодействием клиента с сервлетом.

pps может кто встречал цифры с тестами времени отклика веб-сервиса и удалённого вызова ?

Автор: COVD 21.4.2010, 18:17
Если локально быстро, а удаленно медленно, значит медленный интернет. 
зы. бессмысленно.

Автор: KostenkoSergey 22.4.2010, 12:42
Локально - оно наверное через одну ВМ работает - сичас пишу сравнительный тест - отпишусь о результатах.

Автор: KostenkoSergey 22.4.2010, 13:40
И так для теста был выбран JBoss 4.2.3 GA, EJB 3.0, Hessian как веб сервис.
Если кому лень читать суть изложу что проверял:
1. Локап ремоте-ежб, и выполнение 50-ти удалённых вызовов
2. 50 вызовов вебсервиса
3. 50 вызовов EJB через веб-сервис

Код который использовался привожу ниже:

Интерфейс - общий для вебсервиса и EJB:
Код

import javax.ejb.*;

@Remote
public interface IHello {
    public String sayHello(); 
    public String sayHelloViaEjb();
}


Код EJB:
Код

import javax.ejb.Stateless;
import org.jboss.annotation.ejb.RemoteBinding;

@Stateless
@RemoteBinding(jndiBinding = "HelloBean")
public class HelloBean implements IHello{
    public String sayHello() {
        return "Hello EJB Remote";
    }
    public String sayHelloViaEjb() {
        return "not implement";
    }
}


Код вебсервиса:
Код

import javax.naming.InitialContext;
import com.caucho.hessian.server.HessianServlet;
import ua.ks.ejb.IHello;

public class HelloServic extends HessianServlet implements IHello{
    IHello ih = null; 
    public HelloServic() {
        try {
            InitialContext ctx = new InitialContext();
            ih = (IHello)ctx.lookup("HelloBean");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    public String sayHello() {
        return "HelloService";
    }
    public String sayHelloViaEjb() {
        return "HelloService [" + ih.sayHello()+"]" ;
    }
}


И собсно говоря, код клиента:
Код

package ua.ks.client;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Properties;
import javax.naming.InitialContext;
import com.caucho.hessian.client.HessianProxyFactory;
import ua.ks.ejb.IHello;

public class WsVsEjbRemote {

    public static void main(String[] arg) throws Exception {
        testEJBRemote();
        testWebService();
        testEJBOwerWebService();
    }

    /**
     * EJB TEST 
     * @throws Exception
     */
    public static void testEJBRemote() throws Exception {
        Properties properties = new Properties();
        properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
        properties.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
        properties.put("java.naming.provider.url","jnp://host:1099");
        InitialContext ctx = new InitialContext(properties);
        
        long time = System.currentTimeMillis();
        IHello ih = (IHello)ctx.lookup("HelloBean");
        System.out.println("Lokup time: " + (System.currentTimeMillis() - time)+ " ms.");
        
        time = System.currentTimeMillis();
        for (int i=0; i<50; i++) {
            System.out.print(ih.sayHello()+" ");
        }
        System.out.println(" \n Execute 50 remote call time: " + (System.currentTimeMillis() - time)+ " ms.");
    }
    /**
     * WEBSERVICE TEST
     * @throws Exception
     */
    public static void testWebService() throws Exception {
        String url = "http://host/HessianWS/HelloServic";
        HessianProxyFactory factory = new HessianProxyFactory();
        
        long time = System.currentTimeMillis();
        IHello service = (IHello) factory.create(IHello.class, url);
        System.out.println("Create proxy time: " + (System.currentTimeMillis() - time)+ " ms.");

        time = System.currentTimeMillis();
        for (int i=0; i<50; i++) {
            System.out.print(service.sayHello() + " ");
        }
        System.out.println("\n Execute 50 webservice call time: " + (System.currentTimeMillis() - time)+ " ms.");
    }
    
    
    /**
     * EJB VIA WEBSERVICE TEST
     */
    public static void testEJBOwerWebService() throws Exception{
        String url = "http://host/HessianWS/HelloServic";
        HessianProxyFactory factory = new HessianProxyFactory();
        
        long time = System.currentTimeMillis();
        IHello service = (IHello) factory.create(IHello.class, url);
        System.out.println("Create proxy time: " + (System.currentTimeMillis() - time)+ " ms.");

        time = System.currentTimeMillis();
        for (int i=0; i<50; i++) {
            System.out.print(service.sayHelloViaEjb() + " ");
        }
        System.out.println("\n Execute 50 ejb call via webservice time: " + (System.currentTimeMillis() - time)+ " ms.");
    }
    
}


Резултат выполения последнего на интернет-канале 3,1 Мбит/с сдедующий:

Lokup time: 687 ms.
Hello EJB Remote Hello EJB Remote Hello EJB Remote Hello .............  
Execute 50 remote call time: 13453 ms.

Create proxy time: 0 ms.
HelloService HelloService HelloService HelloService HelloService..........
Execute 50 webservice call time: 5609 ms.

Create proxy time: 0 ms.
HelloService [Hello EJB Remote] HelloService [Hello EJB Remote] ............
Execute 50 ejb call via webservice time: 5672 ms.


Такие вот пирожки. Имхо, результат тут мало зависит от скорости канала  - проверю ещё дома на 10 мбит/c, думаю результат будет соизмерим.

ззы. Мож кому интересно - на локалхосте результаты такие:
Lokup time: 343 ms.
Hello EJB Remote Hello EJB Remote ....
Execute 50 remote call time: 1047 ms.

Create proxy time: 0 ms.
HelloService HelloService HelloService.......
Execute 50 webservice call time: 297 ms.

Create proxy time: 0 ms.
HelloService [Hello EJB Remote] HelloService [Hello EJB Remote] .........
Execute 50 ejb call via webservice time: 234 ms.

Автор: COVD 22.4.2010, 18:11
Вы подтвердили факт, что локальные коммуникации обычно всегда быстрее (еще и надежнее), чем удаленные.
А вот то, что testEJBOwerWebService у вас работает быстрее, чем testEJBRemote - это странно.

В RMI встроены несколько протоколов связи и выбирается оптимальный. В том числе и HTTP, который применяется для туннелирования, если остальные протоколы запрещены (файерволы). Но для этого на серверной стороне предполагается сервлет, который работает в паре с RMI. Прямое соединение через RMI не может проигрывать варианту  EJBOwerWebService.  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)