Пользовательская команда gRP C для Dropwizard завершается немедленно - PullRequest
0 голосов
/ 13 февраля 2020

Я создал приложение с помощью Dropwizard, которое запускает сервер gRP C. Я не использую обычный сервер и хочу запустить свое приложение, используя вместо этого java -jar my-fat.jar grpc config.yml.

Я дошел до того, что добавил команду в качестве единственной доступной команды во время запуска, переопределив соответствующий метод в класс приложения:

public class App extends Application<Configuration> {

    public static void main(String[] args) throws Exception {
        new App().run(args);
    }

    @Override
    protected void addDefaultCommands(final Bootstrap<Configuration> bootstrap) {
        bootstrap.addCommand(new GrpcCommand(this));
    }
}

Я могу запустить свое приложение, используя java -jar my-fat.jar grpc config.yml. Моя команда выглядит так:

public class GrpcCommand extends EnvironmentCommand<Configuration> {

    public GrpcCommand(Application<Configuration> application) {
        this(application, "grpc", "Runs the Dropwizard application as a gRPC server");
    }

    /**
     * Creates a new environment command.
     *
     * @param application the application providing this command
     * @param name        the name of the command, used for command line invocation
     * @param description a description of the command's purpose
     */
    protected GrpcCommand(final Application<Configuration> application, final String name, final String description) {
        super(application, name, description);
    }

    @Override
    protected void run(final Environment environment, final Namespace namespace, final Configuration configuration) throws Exception {
        final var certificateService = AzureCertificateService.createWithClients(
                AzureSecretClient.create(configuration.getKeyVaultConfiguration()),
                AzureCertificateClient.create(configuration.getKeyVaultConfiguration())
        );

        final var validationService = CertificateValidationService.create(certificateService);
        final var signingService = CertificateSigningService.create(certificateService);

        final Pair<X509Certificate, KeyPair> certificate = certificateService.getSigningCertificateWithKeyPair();

        final BaseApiImpl baseApi = new BaseApiImpl(validationService, signingService);
        final GrpcServer grpcServer = GrpcServer.newBuilder()
                .withBaseApi(baseApi)
                .withConfiguration(configuration.getGrpcConfiguration())
                .withCertificate(certificate.getLeft())
                .withPrivateKey(certificate.getRight().getPrivate())
                .build();

        new Thread(() -> {
            try {
                grpcServer.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).run();

        environment.healthChecks().register("grpc-server", new GrpcServerHealthCheck(grpcServer));
    }
}

Способ запуска потока не для производственного использования, я просто пытаюсь продвинуться вперед. Метод запуска для класса GrpcServer:

@Override
public void start() throws Exception {
    final NettyServerBuilder nettyServerBuilder = NettyServerBuilder.forPort(configuration.getPort())
            .addService(baseApi)
            .intercept(new OriginInterceptor());

    if (certificate != null && privateKey != null) {
        LOG.info("Got certificate and private key, enabling SSL");
        nettyServerBuilder.sslContext(buildSslContext());
    }

    server = nettyServerBuilder
            .build()
            .start();

    LOG.info("Server started at port {}", server.getPort());
}

И я вижу сообщение GrpcServer: Server started at port 50441 в моем журнале при запуске. Тем не менее, приложение не остается открытым. Что мне не хватает? Разве мое использование потока не должно создавать поток, который останавливает выход приложения? Как сохранить работоспособность приложения после запуска сервера gRP C?

1 Ответ

0 голосов
/ 14 февраля 2020

Когда я отключил серверную команду, Jetty также не запускался (разумеется), что ранее поддерживало работу приложения.

Я нашел самое простое решение в gRP C Hello World Пример .

Мой метод запуска теперь выглядит так:

public void start() throws Exception {
    // Everything else as above

    Runtime.getRuntime().addShutdownHook(new Thread(GrpcServer.this::stop));
    LOG.info("Server started at port {}", server.getPort());
    blockUntilShutdown();
}

private void blockUntilShutdown() throws InterruptedException {
    if (server != null) {
        server.awaitTermination();
    }
}
...