一、背景
1、客户两个部门,A部门在平台上训练模型,发布预测服务;B部门为新成立业务部门,需要去调用A的预测服务。B部门对发出的请求、返回都有明确的接口规范。A的预测服务,不同模型请求、返回参数不同,没有确定的格式,不会根据B要求做修改。
二、方案
考虑在用户请求入口加一个proxy服务,功能:
①作为B的访问入口
②解析B发出的请求,筛选平台需要的字段
③将B的请求代理到后方预测服务上
④接收预测服务response,加上B需要字段
三、实现
使用ReverseProxy做代理,用ModifyResponse去修改resp。
省略部分代码,结构体仅作例子用
package apimodel
type SvcRequest struct {
UserTag string `json:"userTag"`//B用户要求的response必带字段,要在request里带着
Data map[string]interface{
} `json:"data"` //B发出的请求,因为不同模型请求json不同,只能用map[string]interface{}
}
type AiProxyRequest struct {
Data map[string]interface{
} `json:"data"` //实际发送到预测服务的请求,剥离用户自定义字段,userTag
}
type SvcResponse struct {
UserTag string `json:"userTag"` //B用户要求的response必带字段
Result map[string]interface{
} `json:"result"` //预测服务返回的结果,因为不同预测输出的json不一样,目前在外面套了一层result
}
const CtxSvcRequest = "SvcRequest" //context中的k-v的key名
main.go
func main() {
flag.InitFlags()
err := config.GetConfig(flag.ConfigFile)
if err != nil {
log.Logger.Error("Get config failed,err msg [%s]", err)
exitError()
}
router := gin.New()
handler.RegisterRoutes(router)
log.Logger.Info("start server at %s", config.ServerConfig.InferenceConfig.ListenPort)