24

记一次rpcx拦截器的实现+使用TLS证书启动

 3 years ago
source link: https://studygolang.com/articles/31557
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

安装

首先,你需要安装 rpcx:

go get -u -v github.com/smallnest/rpcx/...

这一步只会安装 rpcx 的基础功能。如果你想要使用 etcd 作为注册中心,你需要加上etcd这个标签。 (see build tags)

go get -u -v -tags "etcd" github.com/smallnest/rpcx/...

如果你想要使用 quic ,你也需要加上quic这个标签。

go get -u -v -tags "quic etcd" github.com/smallnest/rpcx/...

方便起见,我推荐你安装所有的tags,即使你现在并不需要他们:

go get -u -v -tags "reuseport quic kcp zookeeper etcd consul ping" github.com/smallnest/rpcx/...

tag:

  • quic : 支持 quic 协议
  • kcp : 支持 kcp 协议
  • zookeeper : 支持 zookeeper 注册中心
  • etcd : 支持 etcd 注册中心
  • consul : 支持 consul 注册中心
  • ping : 支持 网络质量负载均衡
  • reuseport : 支持 reuseport

上面内容摘自: https://doc.rpcx.io/part1/qui...

简单的Service实现

实现一个 Sevice 就像写一个单纯的 Go 结构体:

import "context"

type Args struct {
    A int
    B int
}

type Reply struct {
    C int
}

type Arith int

func (t *Arith) Mul(ctx context.Context, args *Args, reply *Reply) error {
    reply.C = args.A * args.B
    return nil
}

注册一个简单服务

s := server.NewServer()
s.RegisterName("Arith", new(Arith), "")
s.Serve("tcp", ":8972") // 可以启动quic(udp)/tcp/http服务

手写一个拦截器

其实是实现plugin的PostReadRequest方法

type SignPlugin struct {
}

// 拦截器
func (signPlugin *SignPlugin) PostReadRequest(ctx context.Context, req *protocol.Message, err error) error {
    //fmt.Println(req.ServiceMethod)
    //fmt.Println(req.ServicePath)
    // 我这是使用json传输的
    p := &你的结构体
    err = json.Unmarshal(req.Payload, p)

    // todo 你的逻辑(数据验证,数据处理等)
    decodeMap := 你处理后的数据(如果不用处理,该步骤可以省略)
    req.Payload = decodeMap
    return err
}

把拦截器add到启动服务中

s := server.NewServer()
siginPlugin := &controller.SignPlugin{}
s.Plugins.Add(siginPlugin) // 把拦截器注册到服务中
s.RegisterName("Arith", new(Arith), "")
s.Serve("tcp", ":8972") // 可以启动quic(udp)/tcp/http服务

到此拦截器已经实现.

下面附上client代码

option := client.DefaultOption
    option.SerializeType = protocol.JSON // 传输数据格式
    // #1
    d := client.NewPeer2PeerDiscovery("[email protected]:8972", "")
    // #2
    xclient := client.NewXClient("Arith", client.Failtry, client.RandomSelect, d,option)
    defer xclient.Close()

    // #3
    args := &example.Args{
        A: 10,
        B: 20,
    }

    // #4
    reply := &example.Reply{}

    // #5
    err := xclient.Call(context.Background(), "Mul", args, reply)
    if err != nil {
        log.Fatalf("failed to call: %v", err)
    }

    log.Printf("%d * %d = %d", args.A, args.B, reply.C)

使用quic(UDP)和TLS证书注意:

  • 使用quic(UDP)时,s.Serve("tcp", "localhost:8972"). address参数必须要写完整,localhost不能省略
  • 使用quic(UDP)时,rpcx对quic协议的支持是通过build tags实现的.默认不会编译quic相关文件.如果要使用,必须自己手动指定tags

    • server+client都需要
    go run -tags quic main.go
  • 使用quic(UDP)时,必须要使用TLS证书

    • server代码
    // 加载tls证书,使用quic必要步骤
    cert, err := tls.LoadX509KeyPair("公钥路径", "私钥路径")
    if err != nil {
        panic("加载证书失败:" + err.Error())
    }
    configs := &tls.Config{Certificates: []tls.Certificate{cert}}
    s = server.NewServer(server.WithTLSConfig(configs))
    • client代码
    conf := &tls.Config{
        InsecureSkipVerify: true, // true=跳过tls证书验证
    }
    
    option := client.DefaultOption
    option.SerializeType = protocol.JSON // 传输数据格式
    option.TLSConfig = conf // 使用tls证书
    d := client.NewPeer2PeerDiscovery("[email protected]:8972", "")
      xclient := client.NewXClient("Arith", client.Failtry, client.RandomSelect, d,option)

有疑问加站长微信联系(非本文作者)

eUjI7rn.png!mobile

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK