diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java
index 019a113a01..1b5e8275fe 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java
@@ -122,6 +122,8 @@ public interface Constants {
String NETTY_EPOLL_ENABLE_KEY = "netty.epoll.enable";
+ String NETTY_IO_URING_ENABLE_KEY = "netty.io_uring.enable";
+
String BIND_IP_KEY = "bind.ip";
String BIND_PORT_KEY = "bind.port";
diff --git a/dubbo-remoting/dubbo-remoting-netty4/pom.xml b/dubbo-remoting/dubbo-remoting-netty4/pom.xml
index dcf8857c17..8d278ee2f6 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/pom.xml
+++ b/dubbo-remoting/dubbo-remoting-netty4/pom.xml
@@ -33,6 +33,7 @@
false
UTF-8
+ 0.0.21.Final
@@ -70,5 +71,24 @@
linux-aarch_64
runtime
+
+
+
+ io.netty.incubator
+ netty-incubator-transport-classes-io_uring
+ ${netty-iouring.version}
+
+
+ io.netty.incubator
+ netty-incubator-transport-native-io_uring
+ ${netty-iouring.version}
+ linux-x86_64
+
+
+ io.netty.incubator
+ netty-incubator-transport-native-io_uring
+ ${netty-iouring.version}
+ linux-aarch_64
+
diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java
index ad3c807cf6..39c04b47a7 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java
@@ -16,11 +16,6 @@
*/
package org.apache.dubbo.remoting.transport.netty4;
-import org.apache.dubbo.common.resource.GlobalResourceInitializer;
-import org.apache.dubbo.remoting.Constants;
-
-import java.util.concurrent.ThreadFactory;
-
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
@@ -31,34 +26,59 @@ import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.incubator.channel.uring.IOUring;
+import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
+import io.netty.incubator.channel.uring.IOUringServerSocketChannel;
+import io.netty.incubator.channel.uring.IOUringSocketChannel;
import io.netty.util.concurrent.DefaultThreadFactory;
+import org.apache.dubbo.common.resource.GlobalResourceInitializer;
+import org.apache.dubbo.remoting.Constants;
+
+import java.util.concurrent.ThreadFactory;
import static org.apache.dubbo.common.constants.CommonConstants.OS_LINUX_PREFIX;
import static org.apache.dubbo.common.constants.CommonConstants.OS_NAME_KEY;
import static org.apache.dubbo.remoting.Constants.NETTY_EPOLL_ENABLE_KEY;
+import static org.apache.dubbo.remoting.Constants.NETTY_IO_URING_ENABLE_KEY;
public class NettyEventLoopFactory {
/**
* netty client bootstrap
*/
public static final GlobalResourceInitializer NIO_EVENT_LOOP_GROUP =
- new GlobalResourceInitializer<>(
- () -> eventLoopGroup(Constants.DEFAULT_IO_THREADS, "NettyClientWorker"),
- eventLoopGroup -> eventLoopGroup.shutdownGracefully());
+ new GlobalResourceInitializer<>(
+ () -> eventLoopGroup(Constants.DEFAULT_IO_THREADS, "NettyClientWorker"),
+ eventLoopGroup -> eventLoopGroup.shutdownGracefully());
public static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {
ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);
- return shouldEpoll()
- ? new EpollEventLoopGroup(threads, threadFactory)
- : new NioEventLoopGroup(threads, threadFactory);
+ if (shouldIOUring()) {
+ return new EpollEventLoopGroup(threads, threadFactory);
+ } else if (shouldIOUring()) {
+ return new IOUringEventLoopGroup(threads, threadFactory);
+ } else {
+ return new NioEventLoopGroup(threads, threadFactory);
+ }
}
public static Class extends SocketChannel> socketChannelClass() {
- return shouldEpoll() ? EpollSocketChannel.class : NioSocketChannel.class;
+ if (shouldEpoll()) {
+ return EpollSocketChannel.class;
+ } else if (shouldIOUring()) {
+ return IOUringSocketChannel.class;
+ } else {
+ return NioSocketChannel.class;
+ }
}
public static Class extends ServerSocketChannel> serverSocketChannelClass() {
- return shouldEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class;
+ if (shouldEpoll()) {
+ return EpollServerSocketChannel.class;
+ } else if (shouldIOUring()) {
+ return IOUringServerSocketChannel.class;
+ } else {
+ return NioServerSocketChannel.class;
+ }
}
private static boolean shouldEpoll() {
@@ -69,4 +89,13 @@ public class NettyEventLoopFactory {
return false;
}
+
+ private static boolean shouldIOUring() {
+ if (Boolean.parseBoolean(System.getProperty(NETTY_IO_URING_ENABLE_KEY, "false"))) {
+ String osName = System.getProperty(OS_NAME_KEY);
+ return osName.toLowerCase().contains(OS_LINUX_PREFIX) && IOUring.isAvailable();
+ }
+
+ return false;
+ }
}
diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactoryTest.java b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactoryTest.java
index 43fbdbe5a6..82884472b0 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactoryTest.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactoryTest.java
@@ -26,6 +26,10 @@ import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.incubator.channel.uring.IOUring;
+import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
+import io.netty.incubator.channel.uring.IOUringServerSocketChannel;
+import io.netty.incubator.channel.uring.IOUringSocketChannel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -34,6 +38,7 @@ import org.junit.jupiter.api.Test;
import static org.apache.dubbo.common.constants.CommonConstants.OS_LINUX_PREFIX;
import static org.apache.dubbo.common.constants.CommonConstants.OS_NAME_KEY;
import static org.apache.dubbo.remoting.Constants.NETTY_EPOLL_ENABLE_KEY;
+import static org.apache.dubbo.remoting.Constants.NETTY_IO_URING_ENABLE_KEY;
/**
* {@link NettyEventLoopFactory}
@@ -48,13 +53,15 @@ class NettyEventLoopFactoryTest {
@AfterEach
public void reset() {
System.clearProperty(NETTY_EPOLL_ENABLE_KEY);
+ System.clearProperty(NETTY_IO_URING_ENABLE_KEY);
}
@Test
void eventLoopGroup() {
if (isEpoll()) {
- EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test");
- Assertions.assertTrue(eventLoopGroup instanceof EpollEventLoopGroup);
+ try (EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test")) {
+ Assertions.assertTrue(eventLoopGroup instanceof EpollEventLoopGroup);
+ }
Class extends SocketChannel> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
Assertions.assertEquals(socketChannelClass, EpollSocketChannel.class);
@@ -64,8 +71,9 @@ class NettyEventLoopFactoryTest {
Assertions.assertEquals(serverSocketChannelClass, EpollServerSocketChannel.class);
} else {
- EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test");
- Assertions.assertTrue(eventLoopGroup instanceof NioEventLoopGroup);
+ try (EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test")) {
+ Assertions.assertTrue(eventLoopGroup instanceof NioEventLoopGroup);
+ }
Class extends SocketChannel> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
Assertions.assertEquals(socketChannelClass, NioSocketChannel.class);
@@ -76,6 +84,41 @@ class NettyEventLoopFactoryTest {
}
}
+
+ @Test
+ void testIOUringEventLoop() {
+ System.setProperty(NETTY_EPOLL_ENABLE_KEY, "false");
+ System.setProperty(NETTY_IO_URING_ENABLE_KEY, "true");
+
+ if (isIOUring()) {
+ try (EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test")) {
+ Assertions.assertTrue(eventLoopGroup instanceof IOUringEventLoopGroup);
+ }
+
+ Class> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
+ Assertions.assertEquals(socketChannelClass, IOUringSocketChannel.class);
+
+ Class> serverSocketChannelClass = NettyEventLoopFactory.serverSocketChannelClass();
+ Assertions.assertEquals(serverSocketChannelClass, IOUringServerSocketChannel.class);
+ } else {
+ try (EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test")) {
+ Assertions.assertTrue(eventLoopGroup instanceof NioEventLoopGroup);
+ }
+
+ Class extends SocketChannel> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
+ Assertions.assertEquals(socketChannelClass, NioSocketChannel.class);
+
+ Class extends ServerSocketChannel> serverSocketChannelClass =
+ NettyEventLoopFactory.serverSocketChannelClass();
+ Assertions.assertEquals(serverSocketChannelClass, NioServerSocketChannel.class);
+ }
+ }
+
+ private boolean isIOUring() {
+ String osName = System.getProperty(OS_NAME_KEY);
+ return osName.toLowerCase().contains(OS_LINUX_PREFIX) && IOUring.isAvailable();
+ }
+
private boolean isEpoll() {
String osName = System.getProperty(OS_NAME_KEY);
return osName.toLowerCase().contains(OS_LINUX_PREFIX) && Epoll.isAvailable();