V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
chengxuyuan0917
V2EX  ›  Go 编程语言

go thrift 和 gprc 的问题

  •  
  •   chengxuyuan0917 · 2018-09-26 22:51:57 +08:00 · 2307 次点击
    这是一个创建于 2276 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在撸一个自己弄着玩的 api 网关, 对外是 http 的 restful 接口, 对内想用 gprc 和 thrift。

    gprc 和 thrift 都可以用生成的文件调用, 这样的话是如果服务端新增接口,那么调用端也要配合新增,就是纯 c/s 模式。 我想的是撸个网关,然后调用内部的服务,内部服务新增接口,不需要修改网关的代码,可以直接调用过去。

    比如,通过 consul 时候发现有新增的服务,调用时候可以省去新增服务的 client 端,网关这边 gprc 可以直接用 gprc.Invoke 调用,不是用 pb 文件的 XX 方法。 但是搞 thrift 时候找不到类似 gprc.Invoke 的方法,不知道怎么弄。 难道 thrift 必须两边都用上生成的文件才可以嘛?

    2 条回复    2018-09-26 23:42:33 +08:00
    Raymon111111
        1
    Raymon111111  
       2018-09-26 22:59:12 +08:00
    thrift 得提供接口的包给调用方才行
    chengxuyuan0917
        2
    chengxuyuan0917  
    OP
       2018-09-26 23:42:33 +08:00
    @Raymon111111
    我知道怎么玩了,
    正常情况下是这样
    ```
    transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    transport, err := thrift.NewTSocket(net.JoinHostPort(HOST, PORT))
    useTransport,_ := transportFactory.GetTransport(transport)
    transport.Open()
    client := usersrv.NewUserInfoServiceClientFactory(useTransport, protocolFactory)


    然后 client.GetUserById(context.TODO(), id)
    ```


    参考了 gprc.Invoke,观察了下 thrift 的调用方法
    ```

    type UserInfoServiceClient struct {
    c thrift.TClient
    }

    // Deprecated: Use NewUserInfoService instead
    func NewUserInfoServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *UserInfoServiceClient {
    return &UserInfoServiceClient{
    c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)),
    }
    }```

    后来,直接自己构造里面的 thrift.TClient,
    stClient:=thrift.NewTStandardClient(protocolFactory.GetProtocol(useTransport), protocolFactory.GetProtocol(useTransport))

    var _args0 usersrv.UserInfoServiceGetUserByNameArgs
    _args0.Namea = "123"
    var _result1 usersrv.UserInfoServiceGetUserByIdResult
    stClient.Call(context.Background(),"getUserById", &_args0, &_result1);
    //if err = stClient.Call(context.Background(),"getUserById", &_args0, &_result1); err != nil {
    // fmt.Println(err)
    // return
    //}
    fmt.Println(_result1.GetSuccess())


    前提是知道入参跟出参是什么,不过自定义网关消息的结构是通用的。比如说现在是
    usersrv.UserInfoServiceGetUserByNameArgs,usersrv.UserInfoServiceGetUserByIdResult,
    以后通用起来可能就是 ApiGateway.MessageRequest , ApiGateway.MessageResponse 这样。只需要接口定义时候确定成通用的格式就好了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2808 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 11:17 · PVG 19:17 · LAX 03:17 · JFK 06:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.