gateway/core/nacos.go

77 lines
2.0 KiB
Go

package core
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/nacos-group/nacos-sdk-go/clients/config_client"
"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
"github.com/nacos-group/nacos-sdk-go/vo"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
type nacosClient struct {
client naming_client.INamingClient
config config_client.IConfigClient
}
func NewNacosClient(c naming_client.INamingClient, n config_client.IConfigClient) nacosClient {
return nacosClient{c, n}
}
// Remote 发起远程调用
func (n nacosClient) Remote(ctx *gin.Context) {
// 取出URI
uri := ctx.Request.RequestURI
// 截取第二个/前面那一段
pathAry := strings.Split(uri, "/")
var service serviceItem
apiService := fmt.Sprintf("/%v", pathAry[1])
for _, s := range ServiceMap {
if s.Path != "" && s.Path == apiService {
service = s
break
}
}
if service.Service == "" {
ctx.String(http.StatusNotFound, "服务不可达")
return
}
if !service.Enable {
ctx.String(http.StatusServiceUnavailable, "系统维护中")
return
}
var apiHost string
// 判断是否是走集群内部负载
if service.Lb.Host != "" {
apiHost = fmt.Sprintf("%s:%v", service.Lb.Host, service.Lb.Port)
} else {
instance, err := n.client.SelectOneHealthyInstance(vo.SelectOneHealthInstanceParam{
ServiceName: service.Service,
})
if err != nil {
Log.Error("获取健康服务失败: %v\n", err.Error())
ctx.String(http.StatusBadGateway, "服务异常: %v", err.Error())
return
}
apiHost = fmt.Sprintf("%s:%v", instance.Ip, instance.Port)
}
u := &url.URL{
Scheme: "http",
Host: apiHost,
}
proxy := httputil.NewSingleHostReverseProxy(u)
ctx.Request.Header.Add("From", "internal")
ctx.Request.Header.Add("uber-trace-id", ctx.GetString("UberTraceId"))
// 重写错误回调
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
Log.Error("代理转发错误: %v", err.Error())
ctx.String(http.StatusInternalServerError, "系统内部错误")
}
proxy.ServeHTTP(ctx.Writer, ctx.Request)
}