This commit is contained in:
道君 2024-06-30 04:45:26 +02:00 committed by GitHub
commit 49a36c8a6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 111 additions and 17 deletions

View File

@ -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";

View File

@ -33,6 +33,7 @@
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<netty-iouring.version>0.0.21.Final</netty-iouring.version>
</properties>
<dependencies>
@ -70,5 +71,24 @@
<classifier>linux-aarch_64</classifier>
<scope>runtime</scope>
</dependency>
<!-- io_uring deps -->
<dependency>
<groupId>io.netty.incubator</groupId>
<artifactId>netty-incubator-transport-classes-io_uring</artifactId>
<version>${netty-iouring.version}</version>
</dependency>
<dependency>
<groupId>io.netty.incubator</groupId>
<artifactId>netty-incubator-transport-native-io_uring</artifactId>
<version>${netty-iouring.version}</version>
<classifier>linux-x86_64</classifier>
</dependency>
<dependency>
<groupId>io.netty.incubator</groupId>
<artifactId>netty-incubator-transport-native-io_uring</artifactId>
<version>${netty-iouring.version}</version>
<classifier>linux-aarch_64</classifier>
</dependency>
</dependencies>
</project>

View File

@ -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<EventLoopGroup> 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;
}
}

View File

@ -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();