把apache Thrift嵌入servlet

 

在 http://developers.facebook.com/thrift/thrift-20070401.pdf  7.1节有如下内容,

 

Thrift services implemented in PHP have also been embedded into the Apache web server, provid- ing transparent backend access to many of our frontend constructs using a THttpClient implementation of the TTransport inter- face.

 

 

但Thrift没有把service嵌入到Servlet中的实现。搜索了以下,有人解决了这个问题。

参见: http://www.google.com/codesearch/p?hl=en&sa=N&cd=1&ct=rc#vusEaWnOsAk/thrift/TServlet.java&q=TServlet

 

我只做了一点修改,其中把com.facebook.thrift改为org.apache.thrift。测试了一下,可以正常运行。

修改后的TServlet.java

 

package servlet; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.TTransportFactory; /** * <p> * A servlet for exposing Thrift services over HTTP. To use, create a subclass * that supplies a {@link TProcessor}. For example, * </p> * * <pre> * public class CalculatorTServlet extends TServlet { * public CalculatorTServlet() { * super(new Calculator.Processor(new CalculatorHandler())); * } * } * </pre> * <p> * This code is based heavily on {@link org.apache.thrift.server.TSimpleServer}. * </p> * * @author Tom White */ public class TServlet extends HttpServlet { protected TProcessor processor_ = null; protected TTransportFactory inputTransportFactory_ = new TTransportFactory(); protected TTransportFactory outputTransportFactory_ = new TTransportFactory(); protected TProtocolFactory inputProtocolFactory_ = new TBinaryProtocol.Factory(); protected TProtocolFactory outputProtocolFactory_ = new TBinaryProtocol.Factory(); public TServlet(TProcessor processor) { processor_ = processor; } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter w = response.getWriter(); w.write("This is a thrift service!"); w.close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/x-thrift"); InputStream in = request.getInputStream(); OutputStream out = response.getOutputStream(); TTransport client = new TIOStreamTransport(in, out); TProcessor processor = null; TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; try { processor = processor_; inputTransport = inputTransportFactory_.getTransport(client); outputTransport = outputTransportFactory_.getTransport(client); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_ .getProtocol(outputTransport); while (processor.process(inputProtocol, outputProtocol)) { } } catch (TTransportException ttx) { // Client died, just move on } catch (TException tx) { tx.printStackTrace(); } catch (Exception x) { x.printStackTrace(); } if (inputTransport != null) { inputTransport.close(); } if (outputTransport != null) { outputTransport.close(); } } }  

 

写一个实现自己service的servlet

UserServiceServlet.java

 

package servlet; import myserver.UserServiceHandler; import mytest.thrift.gen.UserService; public class UserServiceServlet extends TServlet { public UserServiceServlet() { super(new UserService.Processor(new UserServiceHandler())); } } 

 

修改web.xml

加入如下内容

<servlet> <servlet-name>UserServiceServlet</servlet-name> <servlet-class>servlet.UserServiceServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>UserServiceServlet</servlet-name> <url-pattern>/UserService</url-pattern> </servlet-mapping> 

 

启动tomcat

 

Java客户端测试

把client.java中的

TTransport transport = new TSocket("localhost", 9090);

改为

transport = THttpClient.THttpClient("http://localhost:8080/UserService")

 

Python客户端测试

把client.py中的

transport = TSocket.TSocket('localhost', 9090)

改为

transport = THttpClient.THttpClient("http://localhost:8080/UserService")

 

 

最后,尽管http的方式是可以工作的,这样说明了Thrift的传输协议是很容易改变的。但我想需要注意的是服务的并发能力受到了tomcat的限制。如果要追求并发能力,就要使用nonblock的传输方式。

你可能感兴趣的:(apache,exception,servlet,测试,service,Class)