推薦使用EAS提供的官方SDK進行服務調用,從而有效減少編寫調用邏輯的時間並提高調用穩定性。本文介紹官方Golang SDK介面詳情,並以常見類型的輸入輸出為例,提供了使用Golang SDK進行服務調用的完整程式樣本。
背景資訊
使用Golang SDK進行服務調用時,由於在編譯代碼時,Golang的包管理工具會自動從Github上將Golang SDK的代碼下載到本地,因此您無需提前安裝Golang SDK。如果您需要自訂部分調用邏輯,可以先下載Golang SDK代碼,再對其進行修改。
介面列表
類 | 介面 | 描述 |
PredictClient |
|
|
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| 對PredictClient對象進行初始化。在上述設定參數的介面執行完成後,需要調用 | |
|
| |
|
| |
|
| |
|
| |
TFRequest |
|
|
|
| |
|
| |
TFResponse |
|
|
|
| |
TorchRequest |
| TFRequest類的構建函數。 |
|
| |
|
| |
TorchResponse |
|
|
|
| |
QueueClient |
|
|
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
types.Watcher |
|
|
| 功能:關閉一個Watcher對象,用於關閉後端的數串連。 說明 一個用戶端只能啟動一個Watcher對象,使用完成後需要將該對象關閉才能啟動新的Watcher對象。 |
程式樣本
字串輸入輸出樣本
對於使用自訂Processor部署服務的使用者而言,通常採用字串進行服務調用(例如,PMML模型服務的調用),具體的Demo程式如下。
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("182848887922****.cn-shanghai.pai-eas.aliyuncs.com", "scorecard_pmml_example")
client.SetToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****")
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)
}
}
}TensorFlow輸入輸出樣本
使用TensorFlow的使用者,需要將TFRequest和TFResponse分別作為輸入和輸出資料格式,具體Demo樣本如下。
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("182848887922****.cn-shanghai.pai-eas.aliyuncs.com", "mnist_saved_model_example")
client.SetToken("YTg2ZjE0ZjM4ZmE3OTc0NzYxZDMyNmYzMTJjZTQ1YmU0N2FjMTAy****")
client.Init()
tfreq := eas.TFRequest{}
tfreq.SetSignatureName("predict_images")
tfreq.AddFeedFloat32("images", []int64{1, 784}, make([]float32, 784))
for i := 0; i < 100; i++ {
resp, err := client.TFPredict(tfreq)
if err != nil {
fmt.Printf("failed to predict: %v", err)
} else {
fmt.Printf("%v\n", resp)
}
}
}PyTorch輸入輸出樣本
使用PyTorch的使用者,需要將TorchRequest和TorchResponse分別作為輸入和輸出資料格式,具體Demo樣本如下。
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("182848887922****.cn-shanghai.pai-eas.aliyuncs.com", "pytorch_resnet_example")
client.SetTimeout(500)
client.SetToken("ZjdjZDg1NWVlMWI2NTU5YzJiMmY5ZmE5OTBmYzZkMjI0YjlmYWVl****")
client.Init()
req := eas.TorchRequest{}
req.AddFeedFloat32(0, []int64{1, 3, 224, 224}, make([]float32, 150528))
req.AddFetch(0)
for i := 0; i < 10; i++ {
resp, err := client.TorchPredict(req)
if err != nil {
fmt.Printf("failed to predict: %v", err)
} else {
fmt.Println(resp.GetTensorShape(0), resp.GetFloatVal(0))
}
}
}通過VPC網路直連方式調用服務的樣本
通過網路直連方式,您只能訪問部署在EAS專屬資源群組的服務,且需要為該資源群組與使用者指定的vSwitch連通網路後才能使用。關於如何購買EAS專屬資源群組和連通網路,請參見使用EAS資源群組和配置網路連通。該調用方式與普通調用方式相比,僅需增加一行代碼client.SetEndpointType(eas.EndpointTypeDirect)即可,特別適合大流量高並發的服務,具體樣本如下。
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("pai-eas-vpc.cn-shanghai.aliyuncs.com", "scorecard_pmml_example")
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)
}
}
}用戶端串連參數設定的樣本
您可以通過http.Transport屬性佈建要求用戶端的串連參數,範例程式碼如下。
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
"net/http"
"time"
)
func main() {
client := eas.NewPredictClient("pai-eas-vpc.cn-shanghai.aliyuncs.com", "network_test")
client.SetToken("MDAwZDQ3NjE3OThhOTI4ODFmMjJiYzE0MDk1NWRkOGI1MmVhMGI0****")
client.SetEndpointType(eas.EndpointTypeDirect)
client.SetHttpTransport(&http.Transport{
MaxConnsPerHost: 300,
TLSHandshakeTimeout: 100 * time.Millisecond,
ResponseHeaderTimeout: 200 * time.Millisecond,
ExpectContinueTimeout: 200 * time.Millisecond,
})
}佇列服務發送、訂閱資料樣本
通過QueueClient可向佇列服務中發送資料、查詢資料、查詢佇列服務的狀態以及訂閱佇列服務中的資料推送。以下方Demo為例,介紹一個線程向佇列服務中推送資料,另一個線程通過Watcher訂閱佇列服務中推送過來的資料。
在EAS部署非同步推理服務,會自動產生輸入隊列和輸出隊列,通常地址格式如下:
輸入隊列:<domain>/api/predict/<service_name>
輸出隊列:<domain>/api/predict/<service_name>/sink
請根據您實際需要採用<service_name>或者<service_name>/sink構建QueueClient。
const (
QueueEndpoint = "182848887922****.cn-shanghai.pai-eas.aliyuncs.com"
// eg:EAS服務名為test_qservice,則輸入隊列名為test_qservice,輸出隊列名為test_qservice/sink
QueueName = "test_qservice"
QueueToken = "YmE3NDkyMzdiMzNmMGM3ZmE4ZmNjZDk0M2NiMDA3OTZmNzc1MTUx****"
)
queue, err := NewQueueClient(QueueEndpoint, QueueName, QueueToken)
// truncate all messages in the queue
attrs, err := queue.Attributes()
if index, ok := attrs["stream.lastEntry"]; ok {
idx, _ := strconv.ParseUint(index, 10, 64)
queue.Truncate(context.Background(), idx+1)
}
ctx, cancel := context.WithCancel(context.Background())
// create a goroutine to send messages to the queue
go func() {
i := 0
for {
select {
case <-time.NewTicker(time.Microsecond * 1).C:
_, _, err := queue.Put(context.Background(), []byte(strconv.Itoa(i)), types.Tags{})
if err != nil {
fmt.Printf("Error occured, retry to handle it: %v\n", err)
}
i += 1
case <-ctx.Done():
break
}
}
}()
// create a watcher to watch the messages from the queue
watcher, err := queue.Watch(context.Background(), 0, 5, false, false)
if err != nil {
fmt.Printf("Failed to create a watcher to watch the queue: %v\n", err)
return
}
// read messages from the queue and commit manually
for i := 0; i < 100; i++ {
df := <-watcher.FrameChan()
err := queue.Commit(context.Background(), df.Index.Uint64())
if err != nil {
fmt.Printf("Failed to commit index: %v(%v)\n", df.Index, err)
}
}
// everything is done, close the watcher
watcher.Close()
cancel()