将 Java gRPC 服务器绑定到 unix 域套接字

Binding a Java gRPC server to a unix domain socket

我有以下内容,它创建了一个 Java gRPC 服务器并尝试将其绑定到美元 /tmp/foo:

  EpollEventLoopGroup group = new EpollEventLoopGroup();
  Server server =
      NettyServerBuilder.forAddress(new DomainSocketAddress("/tmp/foo"))
          .channelType(EpollServerSocketChannel.class)
          .bossEventLoopGroup(group)
          .workerEventLoopGroup(group)
          .addService(new Impl())
          .build()
          .start();
  server.awaitTermination();

然而,这失败了 bind(..) failed: Invalid argument:

Exception in thread "main" java.io.IOException: Failed to bind
        at io.grpc.netty.NettyServer.start(NettyServer.java:231)
        at io.grpc.internal.ServerImpl.start(ServerImpl.java:151)
        at io.grpc.internal.ServerImpl.start(ServerImpl.java:75)
        at com.google.devtools.javatools.jade.pkgloader.GrpcLocalServer.main(GrpcLocalServer.java:60)
Caused by: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: Invalid argument
        at io.netty.channel.unix.Errors.newIOException(Errors.java:117)
        at io.netty.channel.unix.Socket.bind(Socket.java:291)
        at io.netty.channel.epoll.AbstractEpollChannel.doBind(AbstractEpollChannel.java:714)
        at io.netty.channel.epoll.EpollServerSocketChannel.doBind(EpollServerSocketChannel.java:70)
        at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:558)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1283)
        at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:501)
        at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:486)
        at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:989)
        at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:254)
        at io.netty.bootstrap.AbstractBootstrap.run(AbstractBootstrap.java:364)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403)
        at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:309)
        at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
        at java.lang.Thread.run(Thread.java:745)

我检查过文件 /tmp/foo 不存在,我对它及其父目录有写入权限,并且没有进程绑定到它 (netstat -na | grep /tmp/foo.socket)。我在 Linux 系统上。

我是不是遗漏了什么明显的东西?

使用 EpollServerDomainSocketChannel 而不是 EpollServerSocketChannel 解决了这个问题。

为了将来 copy/paste,以下绑定(侦听)UDS:

EpollEventLoopGroup group = new EpollEventLoopGroup();
Server server = NettyServerBuilder.forAddress(new DomainSocketAddress("/tmp/foo"))
    .channelType(EpollServerDomainSocketChannel.class)
    .workerEventLoopGroup(group)
    .bossEventLoopGroup(group)
    .addService(new Impl())
    .build()