Я предоставляю доступ к следующему сессионному компоненту EJB3 без сохранения состояния через веб-сервис.
@Stateless
public class UserRoleFacade implements UserRoleFacadeLocal {
@PersistenceContext(unitName = "SimpleEA-ejbPU")
private EntityManager em;
public int count() {
System.out.println("thisClass=" + this.getClass().getSimpleName() + "@" + this.hashCode() + ", em=" + em);
try {
Thread.sleep(10000); // 10 sec
} catch (InterruptedException ex) {
Logger.getLogger(UserFacade.class.getName()).log(Level.SEVERE, null, ex);
}
return 0;
}
}
Как видите, он мало что делает - фактически он ничего не делает, но спит 10 секунд после получения запроса. Я создал этот код в качестве эксперимента, чтобы узнать больше о том, как EntityManager работает в многопоточной среде.
Веб-сервис выглядит так:
@WebService(serviceName="UserRole")
public class UserRoleWebService {
@EJB
private UserRoleFacadeLocal ejbRef;// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Web Service Operation")
@WebMethod(operationName = "count")
public int count() {
return ejbRef.count();
}
}
Чтобы выполнить тест, я запустил 5 браузеров, указал на тестер веб-службы и запустил их все. Вот результаты, которые были распечатаны:
INFO: thisClass=UserRoleFacade@11511572, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@23961
INFO: thisClass=UserRoleFacade@32513964, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@1af5c5a
INFO: thisClass=UserRoleFacade@11511572, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@23961
INFO: thisClass=UserRoleFacade@32513964, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@1af5c5a
INFO: thisClass=UserRoleFacade@11511572, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@23961
Чтобы выполнить тест, я воспользовался советом Божо и настроил JMeter с 15 потоками. Вот результаты, которые были распечатаны:
INFO: thisClass=UserRoleFacade@3869465, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@55a5d0, thread=Thread[http-thread-pool-17025-(2),10,Grizzly]
INFO: thisClass=UserRoleFacade@5558947, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@d0e940, thread=Thread[http-thread-pool-17025-(1),10,Grizzly]
INFO: thisClass=UserRoleFacade@20208512, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@635f47, thread=Thread[http-thread-pool-17025-(39),10,Grizzly]
INFO: thisClass=UserRoleFacade@23924919, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@16478c1, thread=Thread[http-thread-pool-17025-(41),10,Grizzly]
INFO: thisClass=UserRoleFacade@6172173, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@121691b, thread=Thread[http-thread-pool-17025-(40),10,Grizzly]
INFO: thisClass=UserRoleFacade@3869465, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@55a5d0, thread=Thread[http-thread-pool-17025-(2),10,Grizzly]
INFO: thisClass=UserRoleFacade@5558947, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@d0e940, thread=Thread[http-thread-pool-17025-(1),10,Grizzly]
INFO: thisClass=UserRoleFacade@23924919, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@16478c1, thread=Thread[http-thread-pool-17025-(39),10,Grizzly]
INFO: thisClass=UserRoleFacade@20208512, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@635f47, thread=Thread[http-thread-pool-17025-(40),10,Grizzly]
INFO: thisClass=UserRoleFacade@6172173, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@121691b, thread=Thread[http-thread-pool-17025-(41),10,Grizzly]
INFO: thisClass=UserRoleFacade@3869465, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@55a5d0, thread=Thread[http-thread-pool-17025-(2),10,Grizzly]
INFO: thisClass=UserRoleFacade@5558947, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@d0e940, thread=Thread[http-thread-pool-17025-(1),10,Grizzly]
INFO: thisClass=UserRoleFacade@23924919, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@16478c1, thread=Thread[http-thread-pool-17025-(39),10,Grizzly]
INFO: thisClass=UserRoleFacade@6172173, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@121691b, thread=Thread[http-thread-pool-17025-(41),10,Grizzly]
INFO: thisClass=UserRoleFacade@20208512, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@635f47, thread=Thread[http-thread-pool-17025-(40),10,Grizzly]
Как вы можете видеть (и то, что я вижу визуально из браузера), это то, что только 2 одновременно работают только 5 потоков. И экземпляры EJB, и EntityManager выглядят так, как будто они где-то ограничены. Где это?
На сервере приложений Glassfish мои настройки выглядят так:
- пул соединений: 8 начальных подключений, 32 макс.
- контейнер ejb: 0 начальных, 32 макс.
Полагаю, все в порядке. Есть ли где-нибудь настройка для EnitiyManager? На что еще мне смотреть?