我已经使用dropwizard创建了一个启动grpc服务器的应用程序。我不使用常规服务器,希望使用 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
在我的日志中。但是,应用程序不会保持打开状态。我错过了什么?我对线程的使用不应该创建一个阻止应用程序退出的线程吗?如何在grpc服务器启动后保持应用程序运行?
1条答案
按热度按时间ki0zmccv1#
当我禁用server命令时,jetty也没有启动(当然),这使应用程序保持了以前的活动状态。
我在grpc hello world示例中找到了最简单的解决方案。
我的启动方法现在如下所示: