Go調(diào)用注冊到Nacos中的服務

服務調(diào)用客戶端

package util

import (
    "fmt"
    "math/rand/v2"
    "net/http"
    "net/url"

    "github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client"
    "github.com/nacos-group/nacos-sdk-go/v2/vo"
)

type ServiceClient struct {
    namingClient naming_client.INamingClient
    webClient    *WebClient
}

func NewServiceClient(namingClient naming_client.INamingClient, webClient *WebClient) *ServiceClient {
    return &ServiceClient{
        namingClient: namingClient,
        webClient:    webClient,
    }
}

func (m *ServiceClient) Get(serviceName string, path string, urlValues url.Values) (int, []byte, error) {
    _, code, bytees, err := m.Do(serviceName, "GET", "application/json;charset=UTF-8", path, urlValues, nil)

    return code, bytees, err
}

func (m *ServiceClient) Post(serviceName string, path string, bodyValue any) (int, []byte, error) {
    _, code, bytees, err := m.Do(serviceName, "POST", "application/json;charset=UTF-8", path, nil, bodyValue)

    return code, bytees, err
}

func (m *ServiceClient) Put(serviceName string, path string, urlValues url.Values, bodyValue any) (int, []byte, error) {
    _, code, bytees, err := m.Do(serviceName, "PUT", "application/json;charset=UTF-8", path, urlValues, bodyValue)

    return code, bytees, err
}

func (m *ServiceClient) Delete(serviceName string, path string, urlValues url.Values, bodyValue any) (int, []byte, error) {
    _, code, bytees, err := m.Do(serviceName, "DELETE", "application/json;charset=UTF-8", path, urlValues, bodyValue)

    return code, bytees, err
}

func (m *ServiceClient) Do(
    serviceName string,
    method string,
    contentType string,
    path string, urlValues url.Values,
    bodyValue any) (*http.Response, int, []byte, error) {
    serviceUrl, err := m.GetServiceUrl(serviceName)

    if err != nil {
        return nil, 0, nil, err
    }

    return m.webClient.Do(method, contentType, serviceUrl, path, urlValues, bodyValue)
}

func (m *ServiceClient) GetServiceUrl(serviceName string) (string, error) {
    service, err := m.namingClient.GetService(vo.GetServiceParam{ServiceName: serviceName})

    if err != nil {
        return "", err
    }

    if !service.Valid {
        return "", fmt.Errorf("服務(%s)不存在", serviceName)
    }

    urls := make([]string, 0, len(service.Hosts))

    for _, instance := range service.Hosts {
        if instance.Enable && instance.Healthy {
            urls = append(urls, fmt.Sprintf("http://%s:%d", instance.Ip, instance.Port))
        }
    }

    if len(urls) == 0 {
        return "", fmt.Errorf("服務(%s)沒有可用的實例", serviceName)
    }

    if len(urls) == 1 {
        return urls[0], nil
    }

    return urls[rand.IntN(len(urls))], nil
}

Http請求客戶端

package util

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
    "net/url"
    "strings"
)

type WebClient struct {
    Client *http.Client
}

func NewWebClient(client *http.Client) *WebClient {
    return &WebClient{Client: client}
}

func (m *WebClient) Get(baseUrl string, path string, urlValues url.Values) (int, []byte, error) {
    _, code, bytees, err := m.Do("GET", "application/json;charset=UTF-8", baseUrl, path, urlValues, nil)

    return code, bytees, err
}

func (m *WebClient) GetRes(baseUrl string, path string, urlValues url.Values) (*http.Response, int, []byte, error) {
    res, code, bytees, err := m.Do("GET", "application/json;charset=UTF-8", baseUrl, path, urlValues, nil)

    return res, code, bytees, err
}

func (m *WebClient) Post(baseUrl string, path string, bodyValue interface{}) (int, []byte, error) {
    _, code, bytees, err := m.Do("POST", "application/json;charset=UTF-8", baseUrl, path, nil, bodyValue)

    return code, bytees, err
}

func (m *WebClient) Put(baseUrl string, path string, urlValues url.Values, bodyValue interface{}) (int, []byte, error) {
    _, code, bytees, err := m.Do("PUT", "application/json;charset=UTF-8", baseUrl, path, urlValues, bodyValue)

    return code, bytees, err
}

func (m *WebClient) Delete(baseUrl string, path string, urlValues url.Values, bodyValue interface{}) (int, []byte, error) {
    _, code, bytees, err := m.Do("DELETE", "application/json;charset=UTF-8", baseUrl, path, urlValues, bodyValue)

    return code, bytees, err
}

func (m *WebClient) Do(method string, contentType string, baseUrl string, path string, urlValues url.Values, bodyValue interface{}) (*http.Response, int, []byte, error) {
    bodyValueBytes, err1 := json.Marshal(bodyValue)

    if err1 != nil {
        return nil, 0, nil, err1
    }

    if req, err := http.NewRequest(method, m.url(baseUrl, path, urlValues), bytes.NewReader(bodyValueBytes)); err != nil {
        return nil, 0, nil, err
    } else {
        return m.doRequest(req, contentType)
    }
}

func (m *WebClient) url(baseUrl string, path string, urlValues url.Values) string {
    result, _ := url.JoinPath(baseUrl, path)

    sb := new(strings.Builder)

    sb.WriteString(result)

    if len(urlValues) > 0 {
        sb.WriteString("?")
        sb.WriteString(urlValues.Encode())
    }

    return sb.String()

}

func (m *WebClient) doRequest(req *http.Request, contentType string) (*http.Response, int, []byte, error) {
    req.Header.Set("Content-Type", contentType)

    if res, err := m.Client.Do(req); err != nil {
        return res, res.StatusCode, nil, err
    } else {
        if resBytes, err := io.ReadAll(res.Body); err != nil {
            return res, res.StatusCode, nil, err
        } else {
            return res, res.StatusCode, resBytes, nil
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容