thrift-跨语言通信解决方案-java

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去回收。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章