zoukankan      html  css  js  c++  java
  • 30.普通API集成到go-micro体系中(2):代码注册与反注册

    首先理一下思路,使用代码去注册其他api到go-micro体系中,我们就需要在代码中模拟出这样的json数据,并发送给我们的micro Registry服务

    {
        "jsonrpc": "2.0",
        "method": "Registry.Deregister",
        "params": [{
            "name": "api.jtthink.com.test",
            "version": "1.0",
            "endpoints": [],
            "nodes": [{
                "address": "192.168.29.1",
                "id": "userservice-uuid",
                "port": 8088
            }]
        }],
        "id": 1
    }

    首先我们构造结构体,构建一个这样的结构体,然后把需要的数据填充进去序列化成json发送给micro Registry就完成了我们的需求

    package sidecar
    
    type JSONRequest struct {
        Jsonrpc string
        Method  string
        Params  []*Service
        Id      int
    }
    
    func NewJSONRequest(service *Service, endpoint string) *JSONRequest {
        return &JSONRequest{Jsonrpc: "2.0", Method: endpoint, Params: []*Service{service}, Id: 1}
    }
    

    把之前的json拆成小的结构体再填充数据整合

    type Service struct {
       Name  string
       Nodes []*ServiceNode
    }
    {
            "name": "api.jtthink.com.test",
            "version": "1.0", //在上面的结构体中version和endpints我们暂时不传
            "endpoints": [],
            "nodes": [{
                "address": "192.168.29.1",
                "id": "userservice-uuid",
                "port": 8088
            }
    }
    type ServiceNode struct {
       Id      string //服务ID,不能重复
       Port    int
       Address string
    }
    {
                "address": "192.168.29.1",
                "id": "userservice-uuid",
                "port": 8088
            }

    实现注册与反注册的函数

    package sidecar
    
    import (
        "bytes"
        "encoding/json"
        "fmt"
        "io/ioutil"
        "log"
        "net/http"
    )
    
    type Service struct {
        Name  string
        Nodes []*ServiceNode
    }
    type ServiceNode struct {
        Id      string //服务ID,不能重复
        Port    int
        Address string
    }
    
    func NewService(name string) *Service {
        return &Service{Name: name, Nodes: make([]*ServiceNode, 0)}
    }
    func NewServiceNode(id string, port int, address string) *ServiceNode {
        return &ServiceNode{Id: id, Port: port, Address: address}
    }
    func (this *Service) AddNode(id string, port int, address string) {
        this.Nodes = append(this.Nodes, NewServiceNode(id, port, address))
    }
    
    var RegistryURI = "http://localhost:8000"
    
    func requestRegistry(jsonrequest *JSONRequest) error { //关键代码。用来请求注册器
        b, err := json.Marshal(jsonrequest)
        if err != nil {
            log.Fatal(err)
            return err
        }
        rsp, err := http.Post(RegistryURI, "application/json", bytes.NewReader(b))//发送Post请求到Registry的地址带上我们的json数据,就可以成功注册啦
        if err != nil {
            return err
        }
        defer rsp.Body.Close()
        res, err := ioutil.ReadAll(rsp.Body)
        if err != nil {
            return err
        }
        fmt.Println(string(res)) //打印出结果
        return nil
    }
    
    func UnRegService(service *Service) error  {
        return requestRegistry(NewJSONRequest(service,"Registry.Deregister")) //反注册只需要改一下endpoint为Registry.Deregister就可以了
    }
    func RegService(service *Service) error {
        return requestRegistry(NewJSONRequest(service,"Registry.Register"))
    }
    

    启用三方api并注册到我们的go-micro体系中

    package main
    
    import (
        "context"
        "fmt"
        "github.com/gin-gonic/gin"
        "github.com/google/uuid"
        "log"
        "micro/sidecar"
        "net/http"
        "os"
        "os/signal"
        "syscall"
    )
    
    func main() {
        ginRouter := gin.Default()
        v1 := ginRouter.Group("/v1")
        {
            v1.Handle("POST", "/test", func(context *gin.Context) {
                context.JSON(200, gin.H{
                    "data": "test",
                })
            })
        }
        server := &http.Server{
            Addr:    ":8088",
            Handler: ginRouter,
        }
        service := sidecar.NewService("api.jtthink.com.test")
        service.AddNode("test-"+uuid.New().String(), 8088, "localhost:8088")
        handler := make(chan error)
        go func() {
            handler <- server.ListenAndServe()
        }()
        go (func() {
            server.ListenAndServe()
        })()
        go func() {
            notify := make(chan os.Signal)
            signal.Notify(notify, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
            handler <- fmt.Errorf("%s", <-notify)
        }()
        //注册服务
        go func() {
            err := sidecar.RegService(service)
            if err != nil {
                handler <- err
            }
        }()
        getHandler := <-handler //阻塞一旦有错误发生,err写入信道,解除阻塞,执行反注册服务
        fmt.Println(getHandler.Error())
        //反注册服务
        err := sidecar.UnRegService(service)
        if err != nil {
            log.Fatal(err)
        }
        err = server.Shutdown(context.Background())
        if err != nil {
            log.Fatal(err)
        }
    
    }
    

    调用第三方服务

    package main
    
    import (
        "context"
        "fmt"
        "github.com/micro/go-micro/client"
        "github.com/micro/go-micro/client/selector"
        "github.com/micro/go-micro/registry"
        "github.com/micro/go-micro/registry/etcd"
        myhttp "github.com/micro/go-plugins/client/http"
        "log"
    )
    
    func main() {
        etcdReg := etcd.NewRegistry(registry.Addrs("106.12.72.181:23791"))
    
        mySelector := selector.NewSelector(
            selector.Registry(etcdReg),
            selector.SetStrategy(selector.RoundRobin),
        )
        getClient := myhttp.NewClient(client.Selector(mySelector), client.ContentType("application/json"))
    
        //1创建request
        req := getClient.NewRequest("api.jtthink.com.test", "/v1/test", map[string]string{}) //这里的request
        //2创建response
        var rsp map[string]interface{} //var rsp map[string]string这里这么写也可以,因为我们的返回值是{"data":"test"},所以都对的上
        err := getClient.Call(context.Background(), req, &rsp) //将返回值映射到map中
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(rsp)
    }
    

    调用结果





  • 相关阅读:
    SQL语句
    [Tips] FTP服务器设置
    [Tips] filezilla连接成功,但是读取列表失败
    [Tips] 安装支持树莓派4b的系统
    [Tips] Ubuntu添加硬盘
    [Tips] BMC添加硬盘并进行raid1设置
    [Tips] docker 中遇到fork/exec /bin/sh: operation not permitted错误
    vue elementui el-cascader级联选择器没子级时出现暂无数据问题
    vue复选框勾选的内容,点击分页之后勾选的状态仍然保存。
    下载导出内容,带类型的//////下载,打印,下载源文件,不加mime类型
  • 原文地址:https://www.cnblogs.com/hualou/p/12146735.html
Copyright © 2011-2022 走看看