1. 概述
本文将探讨 ALTS(应用层传输安全)在 gRPC 应用中的作用。在分布式架构中,确保认证和数据安全既困难又至关重要,而 ALTS 提供了一种简洁高效的解决方案。
ALTS 是 Google 专有的双向认证和传输加密方案,仅在 Google 云基础设施中可用。它简化了 gRPC 服务间的认证和数据加密,只需极少的代码改动即可启用,让开发者能更专注于业务逻辑开发。
2. ALTS 与 TLS 的核心差异
ALTS 与 TLS 相似,但采用了针对 Google 基础设施优化的信任模型。以下是它们的关键区别:
特性 | ALTS | TLS |
---|---|---|
信任模型 | 基于 GCP IAM 服务账户的身份验证 | 基于证书,需管理证书生命周期(续期/撤销) |
设计复杂度 | 简单粗暴 | 复杂 |
使用场景 | 保护 Google 数据中心内的 gRPC 服务 | 保护 HTTPS、邮件、即时通讯、VoIP 等 |
消息序列化 | 使用 Protocol Buffers | 使用 ASN.1 编码的 X.509 证书 |
性能 | 通用设计 | 针对 Google 数据中心的低延迟、高吞吐量通信优化 |
⚠️ 踩坑提示:ALTS 仅在 GCP 环境中有效,跨云部署需改用 TLS。
3. 使用 ALTS 的示例应用
ALTS 在 Google Cloud Platform (GCP) 上默认启用,通过 GCP 服务账户保护 gRPC 服务间的 RPC 调用。该功能运行在 Google 基础设施内的 Compute Engine 或 Kubernetes Engine (GKE) 上。
以医院手术室(OT)预约系统为例,包含前端和后端服务:
系统包含两个运行在 GCP 上的服务:
- 前端服务调用后端服务的 RPC 接口
- 使用 gRPC 框架开发
- 通过内置 ALTS 功能实现数据传输的认证与加密
首先定义 protobuf 文件 ot_booking.proto
:
syntax = "proto3";
package otbooking;
option java_multiple_files = true;
option java_package = "com.baeldung.grpc.alts.otbooking";
service OtBookingService {
rpc getBookingInfo(BookingRequest) returns (BookingResponse) {}
}
message BookingRequest {
string patientID = 1;
string doctorID = 2;
string description = 3;
}
message BookingResponse {
string bookingDate = 1;
string condition = 2;
}
核心类结构如下:
Maven 插件编译 protobuf 后自动生成:
OtBookingServiceGrpc
OtBookingServiceImplBase
BookingRequest
BookingResponse
客户端关键实现:
- 使用
AltsChannelBuilder
创建启用 ALTS 的ManagedChannel
- 通过
OtBookingServiceGrpc
生成阻塞式存根调用服务端接口
服务端关键实现:
- 使用
AltsServerBuilder
启用 ALTS - 注册
ClientAuthInterceptor
进行客户端认证 - 将服务注册到
io.grpc.Server
并启动
4. 基于 ALTS 的应用实现
4.1. 前置条件
ALTS 是 GCP 内置功能,需先准备云资源:
创建 IAM 服务账户:
- 前端服务账户:
prod-ot-booking-client-svc
- 后端服务账户:
prod-ot-booking-svc
- 前端服务账户:
创建虚拟机:
- 前端虚拟机:
prod-booking-client-vm
关联prod-ot-booking-client-svc
- 后端虚拟机:
prod-booking-service-vm
关联prod-ot-booking-svc
- 前端虚拟机:
服务账户作为服务器身份标识,ALTS 使用它们进行授权和加密。
4.2. 代码实现
Maven 依赖:
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-alts</artifactId>
<version>1.63.0</version>
</dependency>
服务端实现:
public class AltsOtBookingServer {
public static void main(String[] args) throws IOException, InterruptedException {
final String CLIENT_SERVICE_ACCOUNT = args[0];
Server server = AltsServerBuilder.forPort(8080)
.intercept(new ClientAuthInterceptor(CLIENT_SERVICE_ACCOUNT))
.addService(new OtBookingService())
.build();
server.start();
server.awaitTermination();
}
}
客户端认证拦截器:
public class ClientAuthInterceptor implements ServerInterceptor {
String clientServiceAccount = null;
public ClientAuthInterceptor(String clientServiceAccount) {
this.clientServiceAccount = clientServiceAccount;
}
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata,
ServerCallHandler<ReqT, RespT> serverCallHandler) {
Status status = AuthorizationUtil.clientAuthorizationCheck(serverCall,
Lists.newArrayList(this.clientServiceAccount));
if (!status.isOk()) {
serverCall.close(status, new Metadata());
}
return serverCallHandler.startCall(serverCall, metadata);
}
}
客户端实现:
public class AltsOtBookingClient {
public static void main(String[] args) {
final String SERVER_ADDRESS = args[0];
final String SERVER_ADDRESS_SERVICE_ACCOUNT = args[1];
ManagedChannel managedChannel = AltsChannelBuilder.forTarget(SERVER_ADDRESS)
.addTargetServiceAccount(SERVER_ADDRESS_SERVICE_ACCOUNT)
.build();
OtBookingServiceGrpc.OtBookingServiceBlockingStub OTBookingServiceStub = OtBookingServiceGrpc
.newBlockingStub(managedChannel);
BookingResponse bookingResponse = OTBookingServiceStub.getBookingInfo(BookingRequest.newBuilder()
.setPatientID("PT-1204")
.setDoctorID("DC-3904")
.build());
managedChannel.shutdown();
}
}
✅ 优势:同一服务账户可关联多个虚拟机,便于服务水平扩展。
4.3. 在 Google Compute Engine 上运行
部署步骤:
克隆代码库:
git clone https://github.com/eugenp/tutorials.git
编译项目:
cd tutorials/grpc mvn clean compile
启动后端服务(在
prod-booking-service-vm
):mvn exec:java -Dexec.mainClass="com.baeldung.grpc.alts.server.AltsOtBookingServer" \ -Dexec.arguments="prod-ot-booking-client-svc@grpc-alts-demo.iam.gserviceaccount.com"
前端发起 RPC 调用(在
prod-booking-client-vm
):mvn exec:java -Dexec.mainClass="com.baeldung.grpc.alts.client.AltsOtBookingClient" \ -Dexec.arguments="10.128.0.2:8080,prod-ot-booking-svc@grpc-alts-demo.iam.gserviceaccount.com"
成功响应示例:
异常场景测试:
禁用客户端服务账户:
- RPC 调用失败,状态码
UNAVAILABLE
- RPC 调用失败,状态码
禁用服务端服务账户:
- 初次调用可能成功(ALTS 缓存导致)
- 重启服务后调用失败,状态码
UNKNOWN
⚠️ 踩坑提示:ALTS 会缓存服务账户状态,修改配置后需重启服务生效。
5. 总结
本文深入探讨了 gRPC Java 库对 ALTS 的支持。通过极简代码即可在 gRPC 服务中启用 ALTS,并借助 GCP IAM 服务账户灵活控制服务授权。
核心优势:
- ✅ 代码改动最小化
- ✅ 与 GCP IAM 深度集成
- ✅ 自动处理证书管理
局限性:
- ❌ 仅限 GCP 基础设施使用
- ❌ 跨云部署需改用 TLS(需手动配置)
本文代码已托管在 GitHub。