最近在撸一个自己弄着玩的 api 网关, 对外是 http 的 restful 接口, 对内想用 gprc 和 thrift。
gprc 和 thrift 都可以用生成的文件调用, 这样的话是如果服务端新增接口,那么调用端也要配合新增,就是纯 c/s 模式。 我想的是撸个网关,然后调用内部的服务,内部服务新增接口,不需要修改网关的代码,可以直接调用过去。
比如,通过 consul 时候发现有新增的服务,调用时候可以省去新增服务的 client 端,网关这边 gprc 可以直接用 gprc.Invoke 调用,不是用 pb 文件的 XX 方法。 但是搞 thrift 时候找不到类似 gprc.Invoke 的方法,不知道怎么弄。 难道 thrift 必须两边都用上生成的文件才可以嘛?
1
Raymon111111 2018-09-26 22:59:12 +08:00
thrift 得提供接口的包给调用方才行
|
2
chengxuyuan0917 OP @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 这样。只需要接口定义时候确定成通用的格式就好了。 |