2016-01-13 20 views
5

Yapmam gereken iki görevi var aynı iş sürecinin bir parçası olan task1 ve task2. Son kullanıcıya, task1 tamamlandığında yanıt vermem gerekiyor, böylece yanıt süresinin en aza indirilmesi gerekiyor.EJB Eşzamansız yöntemlerini kullanmanın doğru yolu

Şu anki yaklaşımım task1 gerçekleştirmek ve task1 bittiğinde, zaman uyumsuz olarak task2 yöntemini çağırmaktır. task2 karmaşık ve bazı dış bağımlılık olduğu için yanıt süresi kontrolüm dışında. websphere 8.0 (kullanımda EJB konteyner) eşzamanlı yöntemler ve asenkron yöntemlerde

@Stateless 
public class SessionBean1 { 

    @Inject 
    SessionBean2 sessionBean2; 

    public void doTask1(){ 
     // task one stuff 
     sessionBean2.doTask2(); 
    } 

} 



@Stateless 
public class SessionBean2 { 

    @Asynchronous 
    public void doTask2(){ 
     // do task2 stuff 
    } 

} 

farklı diş havuzları tarafından işletilmektedir.

Benim ilk varsayımın, task2'un kötü performans göstermesi durumunda bile task1'un bir etkisi olmayacağı, ancak ne yazık ki bu doğru olmadığıydı.

task2 hatalı çalışıyorsa, zaman uyumsuz iş parçacığı havuzundaki tüm iş parçacıkları dolu olacaktır. Bu, asenkron ipliklerin serbest olmasını ve dolayısıyla task1'un etkisi olmasını beklemek için task1 neden olur.

websphrere sunucu günlüklerinde mesajı: The request buffer for thread pool WorkManager.WebSphere_EJB_Container_AsynchMethods_Internal_WorkManager has reached its capacity

Sorum Burada elde etmek çalışıyorum ulaşmak için uygun bir yol olacağını budur.

+0

Java EE 7 kullanıyorsanız, @AccessTimeout (value = xx) ek açıklamasını kullanabilirsiniz, ancak Websphere Java EE 6? – rjdkolb

+0

@mattfreake: Bağlantıda olduğu gibi [image] (http://2.1m.yt/itzn6So.jpg), async yöntem isteklerinin hiçbiri sınırlı değildir ve async dizilerinin sayısına bağlıdır. İş parçacığının sayısını artırabilirim, ancak birkaç dakika için görev2 kötü bir performans sergiliyor olsa bile, görev1im hala beklemek zorunda kalacak. Ayrıca iş parçacığının hiçbiri donanım yapılandırmasıyla sınırlandırılmamıştır. – ares

+1

@jjdkolb tarafından önerilen bir JMS kuyruğu kullanma fikri, iplik havuzunu boyutlandırmak sorunlu ise çok daha iyi bir fikirdir. –

cevap

2

aramanız gerekmektedir olarak inşallah

Bu kullanım örneğini uygun Yönetici Konsolu'nda "EJB eşzamansız yöntem çağırma ayarları" nın boyutu. Bu, asıl iş parçacığı havuzundan önce bir sıra, bu yüzden size biraz daha zaman kazandırabilir.

İdeal olarak bu, yukarıda önerilen zaman aşımları ile birlikte kullanılmalıdır.

+0

Bu iyi bir seçenek gibi görünüyor. Varsayılan olarak, çalışma süresi tarafından işlenir ve ayrılan iş parçacıklarının hiçbirine bağımlı değildir, ancak kaç tane olduğunu anlayamıyorum. Websphrere admin konsolundan son satır var mı? Çalışma zamanı şu anda 20 büyüklüğünü ve maksimum iş parçacığı sayısı değerini kullanır. – ares

+0

Görüntünüze baktığımda, "15 veya 20’den büyük" olarak kabul ediyorum. Bu durumda, durumda 20 olmalıdır. En fazla 15 adet iplik havuzu boyutunu koruyabilir ve kuyruğunuzu çok daha büyük bir şeye yükseltebilirsiniz. Umarım * sıra küçük bir bellek/işlemci ayak izine sahip olmalıdır, bu yüzden mevcut olanları bitirip donanım sınırlarınızı korurken görev bekletme isteklerinizi saklayabilir. Ama eğer görev2 bitmek için belirsiz bir zaman alabilirse, o zaman zaman aşımlarının gitmenin yolu olacağını düşünüyorum. –

2

Sanırım @AccessTimeout sizin için. Bir örnek görüyorum here Bu, .doTask2() 'nın çalışıp sorununuzu önleyebileceği süreyi sınırlayacaktır.

@Stateless 
public class SessionBean1 { 

    @Inject 
    SessionBean2 sessionBean2; 

    public void doTask1(){ 
     // task one stuff 
     sessionBean2.doTask2(); 
    } 

} 

SessionBean2

alternatif olarak
@Stateless 
public class SessionBean2 { 
    @AccessTimeout(60000)//default timeunit is TimeUnit.MILLISECONDS 
    @Asynchronous 
    public void doTask2(){ 
     // do task2 stuff 
    } 

} 

:

handle.get kullanımı, uyumsuz işlem sunar süresini sınırlamak için (xx TimeUnit.xx); yöntem. Ayrıca, Gelecek'i iade etmeniz ve sadece işe yaraması için geçersiz olmanız gerekmeyecektir. Başka bir alternatif "Work istek sırasını artırmak olacağını bir .get

@Stateless 
public class SessionBean1 { 

    @Inject 
    SessionBean2 sessionBean2; 

    public void doTask1(){ 
     // task one stuff 
     Future<Void> handle = sessionBean2.doTask2(); 
     // do other stuff 
     handle.get(10, TimeUnit.SECONDS);//If you want to block later 

    } 

} 

SessionBean2

@Stateless 
public class SessionBean2 { 

    @Asynchronous 
    public Future<Void> doTask2(){ 
     // do task2 stuff 
     new AsyncResult<Void>(Void); 
    } 

} 
+0

@AccessTimeout ekledikten sonra test yükleyeceğim ve sonuçları size bildireceğim. Ancak, çağrının aslında zaman aşımı olduğu durumlarda, görevim2 çağrılmayacaktı. – ares

+1

Eşzamansız olmasını ve her zaman çalıştırılmasını istiyorsanız, JMS kuyruğuna bir – rjdkolb

+0

... ya da EJB zamanlayıcı kullanın, bu da kullanılması daha kolay. –

İlgili konular