Go-Micro基本方式调用http api

xiaohai 2021-05-09 22:25:40 2565人围观 标签: Go 
简介Go-Micro基本方式调用http api

1、最基本的方式,通过服务发现进行调用http api

package main

import (
    "fmt"
    "github.com/micro/go-micro/client/selector"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-plugins/registry/consul"
    "io/ioutil"
    "log"
    "net/http"
)

//基本方式调用服务
func baseCallApi(address string, path string, method string) (string, error) {
    url := "http://" + address + path
    println("请求地址:", url)
    req, err := http.NewRequest(method, url, nil)
    if err != nil {
        log.Fatal(err)
    }
    client := http.DefaultClient
    rsp, err := client.Do(req)
    if err != nil {
        return "", err
    }
    defer rsp.Body.Close()
    buf, _ := ioutil.ReadAll(rsp.Body)
    return string(buf), nil
}

func main() {
    registry := consul.NewRegistry(func(options *registry.Options) {
        options.Addrs = []string{
            "192.168.1.171:8500",
            "192.168.1.177:8500",
            "192.168.1.178:8500",
        }
    })

    //获取服务
    services, err := registry.GetService("gin-web")
    if err != nil {
        log.Fatal(err)
    }

    next := selector.Random(services) //随机从服务中获取
    //next := selector.RoundRobin(services) //轮询算法
    node, err := next()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("NODE ID:", node.Id)
    fmt.Println("ADDRESS:", node.Address)
    fmt.Println("METADATA:", node.Metadata)

    result, err := baseCallApi(node.Address, "/", "GET")
    if err != nil {
        log.Fatal(err)
    }
    println(result)

    result, err = baseCallApi(node.Address, "/version", "GET")
    if err != nil {
        log.Fatal(err)
    }
    println(result)
}

2、使用插件调用

github.com/micro/go-plugins/client/http

首先我们对注册的服务进行改造

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-micro/web"
    "github.com/micro/go-plugins/registry/consul"
    "strconv"
)

//学生类型
type StudentType struct {
    Name   string
    Number int64
}

//请求
type RequestType struct {
    Number int `json:"number"`
}

func main() {
    //注册
    registry := consul.NewRegistry(func(options *registry.Options) {
        options.Addrs = []string{
            "192.168.1.171:8500",
            "192.168.1.177:8500",
            "192.168.1.178:8500",
        }
    })
    routers := gin.Default()
    routers.GET("/", func(context *gin.Context) {
        context.JSON(200, map[string]interface{}{
            "name": 1,
        })
    })
    routers.GET("/version", func(context *gin.Context) {
        context.JSON(200, map[string]interface{}{
            "version": "1.0.0",
        })
    })
    routers.POST("/lists", func(context *gin.Context) {
        var req RequestType
        err := context.Bind(&req)
        if err != nil {
            context.JSON(200, gin.H{
                "status": 200,
                "data":   err.Error(),
            })
            return
        }
        var students []*StudentType
        for i := 1; i <= req.Number; i++ {
            students = append(students, &StudentType{
                Name:   "name_" + strconv.Itoa(i),
                Number: int64(i),
            })
        }
        context.JSON(200, gin.H{
            "status": 200,
            "data":   students,
        })
    })
    server := web.NewService(
        web.Name("gin-web"),    //服务名称
        web.Registry(registry), //注册到服务
        //web.Address(":8080"),//这个可以不写,最好使用配置文件进行配置
        web.Handler(routers),
    )
    server.Init() //加了这句就可以使用命令行的形式去设置我们一些启动的配置
    server.Run()
}

对客户端进行改造:

package main

import (
    "context"
    "fmt"
    "github.com/micro/go-micro/client"
    "github.com/micro/go-micro/client/selector"
    "github.com/micro/go-micro/registry"
    goMicroHttp "github.com/micro/go-plugins/client/http"
    "github.com/micro/go-plugins/registry/consul"
    "io/ioutil"
    "log"
    "net/http"
)

//基本方式调用服务
func baseCallApi(address string, path string, method string) (string, error) {
    url := "http://" + address + path
    println("请求地址:", url)
    req, err := http.NewRequest(method, url, nil)
    if err != nil {
        log.Fatal(err)
    }
    client := http.DefaultClient
    rsp, err := client.Do(req)
    if err != nil {
        return "", err
    }
    defer rsp.Body.Close()
    buf, _ := ioutil.ReadAll(rsp.Body)
    return string(buf), nil
}

//插件方式调用服务
func callApi(selector selector.Selector) {
    myClient := goMicroHttp.NewClient(
        client.Selector(selector),
        client.ContentType("application/json"),
    )
    req := myClient.NewRequest("gin-web", "/lists", map[string]interface{}{"number": 5})
    var resp map[string]interface{}
    err := myClient.Call(context.Background(), req, &resp) //发起请求调用,并返回结果
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(resp)
}

func main() {
    registry := consul.NewRegistry(func(options *registry.Options) {
        options.Addrs = []string{
            "192.168.1.171:8500",
            "192.168.1.177:8500",
            "192.168.1.178:8500",
        }
    })
    s := selector.NewSelector(
        selector.Registry(registry),
        selector.SetStrategy(selector.RoundRobin),
    )
    callApi(s)
}

3、使用proto构造参数进行调用
新增proto目录,进入proto目录,新增model.proto文件,内容如下:

syntax = "proto3";

message StudentModel {
    string name = 1;
    int32 number = 2;
}

message StudentRequest {
    int32 number = 1;
}


message StudentsResponse {
    int32 status = 1;
    repeated StudentModel data = 2;
}

生成命令:

protoc --go_out=./ model.proto

修改客户端:

package main



import (

    "context"

    "fmt"

    "github.com/micro/go-micro/client"

    "github.com/micro/go-micro/client/selector"

    "github.com/micro/go-micro/registry"

    goMicroHttp "github.com/micro/go-plugins/client/http"

    "github.com/micro/go-plugins/registry/consul"

    "io/ioutil"

    "log"

    model "micro-api/proto"

    "net/http"

)



//基本方式调用服务

func baseCallApi(address string, path string, method string) (string, error) {

    url := "http://" + address + path

    println("请求地址:", url)

    req, err := http.NewRequest(method, url, nil)

    if err != nil {

        log.Fatal(err)

    }

    client := http.DefaultClient

    rsp, err := client.Do(req)

    if err != nil {

        return "", err

    }

    defer rsp.Body.Close()

    buf, _ := ioutil.ReadAll(rsp.Body)

    return string(buf), nil

}



//插件方式调用服务

func callApi(selector selector.Selector) {

    myClient := goMicroHttp.NewClient(

        client.Selector(selector),

        client.ContentType("application/json"),

    )

    req := myClient.NewRequest("gin-web", "/lists", model.StudentRequest{Number: 10})

    var resp model.StudentsResponse

    err := myClient.Call(context.Background(), req, &resp) //发起请求调用,并返回结果

    if err != nil {

        log.Fatal(err)

    }

    fmt.Println(resp.Status)

    fmt.Println(resp.Data)

}



func main() {

    registry := consul.NewRegistry(func(options *registry.Options) {

        options.Addrs = []string{

            "192.168.1.171:8500",

            "192.168.1.177:8500",

            "192.168.1.178:8500",

        }

    })

    s := selector.NewSelector(

        selector.Registry(registry),

        selector.SetStrategy(selector.RoundRobin),

    )

    callApi(s)

}