java高可用grpc_Java中使用GRPC(带TLS认证)

本文档详细介绍了如何在Java中使用GRPC实现高可用性,并通过TLS认证确保通信安全。首先,展示了如何编写.proto文件定义服务和消息类型,然后讲解如何编译.proto生成Java代码。接着,创建CA根证书、服务器证书和客户端证书的过程被详述。最后,提供了Server端和Client端的Java代码示例,展示如何配置和使用TLS进行加密通信。通过在Server端和Client端分别运行这些代码,可以在本地完成GRPC的TLS验证通信。
摘要由CSDN通过智能技术生成

0.编写.proto

syntax = "proto3";

option java_multiple_files = true;

option java_package = "io.grpc.examples.helloworld";

option java_outer_classname = "HelloWorldProto";

option objc_class_prefix = "HLW";

package helloworld;

service Greeter {

rpc SayHello (HelloRequest) returns (HelloReply) {}

}

message HelloRequest {

string name = 1;

}

message HelloReply {

string message = 1;

}

1.编译.proto生成Java源文件:

protoc --grpc_out=..\\java --plugin=protoc-gen-grpc=D:\\Dev\\protoc\\protoc-gen-grpc-java-1.9.1-windows-x86_64.exe helloworld.proto

protoc --java_out=..\\java helloworld.proto

2.生成CA根证书、服务器证书及客户端证书

openssl genrsa -passout pass:111111 -des3 -out ca.key 4096

openssl req -passin pass:111111 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=localhost"

openssl genrsa -passout pass:111111 -des3 -out server.key 4096

openssl req -passin pass:111111 -new -key server.key -out server.csr -subj "/CN=localhost"

openssl x509 -req -passin pass:111111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

openssl rsa -passin pass:111111 -in server.key -out server.key

openssl genrsa -passout pass:111111 -des3 -out client.key 4096

openssl req -passin pass:111111 -new -key client.key -out client.csr -subj "/CN=localhost"

openssl x509 -passin pass:111111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

openssl rsa -passin pass:111111 -in client.key -out client.key

openssl pkcs8 -topk8 -nocrypt -in client.key -out client.pem

openssl pkcs8 -topk8 -nocrypt -in server.key -out server.pem

3.编写Server端代码

package io.grpc.examples.helloworldtls;

import io.grpc.Server;

import io.grpc.examples.helloworld.GreeterGrpc;

import io.grpc.examples.helloworld.HelloReply;

import io.grpc.examples.helloworld.HelloRequest;

import io.grpc.netty.GrpcSslContexts;

import io.grpc.netty.NettyServerBuilder;

import io.grpc.stub.StreamObserver;

import io.netty.handler.ssl.ClientAuth;

import io.netty.handler.ssl.SslContextBuilder;

import io.netty.handler.ssl.SslProvider;

import java.io.File;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.util.logging.Logger;

public class HelloWorldServerTls {

private static final Logger logger = Logger.getLogger(HelloWorldServerTls.class.getName());

private Server server;

private final String host;

private final int port;

private final String certChainFilePath;

private final String privateKeyFilePath;

private final String trustCertCollectionFilePath;

public HelloWorldServerTls(String host,

int port,

String certChainFilePath,

String privateKeyFilePath,

String trustCertCollectionFilePath) {

this.host = host;

this.port = port;

this.certChainFilePath = certChainFilePath;

this.privateKeyFilePath = privateKeyFilePath;

this.trustCertCollectionFilePath = trustCertCollectionFilePath;

}

private SslContextBuilder getSslContextBuilder() {

SslContextBuilder sslClientContextBuilder = SslContextBuilder.forServer(new File(certChainFilePath),

new File(privateKeyFilePath));

if (trustCertCollectionFilePath != null) {

sslClientContextBuilder.trustManager(new File(trustCertCollectionFilePath));

sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);

}

return GrpcSslContexts.configure(sslClientContextBuilder,

SslProvider.OPENSSL);

}

private void start() throws IOException {

server = NettyServerBuilder.forAddress(new InetSocketAddress(host, port))

.addService(new GreeterImpl())

.sslContext(getSslContextBuilder().build())

.build()

.start();

logger.info("Server started, listening on " + port);

Runtime.getRuntime().addShutdownHook(new Thread() {

@Override

public void run() {

// Use stderr here since the logger may have been reset by its JVM shutdown hook.

System.err.println("*** shutting down gRPC server since JVM is shutting down");

HelloWorldServerTls.this.stop();

System.err.println("*** server shut down");

}

});

}

private void stop() {

if (server != null) {

server.shutdown();

}

}

private void blockUntilShutdown() throws InterruptedException {

if (server != null) {

server.awaitTermination();

}

}

public static void main(String[] args) throws IOException, InterruptedException {

if (args.length < 4 || args.length > 5) {

System.out.println(

"USAGE: HelloWorldServerTls host port certChainFilePath privateKeyFilePath " +

"[trustCertCollectionFilePath]\n Note: You only need to supply trustCertCollectionFilePath if you want " +

"to enable Mutual TLS.");

System.exit(0);

}

final HelloWorldServerTls server = new HelloWorldServerTls(args[0],

Integer.parseInt(args[1]),

args[2],

args[3],

args.length == 5 ? args[4] : null);

server.start();

server.blockUntilShutdown();

}

static class GreeterImpl extends GreeterGrpc.GreeterImplBase {

@Override

public void sayHello(HelloRequest req, StreamObserver responseObserver) {

HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();

responseObserver.onNext(reply);

responseObserver.onCompleted();

}

}

}

4.编写Client端代码

package io.grpc.examples.helloworldtls;

import io.grpc.ManagedChannel;

import io.grpc.StatusRuntimeException;

import io.grpc.examples.helloworld.GreeterGrpc;

import io.grpc.examples.helloworld.HelloReply;

import io.grpc.examples.helloworld.HelloRequest;

import io.grpc.examples.helloworld.HelloWorldServer;

import io.grpc.netty.GrpcSslContexts;

import io.grpc.netty.NegotiationType;

import io.grpc.netty.NettyChannelBuilder;

import io.netty.handler.ssl.SslContext;

import io.netty.handler.ssl.SslContextBuilder;

import javax.net.ssl.SSLException;

import java.io.File;

import java.util.concurrent.TimeUnit;

import java.util.logging.Level;

import java.util.logging.Logger;

public class HelloWorldClientTls {

private static final Logger logger = Logger.getLogger(HelloWorldClientTls.class.getName());

private final ManagedChannel channel;

private final GreeterGrpc.GreeterBlockingStub blockingStub;

private static SslContext buildSslContext(String trustCertCollectionFilePath,

String clientCertChainFilePath,

String clientPrivateKeyFilePath) throws SSLException {

SslContextBuilder builder = GrpcSslContexts.forClient();

if (trustCertCollectionFilePath != null) {

builder.trustManager(new File(trustCertCollectionFilePath));

}

if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {

builder.keyManager(new File(clientCertChainFilePath), new File(clientPrivateKeyFilePath));

}

return builder.build();

}

public HelloWorldClientTls(String host,

int port,

SslContext sslContext) throws SSLException {

this(NettyChannelBuilder.forAddress(host, port)

.negotiationType(NegotiationType.TLS)

.sslContext(sslContext)

.build());

}

HelloWorldClientTls(ManagedChannel channel) {

this.channel = channel;

blockingStub = GreeterGrpc.newBlockingStub(channel);

}

public void shutdown() throws InterruptedException {

channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);

}

public void greet(String name) {

logger.info("Will try to greet " + name + " ...");

HelloRequest request = HelloRequest.newBuilder().setName(name).build();

HelloReply response;

try {

response = blockingStub.sayHello(request);

} catch (StatusRuntimeException e) {

logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());

return;

}

logger.info("Greeting: " + response.getMessage());

}

public static void main(String[] args) throws Exception {

if (args.length < 2 || args.length == 4 || args.length > 5) {

System.out.println("USAGE: HelloWorldClientTls host port [trustCertCollectionFilePath] " +

"[clientCertChainFilePath] [clientPrivateKeyFilePath]\n Note: clientCertChainFilePath and " +

"clientPrivateKeyFilePath are only needed if mutual auth is desired. And if you specify " +

"clientCertChainFilePath you must also specify clientPrivateKeyFilePath");

System.exit(0);

}

{

HelloWorldClientTls client;

switch (args.length) {

case 2:

client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]),

buildSslContext(null, null, null));

break;

case 3:

client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]),

buildSslContext(args[2], null, null));

break;

default:

client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]),

buildSslContext(args[2], args[3], args[4]));

}

try {

String user = "world";

if (args.length > 0) {

user = args[0]; /* Use the arg as the name to greet if provided */

}

client.greet(user);

} finally {

client.shutdown();

}

}

}

}

5.分别运行Server、Client代码:

(Server端加入运行参数:localhost 50051 D:\openssl-keys\server.crt D:\openssl-keys\server.pem)

(Client端加入运行参数:localhost 50051 D:\openssl-keys\ca.crt D:\openssl-keys\client.crt D:\openssl-keys\client.pem)

运行如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值