Netty-based HTTP/2 transport implementation for gRPC Java providing high-performance network communication
—
Low-level socket information access and native optimization features for advanced performance tuning and monitoring.
import io.grpc.netty.NettySocketSupport;
import io.grpc.netty.NettySocketSupport.NativeSocketOptions;
import io.grpc.InternalChannelz.TcpInfo;
import io.netty.channel.Channel;
import com.google.common.collect.ImmutableMap;Utility class for accessing native socket information and options from Netty channels.
public static NativeSocketOptions getNativeSocketOptions(Channel ch);Parameters:
ch - Netty channel to inspectReturns: NativeSocketOptions containing socket information, or null if not available
Container class providing access to TCP socket information and native socket options.
public class NativeSocketOptions {
// Methods for accessing socket information
public SocketOption<Integer> getSocketOption(String name);
public Map<String, Object> getAllOptions();
}Note: The exact API surface depends on the underlying native transport implementation and platform support.
import io.grpc.netty.NettySocketSupport;
import io.grpc.netty.NettySocketSupport.NativeSocketOptions;
import io.netty.channel.Channel;
// Get channel from established connection
Channel channel = getNettyChannel(); // From your gRPC channel/server
NativeSocketOptions socketOptions = NettySocketSupport.getNativeSocketOptions(channel);
if (socketOptions != null) {
// Access native socket information
System.out.println("Native socket options available");
// Get specific socket options (platform-dependent)
Map<String, Object> allOptions = socketOptions.getAllOptions();
allOptions.forEach((key, value) ->
System.out.println(key + ": " + value));
} else {
System.out.println("Native socket options not available");
}import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.epoll.EpollChannelOption;
// When using epoll transport on Linux
if (channel instanceof EpollSocketChannel) {
EpollSocketChannel epollChannel = (EpollSocketChannel) channel;
// Access TCP_INFO (Linux-specific)
EpollTcpInfo tcpInfo = epollChannel.tcpInfo();
if (tcpInfo != null) {
System.out.println("RTT: " + tcpInfo.rtt());
System.out.println("RTT variance: " + tcpInfo.rttvar());
System.out.println("Send buffer: " + tcpInfo.sndMss());
System.out.println("Receive buffer: " + tcpInfo.rcvMss());
}
}import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ConnectionMonitor {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void startMonitoring(Channel channel) {
scheduler.scheduleAtFixedRate(() -> {
NativeSocketOptions options = NettySocketSupport.getNativeSocketOptions(channel);
if (options != null) {
logSocketMetrics(options);
}
}, 0, 30, TimeUnit.SECONDS);
}
private void logSocketMetrics(NativeSocketOptions options) {
Map<String, Object> metrics = options.getAllOptions();
// Log metrics to your monitoring system
System.out.println("Socket metrics: " + metrics);
}
}import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.epoll.EpollChannelOption;
// Configure epoll-specific options
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(EpollServerSocketChannel.class)
.childOption(EpollChannelOption.TCP_CORK, false)
.childOption(EpollChannelOption.TCP_QUICKACK, true)
.childOption(EpollChannelOption.SO_REUSEPORT, true);
// Access epoll-specific information
if (channel instanceof EpollSocketChannel) {
EpollSocketChannel epollChannel = (EpollSocketChannel) channel;
// Get TCP connection info
EpollTcpInfo info = epollChannel.tcpInfo();
if (info != null) {
System.out.println("Connection state: " + info.state());
System.out.println("Congestion window: " + info.sndCwnd());
System.out.println("Slow start threshold: " + info.sndSsthresh());
}
}import io.netty.channel.kqueue.KQueueSocketChannel;
import io.netty.channel.kqueue.KQueueChannelOption;
// Configure kqueue-specific options
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(KQueueServerSocketChannel.class)
.childOption(KQueueChannelOption.SO_REUSEPORT, true);import io.grpc.netty.NettyChannelBuilder;
import io.grpc.ConnectivityState;
ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", 9090)
.usePlaintext()
.build();
// Monitor channel state changes
channel.notifyWhenStateChanged(ConnectivityState.IDLE, () -> {
// Access underlying Netty channel when connected
if (channel.getState(false) == ConnectivityState.READY) {
// Get Netty channel (requires reflection or internal APIs)
monitorSocketOptions(channel);
}
});import io.grpc.netty.NettyServerBuilder;
public class MonitoringServerInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
// Access transport attributes
Attributes attributes = call.getAttributes();
// Monitor connection if available
monitorConnection(call);
return next.startCall(call, headers);
}
private void monitorConnection(ServerCall<?, ?> call) {
// Access underlying transport information
// Implementation depends on internal gRPC APIs
}
}import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.epoll.EpollSocketChannel;
// Use native epoll transport for better performance
EventLoopGroup bossGroup = new EpollEventLoopGroup(1);
EventLoopGroup workerGroup = new EpollEventLoopGroup();
Server server = NettyServerBuilder.forPort(9090)
.channelType(EpollServerSocketChannel.class)
.bossEventLoopGroup(bossGroup)
.workerEventLoopGroup(workerGroup)
.withChildOption(EpollChannelOption.TCP_NODELAY, true)
.withChildOption(EpollChannelOption.SO_KEEPALIVE, true)
.withChildOption(EpollChannelOption.SO_REUSEPORT, true)
.addService(new GreeterImpl())
.build();
// Client with epoll
ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", 9090)
.channelType(EpollSocketChannel.class)
.eventLoopGroup(new EpollEventLoopGroup())
.usePlaintext()
.build();| Platform | Transport | Channel Types | Benefits |
|---|---|---|---|
| Linux | Epoll | EpollSocketChannel, EpollServerSocketChannel | Better performance, more socket options |
| macOS/BSD | KQueue | KQueueSocketChannel, KQueueServerSocketChannel | Native BSD socket support |
| All | NIO | NioSocketChannel, NioServerSocketChannel | Cross-platform compatibility |
import io.netty.channel.ChannelOption;
// Standard socket options (cross-platform)
NettyServerBuilder.forPort(9090)
.withChildOption(ChannelOption.TCP_NODELAY, true)
.withChildOption(ChannelOption.SO_KEEPALIVE, true)
.withChildOption(ChannelOption.SO_SNDBUF, 65536)
.withChildOption(ChannelOption.SO_RCVBUF, 65536)
.withChildOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);import io.netty.channel.epoll.EpollChannelOption;
// Linux epoll-specific options
.withChildOption(EpollChannelOption.TCP_CORK, false)
.withChildOption(EpollChannelOption.TCP_QUICKACK, true)
.withChildOption(EpollChannelOption.SO_REUSEPORT, true)
.withChildOption(EpollChannelOption.TCP_FASTOPEN, 3)import io.netty.channel.epoll.Epoll;
import io.netty.channel.kqueue.KQueue;
System.out.println("Epoll available: " + Epoll.isAvailable());
if (!Epoll.isAvailable()) {
System.out.println("Epoll unavailability cause: " + Epoll.unavailabilityCause());
}
System.out.println("KQueue available: " + KQueue.isAvailable());
if (!KQueue.isAvailable()) {
System.out.println("KQueue unavailability cause: " + KQueue.unavailabilityCause());
}// Enable Netty logging
System.setProperty("io.netty.leakDetection.level", "paranoid");
System.setProperty("io.netty.leakDetection.targetRecords", "20");
// Log socket option configuration
Logger logger = LoggerFactory.getLogger("socket.config");
logger.info("Configuring socket options...");Install with Tessl CLI
npx tessl i tessl/maven-io-grpc--grpc-netty