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)
}