EAS支持通过Python官方SDK或自行实现调用逻辑的方式对服务进行VPC高速直连调用。本文详细介绍这两种调用方式的实现方法。
调用原理
VPC高速直连调用、公网调用及VPC地址调用的链路如下图所示。
开启服务运行所在资源组的VPC高速直连功能后,EAS会在您指定的安全组内绑定辅助网卡,打通您的VPC和EAS服务实例之间的网络。之后您可以在自己的VPC中直接访问EAS实例,无需通过网关访问服务,避免了四层SLB和七层网络转发。同时,EAS预置的RPC实现了HTTP相关协议栈,对于高QPS(Queries Per Second)的大流量服务(例如图像服务),可以大幅度提高访问性能、降低访问延时。
前提条件
如果您使用专属资源组部署服务,则部署服务前,需要为专属资源组开通VPC高速直连功能,详情请参见配置网络连通。
安全组控制ECS实例机器的出入流量,用户的ECS实例和EAS服务实例之间的网络互通也受安全组的配置控制。默认普通安全组内,实例之间是内网互通的,您可以在配置VPC高速直连时,选择需要访问在线服务的ECS实例所在安全组,从而支持实例之间网络互通。当需要配置使用不同的安全组时,请设置安全组的规则支持ECS实例之间能够互通。
调用方式
为方便用户调用服务,EAS提供了以下两种方式实现VPC高速直连调用:
EAS封装了调用逻辑并提供了Python SDK、Java SDK和Golang SDK的调用方法,您可以直接使用SDK实现VPC高速直连调用。
推荐使用官方SDK调用服务,从而有效减少编写调用逻辑的时间并提高服务调用稳定性。如果您需要使用其他语言或希望自己编写实现调用逻辑,下文也提供了方法指导供您参考。此外,自行实现调用逻辑需要根据不同框架构建服务请求,详情请参见构建通用Processor服务请求。
使用官方SDK调用
Python SDK调用
使用Python官方SDK调用服务的方法如下:
安装。
pip install -U eas-prediction --user
该Python SDK的调用详情请参见Python SDK使用说明。
编写调用程序。
以字符串作为输入输出的程序示例如下,其他格式(TensorFlow或PyTorch等)的输入输出的程序示例请参见Python SDK使用说明。
#!/usr/bin/env python from eas_prediction import PredictClient from eas_prediction import StringRequest from eas_prediction import TFRequest from eas_prediction import ENDPOINT_TYPE_DIRECT if __name__ == '__main__': client = PredictClient('http://pai-eas-vpc.cn-shanghai.aliyuncs.com', 'mnist_saved_model_example') # 替换为服务Token。您可以单击目标服务的服务方式列下的调用信息来查看Token信息。 client.set_token('M2FhNjJlZDBmMzBmMzE4NjFiNzZhMmUxY2IxZjkyMDczNzAzYjFi****') client.set_endpoint_type(ENDPOINT_TYPE_DIRECT) # 表示通过直连通道访问服务。 client.init() # request = StringRequest('[{}]') req = TFRequest('predict_images') req.add_feed('images', [1, 784], TFRequest.DT_FLOAT, [1] * 784) for x in range(0, 1000000): resp = client.predict(req) print(resp)
其中
client = PredictClient()
的函数入参分别为高速直连Endpoint地址(endpoint参数),服务的名称(service_name参数)。高速直连Endpoint地址和地域绑定的,他的格式是pai-eas-vpc.{RegionId}.aliyuncs.com
,例如华东2(上海)地域的高速直连Endpoint地址为pai-eas-vpc.cn-shanghai.aliyuncs.com
。
Java SDK调用
使用Java官方SDK调用服务的方法如下:
添加依赖项,EAS SDK的最新版本以Maven仓库中显示的为准。
<dependency> <groupId>com.aliyun.openservices.eas</groupId> <artifactId>eas-sdk</artifactId> <version>2.0.13</version> </dependency>
该Java SDK的调用详情请参见Java SDK使用说明。
编写调用程序。
import com.aliyun.openservices.eas.predict.http.PredictClient; import com.aliyun.openservices.eas.predict.http.HttpConfig; public class TestString { public static void main(String[] args) throws Exception { // 为了确保client对象被正确共享,应当在启动时创建并初始化client对象,而不是在每个请求中都创建一个新的client对象。 PredictClient client = new PredictClient(new HttpConfig()); // 替换为服务Token。您可以单击目标服务的服务方式列下的调用信息来查看Token信息。 client.setToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****"); // 直连访问时请使用setDirectEndpoint方法,设置pai-eas-vpc.{region_id}.aliyuncs.com的域名进行访问,例如华东2(上海)为cn-shanghai。 client.setDirectEndpoint("pai-eas-vpc.cn-shanghai.aliyuncs.com"); // 替换为服务名称。 client.setModelName("scorecard_pmml_example"); // 定义输入字符串。 String request = "[{\"money_credit\": 3000000}, {\"money_credit\": 10000}]"; System.out.println(request); // 通过EAS返回字符串。 try { String response = client.predict(request); System.out.println(response); } catch (Exception e) { e.printStackTrace(); } // 关闭客户端。 client.shutdown(); return; } }
Golang SDK调用
使用Golang SDK进行服务调用时,由于在编译代码时,Golang的包管理工具会自动从Github上将Golang SDK的代码下载到本地,因此您无需提前安装Golang SDK。该Golang SDK的调用详情请参见Golang SDK使用说明。
使用Golang官方SDK调用服务的方法如下:
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
// 设置pai-eas-vpc.{region_id}.aliyuncs.com的域名进行访问,例如华东2(上海)为cn-shanghai。请替换为目标服务所在地域和服务名称。
client := eas.NewPredictClient("pai-eas-vpc.cn-shanghai.aliyuncs.com", "scorecard_pmml_example")
// 替换为服务Token。您可以单击目标服务的服务方式列下的调用信息来查看Token信息。
client.SetToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****")
client.SetEndpointType(eas.EndpointTypeDirect)
client.Init()
req := "[{\"fea1\": 1, \"fea2\": 2}]"
for i := 0; i < 100; i++ {
resp, err := client.StringPredict(req)
if err != nil {
fmt.Printf("failed to predict: %v\n", err.Error())
} else {
fmt.Printf("%v\n", resp)
}
}
}
自行实现调用逻辑
推荐您使用PAI提供的官方SDK来进行直连访问,如果您有特殊业务场景的需求,需要使用其他语言或希望自己编写调用逻辑,则可以参见如下方法,自行实现直连访问功能,采用HTTP接口调用。EAS提供服务发现机制,在VPC环境中,通过如下地址即可获得服务的后端地址列表。
地域 | 地址 |
华东2(上海) | http://pai-eas-vpc.cn-shanghai.aliyuncs.com/exported/apis/eas.alibaba-inc.k8s.io/v1/upstreams/ |
华北2(北京) | http://pai-eas-vpc.cn-beijing.aliyuncs.com/exported/apis/eas.alibaba-inc.k8s.io/v1/upstreams/ |
华东1(杭州) | http://pai-eas-vpc.cn-hangzhou.aliyuncs.com/exported/apis/eas.alibaba-inc.k8s.io/v1/upstreams/ |
例如访问华东1(杭州)的mnist_saved_model_example服务(该服务有两个Instance),示例如下。
$curl http://pai-eas-vpc.cn-hangzhou.aliyuncs.com/exported/apis/eas.alibaba-inc.k8s.io/v1/upstreams/mnist_saved_model_example
获得的服务后端地址列表如下。
{
"correlative": [
"mnist_saved_model_example"
],
"endpoints": {
"items": [
{
"app": "mnist-saved-model-example",
"ip": "172.16.XX.XX",
"port": 50000,
"weight": 100
},
{
"app": "mnist-saved-model-example",
"ip": "172.16.XX.XX",
"port": 50000,
"weight": 100
}
]
}
}
如上所示,通过服务发现可以获得客户模型服务mnist_saved_model_example的两个实例的ip、port及weight信息。相关的IP在用户部署服务时选择的VPC中即可直接连通。
对于通过服务发现来进行直连访问的方法请参考如下步骤:
客户端代码中建立后台线程,定时访问上述的服务发现服务,建议每5秒访问一次,获取当前服务最新的实例列表,并将其保存在本地缓存中。
在发起推理请求时,从本地缓存中获取一个实例IP+端口发起访问,可使用Weighted Round Robin算法进行获取,也可根据自己的业务逻辑来进行选择。
发起请求时,如遇连接失败等情况,则表示服务实例可能发生异常(如用户实例发生crash等),客户端需要进行重试,重新从缓存中获取一个新的实例,在本地缓存中实例数多于1的情况下,新IP+Port组合应该避免与已经失败的IP+Port相同,即确保更换一个实例进行重试。
在使用服务发现进行直连访问时,请遵循下面几条原则,否则可能导致服务访问异常:
服务发现服务是一个旁路的服务,不可在每次发起请求时对服务发现服务进行请求。
访问服务发现服务时,在返回状态码为200且返回实例数不为空时,再更新缓存,返回非200时,千万不能清空缓存。
直连的方式负载均衡和重试逻辑都需要在客户端侧完成,稳定性依赖客户端实现,平台侧不负责直连场景的客户端请求容错,在实现时请严格遵循上述的步骤来实现容错逻辑,否则平台侧无法保障SLA。
完整的实现流程,请参见Python SDK的实现。
相关文档
更多的服务调用方式,请参见调用方式概览。