77 lines
2.0 KiB
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)
|
|
}
|