把apache Thrift嵌入servlet
在 https://www.wendangku.net/doc/2d8597712.html,/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中的实现。搜索了以下,有人解决了这个问题。
参见: https://www.wendangku.net/doc/2d8597712.html,/codesearch/p?hl=en&sa=N&cd=1&ct=rc#vusEaWnOsAk/thrift/TServlet.java&q=TServlet
我只做了一点修改,其中把com.facebook.thrift改为org.apache.thrift。测试了一下,可以正常运行。
修改后的TServlet.java
[c-sharp] view plaincopy
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;
/**
*
* A servlet for exposing Thrift services over HTTP. To use, create a subclass
* that supplies a {@link TProcessor}. For example,
*
* public class CalculatorTServlet extends TServlet {
* public CalculatorTServlet() {
* super(new Calculator.Processor(new CalculatorHandler()));
* }
* }
*
* This code is based heavily on {@link org.apache.thrift.server.TSimpleServer}.
*
sponse 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
[c-sharp] view plaincopy
package servlet;
import https://www.wendangku.net/doc/2d8597712.html,erServiceHandler;
import https://www.wendangku.net/doc/2d8597712.html,erService;
public class UserServiceServlet extends TServlet {
public UserServiceServlet() {
super(new UserService.Processor(new UserServiceHandler()));
}
}
修改web.xml
加入如下内容
[c-sharp] view plaincopy
启动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的传输方式。