瀏覽代碼

Save expensive slow path type checks (#7942)

Francesco Nigro 2 年之前
父節點
當前提交
81e5aa82d7

+ 1 - 1
frameworks/Java/netty/netty.dockerfile

@@ -10,4 +10,4 @@ COPY --from=maven /netty/target/netty-example-0.1-jar-with-dependencies.jar app.
 
 EXPOSE 8080
 
-CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-jar", "app.jar"]
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-Dio.netty.buffer.checkBounds=false", "-Dio.netty.buffer.checkAccessible=false", "-jar", "app.jar"]

+ 3 - 2
frameworks/Java/netty/pom.xml

@@ -11,7 +11,8 @@
 	<properties>
 		<maven.compiler.source>11</maven.compiler.source>
 		<maven.compiler.target>11</maven.compiler.target>
-		<netty.version>4.1.86.Final</netty.version>
+		<netty.version>4.1.89.Final</netty.version>
+		<io_uring.version>0.0.18.Final</io_uring.version>
 	</properties>
 
 	<packaging>jar</packaging>
@@ -41,7 +42,7 @@
 		<dependency>
 			<groupId>io.netty.incubator</groupId>
 			<artifactId>netty-incubator-transport-native-io_uring</artifactId>
-			<version>0.0.15.Final</version>
+			<version>${io_uring.version}</version>
 			<classifier>linux-x86_64</classifier>
 		</dependency>
 

+ 16 - 0
frameworks/Java/netty/src/main/java/hello/HelloServerHandler.java

@@ -28,8 +28,10 @@ import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.handler.codec.http.DefaultFullHttpResponse;
+import io.netty.handler.codec.http.DefaultHttpRequest;
 import io.netty.handler.codec.http.FullHttpResponse;
 import io.netty.handler.codec.http.HttpRequest;
+import io.netty.handler.codec.http.LastHttpContent;
 import io.netty.util.AsciiString;
 import io.netty.util.CharsetUtil;
 import io.netty.util.ReferenceCountUtil;
@@ -88,6 +90,20 @@ public class HelloServerHandler extends ChannelInboundHandlerAdapter {
 
 	@Override
 	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+		// fast path
+		if (msg == LastHttpContent.EMPTY_LAST_CONTENT) {
+			return;
+		}
+		if (msg.getClass() == DefaultHttpRequest.class) {
+			DefaultHttpRequest request = (DefaultHttpRequest) msg;
+			process(ctx, request);
+		} else {
+			channelReadSlowPath(ctx, msg);
+		}
+	}
+
+	private void channelReadSlowPath(ChannelHandlerContext ctx, Object msg) throws Exception {
+		// slow path
 		if (msg instanceof HttpRequest) {
 			try {
 				HttpRequest request = (HttpRequest) msg;

+ 29 - 3
frameworks/Java/netty/src/main/java/hello/HelloServerInitializer.java

@@ -4,12 +4,17 @@ import java.util.concurrent.ScheduledExecutorService;
 
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.codec.http.DefaultFullHttpResponse;
+import io.netty.handler.codec.http.DefaultHttpRequest;
+import io.netty.handler.codec.http.HttpMessage;
+import io.netty.handler.codec.http.HttpMethod;
 import io.netty.handler.codec.http.HttpRequestDecoder;
 import io.netty.handler.codec.http.HttpResponseEncoder;
+import io.netty.handler.codec.http.HttpVersion;
 
 public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
 
-	private ScheduledExecutorService service;
+	private final ScheduledExecutorService service;
 
 	public HelloServerInitializer(ScheduledExecutorService service) {
 		this.service = service;
@@ -18,8 +23,29 @@ public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
 	@Override
 	public void initChannel(SocketChannel ch) throws Exception {
 		ch.pipeline()
-                .addLast("encoder", new HttpResponseEncoder())
-                .addLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false))
+                .addLast("encoder", new HttpResponseEncoder() {
+					@Override
+					public boolean acceptOutboundMessage(final Object msg) throws Exception {
+						if (msg.getClass() == DefaultFullHttpResponse.class) {
+							return true;
+						}
+						return super.acceptOutboundMessage(msg);
+					}
+				})
+                .addLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false) {
+
+					@Override
+					protected HttpMessage createMessage(final String[] initialLine) throws Exception {
+						return new DefaultHttpRequest(
+								HttpVersion.valueOf(initialLine[2]),
+								HttpMethod.valueOf(initialLine[0]), initialLine[1], validateHeaders);
+					}
+
+					@Override
+					protected boolean isContentAlwaysEmpty(final HttpMessage msg) {
+						return false;
+					}
+				})
                 .addLast("handler", new HelloServerHandler(service));
 	}
 }