CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-grpc--grpc-netty

Netty-based HTTP/2 transport implementation for gRPC Java providing high-performance network communication

Pending
Overview
Eval results
Files

socket-support.mddocs/

Socket Support

Low-level socket information access and native optimization features for advanced performance tuning and monitoring.

Core Imports

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;

NettySocketSupport

Utility class for accessing native socket information and options from Netty channels.

public static NativeSocketOptions getNativeSocketOptions(Channel ch);

Parameters:

  • ch - Netty channel to inspect

Returns: NativeSocketOptions containing socket information, or null if not available

NativeSocketOptions

Container class providing access to TCP socket information and native socket options.

Socket Information Access

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.

Usage Examples

Basic Socket Information

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");
}

TCP Information Monitoring

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

Performance Monitoring Integration

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);
    }
}

Platform-Specific Features

Linux (Epoll Transport)

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

macOS/BSD (KQueue Transport)

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

Integration with gRPC Channels

Client Channel Monitoring

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);
    }
});

Server Connection Monitoring

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
    }
}

Native Transport Configuration

High-Performance Linux Setup

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

Available Native Transports

PlatformTransportChannel TypesBenefits
LinuxEpollEpollSocketChannel, EpollServerSocketChannelBetter performance, more socket options
macOS/BSDKQueueKQueueSocketChannel, KQueueServerSocketChannelNative BSD socket support
AllNIONioSocketChannel, NioServerSocketChannelCross-platform compatibility

Socket Option Configuration

Common Socket Options

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

Linux-Specific Options

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)

Troubleshooting Socket Issues

Check Native Transport Availability

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

Debug Socket Configuration

// 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...");

Best Practices

  1. Use Native Transports: Enable epoll on Linux, kqueue on macOS for better performance
  2. Monitor Sparingly: Socket monitoring has overhead, use judiciously
  3. Platform-Specific Tuning: Configure platform-specific options for optimal performance
  4. Resource Management: Properly shut down custom event loop groups
  5. Testing: Test with different transports to verify compatibility
  6. Documentation: Document native transport requirements for deployment

Install with Tessl CLI

npx tessl i tessl/maven-io-grpc--grpc-netty

docs

client-transport.md

index.md

protocol-negotiation.md

server-transport.md

socket-support.md

ssl-tls.md

tile.json