Browse Source

Minor optimization tweaks:

 - Update Netty to version 4.0.16.
 - Use the native Epoll transport if available.
 - Register the Jackson Afterburner module to speedup the marshaling to json.
luis.neves 11 years ago
parent
commit
a35157c50a

+ 74 - 68
netty/pom.xml

@@ -1,72 +1,78 @@
-<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">
+<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">
 
-  <modelVersion>4.0.0</modelVersion>
+	<modelVersion>4.0.0</modelVersion>
 
-  <groupId>com.techempower</groupId>
-  <artifactId>netty-example</artifactId>
-  <version>0.1</version>
-  
-  <packaging>jar</packaging>
+	<groupId>com.techempower</groupId>
+	<artifactId>netty-example</artifactId>
+	<version>0.1</version>
 
-  <dependencies>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-codec-http</artifactId>
-      <version>4.0.14.Beta1</version>
-    </dependency>
-	 <dependency>
-		<groupId>com.fasterxml.jackson.core</groupId>
-		<artifactId>jackson-databind</artifactId>
-		<version>2.3.0</version>
-	 </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-      <version>2.1.1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.javassist</groupId>
-      <artifactId>javassist</artifactId>
-      <version>3.18.0-GA</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>
-        <configuration>
-          <source>1.7</source>
-          <target>1.7</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 -->
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+	<packaging>jar</packaging>
+
+	<dependencies>
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-codec-http</artifactId>
+			<version>4.0.16.Final</version>
+		</dependency>
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-transport-native-epoll</artifactId>
+			<version>4.0.16.Final</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.3.1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.module</groupId>
+			<artifactId>jackson-module-afterburner</artifactId>
+			<version>2.3.1</version>
+		</dependency>
+		<dependency>
+			<groupId>javassist</groupId>
+			<artifactId>javassist</artifactId>
+			<version>RELEASE</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>
+				<configuration>
+					<source>1.7</source>
+					<target>1.7</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 -->
+						<goals>
+							<goal>single</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
 </project>

+ 15 - 9
netty/src/main/java/hello/HelloServerHandler.java

@@ -2,13 +2,6 @@ package hello;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-import com.fasterxml.jackson.databind.*;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
@@ -22,12 +15,19 @@ import io.netty.handler.codec.http.HttpResponseStatus;
 import io.netty.handler.codec.http.HttpVersion;
 import io.netty.util.CharsetUtil;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
+
 
 public class HelloServerHandler extends SimpleChannelInboundHandler<Object> {
     private final SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
     private CharSequence date;
 
-    private static final ObjectMapper MAPPER = new ObjectMapper();
     private final ByteBuf buffer = Unpooled.directBuffer().writeBytes("Hello, World!".getBytes(CharsetUtil.UTF_8));
     private final CharSequence contentLength = HttpHeaders.newEntity(String.valueOf(buffer.readableBytes()));
 
@@ -39,6 +39,12 @@ public class HelloServerHandler extends SimpleChannelInboundHandler<Object> {
     private static final CharSequence DATE_ENTITY = HttpHeaders.newEntity(HttpHeaders.Names.DATE);
     private static final CharSequence CONTENT_LENGTH_ENTITY = HttpHeaders.newEntity(HttpHeaders.Names.CONTENT_LENGTH);
     private static final CharSequence SERVER_ENTITY = HttpHeaders.newEntity(HttpHeaders.Names.SERVER);
+    private static final ObjectMapper MAPPER;
+    
+    static{
+    	MAPPER = new ObjectMapper();
+    	MAPPER.registerModule(new AfterburnerModule());
+    }
 
     @Override
     public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
@@ -50,7 +56,7 @@ public class HelloServerHandler extends SimpleChannelInboundHandler<Object> {
                     writeResponse(ctx, request, buffer.duplicate().retain(), TYPE_PLAIN, contentLength);
                     return;
                 case "/json":
-                    byte[] json = MAPPER.writeValueAsBytes(Collections.singletonMap("message", "Hello, World!"));
+                    byte[] json = MAPPER.writeValueAsBytes(new Message("Hello, World!"));
                     writeResponse(ctx, request, Unpooled.wrappedBuffer(json), TYPE_JSON,
                             String.valueOf(json.length));
                     return;

+ 32 - 16
netty/src/main/java/hello/HelloWebServer.java

@@ -5,14 +5,18 @@ import io.netty.buffer.PooledByteBufAllocator;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.EventLoopGroup;
+import io.netty.channel.ServerChannel;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollServerSocketChannel;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
 import io.netty.util.ResourceLeakDetector;
+import io.netty.util.ResourceLeakDetector.Level;
 
 
 public class HelloWebServer {
     static {
-        ResourceLeakDetector.setEnabled(false);
+        ResourceLeakDetector.setLevel(Level.DISABLED);
     }
 
     private final int port;
@@ -22,22 +26,34 @@ public class HelloWebServer {
     }
 
     public void run() throws Exception {
-        // Configure the server.
-        EventLoopGroup group = new NioEventLoopGroup();
-        try {
-            ServerBootstrap b = new ServerBootstrap();
-            b.group(group)
-             .childHandler(new HelloServerInitializer())
-             .channel(NioServerSocketChannel.class)
-             .option(ChannelOption.SO_BACKLOG, 1024)
-             .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
-             
-            Channel ch = b.bind(port).sync().channel();
-            ch.closeFuture().sync();
-        } finally {
-            group.shutdownGracefully().sync();
-        }
+		// Configure the server.
+
+		String os = System.getProperty("os.name").toLowerCase();
+
+		boolean is_linux = os.contains("linux");
+		
+		if (is_linux) {
+			doRun( new EpollEventLoopGroup(), EpollServerSocketChannel.class);
+		}
+		else {
+			doRun(new NioEventLoopGroup(), NioServerSocketChannel.class);
+		} 
     }
+    
+	private void doRun(EventLoopGroup loupGroup, Class<? extends ServerChannel> serverChannelClass) throws InterruptedException	{
+		try {
+			ServerBootstrap b = new ServerBootstrap();
+			b.option(ChannelOption.SO_BACKLOG, 1024);			
+			b.group(loupGroup).channel(serverChannelClass).childHandler(new HelloServerInitializer());			
+			b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
+
+			Channel ch = b.bind(port).sync().channel();
+			ch.closeFuture().sync();
+		}
+		finally {
+			loupGroup.shutdownGracefully().sync();
+		}
+	}
 
     public static void main(String[] args) throws Exception {
         int port;

+ 15 - 0
netty/src/main/java/hello/Message.java

@@ -0,0 +1,15 @@
+package hello;
+
+public class Message {
+	
+	private final String message;
+
+	public Message(String message) {
+		super();
+		this.message = message;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+}