Receive 404 error "The requested resource could not be found." when stress test my server

1,772 views
Skip to first unread message

Richard Grossman

unread,
Nov 6, 2013, 9:30:13 AM11/6/13
to spray...@googlegroups.com

Hi

Still fighting to put in production a server based on Spray + Akka on Tomcat 7. Machines are EC2 instances.
But it's not important for my current problem.

For the purpose of this Post I've written a complete sample that minic my real server expect that I make nothing here just the logic around spray and akka.
So I make test with JMeter I don't try to overkill the server just make a light test:

With ThreadGroup number of thread = 1 I run for hour with no problem
When I up the threads to only 5 concurrents I begin to receive a lot of error with response : The requested resource could not be found.

The detail of the http query is 

hread Name: Thread Group 1-4
Sample Start: 2013-11-06 15:36:05 IST
Load time: 2097
Latency: 2097
Size in bytes: 192
Headers size in bytes: 150
Body size in bytes: 42
Sample Count: 1
Error Count: 1
Response code: 404
Response message: Not Found

Response headers:
HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=UTF-8
Content-Length: 42
Date: Wed, 06 Nov 2013 13:36:07 GMT


HTTPSampleResult fields:
ContentType: text/plain;charset=UTF-8
DataEncoding: UTF-8



The code I test

package com.inneractive.exchange.test

import akka.actor.{ActorRef, Props, Actor}
import spray.routing.{ExceptionHandler, MissingQueryParamRejection, RejectionHandler, HttpService}
import scala.concurrent.duration._
import akka.pattern.{ask, pipe}
import spray.util.LoggingContext
import spray.http._
import spray.http.HttpResponse
import spray.http.HttpEntity
import akka.util.Timeout
import spray.httpx.marshalling.Marshaller
import scala.concurrent.{Await, ExecutionContext, Future}
import scala.util.control.NonFatal
import com.inneractive.services.events.exception.ClickHTTPOperationException
import scala.util.{Failure, Success}


/**
 * User: richard
 * Date: 11/6/13
 * Time: 12:00 PM
 */

sealed trait Message

case class Message1(m: String, n: Int) extends Message

case class Message2(m: String, n: Int) extends Message

case class Message3(m: String, n: Int) extends Message

class Actor4 extends Actor {
  implicit def executionContext = context.dispatcher
  implicit val timeout = Timeout(2 seconds)

  def receive: Actor4#Receive = {
    case Message3(m, n) => {
      context.system.scheduler.scheduleOnce(100 millis, self, Message3(m, n))
      sender ! (m + " Count:" + n)
    }
  }
}

class Actor2 extends Actor {

  def receive: Actor2#Receive = {
    case Message2(m, n) => {
      println("Get Message:" + m + " count:" + n)
      sender ! Message3(m, n)
    }
  }
}

class Actor1 extends Actor {
  implicit def executionContext = context.dispatcher
  implicit val timeout = Timeout(2 seconds)

  val actor2 = context.actorOf(Props[Actor2])
  val actor4 = context.actorOf(Props[Actor4])
  var controllerActor: ActorRef = _

  var count = 0

  def receive: Actor1#Receive = {

    case Message1(m, n) => {
      controllerActor = sender
      count += 1
      actor2 ! Message2(m, count)
    }

    case Message3(m, n) => {
      val future = (actor4 ? Message3(m, n)).mapTo[String]
      future pipeTo controllerActor
    }

  }
}

class TestController extends Actor with TestHttpService {
  def actorRefFactory = context

  def receive = runRoute(mappings)
}

trait TestHttpService extends HttpService {
  implicit def executionContext = actorRefFactory.dispatcher

  implicit val timeout = Timeout(2 seconds)

  val actionActor = actorRefFactory.actorFor("/user/application/actor1")
  implicit val rejectionHandler = RejectionHandler {
    case MissingQueryParamRejection(paramName) :: _ => ctx => ctx.complete(StatusCodes.BadRequest)
  }

  /**
   * Exception handler - when an exception is thrown, display fallback ad
   */
  implicit def exceptionHandler(implicit log: LoggingContext) = ExceptionHandler {
    case NonFatal(e: ClickHTTPOperationException) => ctx => {
      ctx.complete("ERROR")
    }

    case NonFatal(e) => ctx => {
      log.error(e, "Error during processing of request {}", ctx.request)
      ctx.complete("ERROR")
    }
  }



  def mappings(implicit log: LoggingContext) = {
    get {
      path("test") {
        parameterMap {
          requestParams => {
            respondWithMediaType(MediaTypes.`text/html`) {
              onComplete(actionActor ? Message1(requestParams.getOrElse("", ""), 0)) {
                case Success(result : String) => complete(result)
                case Failure(e) => reject
              }
            }
          }
        }
      }
    }
  }

}

Johannes Rudolph

unread,
Nov 6, 2013, 11:28:40 AM11/6/13
to spray...@googlegroups.com
Hi Richard,

which versions of spray are that exactly? You are using spray-servlet,
right? Can you package the whole example into a stand-alone example
with sbt project for us to test?

Johannes
> --
> You received this message because you are subscribed to the Google Groups
> "spray-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to spray-user+...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.



--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Richard Grossman

unread,
Nov 6, 2013, 12:20:16 PM11/6/13
to spray...@googlegroups.com, johannes...@googlemail.com
Hi

Is it ok if it's maven instead of sbt ?
Thanks

Johannes Rudolph

unread,
Nov 8, 2013, 5:27:56 AM11/8/13
to Richard Grossman, spray...@googlegroups.com
Hi Richard,

On Wed, Nov 6, 2013 at 6:20 PM, Richard Grossman <rich...@gmail.com> wrote:
> Is it ok if it's maven instead of sbt ?
> Thanks

Yes, of course.
Reply all
Reply to author
Forward
0 new messages