Search code examples
thriftforwardingbroker

Forwarding Thrift service requests across servers running on different machines


I have an Ubuntu server running on my Mac and I have Thrift servers running on both Ubuntu and Mac. The services that each Thrift server offers is different.

The limitation is that I need to expose only the Mac Thrift server IP and port to the clients.

Is there any way by which I can forward the requests coming from the clients to ubuntu server from the Mac thrift server? Or for that matter is it possible to have any other broker that can have do the forwarding based on the service being requested for?


Solution

  • Sure. At least three approaches come to my mind. It mostly depends on how the API is designed and whether or not you are able to change it.

    Approach 1: Naive approach

    Handy if you can't or won't change the API. Each request handler function simply forwardes the data to another, but otherwise completely similar service that shares the same Thrift IDL definitions. Same with responses. Very trivial to implement, but maybe less efficient, because messages need to be decoded and encoded on the proxy, which requires to have the proxy always up-to-date and being aware of old versions of that API.

    Approach 2: More generic

    To avoid implementing each and every API function on the proxy just to do some stupid data shuffling, especially when the API is going to evolve over time, one could put all requests and responses into some universal wrapper union, like so, leaving you with on single API call that is als very easy to implement on the proxy:

    union AllRequests {
      1: FooRequest foo
      2: BarRequest bar
      // more as needed
    }
    
    
    union AllResponses {
      1: FooResponse foo
      2: BarResponse bar
      // more as needed
    }
    
    service Fowarding {
        AllResponses  HandleRequest( 1: AllRequests request)
    }
    

    Messages still need to be decoded and encoded on the proxy, plus the same considerations re IDL versioning apply. Additionally, the data format is quite formal, but that is in fact not necessarily a bad thing. If at some day you want to switch to a MQ system, or if you plan to record/playback service calls using Thrift serialization, this will be the way to go anyway.

    Approach 3: Nested serialization

    The payload message can be serialized into a BLOB, which is then sent to the proxy server, who forwards it to the final destination.

    service Fowarding {
        binary  HandleRequest( 1: binary request)
    }
    

    The single most benefit here is, that the proxy does not need to know anything about what's in the binary data. It is fully transparent to him. This also means, that the proxy does not even need to know about the IDL used to serialize these data. Last not least, it also allows to add some meta data to the binary data, if that is needed to optimize routing and/or processing:

    struct BinaryRequest {
      1: binary data
      2: string preferredRoute
    }
    

    The price to pay is obviously the double serialization overhead.