2014-10-27 14 views
7

yüksek eşzamanlılık nasıl kontrol etmekBu Future and Thread.sleep örneğinde spray.io ile yüksek eşzamanlılık nasıl elde edilir? Aşağıdaki POC çalışıyordum

implicit def executionContext = context.system.dispatchers.lookup("async-futures-dispatcher") 
    implicit val timeout = 10 seconds 


    val contestroute = "/contestroute" { 
     get { 
      respondWithMediaType(`application/json`) { 
      dynamic { 
       onSuccess(
        Future { 
        val start = System.currentTimeMillis() 
        // np here should be dealt by 200 threads defined below, so why 
        // overall time takes so long? why doesn't it really utilize all 
        // threads I have given to it? how to update the code so it 
        // utilizes the 200 threads? 
        Thread.sleep(5000) 
        val status = s"timediff ${System.currentTimeMillis() - start}ms ${Thread.currentThread().getName}" 
        status 
        }) { time => 
        complete(s"status: $time") 
       } 
      } 
      } 
     } 
    } 

Benim yapılandırma: Ancak

async-futures-dispatcher { 
    # Dispatcher is the name of the event-based dispatcher 
    type = Dispatcher 
    # What kind of ExecutionService to use 
    executor = "thread-pool-executor" 
    # Configuration for the thread pool 
    thread-pool-executor { 
    # minimum number of threads to cap factor-based core number to 
    core-pool-size-min = 200 
    # No of core threads ... ceil(available processors * factor) 
    core-pool-size-factor = 20.0 
    # maximum number of threads to cap factor-based number to 
    core-pool-size-max = 200 
    } 
    # Throughput defines the maximum number of messages to be 
    # processed per actor before the thread jumps to the next actor. 
    # Set to 1 for as fair as possible. 
    throughput = 100 
} 

böyle apache tezgah çalıştırın:

ab -n 200 -c 50 http://LAP:8080/contestroute 

Sonuçlar I şu şekilde olsun:

Server Software:  Apache-Coyote/1.1 
Server Port:erred:  37500 bytes 
HTML transferred:  10350 bytes 
Requests per second: 4.31 [#/sec] (mean) 
Time per request:  34776.278 [ms] (mean) 
Time per request:  231.842 [ms] (mean, across all concurrent requests) 
Transfer rate:   1.05 [Kbytes/sec] received 

Connection Times (ms) 
       min mean[+/-sd] median max 
Connect:  5 406 1021.3  7 3001 
Processing: 30132 30466 390.8 30308 31231 
Waiting: 30131 30464 391.8 30306 31231 
Total:  30140 30872 998.9 30353 33228   8080 

Document Path:   /contestroute 
Document Length:  69 bytes 

Concurrency Level:  150 
Time taken for tests: 34.776 seconds 
Complete requests:  150 
Failed requests:  0 
Write errors:   0 
Non-2xx responses:  150 
Total transferred:  37500 bytes 
HTML transferred:  10350 bytes 
Requests per second: 4.31 [#/sec] (mean) 
Time per request:  34776.278 [ms] (mean) 
Time per request:  231.842 [ms] (mean, across all concurrent requests) 
Transfer rate:   1.05 [Kbytes/sec] received 

Connection Times (ms) 
       min mean[+/-sd] median max 
Connect:  5 406 1021.3  7 3001 
Processing: 30132 30466 390.8 30308 31231 
Waiting: 30131 30464 391.8 30306 31231 
Total:  30140 30872 998.9 30353 33228 

Büyük bir şey mi özlüyorum? spray ve futures benim verdiğim tüm konuları kullanmak için değiştirmek için neye ihtiyacım var?

sizin örnekte

+2

Bu örnek kod, ama neden 'Gelecek' olarak yürüten kodun içinde 'uyu'. Bunu yaparak, bu Gelecek'i 5 saniyeliğine görev dışı bırakan iş parçacığını alıyorsunuz ve bu 5 saniye boyunca başka bir aktöre/geleceğe atanamazsınız. – cmbaxter

+0

Uzun süren bir çalışmayı simüle ediyorum, bu yüzden bu uzun çalışma işlemini gerçekleştirmek için 200 iş parçacığı kullanıp kullanamayacağımı anlayabiliyorum. – Jas

+1

Sprey için temeldeki aktör sisteminin aynı zamanda "async-futures-dispatcher" yürütme bağlamını topladığından emin değil misiniz? Yanlışlıkla seçmekse (örtük olarak tanımlandığı için), bu sorunun bir parçası olabilir. Akka ana dağıtıcısından ayrı bir yürütme bağlamında engelleme kodunu güvenlik duvarı üzerinden kapatmak iyi bir fikirdir, ancak akka, bu rotayı temsil eden aktörleri çalıştırmak için bu yürütme bağlamını kullanıyorsa, bu amaca hizmet etmeyecektir. – cmbaxter

cevap

13

tüm sprey işlemleri ve operasyonlar aynı bağlamda gerçekleşmesi engelleme (i erkek kedi servlet 3.0 üstünde koşuyorum eklemek için). 2 bağlamı ayırmanız gerekir:

Ayrıca, dinamik kullanmanın nedenini de görmüyorum, sanırım sadece 'tamam' iyi olmalı.

implicit val timeout = 10.seconds 

    // Execution Context for blocking ops 
    val blockingExecutionContext = { 
    ExecutionContext.fromExecutor(Executors.newFixedThreadPool(2000)) 
    } 

    // Execution Context for Spray 
    import context.dispatcher 

    override def receive: Receive = runRoute(contestroute) 

    val contestroute = path("contestroute") { 
    get { 

     complete { 
      Future.apply { 
      val start = System.currentTimeMillis() 
      // np here should be dealt by 200 threads defined below, so why 
      // overall time takes so long? why doesn't it really utilize all 
      // threads I have given to it? how to update the code so it 
      // utilizes the 200 threads? 
      Thread.sleep(5000) 
      val status = s"timediff ${System.currentTimeMillis() - start}ms ${Thread.currentThread().getName}" 
      status 
      }(blockingExecutionContext) 
     } 

    } 
    } 

Bundan sonra

ab -n 200 -c 200 http://LAP:8080/contestroute 

ile test edebilirsiniz ve bu sprey engelleme operasyonları

Sonuçları için 200 konuları yaratacak görürsünüz: Biliyorum

Concurrency Level:  200 
Time taken for tests: 5.096 seconds 
+1

Küçük düzeltme: "200 iş parçacığı yaratan" bir sprey değil ama Scala/Akka'nın bir özelliği. – jrudolph

+2

Bu benim yorumumda söylediğim gibi, spreyin de engellemenin oluştuğu bağlamı kullandığını ve böylece sistemin verimini ciddi şekilde sınırlandıracağını söyledi. – cmbaxter

+0

Bu yaklaşım, tek bir iş parçacığının hala tüm yönlendirmeyi (= tüm darboğazlar + tüm istekleri engelleme tehlikesi) işlediği anlamına gelmez mi? Yüksek eşzamanlılık elde etmek için, gelen isteklerin sunucu elden yönetilmesinin mümkün olan en kısa zamanda yeni bir iş parçacığına yapılmaması gerekir mi? – user48956