Server
我们提出了一个新的抽象server,TMultiplexingServer,它可以使用TLookupMultiplexer绑定任何server信息到任何transport和任何protocol。该类抽象了对象创建的底层复杂性,并公开两个抽象方法,getServer和configureMultiplexer,用来被任何继承该类的类实现。该类使得用户可以在创建server对象时识别出server transport、protocol,因此提供了额外的灵活性,当涉及到将不同的transport和protocol的多个service绑定到同一server,而无需额外的编码工作。
Source Code
我们扩展了Thrift Java库【version 0.9.0】,并增加了一个以ext命名的源文件夹,包含multiplexing组件的底层实现。此外,build.xml已被修改以先后和扩展的源代码。该方案的兼容性已经过测试与目前稳定版本0.8.0 Thrift无缝继承。为了使用Thrift的multiplexing功能,你需要从git-hub download/pull扩展的Thrift库源代码,然后在下载的Thrift Java库上运行ant命令。这将在build文件夹中生成libthrift-xxx.jar,可以被开发人员用于创建自己的企业解决方案。
怎样使用Thrift Multiplexing?
multiplexing server可以通过扩展org.apache.thrift.server.TMultiplexingServer类,并通过实现抽象方法configureMultiplexer()和getServer(TServerTransportserverTransport,TProtocolFactoryprotFactory,TProcessor processor)来创建。示例代码提供如下:
第一步:继承TMultiplexingServer类创建server类。
public class Server1<T extends TServerTransport, F extends TProtocolFactory> extends TMultiplexingServer<T, F>
第二步:有选择的重载默认的构造函数以接收server transport和protocol。
public Server1(T serverTransport, F protFactory) { super(serverTransport, protFactory); }
第三步:实现configureMultiplexer()方法以配置lookup multiplexer。作为配置的一部分,你需要创建包含绑定到server上所有service以及相应的service information详细信息列表的MultiplexerArgs。示例如下,我们已经绑定HR和Finance service到Server1
@Override protected List<MultiplexerArgs<URIContext, TProcessor>> configureMultiplexer() { // list of multiplexer arguments List<MultiplexerArgs<URIContext, TProcessor>> args = new ArrayList<MultiplexerArgs<URIContext, TProcessor>>(); // configuring HR service context TProcessor processor = new HRService.Processor<HRServiceImpl>( new HRServiceImpl()); URIContext context = new URIContext(Constants.HR_CONTEXT, "HumanResource_Service"); MultiplexerArgs<URIContext, TProcessor> arg = new MultiplexerArgs<URIContext, TProcessor>( processor, context); args.add(arg); // configuring FIN service context processor = new FinanceService.Processor<FinanceServiceImpl>( new FinanceServiceImpl()); context = new URIContext(Constants.FIN_CONTEXT, "Finance_Service"); arg = new MultiplexerArgs<URIContext, TProcessor>(processor, context); args.add(arg); return args; }
第四步:实现getServer(…)方法以创建目的Server的实例。在下面的示例中,我们使用参数创建了一个ThreadProolServer的实例。
@Override protected TServer getServer (TServerTransport serverTransport, TProtocolFactory protFactory, TProcessor processor) { //creating server args Args serverArgs= new Args(serverTransport); serverArgs.protocolFactory(protFactory); serverArgs.transportFactory(new TTransportFactory()); serverArgs.processor(processor); serverArgs.minWorkerThreads=1; serverArgs.maxWorkerThreads=5; //creating server instance return new TThreadPoolServer(serverArgs); }
第五步:使用何时的transport和protocol创建server类的实例,并启动server
public static void main(String[] args) { //identifying server transport TServerSocket SERVER1_TRANSPORT = new TServerSocket(Constants.SERVICE1_PORT); //identifying server protocol Factory SERVER1_FACTORY = new TBinaryProtocol.Factory(); //creating server instances for specific transport and protocol Server1<TServerSocket, TBinaryProtocol.Factory> server1 = new Server1<TServerSocket, TBinaryProtocol.Factory>(SERVER1_TRANSPORT, SERVER1_FACTORY); //starting server server1.start(); }
创建一个客户端查询registry并使用service context
一个来查询multiplexing server registry的客户端可以从org.apache.thrift.registry.TRegistryClientFactory类获得。class.TRegistryClientFactory是便利类,它提供multiplexing客户端的实例。在客户端侧,你可以使用工厂的静态方法getClient(..)以获取registry客户端。它可以进一步用来查询registry和确定合适的server处理该请求。下面提供的示例代码是关于客户端使用的finance service检索雇员的税务细节的客户端:
public double getTaxDetails(intempId){ TTransport transport = null; TProtocol protocol = null; try { //transport transport = new TSocket(Constants.SERVICE_IP, Constants.SERVICE1_PORT, 60); //Multiplexing protocol protocol = Factory.getProtocol(new TBinaryProtocol(transport), TConstants.LOOKUP_CONTEXT); //Procuring Registry client TRegistry client = TRegistryFactory.getClient(protocol); //opening transport transport.open(); //querying registry to get context Set<URIContext> contexts = client.lookupByName("Finance_Service"); //executing the request on appropriate service using the context if(contexts.size()==1){ URIContext uricontext = contexts.iterator().next(); protocol = newTMultiplexProtocol(newTBinaryProtocol(transport),uricontext.getContext()) ; com.service.FinanceService.Client finService = new com.service.FinanceService.Client(protocol); return finService.getTaxDeductedTillDate(empId); } }finally { if(transport!=null) //closing transport transport.close(); } }
明智的投资利润丰厚
Thrift在当今的企业环境中有巨大优势,因为它通过有效的方式解决了所有大数据解决方案带来的挑战,并提供了一个公开为整个网络提供服务的解决方案。大多数企业,特别是在生产环境中,具有有限的端口,打开新的端口将引入相关的成本。使用Thrift作为解决方案的RPC机制是考虑到端口的有限。此外,像Hadoop、Hive、HBase、Cassandra、NoSQL数据存储等等,以及其他企业软件,如Web服务器、应用服务器和ESBs已经使用了多个端口。在成本和资源方面,如果企业将服务公开到网络上,然后为每个服务打开额外的端口是低效的。这一企业问题,可以通过Thrift multiplexing的帮助,减少端口数为一个,用很小的开发和管理开支绑定所有的服务。
一个组织投资于这项技术肯定会收获快速的周转时间和开发成本低的好处。此外,从长远来看,对复用做扩展,减少了企业的维护和管理费用,使得这项投资的利润丰厚。随着复用,多个services可以绑定在一个Thrift服务器上,从而降低维护成本。服务的模块化设计可以使用复用减少服务未来发展的成本,引入新的服务/功能或修改现有服务。因此,复用以其简单的实现,不仅使投资划算,而且使业务增值。
总结
因为可靠和高效的方式跨编程语言通信,近来Thrift已经成为一项强大的技术。企业应对大数据等先进技术,可以使用Thrift解决方案通过有效地利用企业资源以低维护成本,来绑定多个服务到网络。
参考:
[4] http://code.google.com/p/protobuf/
[8] http://cassandra.apache.org/
[9] git://github.com/impetus-opensource/thrift.git
英文原文:
(完)
本文作者 : cyningsun
版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!