Browse Source

migrate old postgres code to new async driver and added mysql to the list of implementations

Signed-off-by: Paulo Lopes <[email protected]>
Paulo Lopes 9 years ago
parent
commit
a9cc6d974e

+ 1 - 1
frameworks/Java/vertx-web/Readme.md

@@ -56,7 +56,7 @@ repo and wrk is on your path. The final argument after the `--` is the desired p
 plaintext scenario at a pipeline depth of 16, [just like the Techempower Benchmarks](https://github.com/TechEmpower/FrameworkBenchmarks/blob/6594d32db618c6ca65e0106c5adf2671f7b63654/toolset/benchmark/framework_test.py#L640).
 
 ```
-wrk -c 256 -t 32 -d 10 -s ./scripts/pipeline.lua http://127.0.0.1:8080/plaintext -- 16
+wrk -c 256 -t 32 -d 15 -s ./scripts/pipeline.lua http://localhost:8080/psql/update?queries=20 -- 16
 ```
 
 *Note you may want to tweak the number of client threads (the `-t` arg) being used based on the specs of your load

+ 26 - 5
frameworks/Java/vertx-web/benchmark_config.json

@@ -41,12 +41,33 @@
       "notes": "",
       "versus": ""
     },
+    "mysql": {
+      "setup_file": "setup",
+      "db_url": "/mysql/db",
+      "query_url": "/mysql/queries?queries=",
+      "fortune_url": "/mysql/fortunes",
+      "update_url": "/mysql/update?queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "Postgres",
+      "framework": "vertx-web",
+      "language": "Java",
+      "orm": "Raw",
+      "platform": "vertx",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "vertx-web-mysql",
+      "notes": "",
+      "versus": ""
+    },
     "postgres": {
       "setup_file": "setup",
-      "db_url": "/jdbc/db",
-      "query_url": "/jdbc/queries?queries=",
-      "fortune_url": "/jdbc/fortunes",
-      "update_url": "/jdbc/update?queries=",
+      "db_url": "/psql/db",
+      "query_url": "/psql/queries?queries=",
+      "fortune_url": "/psql/fortunes",
+      "update_url": "/psql/update?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",
@@ -58,7 +79,7 @@
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "vertx-web-jdbc",
+      "display_name": "vertx-web-postgres",
       "notes": "",
       "versus": ""
     }

+ 2 - 8
frameworks/Java/vertx-web/pom.xml

@@ -12,7 +12,7 @@
   <properties>
     <!-- the main class -->
     <main.verticle>io.vertx.benchmark.App</main.verticle>
-    <vertx.version>3.2.0</vertx.version>
+    <vertx.version>3.2.1</vertx.version>
   </properties>
 
   <dependencies>
@@ -36,7 +36,7 @@
 
     <dependency>
       <groupId>io.vertx</groupId>
-      <artifactId>vertx-jdbc-client</artifactId>
+      <artifactId>vertx-mysql-postgresql-client</artifactId>
       <version>${vertx.version}</version>
     </dependency>
 
@@ -46,12 +46,6 @@
       <version>${vertx.version}</version>
     </dependency>
 
-    <dependency>
-      <groupId>org.postgresql</groupId>
-      <artifactId>postgresql</artifactId>
-      <version>9.4-1206-jdbc42</version>
-    </dependency>
-
   </dependencies>
 
   <build>

+ 1 - 1
frameworks/Java/vertx-web/setup.sh

@@ -6,4 +6,4 @@ fw_depends java maven
 
 mvn clean package
 
-java -Xms2G -Xmx2G -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -Dvertx.disableWebsockets=true -Dvertx.flashPolicyHandler=false -Dvertx.threadChecks=false -Dvertx.disableContextTimings=true -Dvertx.disableTCCL=true -jar target/vertx-benchmark-1.0.0-SNAPSHOT-fat.jar --conf src/main/conf/config.json &
+java -Xms2G -Xmx2G -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -Dvertx.disableWebsockets=true -Dvertx.flashPolicyHandler=false -Dvertx.threadChecks=false -Dvertx.disableContextTimings=true -Dvertx.disableTCCL=true -jar target/vertx-benchmark-1.0.0-SNAPSHOT-fat.jar --instances `grep --count ^processor /proc/cpuinfo` --conf src/main/conf/config.json &

+ 5 - 4
frameworks/Java/vertx-web/src/main/conf/config.json

@@ -2,8 +2,9 @@
   "connection_string": "mongodb://localhost:27017",
   "db_name": "hello_world",
 
-  "url": "jdbc:postgresql://localhost:5432/hello_world",
-  "driver_class": "org.postgresql.Driver",
-  "user": "benchmarkdbuser",
-  "password": "benchmarkdbpass"
+  "host": "localhost",
+  "username": "benchmarkdbuser",
+  "password": "benchmarkdbpass",
+  "database": "hello_world",
+  "maxPoolSize": 32
 }

+ 99 - 32
frameworks/Java/vertx-web/src/main/java/io/vertx/benchmark/App.java

@@ -7,7 +7,9 @@ import io.vertx.core.*;
 import io.vertx.core.http.HttpHeaders;
 import io.vertx.core.json.JsonArray;
 import io.vertx.core.json.JsonObject;
-import io.vertx.ext.jdbc.JDBCClient;
+import io.vertx.ext.asyncsql.AsyncSQLClient;
+import io.vertx.ext.asyncsql.MySQLClient;
+import io.vertx.ext.asyncsql.PostgreSQLClient;
 import io.vertx.ext.mongo.MongoClient;
 import io.vertx.ext.sql.SQLConnection;
 import io.vertx.ext.web.Router;
@@ -168,13 +170,30 @@ public class App extends AbstractVerticle {
   /**
    * JDBC implementation
    */
-  private final class JDBC {
-    private final JDBCClient database;
+  private final class AsyncSQL {
+
+    public static final int MYSQL = 0;
+    public static final int POSTGRES = 1;
+
+    private final AsyncSQLClient database;
+    private final int dbms;
+
     // In order to use a template we first need to create an engine
     private final HandlebarsTemplateEngine engine;
 
-    public JDBC(Vertx vertx, JsonObject config) {
-      this.database = JDBCClient.createShared(vertx, config);
+    public AsyncSQL(Vertx vertx, int driver, JsonObject config) {
+      switch (driver) {
+        case MYSQL:
+          this.database = MySQLClient.createNonShared(vertx, config);
+          this.dbms = MYSQL;
+          break;
+        case POSTGRES:
+          this.database = PostgreSQLClient.createNonShared(vertx, config);
+          this.dbms = POSTGRES;
+          break;
+        default:
+          throw new RuntimeException("Unsupported DB");
+      }
       this.engine = HandlebarsTemplateEngine.create();
     }
 
@@ -216,7 +235,7 @@ public class App extends AbstractVerticle {
 
     public final void queriesHandler(final RoutingContext ctx) {
       final int queries = Helper.getQueries(ctx.request());
-      final World[] worlds = new World[queries];
+      final JsonArray worlds = new JsonArray();
 
       database.getConnection(getConnection -> {
         if (getConnection.failed()) {
@@ -235,7 +254,7 @@ public class App extends AbstractVerticle {
                   .putHeader(HttpHeaders.SERVER, SERVER)
                   .putHeader(HttpHeaders.DATE, date)
                   .putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
-                  .end(new JsonArray(Arrays.asList(worlds)).encode());
+                  .end(worlds.encode());
 
               conn.close();
             } else {
@@ -259,7 +278,7 @@ public class App extends AbstractVerticle {
 
                 final JsonArray row = resultSet.get(0);
 
-                worlds[idx] = new World(row.getInteger(0), row.getInteger(1));
+                worlds.add(new World(row.getInteger(0), row.getInteger(1)));
                 self.handle(idx + 1);
               });
             }
@@ -322,7 +341,16 @@ public class App extends AbstractVerticle {
 
     public final void updateHandler(final RoutingContext ctx) {
       final int queries = Helper.getQueries(ctx.request());
-      final World[] worlds = new World[queries];
+      final JsonArray worlds = new JsonArray();
+
+      final StringBuffer batch;
+
+      if (dbms == POSTGRES) {
+        // Postgres can batch queries
+        batch = new StringBuffer();
+      } else {
+        batch = null;
+      }
 
       database.getConnection(getConnection -> {
         if (getConnection.failed()) {
@@ -336,14 +364,34 @@ public class App extends AbstractVerticle {
           @Override
           public void handle(Integer idx) {
             if (idx == queries) {
-              // stop condition
-              ctx.response()
-                  .putHeader(HttpHeaders.SERVER, SERVER)
-                  .putHeader(HttpHeaders.DATE, date)
-                  .putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
-                  .end(new JsonArray(Arrays.asList(worlds)).encode());
+              switch (dbms) {
+                case MYSQL:
+                  ctx.response()
+                      .putHeader(HttpHeaders.SERVER, SERVER)
+                      .putHeader(HttpHeaders.DATE, date)
+                      .putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
+                      .end(worlds.encode());
 
-              conn.close();
+                  conn.close();
+                  break;
+                case POSTGRES:
+                  // stop condition, first run the batch update
+                  conn.update(batch.toString(), update -> {
+                    if (update.failed()) {
+                      ctx.fail(update.cause());
+                      conn.close();
+                      return;
+                    }
+                    ctx.response()
+                        .putHeader(HttpHeaders.SERVER, SERVER)
+                        .putHeader(HttpHeaders.DATE, date)
+                        .putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
+                        .end(worlds.encode());
+
+                    conn.close();
+                  });
+                  break;
+              }
             } else {
 
               final Handler<Integer> self = this;
@@ -365,17 +413,31 @@ public class App extends AbstractVerticle {
                 }
 
                 final int newRandomNumber = Helper.randomWorld();
-
-                conn.update("UPDATE WORLD SET randomnumber = " + newRandomNumber + " WHERE id = " + id, update -> {
-                  if (update.failed()) {
-                    ctx.fail(update.cause());
-                    conn.close();
-                    return;
-                  }
-
-                  worlds[idx] = new World(id, newRandomNumber);
-                  self.handle(idx + 1);
-                });
+                worlds.add(new World(id, newRandomNumber));
+
+                switch (dbms) {
+                  case MYSQL:
+                    conn.update("UPDATE WORLD SET randomnumber = " + newRandomNumber + " WHERE id = " + id, update -> {
+                      if (update.failed()) {
+                        ctx.fail(update.cause());
+                        conn.close();
+                        return;
+                      }
+
+                      self.handle(idx + 1);
+                    });
+                    break;
+                  case POSTGRES:
+                    batch
+                        .append("UPDATE WORLD SET randomnumber = ")
+                        .append(newRandomNumber)
+                        .append(" WHERE id = ")
+                        .append(id)
+                        .append("; ");
+
+                    self.handle(idx + 1);
+                    break;
+                }
               });
             }
           }
@@ -394,7 +456,8 @@ public class App extends AbstractVerticle {
     vertx.setPeriodic(1000, handler -> date = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
 
     final MongoDB mongoDB = new MongoDB(vertx, config());
-    final JDBC jdbc = new JDBC(vertx, config());
+    final AsyncSQL psql = new AsyncSQL(vertx, AsyncSQL.POSTGRES, config());
+    final AsyncSQL mysql = new AsyncSQL(vertx, AsyncSQL.MYSQL, config());
 
     /**
      * This test exercises the framework fundamentals including keep-alive support, request routing, request header
@@ -413,7 +476,8 @@ public class App extends AbstractVerticle {
      * and database connection pool.
      */
     app.get("/mongo/db").handler(mongoDB::dbHandler);
-    app.get("/jdbc/db").handler(jdbc::dbHandler);
+    app.get("/psql/db").handler(psql::dbHandler);
+    app.get("/mysql/db").handler(mysql::dbHandler);
 
     /**
      * This test is a variation of Test #2 and also uses the World table. Multiple rows are fetched to more dramatically
@@ -421,14 +485,16 @@ public class App extends AbstractVerticle {
      * demonstrates all frameworks' convergence toward zero requests-per-second as database activity increases.
      */
     app.get("/mongo/queries").handler(mongoDB::queriesHandler);
-    app.get("/jdbc/queries").handler(jdbc::queriesHandler);
+    app.get("/psql/queries").handler(psql::queriesHandler);
+    app.get("/mysql/queries").handler(mysql::queriesHandler);
 
     /**
      * This test exercises the ORM, database connectivity, dynamic-size collections, sorting, server-side templates,
      * XSS countermeasures, and character encoding.
      */
     app.get("/mongo/fortunes").handler(mongoDB::fortunesHandler);
-    app.get("/jdbc/fortunes").handler(jdbc::fortunesHandler);
+    app.get("/psql/fortunes").handler(psql::fortunesHandler);
+    app.get("/mysql/fortunes").handler(mysql::fortunesHandler);
 
     /**
      * This test is a variation of Test #3 that exercises the ORM's persistence of objects and the database driver's
@@ -436,7 +502,8 @@ public class App extends AbstractVerticle {
      * read-then-write style database operations.
      */
     app.route("/mongo/update").handler(mongoDB::updateHandler);
-    app.route("/jdbc/update").handler(jdbc::updateHandler);
+    app.route("/psql/update").handler(psql::updateHandler);
+    app.route("/mysql/update").handler(mysql::updateHandler);
 
     /**
      * This test is an exercise of the request-routing fundamentals only, designed to demonstrate the capacity of