Переглянути джерело

Upgrade to Blaze 0.14.0-M3 + replace Jackson by jsoniter-scala (#3788)

* Upgrade to Blaze 0.14.0-M3 + replace Jackson by jsoniter-scala

* Fix content types

* Add NUMA + aggressive opts
Andriy Plokhotnyuk 7 роки тому
батько
коміт
3ef572430c

+ 5 - 4
frameworks/Scala/blaze/README.md

@@ -3,8 +3,8 @@
 ## Infrastructure Software Versions
 The tests were run with:
 
-* [Java Oracle 1.8.0_101](http://www.oracle.com/technetwork/java/javase)
-* [blaze 0.13.0](https://github.com/http4s/blaze/)
+* [Java Oracle 1.8.0](http://www.oracle.com/technetwork/java/javase)
+* [blaze 0.14.0-M3](https://github.com/http4s/blaze/)
 
 ## Test URLs
 ### JSON Encoding Test
@@ -16,6 +16,7 @@ http://localhost:8080/json
 http://localhost:8080/plaintext
 
 ## How to run
-sbt 'oneJar'
+sbt assembly
+
+java -server -Xms2g -Xmx2g -XX:NewSize=1g -XX:MaxNewSize=1g -XX:InitialCodeCacheSize=256m -XX:ReservedCodeCacheSize=256m -XX:+UseParallelGC -XX:+UseNUMA -XX:+AggressiveOpts -XX:-UseBiasedLocking -XX:+AlwaysPreTouch -jar target/scala-2.12/blaze-assembly-1.0.jar
 
-java -jar target/scala-2.11/blaze_2.11-1.0-SNAPSHOT-one-jar.jar

+ 1 - 1
frameworks/Scala/blaze/blaze.dockerfile

@@ -4,4 +4,4 @@ COPY project project
 COPY src src
 COPY build.sbt build.sbt
 RUN sbt assembly -batch
-CMD ["java", "-jar", "target/scala-2.12/blaze-assembly-1.0.jar"]
+CMD ["java", "-server", "-Xms2g", "-Xmx2g", "-XX:NewSize=1g", "-XX:MaxNewSize=1g", "-XX:InitialCodeCacheSize=256m", "-XX:ReservedCodeCacheSize=256m", "-XX:+UseParallelGC", "-XX:+UseNUMA", "-XX:+AggressiveOpts", "-XX:-UseBiasedLocking", "-XX:+AlwaysPreTouch", "-jar", "target/scala-2.12/blaze-assembly-1.0.jar"]

+ 3 - 5
frameworks/Scala/blaze/build.sbt

@@ -2,11 +2,9 @@ name := "blaze"
 
 version := "1.0"
 
-scalaVersion := "2.12.5"
-
-val blazeVersion = "0.13.0"
+scalaVersion := "2.12.6"
 
 libraryDependencies ++= Seq(
-	"org.http4s" %% "blaze-http" % blazeVersion,
-	"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.8.4"
+	"org.http4s" %% "blaze-http" % "0.14.0-M3",
+	"com.github.plokhotnyuk.jsoniter-scala" %% "macros" % "0.27.1"
 )

+ 31 - 32
frameworks/Scala/blaze/src/main/scala/Main.scala

@@ -1,50 +1,49 @@
 package blaze.techempower.benchmark
 
+import java.lang.Runtime._
 import java.net.InetSocketAddress
+import java.nio.ByteBuffer
+import java.nio.channels.AsynchronousChannelGroup
 import java.nio.charset.StandardCharsets.UTF_8
+import java.util.concurrent.ForkJoinPool
+import java.util.concurrent.ForkJoinPool._
 
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.module.scala.DefaultScalaModule
-
-import org.http4s.blaze.channel.SocketConnection
+import org.http4s.blaze.channel.nio2.NIO2SocketServerGroup
 import org.http4s.blaze.http._
+import org.http4s.blaze.http.HttpServerStageConfig
+import org.http4s.blaze.http.http1.server.Http1ServerStage
+import org.http4s.blaze.pipeline.LeafBuilder
+import com.github.plokhotnyuk.jsoniter_scala.macros._
+import com.github.plokhotnyuk.jsoniter_scala.core._
+import org.http4s.blaze.channel.SocketConnection
+import org.http4s.blaze.http.RouteAction._
 
 import scala.concurrent.Future
 
-object Main {
-
-  private val mapper: ObjectMapper = new ObjectMapper().registerModule(DefaultScalaModule)
-
-  private val plaintextResult = Future.successful {
-    val hs = Seq("server" -> "blaze", "content-type" -> "text/plain")
-    RouteAction.Ok("Hello, World!".getBytes(UTF_8), hs)
-  }
+case class Message(message: String)
 
-  private def notFound(path: String) = Future.successful {
-    RouteAction.String(s"Not found: $path", 404, "Not Found", Nil)
-  }
+object Main {
+  private val config = HttpServerStageConfig()
+  private val fjp = new ForkJoinPool(getRuntime.availableProcessors, defaultForkJoinWorkerThreadFactory, null, true)
+  private val jsonHeaders = Seq("server" -> "blaze", "content-type" -> "application/json")
+  private val plaintextHeaders = Seq("server" -> "blaze", "content-type" -> "text/plain")
 
-  // HTTP service definition
-  private def service(request: HttpRequest): Future[RouteAction] = request.uri match {
-    case "/plaintext" => plaintextResult
+  private implicit val codec: JsonValueCodec[Message] = JsonCodecMaker.make[Message](CodecMakerConfig())
 
-    case "/json" => Future.successful {
-      val msg = mapper.writeValueAsBytes(Map("message" -> "Hello, World!"))
-      RouteAction.Ok(msg, Seq("server" -> "blaze", "content-type" -> "application/json"))
+  def serve(request: HttpRequest): Future[RouteAction] = Future.successful {
+    request.url match {
+      case "/plaintext" => Ok("Hello, World!".getBytes(UTF_8), plaintextHeaders)
+      case "/json" => Ok(writeToArray(Message("Hello, World!")), jsonHeaders)
     }
-
-    case other => notFound(other)
   }
 
-  def main(args: Array[String]): Unit = {
-    val srvc = { _: SocketConnection => service(_:HttpRequest) }
-    val server = Http1Server(srvc, new InetSocketAddress(8080), HttpServerStageConfig())
-      .getOrElse(sys.error("Failed to bind socket"))
+  def connect(conn: SocketConnection): Future[LeafBuilder[ByteBuffer]] =
+    Future.successful(LeafBuilder(new Http1ServerStage(serve, config)))
 
-    try server.channel.join()
-    finally {
-      server.group.closeGroup()
-    }
+  def main(args: Array[String]): Unit = {
+    NIO2SocketServerGroup(group = Some(AsynchronousChannelGroup.withThreadPool(fjp)))
+      .bind(new InetSocketAddress(8080), connect)
+      .getOrElse(sys.error("Failed to start server."))
+      .join()
   }
 }
-