thrift是一款跨語言通信的rpc框架,它可以使你像調用本地方法一樣和其他系統通信:
thrift需要定義一份以.thrift爲後綴的文件,thrift就是通過這個文件來編譯生成對應不同語言的調用文件。
環境的配置和文件的定義都很簡單,直接開始代碼:
在thrift文件的目錄運行命令:thrift -gen java xxx.thrift
結果會在目錄下生成java文件
將生成的java文件拷貝到項目裏面,
pom導入thrift的jar:
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
thrift本質還是socket鏈接,所以java可以做客戶端調用別人也可以做服務器端被別人調用,
thrift做服務器:
package com.koala.console.configuration;
import com.koala.console.service.neo4j.FaceLinkServ;
import com.koala.console.service.neo4j.impl.FacezLinkServImpl;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ThriftServer {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${thrift.server.port}")
private int port;
@Value("${thrift.minWorkerThreads}")
private int minThreads;
@Value("${thrift.maxWorkerThreads}")
private int maxThreads;
private TBinaryProtocol.Factory protocolFactory;
private TTransportFactory transportFactory;
@Autowired
private FacezLinkServImpl faceServ;
public void init() {
protocolFactory = new TBinaryProtocol.Factory();
transportFactory = new TTransportFactory();
}
public void start() {
//TMultiplexedProcessor processor = new TMultiplexedProcessor();
//processor.registerProcessor(JazzService.class.getSimpleName(), new JazzService.Processor<JazzService.Iface>(hadoopService));
TProcessor processor = new FaceLinkServ.Processor<FaceLinkServ.Iface>(faceServ);
init();
try {
TServerTransport transport = new TServerSocket(port);
TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(transport);
tArgs.processor(processor);
tArgs.protocolFactory(protocolFactory);
tArgs.transportFactory(transportFactory);
tArgs.minWorkerThreads(minThreads);
tArgs.maxWorkerThreads(maxThreads);
TServer server = new TThreadPoolServer(tArgs);
//TServer server = new TSimpleServer(tArgs);
logger.info("thrift服務啓動成功, 端口={}", port);
server.serve();
} catch (Exception e) {
logger.error("thrift服務啓動失敗", e);
}
}
}
public class CloudApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(CloudApplication.class, args);
ThriftServer thriftServer = context.getBean(ThriftServer.class);
thriftServer.start();
}
}
隨着項目啓動thrift服務器也就啓動了。
thrift客戶端:
package com.koala.console.configuration;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.resource.ClassPathResource;
import com.koala.console.service.neo4j.FaceServ;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransportException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.BufferedInputStream;
import java.io.File;
import java.util.Properties;
@Slf4j
@Component
public class JazzClient {
private FaceServ.Client jazzService;
private TBinaryProtocol protocol;
private TSocket transport;
private static Integer port;
private static String host;
private static Integer socketTimeout;
private static Integer connectTimeout;
public void init() {
transport = new TSocket(this.getHost(), this.getPort(),this.getSocketTimeout(), this.getConnectTimeout());
protocol = new TBinaryProtocol(transport);
jazzService = new FaceServ.Client(protocol);
}
public FaceServ.Client getJazzService() throws TTransportException {
return jazzService;
}
public void open() throws TTransportException {
transport.open();
}
public void close() {
transport.close();
}
public String getHost() {
return host;
}
@Value("${thrift.client.port}")
public void setPort(Integer port) {
JazzClient.port = port;
}
public int getPort() {
return port;
}
@Value("${thrift.client.host}")
public void setHost(String host) {
JazzClient.host = host;
}
@Value("${thrift.client.socketTimeout}")
public void setSocketTimeout(Integer socketTimeout) {
JazzClient.socketTimeout = socketTimeout;
}
@Value("${thrift.client.connectTimeout}")
public void setConnectTimeout(Integer connectTimeout) {
JazzClient.connectTimeout = connectTimeout;
}
public Integer getSocketTimeout() {
return socketTimeout;
}
public Integer getConnectTimeout() {
return connectTimeout;
}
}
JazzClient jazzClient = new JazzClient();
try {
jazzClient.init();
jazzClient.open();
imgSearchResult = jazzClient.getJazzService()
.searchSimilasByImg(img, cameras, start, last, max, threshold);
} finally {
jazzClient.close();
}
由於spring實例化是單例的導致每次都在使用同一個鏈接,所以多次請求的時候就不行了,乾脆讓他每次new對象去打開新的連接,最後讓jvm去回收。