Netty systemd ленивая инициализация - PullRequest
0 голосов
/ 04 мая 2018

Можно ли инициализировать netty lazy через systemd / inetd, используя унаследованный канал сокета сервера? Мы использовали это на нашем старом сервере на базе Jetty, где Jetty вызывала Java System.inheritedChannel (), чтобы получить сокет, созданный с помощью systemd при отложенной инициализации.

Я много искал, и все, что я нашел, это билет Jira, который говорит, что он предположительно поддерживается в версии 4: https://issues.jboss.org/browse/NETTY-309.

Но у этого билета jira нет примера, и я не смог найти ни документации, ни чего-либо в исходном коде, который мог бы указать мне, как добиться этого в netty.

Любая помощь будет оценена.
Спасибо

EDIT: Просто чтобы прояснить, что я хочу знать, возможно ли активировать сокет моего java-приложения с помощью systemd, а затем каким-то образом передать ссылку на сокет netty.

РЕДАКТИРОВАТЬ 2: Вот подход, предложенный Норманом Майером, но на самом деле он терпит неудачу, за исключением следующего:

public class MyServerBootStrap {

  private ServiceContext ctx;
  private Config config;
  private Collection<Channel> channels;
  private Collection<Connector> connectors;

  public MyServerBootStrap(List<Connector> connectors) {
    this.ctx = ApplicationContext.getInstance();
    this.config = ctx.getMainConfig();
    this.connectors = connectors;
    this.channels = new ArrayList<>(connectors.size());
  }

  public void run(Connector connector) throws RuntimeException, IOException, InterruptedException {
    EventLoopGroup bossGroup = new NioEventLoopGroup(config.getInt("http_acceptor_threads", 0));
    EventLoopGroup workerGroup = new NioEventLoopGroup(config.getIntError("http_server_threads"));

    final SocketAddress addr;
    final ChannelFactory<ServerChannel> channelFactory;
    if (connector.geEndpoint().isInherited()) {
      System.out.println(
          "Trying to bootstrap inherited channel: " + connector.geEndpoint().getDescription());
      ServerSocketChannel channel = (ServerSocketChannel) System.inheritedChannel();

      addr = channel.getLocalAddress();
      System.out.println("Channel localAddress(): " + addr);
      channelFactory = new MyChannelFactory(channel);
    } else {
      System.out.println(
          "Trying to bootstrap regular channel: " + connector.geEndpoint().getDescription());
      addr = connector.geEndpoint().getSocketAdress();
      channelFactory = new MyChannelFactory(null);
    }

    ServerBootstrap b = new ServerBootstrap();
    b
        .group(bossGroup, workerGroup)
        .localAddress(addr)
        .channelFactory(channelFactory)
        .childHandler(new ChannelInitializerRouter(Collections.singletonList(connector)))
        .childOption(ChannelOption.SO_KEEPALIVE, true);

    if (config.contains("tcp_max_syn_backlog")) {
      b.option(ChannelOption.SO_BACKLOG, config.getIntError("tcp_max_syn_backlog"));
    }

    Channel serverChannel = b.bind().sync().channel();
    channels.add(serverChannel);
  }

  public void run() throws RuntimeException {
    try {
      for (Connector connector : connectors) {
        run(connector);
      }
      for (Channel channel : channels) {
        channel.closeFuture().sync();
      }
    } catch (Throwable exc) {
      throw new RuntimeException("Failed to start web-server", exc);
    } finally {
      // TODO: fix this
      // workerGroup.shutdownGracefully();
      // bossGroup.shutdownGracefully();
    }
  }
}


class MyChannelFactory implements io.netty.channel.ChannelFactory<ServerChannel> {

  private ServerSocketChannel channel;

  public MyChannelFactory(ServerSocketChannel ch) {
    this.channel = ch;
  }

  @Override
  public ServerChannel newChannel() {
    if (channel == null) {
      return new NioServerSocketChannel();
    } else {
      return new NioServerSocketChannel(channel);
    }
  }

}

.log:

 Trying to bootstrap inherited channel: public (tcp port: 8080)
 Channel localAddress(): /0:0:0:0:0:0:0:0:8080
 java.lang.RuntimeException: Failed to start web-server
         at MyServerBootStrap.run(MyServerBootStrap.java:85)
         at MyServer.run(MyServer.java:61)
         at Main.start(Main.java:96)
         at Main.main(Main.java:165)
 Caused by: java.nio.channels.AlreadyBoundException
         at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:216)
         at sun.nio.ch.InheritedChannel$InheritedServerSocketChannelImpl.bind(InheritedChannel.java:92)
         at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:128)
         at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:558)
         at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1338)
         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:999)
         at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:254)
         at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:366)
         at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
         at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
         at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)
         at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
         at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
         at java.lang.Thread.run(Thread.java:748)

1 Ответ

0 голосов
/ 06 мая 2018

Да, это должно быть возможно.

NioServerSocketChannel позволяет вам обернуть существующий Channel через его конструктор. Поэтому все, что вам нужно сделать, это написать свой собственный ChannelFactory и использовать его с ServerBootstrap, чтобы убедиться, что вы создаете NioServerSocketChannel, который обернет его.

Другой подход заключается в том, чтобы вообще не использовать ServerBootstrap, а просто зарегистрировать вызов и т. Д. С вручную созданным NioServerSocketChannel.

...