PAI-EAS支持通过gRPC协议进行高性能的模型推理调用。与HTTP/JSON相比,gRPC具有更高的序列化效率和更好的流式传输支持,适用于对性能敏感或需要流式推理的场景。
前提条件
在开始之前,请确保已满足以下条件:
已部署EAS推理服务
Golang 开发环境已配置(推荐 Go 1.18 及以上版本)
已安装必要的 gRPC 依赖包
核心要点
服务地址格式
通过网关调用时,从控制台获取对应地址后,提取域名部分并追加端口号:80即可,步骤参见获取访问地址和Token。
端口固定为80,因为EAS通过网关对外提供gRPC服务时,该网关的端口固定为80。
地址示例:
调用方式 | 控制台地址示例 | gRPC端点(追加 |
公网调用 |
|
|
VPC调用 |
|
|
注意:gRPC端点不包含http://前缀。
Token 鉴权
调用 PAI-EAS gRPC 推理服务的核心在于通过 Metadata传递鉴权Token。PAI-EAS 使用 Bearer Token 进行身份验证,在发起gRPC调用时,需要在Metadata中如下设置authorization字段:
authorization: Bearer <Token>其中Token值必须使用Bearer前缀(注意Bearer与Token之间有一个空格),Token本身可在EAS控制台的目标服务详情页面获取。
代码示例
在编写调用代码之前,请先准备好对应服务的 proto 文件并编译生成客户端代码。
以下示例展示通过gRPC协议调用PAI-EAS推理服务的核心流程。其相关的proto文件及服务端代码参见gRPC服务demo。
package main
import (
"context"
"log"
"time"
pb "your-project/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
)
func main() {
// 替换为实际的gRPC服务地址(可从EAS控制台调用信息面板获取)
// 公网调用地址格式为:服务名.{uid}.{region}.pai-eas.aliyuncs.com:80 (端口固定80)
host := "your-service-endpoint:your port"
// 替换为您的服务Token(可在EAS控制台服务详情页面获取)
token := "your-service-token"
log.Printf("正在连接EAS gRPC服务 (%s)...", host)
// 1. 建立连接(连接是线程安全的,建议创建后复用)
conn, err := grpc.NewClient(
host,
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatalf("连接失败:%v", err)
}
defer conn.Close()
// 2. 创建客户端
client := pb.NewGreeterServiceClient(conn)
// 3. 通过 gRPC metadata 注入鉴权 Token
md := metadata.Pairs("authorization", "Bearer " + token)
ctx := metadata.NewOutgoingContext(context.Background(), md)
// 4. 设置超时
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
// 5. 构造请求
req := &pb.HelloRequest{Name: "World"}
// 6. 发起调用
resp, err := client.SayHello(ctx, req)
if err != nil {
log.Fatalf("调用失败:%v", err)
}
log.Printf("收到响应:%s", resp.Message)
}import grpc
import helloworld_pb2
import helloworld_pb2_grpc
# 替换为实际的gRPC服务地址(可从EAS控制台调用信息面板获取)
# 公网调用地址格式为:服务名.{uid}.{region}.pai-eas.aliyuncs.com:80 (端口固定80)
host = "your-service-endpoint:your port"
# 替换为您的服务Token(可在EAS控制台服务详情页面获取)
token = "your-service-token"
# 1. 创建通道 (连接服务端)
channel = grpc.insecure_channel(host)
# 2. 初始化 Stub (客户端句柄)
stub = helloworld_pb2_grpc.GreeterServiceStub(channel)
# 3. 构造请求
request = helloworld_pb2.HelloRequest(name="World")
# 4. 构造鉴权metadata,将Token传递给PAI-EAS服务
metadata = (("authorization", "Bearer " + token),)
print("正在发起 gRPC 调用...")
try:
# 5. 发起请求 (同步调用),注意传入metadata以完成鉴权
response = stub.SayHello(request, metadata=metadata, timeout=5.0)
print(response.message)
except grpc.RpcError as e:
print(f"调用失败:{e.code()} - {e.details()}")
finally:
channel.close()最佳实践
连接复用:gRPC连接是线程安全的,建议在应用启动时创建连接并复用,而不是每次请求新建。
重要默认情况下空闲连接可能被网络设备切断。生产环境中务必启用 Keepalive 心跳(Go 使用
KeepaliveParams,Python 使用options),以主动维持连接活跃,实现真正的无感自动重连。超时设置:强烈建议为每次gRPC调用设置合理的超时时间,避免因网络或服务异常导致请求长时间阻塞。
常见问题
Q:鉴权失败(UNAUTHENTICATED)
请检查Token是否正确、是否已过期,以及Metadata中的authorization字段名是否拼写正确。注意Token值必须使用Bearer前缀,且Bearer与Token之间有一个空格。
Q:连接超时(UNAVAILABLE)
确认gRPC端点是否正确,以及网络是否可达。
如使用VPC调用地址,请确保客户端与EAS服务在同一地域的VPC网络内,并检查安全组规则是否放行了对应端口。
附录
gRPC服务demo
接口定义
在项目根目录创建文件
helloworld.proto,定义一个GreeterService服务,包含一个SayHello方法:请求:
HelloRequest,包含一个name字段(字符串)响应:
HelloResponse,包含一个message字段(字符串)
编译生成
.proto文件对应的代码helloworld_pb2_grpc.py、helloworld_pb2.py(以 Python 为例):python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto
2. 服务端部署
部署服务到EAS,项目结构如下:
my-grpc-demo
├── helloworld_pb2_grpc.py
├── helloworld_pb2.py
└── server.py