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" "io/ioutil" "net/http" "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) } // 组装内部接口 apiUrl := fmt.Sprintf("http://%v%v", apiHost, uri) // 创建Request对象 req, err := http.NewRequest(ctx.Request.Method, apiUrl, ctx.Request.Body) if err != nil { Log.Error("请求异常: %v\n", err) ctx.String(http.StatusBadGateway, "请求异常: %v", err.Error()) return } // 填充Form参数(大概率用不上) req.Form = ctx.Request.Form // 填充链路追踪标记 req.Header.Add("uber-trace-id", ctx.GetString("UberTraceId")) // 请求ID req.Header.Add("X-Request-Id", ctx.GetString("X-Request-Id")) // 设置来源 req.Header.Add("From", "internal") // 发起请求 client := &http.Client{} response, err := client.Do(req) if err != nil { Log.Error("请求异常: %v\n", err) ctx.String(http.StatusBadGateway, "请求异常:%v", err.Error()) return } // 返回结果到前端 sss, _ := ioutil.ReadAll(response.Body) Log.Debug(string(sss)) ctx.String(response.StatusCode, string(sss)) }