Selaa lähdekoodia

Added benchmarks for Rapidoid using the high-level API. (#2256)

Nikolche Mihajlovski 9 vuotta sitten
vanhempi
commit
2caff5f905

+ 15 - 0
frameworks/Java/rapidoid/README.md

@@ -1,3 +1,18 @@
 # Rapidoid Benchmarking Test
 
 This is the Rapidoid portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### Plaintext and JSON Encoding tests - using Rapidoid's high-level API (rapidoid-quick)
+* [highlevel/Main.java](src/main/java/highlevel/Main.java)
+
+### Fortunes test - using Rapidoid's high-level API (rapidoid-quick)
+* [highlevel/Main.java](src/main/java/highlevel/Main.java)
+* [highlevel/FortunesHandler.java](src/main/java/highlevel/FortunesHandler.java)
+* [fortunes.html](src/main/resources/fortunes.html)
+
+### Plaintext and JSON Encoding tests - using Rapidoid's low-level API (rapidoid-http-fast)
+* [lowlevel/Main.java](src/main/java/lowlevel/Main.java)
+* [lowlevel/PlaintextAndJsonServer.java](src/main/java/lowlevel/PlaintextAndJsonServer.java)
+
+## Versions
+Rapidoid 5.2.2 (http://www.rapidoid.org)

+ 59 - 20
frameworks/Java/rapidoid/benchmark_config.json

@@ -1,24 +1,63 @@
 {
   "framework": "rapidoid",
-  "tests": [{
-    "default": {
-      "setup_file": "setup",
-      "json_url": "/json",
-      "plaintext_url": "/plaintext",
-      "port": 8080,
-      "approach": "Stripped",
-      "classification": "Platform",
-      "database": "None",
-      "framework": "rapidoid",
-      "language": "Java",
-      "orm": "Raw",
-      "platform": "Rapidoid",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "rapidoid",
-      "notes": "",
-      "versus": "rapidoid"
+  "tests": [
+    {
+      "default": {
+        "setup_file": "setup-high-level",
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Platform",
+        "database": "None",
+        "framework": "rapidoid",
+        "language": "Java",
+        "orm": "raw",
+        "platform": "Rapidoid",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "rapidoid",
+        "notes": "",
+        "versus": ""
+      },
+      "mysql": {
+        "setup_file": "setup-high-level",
+        "fortune_url": "/fortunes/mysql",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Platform",
+        "database": "MySQL",
+        "framework": "rapidoid",
+        "language": "Java",
+        "orm": "micro",
+        "platform": "Rapidoid",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "rapidoid",
+        "notes": "",
+        "versus": ""
+      },
+      "http-fast": {
+        "setup_file": "setup-low-level",
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Platform",
+        "database": "None",
+        "framework": "rapidoid-http-fast",
+        "language": "Java",
+        "orm": "Raw",
+        "platform": "Rapidoid",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "rapidoid-http-fast",
+        "notes": "",
+        "versus": ""
+      }
     }
-  }]
+  ]
 }

+ 24 - 36
frameworks/Java/rapidoid/pom.xml

@@ -1,71 +1,59 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
 	<modelVersion>4.0.0</modelVersion>
 
-    <groupId>com.techempower</groupId>
-    <artifactId>rapidoid</artifactId>
-    <version>1.0</version>
+	<groupId>com.techempower</groupId>
+	<artifactId>rapidoid</artifactId>
+	<version>1.0</version>
 	<packaging>jar</packaging>
-	
-     <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    </properties>
-    
-    <dependencies>
-        <dependency>
-            <groupId>org.rapidoid</groupId>
-            <artifactId>rapidoid-http</artifactId>
-            <version>3.0.0</version>
-        </dependency>
-	<dependency>
-		<groupId>com.fasterxml.jackson.core</groupId>
-		<artifactId>jackson-databind</artifactId>
-		<version>2.6.0-rc2</version>
-	</dependency>
-	<dependency>
-		<groupId>com.fasterxml.jackson.module</groupId>
-		<artifactId>jackson-module-afterburner</artifactId>
-		<version>2.6.0-rc2</version>
-	</dependency>
-    </dependencies>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.rapidoid</groupId>
+			<artifactId>rapidoid-quick</artifactId>
+			<version>5.2.2</version>
+		</dependency>
+	</dependencies>
 
 	<build>
 		<plugins>
+
 			<plugin>
 				<inherited>true</inherited>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-compiler-plugin</artifactId>
-				<version>2.3.2</version>
+				<version>3.1</version>
 				<configuration>
-					<source>1.7</source>
-					<target>1.7</target>
+					<source>1.8</source>
+					<target>1.8</target>
 					<optimize>true</optimize>
 					<debug>false</debug>
 				</configuration>
 			</plugin>
+
 			<plugin>
 				<artifactId>maven-assembly-plugin</artifactId>
 				<configuration>
-					<archive>
-						<manifest>
-							<mainClass>hello.HelloWebServer</mainClass>
-						</manifest>
-					</archive>
 					<descriptorRefs>
 						<descriptorRef>jar-with-dependencies</descriptorRef>
 					</descriptorRefs>
 				</configuration>
 				<executions>
 					<execution>
-						<id>make-assembly</id> <!-- this is used for inheritance merges -->
-						<phase>package</phase> <!-- bind to the packaging phase -->
+						<id>make-assembly</id>
+						<phase>package</phase>
 						<goals>
 							<goal>single</goal>
 						</goals>
 					</execution>
 				</executions>
 			</plugin>
+
 		</plugins>
 	</build>
 </project>

+ 8 - 0
frameworks/Java/rapidoid/setup-high-level.sh

@@ -0,0 +1,8 @@
+#!/bin/bash
+
+fw_depends java maven
+
+mvn clean compile assembly:single
+
+cd target
+java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -cp rapidoid-1.0-jar-with-dependencies.jar highlevel.Main dbhost="$DBHOST" &

+ 1 - 1
frameworks/Java/rapidoid/setup.sh → frameworks/Java/rapidoid/setup-low-level.sh

@@ -5,4 +5,4 @@ fw_depends java maven
 mvn clean compile assembly:single
 
 cd target
-java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -jar rapidoid-1.0-jar-with-dependencies.jar &
+java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -cp rapidoid-1.0-jar-with-dependencies.jar lowlevel.Main &

+ 11 - 7
frameworks/Java/rapidoid/source_code

@@ -1,7 +1,11 @@
-./rapidoid/src/
-./rapidoid/src/main
-./rapidoid/src/main/java
-./rapidoid/src/main/java/hello
-./rapidoid/src/main/java/hello/HelloWebServer.java
-./rapidoid/src/main/java/hello/SimpleHttpProtocol.java
-./rapidoid/src/main/java/hello/Message.java
+./rapidoid/src/main/java/common
+./rapidoid/src/main/java/common/Fortune.java
+./rapidoid/src/main/java/common/Helper.java
+./rapidoid/src/main/java/common/Message.java
+./rapidoid/src/main/java/highlevel
+./rapidoid/src/main/java/highlevel/Main.java
+./rapidoid/src/main/java/lowlevel
+./rapidoid/src/main/java/lowlevel/Main.java
+./rapidoid/src/main/java/lowlevel/PlaintextAndJsonServer.java
+./rapidoid/src/main/java/resources
+./rapidoid/src/main/java/resources/fortunes.html

+ 48 - 0
frameworks/Java/rapidoid/src/main/java/common/Fortune.java

@@ -0,0 +1,48 @@
+package common;
+
+import org.rapidoid.u.U;
+
+public class Fortune implements Comparable<Fortune> {
+
+	private int id;
+	private String message;
+
+	public Fortune() {
+	}
+
+	public Fortune(int id, String message) {
+		this.id = id;
+		this.message = message;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public Fortune setId(int id) {
+		this.id = id;
+		return this;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public Fortune setMessage(String message) {
+		this.message = message;
+		return this;
+	}
+
+	@Override
+	public String toString() {
+		return "Fortune{" +
+			"id=" + id +
+			", message='" + message + '\'' +
+			'}';
+	}
+
+	@Override
+	public int compareTo(Fortune o) {
+		return U.compare(this.message, o.message);
+	}
+}

+ 12 - 0
frameworks/Java/rapidoid/src/main/java/common/Helper.java

@@ -0,0 +1,12 @@
+package common;
+
+public class Helper {
+
+	// this configuration was copied from the undertow-example project
+	public static final String MYSQL_CONFIG = "jdbcCompliantTruncation=false" +
+		"&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true" +
+		"&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048" +
+		"&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false" +
+		"&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true";
+
+}

+ 1 - 1
frameworks/Java/rapidoid/src/main/java/hello/Message.java → frameworks/Java/rapidoid/src/main/java/common/Message.java

@@ -1,4 +1,4 @@
-package hello;
+package common;
 
 public class Message {
 

+ 0 - 12
frameworks/Java/rapidoid/src/main/java/hello/HelloWebServer.java

@@ -1,12 +0,0 @@
-package hello;
-
-import org.rapidoid.net.Serve;
-
-public class HelloWebServer {
-
-	public static void main(String[] args) throws Exception {
-		int port = args.length > 0 ? Integer.parseInt(args[0]) : 8080;
-		Serve.server().protocol(new SimpleHttpProtocol()).port(port).build().start();
-	}
-
-}

+ 0 - 178
frameworks/Java/rapidoid/src/main/java/hello/SimpleHttpProtocol.java

@@ -1,178 +0,0 @@
-package hello;
-
-/*
- * #%L
- * rapidoid-demo
- * %%
- * Copyright (C) 2014 - 2015 Nikolche Mihajlovski
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-import org.rapidoid.buffer.Buf;
-import org.rapidoid.bytes.BytesUtil;
-import org.rapidoid.data.Range;
-import org.rapidoid.data.Ranges;
-import org.rapidoid.http.HttpParser;
-import org.rapidoid.net.Protocol;
-import org.rapidoid.net.abstracts.Channel;
-import org.rapidoid.net.impl.RapidoidHelper;
-import org.rapidoid.util.Dates;
-import org.rapidoid.wrap.BoolWrap;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
-
-public class SimpleHttpProtocol implements Protocol {
-
-	private static final byte[] HTTP_200_OK = "HTTP/1.1 200 OK\r\n".getBytes();
-
-	private static final byte[] HTTP_404_NOT_FOUND = "HTTP/1.1 404 Not Found\r\nContent-Length: 10\r\n\r\nNot found!"
-			.getBytes();
-
-	private static final byte[] CONN_KEEP_ALIVE = "Connection: keep-alive\r\n"
-			.getBytes();
-
-	private static final byte[] CONN_CLOSE = "Connection: close\r\n".getBytes();
-
-	private static final byte[] SERVER_X = "Server: X\r\n".getBytes();
-
-	private static final byte[] CONTENT_LENGTH_HDR = "Content-Length: "
-			.getBytes();
-
-	private static final byte[] CONTENT_TYPE_PLAIN = "Content-Type: text/plain; charset=UTF-8\r\n"
-			.getBytes();
-
-	private static final byte[] CONTENT_TYPE_JSON = "Content-Type: application/json; charset=UTF-8\r\n"
-			.getBytes();
-
-	private static final byte[] CONTENT_LENGTH = "Content-Length:           "
-			.getBytes();
-
-	private static final byte[] RESPONSE = "Hello, World!".getBytes();
-
-	private static final byte[] DATE_HDR = "Date: ".getBytes();
-
-	private static final byte[] RESPONSE_LENGTH = String.valueOf(
-			RESPONSE.length).getBytes();
-
-	private static final byte[] URI_PLAIN = "/plaintext".getBytes();
-
-	private static final byte[] URI_JSON = "/json".getBytes();
-
-	private static final HttpParser HTTP_PARSER = new HttpParser();
-
-	public static final ObjectMapper MAPPER = mapper();
-
-	private static ObjectMapper mapper() {
-		ObjectMapper mapper = new ObjectMapper();
-		mapper.registerModule(new AfterburnerModule());
-		return mapper;
-	}
-
-	public void process(Channel ctx) {
-		if (ctx.isInitial()) {
-			return;
-		}
-
-		Buf buf = ctx.input();
-		RapidoidHelper helper = ctx.helper();
-
-		Range[] ranges = helper.ranges1.ranges;
-		Ranges headers = helper.ranges2;
-
-		BoolWrap isGet = helper.booleans[0];
-		BoolWrap isKeepAlive = helper.booleans[1];
-
-		Range verb = ranges[ranges.length - 1];
-		Range uri = ranges[ranges.length - 2];
-		Range path = ranges[ranges.length - 3];
-		Range query = ranges[ranges.length - 4];
-		Range protocol = ranges[ranges.length - 5];
-		Range body = ranges[ranges.length - 6];
-
-		HTTP_PARSER.parse(buf, isGet, isKeepAlive, body, verb, uri, path,
-				query, protocol, headers, helper);
-
-		response(ctx, buf, path, isGet.value, isKeepAlive.value);
-	}
-
-	private void response(Channel ctx, Buf buf, Range path, boolean isGet,
-			boolean isKeepAlive) {
-		boolean processed = false;
-
-		if (isGet) {
-
-			ctx.write(HTTP_200_OK);
-
-			ctx.write(isKeepAlive ? CONN_KEEP_ALIVE : CONN_CLOSE);
-
-			ctx.write(SERVER_X);
-
-			ctx.write(DATE_HDR);
-			ctx.write(Dates.getDateTimeBytes());
-			ctx.write(CR_LF);
-
-			if (BytesUtil.matches(buf.bytes(), path, URI_PLAIN, true)
-					|| path.length == 1) {
-				handlePlaintext(ctx);
-				processed = true;
-			} else if (BytesUtil.matches(buf.bytes(), path, URI_JSON, true)) {
-				handleJson(ctx);
-				processed = true;
-			}
-
-			ctx.closeIf(!isKeepAlive);
-		}
-
-		if (!processed) {
-			ctx.write(HTTP_404_NOT_FOUND);
-			ctx.close();
-		}
-	}
-
-	private void handlePlaintext(Channel ctx) {
-		ctx.write(CONTENT_LENGTH_HDR);
-		ctx.write(RESPONSE_LENGTH);
-		ctx.write(CR_LF);
-
-		ctx.write(CONTENT_TYPE_PLAIN);
-		ctx.write(CR_LF);
-		ctx.write(RESPONSE);
-	}
-
-	private void handleJson(Channel ctx) {
-		Buf output = ctx.output();
-
-		ctx.write(CONTENT_TYPE_JSON);
-		ctx.write(CONTENT_LENGTH);
-
-		int posConLen = output.size() - 10;
-		ctx.write(CR_LF);
-		ctx.write(CR_LF);
-
-		int posBefore = output.size();
-
-		Message msg = new Message("Hello, World!");
-		try {
-			MAPPER.writeValue(output.asOutputStream(), msg);
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-
-		int posAfter = output.size();
-		output.putNumAsText(posConLen, posAfter - posBefore, false);
-	}
-
-}

+ 36 - 0
frameworks/Java/rapidoid/src/main/java/highlevel/FortunesHandler.java

@@ -0,0 +1,36 @@
+package highlevel;
+
+import common.Fortune;
+import org.rapidoid.http.Req;
+import org.rapidoid.http.ReqRespHandler;
+import org.rapidoid.http.Resp;
+import org.rapidoid.render.Template;
+import org.rapidoid.render.Templates;
+import org.rapidoid.sql.JdbcClient;
+
+import java.util.Collections;
+import java.util.List;
+
+public class FortunesHandler implements ReqRespHandler {
+
+	private final Template fortunesTmpl = Templates.load("fortunes.html");
+
+	private final JdbcClient jdbc;
+
+	public FortunesHandler(JdbcClient jdbc) {
+		this.jdbc = jdbc;
+	}
+
+	@Override
+	public Object execute(Req req, Resp resp) throws Exception {
+
+		List<Fortune> fortunes = jdbc.query(Fortune.class, "SELECT * FROM fortune");
+
+		fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+
+		Collections.sort(fortunes);
+
+		return fortunesTmpl.renderToBytes(fortunes);
+	}
+
+}

+ 44 - 0
frameworks/Java/rapidoid/src/main/java/highlevel/Main.java

@@ -0,0 +1,44 @@
+package highlevel;
+
+import common.Helper;
+import common.Message;
+import org.rapidoid.config.Conf;
+import org.rapidoid.http.MediaType;
+import org.rapidoid.log.Log;
+import org.rapidoid.setup.App;
+import org.rapidoid.setup.On;
+import org.rapidoid.sql.JDBC;
+import org.rapidoid.sql.JdbcClient;
+
+public class Main {
+
+	public static void main(String[] args) {
+
+		App.args(args,
+			"production",
+			"c3p0.maxPoolSize=256",
+			"c3p0.maxIdleTimeExcessConnections=256",
+			"c3p0.maxStatementsPerConnection=3",
+			"http.serverName=X",
+			"http.mandatoryHeaders.connection=false",
+			"http.timeout=0");
+
+		String dbHost = Conf.ROOT.entry("dbhost").or("localhost");
+		Log.info("Database hostname is: " + dbHost);
+
+		On.port(8080);
+
+		On.get("/plaintext").managed(false).contentType(MediaType.TEXT_PLAIN).serve("Hello, world!");
+
+		On.get("/json").managed(false).json(() -> new Message("Hello, world!"));
+
+		JdbcClient mysqlJdbc = JDBC.newApi()
+			.url("jdbc:mysql://" + dbHost + ":3306/hello_world?" + Helper.MYSQL_CONFIG)
+			.username("benchmarkdbuser")
+			.password("benchmarkdbpass")
+			.pooled();
+
+		On.get("/fortunes/mysql").html(new FortunesHandler(mysqlJdbc));
+	}
+
+}

+ 9 - 0
frameworks/Java/rapidoid/src/main/java/lowlevel/Main.java

@@ -0,0 +1,9 @@
+package lowlevel;
+
+public class Main {
+
+	public static void main(String[] args) throws Exception {
+		new PlaintextAndJsonServer().listen(8080);
+	}
+
+}

+ 40 - 0
frameworks/Java/rapidoid/src/main/java/lowlevel/PlaintextAndJsonServer.java

@@ -0,0 +1,40 @@
+package lowlevel;
+
+import common.Message;
+import org.rapidoid.buffer.Buf;
+import org.rapidoid.data.BufRange;
+import org.rapidoid.data.BufRanges;
+import org.rapidoid.http.AbstractHttpServer;
+import org.rapidoid.http.HttpStatus;
+import org.rapidoid.http.MediaType;
+import org.rapidoid.net.abstracts.Channel;
+
+public class PlaintextAndJsonServer extends AbstractHttpServer {
+
+	private static final byte[] URI_PLAINTEXT = "/plaintext".getBytes();
+
+	private static final byte[] URI_JSON = "/json".getBytes();
+
+	private static final byte[] HELLO_WORLD = "Hello, World!".getBytes();
+
+	public PlaintextAndJsonServer() {
+		super("X", "", "", false);
+	}
+
+	@Override
+	protected HttpStatus handle(Channel ctx, Buf buf, BufRange verb, BufRange uri, BufRange path, BufRange query,
+	                            BufRange protocol, BufRanges headers, boolean isGet, boolean isKeepAlive, BufRange body) {
+
+		if (isGet) {
+			if (matches(buf, path, URI_PLAINTEXT)) {
+				return ok(ctx, isKeepAlive, HELLO_WORLD, MediaType.TEXT_PLAIN);
+
+			} else if (matches(buf, path, URI_JSON)) {
+				return serializeToJson(ctx, isKeepAlive, new Message("Hello, World!"));
+			}
+		}
+
+		return HttpStatus.NOT_FOUND;
+	}
+
+}

+ 8 - 0
frameworks/Java/rapidoid/src/main/resources/fortunes.html

@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head><title>Fortunes</title></head>
+<body><table>
+<tr><th>id</th><th>message</th></tr>
+{{#.}}<tr><td>${id}</td><td>${message}</td></tr>{{/.}}
+</table></body>
+</html>