Merge 76d29c8537 into 11d5bd9ffa
This commit is contained in:
commit
49a36c8a6e
|
|
@ -122,6 +122,8 @@ public interface Constants {
|
||||||
|
|
||||||
String NETTY_EPOLL_ENABLE_KEY = "netty.epoll.enable";
|
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_IP_KEY = "bind.ip";
|
||||||
|
|
||||||
String BIND_PORT_KEY = "bind.port";
|
String BIND_PORT_KEY = "bind.port";
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<skip_maven_deploy>false</skip_maven_deploy>
|
<skip_maven_deploy>false</skip_maven_deploy>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<netty-iouring.version>0.0.21.Final</netty-iouring.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
@ -70,5 +71,24 @@
|
||||||
<classifier>linux-aarch_64</classifier>
|
<classifier>linux-aarch_64</classifier>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.dubbo.remoting.transport.netty4;
|
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.EventLoopGroup;
|
||||||
import io.netty.channel.epoll.Epoll;
|
import io.netty.channel.epoll.Epoll;
|
||||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
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.SocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
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 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_LINUX_PREFIX;
|
||||||
import static org.apache.dubbo.common.constants.CommonConstants.OS_NAME_KEY;
|
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_EPOLL_ENABLE_KEY;
|
||||||
|
import static org.apache.dubbo.remoting.Constants.NETTY_IO_URING_ENABLE_KEY;
|
||||||
|
|
||||||
public class NettyEventLoopFactory {
|
public class NettyEventLoopFactory {
|
||||||
/**
|
/**
|
||||||
* netty client bootstrap
|
* netty client bootstrap
|
||||||
*/
|
*/
|
||||||
public static final GlobalResourceInitializer<EventLoopGroup> NIO_EVENT_LOOP_GROUP =
|
public static final GlobalResourceInitializer<EventLoopGroup> NIO_EVENT_LOOP_GROUP =
|
||||||
new GlobalResourceInitializer<>(
|
new GlobalResourceInitializer<>(
|
||||||
() -> eventLoopGroup(Constants.DEFAULT_IO_THREADS, "NettyClientWorker"),
|
() -> eventLoopGroup(Constants.DEFAULT_IO_THREADS, "NettyClientWorker"),
|
||||||
eventLoopGroup -> eventLoopGroup.shutdownGracefully());
|
eventLoopGroup -> eventLoopGroup.shutdownGracefully());
|
||||||
|
|
||||||
public static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {
|
public static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {
|
||||||
ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);
|
ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);
|
||||||
return shouldEpoll()
|
if (shouldIOUring()) {
|
||||||
? new EpollEventLoopGroup(threads, threadFactory)
|
return new EpollEventLoopGroup(threads, threadFactory);
|
||||||
: new NioEventLoopGroup(threads, threadFactory);
|
} else if (shouldIOUring()) {
|
||||||
|
return new IOUringEventLoopGroup(threads, threadFactory);
|
||||||
|
} else {
|
||||||
|
return new NioEventLoopGroup(threads, threadFactory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<? extends SocketChannel> socketChannelClass() {
|
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() {
|
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() {
|
private static boolean shouldEpoll() {
|
||||||
|
|
@ -69,4 +89,13 @@ public class NettyEventLoopFactory {
|
||||||
|
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ import io.netty.channel.socket.ServerSocketChannel;
|
||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
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.AfterEach;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
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_LINUX_PREFIX;
|
||||||
import static org.apache.dubbo.common.constants.CommonConstants.OS_NAME_KEY;
|
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_EPOLL_ENABLE_KEY;
|
||||||
|
import static org.apache.dubbo.remoting.Constants.NETTY_IO_URING_ENABLE_KEY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link NettyEventLoopFactory}
|
* {@link NettyEventLoopFactory}
|
||||||
|
|
@ -48,13 +53,15 @@ class NettyEventLoopFactoryTest {
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void reset() {
|
public void reset() {
|
||||||
System.clearProperty(NETTY_EPOLL_ENABLE_KEY);
|
System.clearProperty(NETTY_EPOLL_ENABLE_KEY);
|
||||||
|
System.clearProperty(NETTY_IO_URING_ENABLE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void eventLoopGroup() {
|
void eventLoopGroup() {
|
||||||
if (isEpoll()) {
|
if (isEpoll()) {
|
||||||
EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test");
|
try (EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test")) {
|
||||||
Assertions.assertTrue(eventLoopGroup instanceof EpollEventLoopGroup);
|
Assertions.assertTrue(eventLoopGroup instanceof EpollEventLoopGroup);
|
||||||
|
}
|
||||||
|
|
||||||
Class<? extends SocketChannel> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
|
Class<? extends SocketChannel> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
|
||||||
Assertions.assertEquals(socketChannelClass, EpollSocketChannel.class);
|
Assertions.assertEquals(socketChannelClass, EpollSocketChannel.class);
|
||||||
|
|
@ -64,8 +71,9 @@ class NettyEventLoopFactoryTest {
|
||||||
Assertions.assertEquals(serverSocketChannelClass, EpollServerSocketChannel.class);
|
Assertions.assertEquals(serverSocketChannelClass, EpollServerSocketChannel.class);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test");
|
try (EventLoopGroup eventLoopGroup = NettyEventLoopFactory.eventLoopGroup(1, "test")) {
|
||||||
Assertions.assertTrue(eventLoopGroup instanceof NioEventLoopGroup);
|
Assertions.assertTrue(eventLoopGroup instanceof NioEventLoopGroup);
|
||||||
|
}
|
||||||
|
|
||||||
Class<? extends SocketChannel> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
|
Class<? extends SocketChannel> socketChannelClass = NettyEventLoopFactory.socketChannelClass();
|
||||||
Assertions.assertEquals(socketChannelClass, NioSocketChannel.class);
|
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() {
|
private boolean isEpoll() {
|
||||||
String osName = System.getProperty(OS_NAME_KEY);
|
String osName = System.getProperty(OS_NAME_KEY);
|
||||||
return osName.toLowerCase().contains(OS_LINUX_PREFIX) && Epoll.isAvailable();
|
return osName.toLowerCase().contains(OS_LINUX_PREFIX) && Epoll.isAvailable();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue