Просмотр исходного кода

Optimize light-java multiple queries/updates and upgrade framework to 1.2.5 from 1.2.3 (#2666)

* optimize plaintext and router

* optimize multiple queries and updates

* upgrade to light-java 1.2.5
Steve Hu 8 лет назад
Родитель
Сommit
db3d5eda58

+ 4 - 5
frameworks/Java/light-java/pom.xml

@@ -17,8 +17,8 @@
     <properties>
         <java.version>1.8</java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <version.light-java>1.2.3</version.light-java>
-        <version.light-java-rest>1.2.3</version.light-java-rest>
+        <version.light-java>1.2.5</version.light-java>
+        <version.light-java-rest>1.2.5</version.light-java-rest>
         <version.jackson>2.8.2</version.jackson>
         <version.slf4j>1.7.22</version.slf4j>
         <version.jose4j>0.5.2</version.jose4j>
@@ -27,12 +27,11 @@
         <version.commons.io>2.5</version.commons.io>
         <version.commons.codec>1.10</version.commons.codec>
         <version.encoder>1.2</version.encoder>
-        <version.metrics>3.1.2</version.metrics>
         <version.logback>1.1.9</version.logback>
         <version.junit>4.12</version.junit>
         <version.mockito>2.1.0-beta.124</version.mockito>
-        <version.undertow>1.4.10.Final</version.undertow>
-        <!--<version.undertow>1.2.5.Final</version.undertow>-->
+        <!--<version.undertow>1.4.10.Final</version.undertow>-->
+        <version.undertow>1.2.5.Final</version.undertow>
         <version.jsonpath>2.2.0</version.jsonpath>
         <version.httpclient>4.5.2</version.httpclient>
         <version.httpasyncclient>4.1.2</version.httpasyncclient>

+ 65 - 0
frameworks/Java/light-java/src/main/java/com/networknt/techempower/Helper.java

@@ -1,10 +1,17 @@
 package com.networknt.techempower;
 
 import com.google.common.net.MediaType;
+import com.networknt.techempower.model.World;
 import io.undertow.server.HttpServerExchange;
 
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.util.Deque;
+import java.util.List;
 import java.util.concurrent.*;
+import java.util.stream.Collectors;
 
 /**
  * Provides utility methods for the benchmark tests.
@@ -58,4 +65,62 @@ public final class Helper {
                     new LinkedBlockingQueue<Runnable>(cpuCount * 100),
                     new ThreadPoolExecutor.CallerRunsPolicy());
 
+
+    public static World selectWorld(DataSource ds) {
+        try (final Connection connection = ds.getConnection()) {
+            try (PreparedStatement statement = connection.prepareStatement(
+                    "SELECT * FROM world WHERE id = ?",
+                    ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
+                statement.setInt(1, Helper.randomWorld());
+                try (ResultSet resultSet = statement.executeQuery()) {
+                    resultSet.next();
+                    return new World(
+                            resultSet.getInt("id"),
+                            resultSet.getInt("randomNumber"));
+                }
+            }
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static World updateWorld(DataSource ds) {
+        World world;
+        try (final Connection connection = ds.getConnection()) {
+            try (PreparedStatement update = connection.prepareStatement(
+                    "UPDATE world SET randomNumber = ? WHERE id= ?")) {
+                try (PreparedStatement query = connection.prepareStatement(
+                        "SELECT * FROM world WHERE id = ?",
+                        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
+
+                    query.setInt(1, Helper.randomWorld());
+                    try (ResultSet resultSet = query.executeQuery()) {
+                        resultSet.next();
+                        world = new World(
+                                resultSet.getInt("id"),
+                                resultSet.getInt("randomNumber"));
+                    }
+                }
+                world.randomNumber = Helper.randomWorld();
+                update.setInt(1, world.randomNumber);
+                update.setInt(2, world.id);
+                update.executeUpdate();
+                return world;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) {
+        CompletableFuture<Void> allDoneFuture =
+                CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
+        return allDoneFuture.thenApply(v ->
+                futures.stream().
+                        map(future -> future.join()).
+                        collect(Collectors.<T>toList())
+        );
+    }
+
 }

+ 1 - 1
frameworks/Java/light-java/src/main/java/com/networknt/techempower/handler/DbPostgresqlGetHandler.java

@@ -26,7 +26,7 @@ import javax.sql.DataSource;
 public class DbPostgresqlGetHandler implements HttpHandler {
     private final DataSource ds = PostgresStartupHookProvider.ds;
     private DslJson<Object> dsl = new DslJson<>();
-    private JsonWriter writer = dsl.newWriter(25000);
+    private JsonWriter writer = dsl.newWriter(1024);
 
     @Override
     public void handleRequest(HttpServerExchange exchange) throws Exception {

+ 1 - 1
frameworks/Java/light-java/src/main/java/com/networknt/techempower/handler/JsonGetHandler.java

@@ -21,7 +21,7 @@ import org.apache.commons.lang3.StringEscapeUtils;
 
 public class JsonGetHandler implements HttpHandler {
     private DslJson<Object> dsl = new DslJson<>();
-    private JsonWriter writer = dsl.newWriter(25000);
+    private JsonWriter writer = dsl.newWriter(1024);
 
     @Override
     public void handleRequest(HttpServerExchange exchange) throws Exception {

+ 11 - 36
frameworks/Java/light-java/src/main/java/com/networknt/techempower/handler/QueriesMysqlGetHandler.java

@@ -17,10 +17,14 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import org.apache.commons.lang3.StringEscapeUtils;
 
@@ -29,7 +33,7 @@ import javax.sql.DataSource;
 public class QueriesMysqlGetHandler implements HttpHandler {
     private final DataSource ds = MysqlStartupHookProvider.ds;
     private DslJson<Object> dsl = new DslJson<>();
-    private JsonWriter writer = dsl.newWriter(25000);
+    private JsonWriter writer = dsl.newWriter(1024);
 
     @Override
     public void handleRequest(HttpServerExchange exchange) throws Exception {
@@ -37,46 +41,17 @@ public class QueriesMysqlGetHandler implements HttpHandler {
             exchange.dispatch(this);
             return;
         }
+        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
 
         int queries = Helper.getQueries(exchange);
 
-        World[] worlds = new World[queries];
-        try (final Connection connection = ds.getConnection()) {
-            Map<Integer, Future<World>> futureWorlds = new ConcurrentHashMap<>();
-            for (int i = 0; i < queries; i++) {
-                futureWorlds.put(i, Helper.EXECUTOR.submit(new Callable<World>(){
-                    @Override
-                    public World call() throws Exception {
-                        try (PreparedStatement statement = connection.prepareStatement(
-                                "SELECT * FROM world WHERE id = ?",
-                                ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
-
-                            statement.setInt(1, Helper.randomWorld());
-                            try (ResultSet resultSet = statement.executeQuery()) {
-                                resultSet.next();
-                                return new World(
-                                        resultSet.getInt("id"),
-                                        resultSet.getInt("randomNumber"));
-                            }
-                        }
-                    }
-                }));
-            }
+        List<CompletableFuture<World>> worlds = IntStream.range(0, queries)
+                .mapToObj(i -> CompletableFuture.supplyAsync(() -> Helper.selectWorld(ds), Helper.EXECUTOR))
+                .collect(Collectors.toList());
 
-            for (int i = 0; i < queries; i++) {
-                worlds[i] = futureWorlds.get(i).get();
-            }
-        }
-        /*
-        // 1429 432
-        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
-        exchange.getResponseSender().send(mapper.writeValueAsString(worlds));
-        */
-
-        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
+        CompletableFuture<List<World>> allDone = Helper.sequence(worlds);
         writer.reset();
-        writer.serialize(worlds, queries);
+        writer.serialize(allDone.get());
         exchange.getResponseSender().send(ByteBuffer.wrap(writer.toByteArray()));
-
     }
 }

+ 12 - 41
frameworks/Java/light-java/src/main/java/com/networknt/techempower/handler/QueriesPostgresqlGetHandler.java

@@ -17,11 +17,10 @@ import java.nio.ByteBuffer;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Future;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import org.apache.commons.lang3.StringEscapeUtils;
 
@@ -30,7 +29,7 @@ import javax.sql.DataSource;
 public class QueriesPostgresqlGetHandler implements HttpHandler {
     private final DataSource ds = PostgresStartupHookProvider.ds;
     private DslJson<Object> dsl = new DslJson<>();
-    private JsonWriter writer = dsl.newWriter(25000);
+    private JsonWriter writer = dsl.newWriter(1024);
 
     @Override
     public void handleRequest(HttpServerExchange exchange) throws Exception {
@@ -38,46 +37,18 @@ public class QueriesPostgresqlGetHandler implements HttpHandler {
             exchange.dispatch(this);
             return;
         }
+        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
 
         int queries = Helper.getQueries(exchange);
 
-        World[] worlds = new World[queries];
-        try (final Connection connection = ds.getConnection()) {
-            Map<Integer, Future<World>> futureWorlds = new ConcurrentHashMap<>();
-            for (int i = 0; i < queries; i++) {
-                futureWorlds.put(i, Helper.EXECUTOR.submit(new Callable<World>(){
-                    @Override
-                    public World call() throws Exception {
-                        try (PreparedStatement statement = connection.prepareStatement(
-                                "SELECT * FROM world WHERE id = ?",
-                                ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
-
-                            statement.setInt(1, Helper.randomWorld());
-                            try (ResultSet resultSet = statement.executeQuery()) {
-                                resultSet.next();
-                                return new World(
-                                        resultSet.getInt("id"),
-                                        resultSet.getInt("randomNumber"));
-                            }
-                        }
-                    }
-                }));
-            }
-
-            for (int i = 0; i < queries; i++) {
-                worlds[i] = futureWorlds.get(i).get();
-            }
-        }
-
-        /*
-        // 2137
-        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
-        exchange.getResponseSender().send(mapper.writeValueAsString(worlds));
-        */
+        List<CompletableFuture<World>> worlds = IntStream.range(0, queries)
+                .mapToObj(i -> CompletableFuture.supplyAsync(() -> Helper.selectWorld(ds), Helper.EXECUTOR))
+                .collect(Collectors.toList());
 
-        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
+        CompletableFuture<List<World>> allDone = Helper.sequence(worlds);
         writer.reset();
-        writer.serialize(worlds, queries);
+        writer.serialize(allDone.get());
         exchange.getResponseSender().send(ByteBuffer.wrap(writer.toByteArray()));
     }
+
 }

+ 12 - 51
frameworks/Java/light-java/src/main/java/com/networknt/techempower/handler/UpdatesMysqlGetHandler.java

@@ -7,27 +7,18 @@ import com.networknt.techempower.db.mysql.MysqlStartupHookProvider;
 import com.networknt.techempower.model.World;
 import io.undertow.server.HttpHandler;
 import io.undertow.server.HttpServerExchange;
-import io.undertow.util.Headers;
-import io.undertow.util.HttpString;
-
-import java.nio.ByteBuffer;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Future;
-
-import org.apache.commons.lang3.StringEscapeUtils;
 
 import javax.sql.DataSource;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 public class UpdatesMysqlGetHandler implements HttpHandler {
     private final DataSource ds = MysqlStartupHookProvider.ds;
     private DslJson<Object> dsl = new DslJson<>();
-    private JsonWriter writer = dsl.newWriter(25000);
+    private JsonWriter writer = dsl.newWriter(1024);
 
     @Override
     public void handleRequest(HttpServerExchange exchange) throws Exception {
@@ -36,44 +27,14 @@ public class UpdatesMysqlGetHandler implements HttpHandler {
             return;
         }
         int queries = Helper.getQueries(exchange);
-        World[] worlds = new World[queries];
-        try (final Connection connection = ds.getConnection()) {
-            Map<Integer, Future<World>> futureWorlds = new ConcurrentHashMap<>();
-            for (int i = 0; i < queries; i++) {
-                futureWorlds.put(i, Helper.EXECUTOR.submit(new Callable<World>() {
-                    @Override
-                    public World call() throws Exception {
-                        World world;
-                        try (PreparedStatement update = connection.prepareStatement(
-                                "UPDATE world SET randomNumber = ? WHERE id= ?")) {
-                            try (PreparedStatement query = connection.prepareStatement(
-                                    "SELECT * FROM world WHERE id = ?",
-                                    ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
 
-                                query.setInt(1, Helper.randomWorld());
-                                try (ResultSet resultSet = query.executeQuery()) {
-                                    resultSet.next();
-                                    world = new World(
-                                            resultSet.getInt("id"),
-                                            resultSet.getInt("randomNumber"));
-                                }
-                            }
-                            world.randomNumber = Helper.randomWorld();
-                            update.setInt(1, world.randomNumber);
-                            update.setInt(2, world.id);
-                            update.executeUpdate();
-                            return world;
-                        }
-                    }
-                }));
-            }
-            for (int i = 0; i < queries; i++) {
-                worlds[i] = futureWorlds.get(i).get();
-            }
-        }
-        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
+        List<CompletableFuture<World>> worlds = IntStream.range(0, queries)
+                .mapToObj(i -> CompletableFuture.supplyAsync(() -> Helper.updateWorld(ds), Helper.EXECUTOR))
+                .collect(Collectors.toList());
+
+        CompletableFuture<List<World>> allDone = Helper.sequence(worlds);
         writer.reset();
-        writer.serialize(worlds, queries);
+        writer.serialize(allDone.get());
         exchange.getResponseSender().send(ByteBuffer.wrap(writer.toByteArray()));
     }
 }

+ 11 - 37
frameworks/Java/light-java/src/main/java/com/networknt/techempower/handler/UpdatesPostgresqlGetHandler.java

@@ -16,10 +16,14 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import org.apache.commons.lang3.StringEscapeUtils;
 
@@ -28,7 +32,7 @@ import javax.sql.DataSource;
 public class UpdatesPostgresqlGetHandler implements HttpHandler {
     private final DataSource ds = PostgresStartupHookProvider.ds;
     private DslJson<Object> dsl = new DslJson<>();
-    private JsonWriter writer = dsl.newWriter(25000);
+    private JsonWriter writer = dsl.newWriter(1024);
 
     @Override
     public void handleRequest(HttpServerExchange exchange) throws Exception {
@@ -37,44 +41,14 @@ public class UpdatesPostgresqlGetHandler implements HttpHandler {
             return;
         }
         int queries = Helper.getQueries(exchange);
-        World[] worlds = new World[queries];
-        try (final Connection connection = ds.getConnection()) {
-            Map<Integer, Future<World>> futureWorlds = new ConcurrentHashMap<>();
-            for (int i = 0; i < queries; i++) {
-                futureWorlds.put(i, Helper.EXECUTOR.submit(new Callable<World>() {
-                    @Override
-                    public World call() throws Exception {
-                        World world;
-                        try (PreparedStatement update = connection.prepareStatement(
-                                "UPDATE world SET randomNumber = ? WHERE id= ?")) {
-                            try (PreparedStatement query = connection.prepareStatement(
-                                    "SELECT * FROM world WHERE id = ?",
-                                    ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
 
-                                query.setInt(1, Helper.randomWorld());
-                                try (ResultSet resultSet = query.executeQuery()) {
-                                    resultSet.next();
-                                    world = new World(
-                                            resultSet.getInt("id"),
-                                            resultSet.getInt("randomNumber"));
-                                }
-                            }
-                            world.randomNumber = Helper.randomWorld();
-                            update.setInt(1, world.randomNumber);
-                            update.setInt(2, world.id);
-                            update.executeUpdate();
-                            return world;
-                        }
-                    }
-                }));
-            }
-            for (int i = 0; i < queries; i++) {
-                worlds[i] = futureWorlds.get(i).get();
-            }
-        }
-        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
+        List<CompletableFuture<World>> worlds = IntStream.range(0, queries)
+                .mapToObj(i -> CompletableFuture.supplyAsync(() -> Helper.updateWorld(ds), Helper.EXECUTOR))
+                .collect(Collectors.toList());
+
+        CompletableFuture<List<World>> allDone = Helper.sequence(worlds);
         writer.reset();
-        writer.serialize(worlds, queries);
+        writer.serialize(allDone.get());
         exchange.getResponseSender().send(ByteBuffer.wrap(writer.toByteArray()));
     }
 }

+ 1 - 1
frameworks/Java/light-java/src/main/resources/config/mysql.json

@@ -3,7 +3,7 @@
   "jdbcUrl": "jdbc:mysql://TFB-database:3306/hello_world",
   "username": "benchmarkdbuser",
   "password": "benchmarkdbpass",
-  "maximumPoolSize": 200,
+  "maximumPoolSize": 256,
   "useServerPrepStmts": true,
   "cachePrepStmts": true,
   "cacheCallableStmts": true,

+ 1 - 1
frameworks/Java/light-java/src/main/resources/config/postgres.json

@@ -3,5 +3,5 @@
   "jdbcUrl": "jdbc:postgresql://TFB-database:5432/hello_world",
   "username": "benchmarkdbuser",
   "password": "benchmarkdbpass",
-  "maximumPoolSize": 200
+  "maximumPoolSize": 256
 }