Apache Thrift: resume of a real experience
Introduction
Here a list of personal considerations and facts, collected along my experience using Thrift on million rpc call per day.
When use Thrift ?
- Rapid Development: allow a quickly services definition.
- Alternative: soap with his wsdl sucks, Thrift is much more easy and fun.
- Bridge: ensure communication between different services written in different languages.
PRO
- Adapting: this is the essential of Thrift. You can easily change settings, like protocols and transport, without change the structure or logic of your program.
- Automatic Interface: for both client and server, the Thrift binary utility generate the interface ready to use.
- Easy..very easy: with the generated interface, you can easily create your client/server in few line of code without other dependencies or difficult steps to follow.
- Debug: using the TDebugProtocol you can inspect your data.
- Mature: used in many projects.
- Safety exceptions: Thrift is provided with all the exception definition you need to face with all the possible errors.
- Dependencies: no other build dependencies.
- Many Protocols: which are TBinaryProtocol, TCompactProtocol, TSimpleJSONProtocol, TJSONProtocol, TDenseProtocol, TDebugProtocol.
- Many Transports: which are TFileTransport,TFramedTransport,TSocket,TZlibTransport,TMemoryTransport.
- Many kind of server: which are TSimpleServer,TFramedTransport,TThreadPoolServer,TNonblockingServer
CONS
- Poor Documentation: this mean that if you want extend or change some internal behaviour, or create something much more advanced with Thrift, it will be not a easy task.
- No Built-in Authentication: you need to create your own authentication method.
- No Built-in Bidirection: you have to create bidirectional messaging by your own.
Tips
1 - Reuse common services
With Thrift reuse your services is very easy. Suppose that you want monitoring the cpu performance of all your different services or check the memory consuption: all the different servers you set up, can share common rpc services just adding few line of code. Here an example:
server-collect-data.cpp
main() {
/* Init the server: CollectDataRpcServer is a wrapper for the Thrift servers type */
CollectDataRpcServer server;
server.setPort(ini_file.read_port());
server.setMode(ini_file.read_mode());
server.setThreads(ini_file.read_num_threads());
/* Definition of your service: collect_data */
boost::shared_ptr<collect_data> handler_collect_data(
new collect_dataHandler());
boost::shared_ptr<apache::thrift::TProcessor> processor_collect_data(
new collect_dataProcessor(handler_collect_data));
server.registerService("CollectData", processor_collect_data);
/* Add cpu_info (common task) to your custom server */
boost::shared_ptr<common::CpuInfo> handler_cpu_info(
new common::CpuInfo());
boost::shared_ptr<apache::thrift::TProcessor> processor_cpu_info(
new common::cpu_infoProcessor(handler_cpu_info));
server.registerService("CpuInfo", processor_cpu_info);
/* Add memory_info (common task) to your custom server */
boost::shared_ptr<common::MemoryInfo> handler_memory_info(
new common::MemoryInfo());
boost::shared_ptr<apache::thrift::TProcessor> processor_memory_info(
new common::memory_infoProcessor(handler_memory_info));
server.registerService("MemoryInfo", processor_memory_info);
server.serve();
}
Both 'processorcpuinfo' and 'processormemoryinfo' can be reused in all Thrift servers without additional effort.
2 - Align client/server settings
Client and Server must have the same settings in term of protocols and transport.
It may happen that client has different settings, and no error is signaled by the client, and no data is received by the server.
3 - Use Binary
Binary serialization protocols is much more fast that the others.
You can always change your parameters and debugging using TDebugProtocol.
4 - Configure file
For manage several Thrift server, you should consider to manage setting into a ini file like this
[THRIFT-SERVER]
#available mode: TSimpleServer, TThreadPoolServer, TThreadedServer, TNonblockingServer
thrift_server_mode = TNonblockingServer
thrift_server_port = 1234
#to set only if server_mode = TThreadPoolServer or TNonblockingServer
thrift_server_threads = 24
Conclusion
Rapid development, no other dependencies, excellent throughput,
but poor documentation that discourage to explore in depth how it works.