springBoot整合thrift

前言: thrift的基础知识

1.Thrift的服务端

1.1.引入maven依赖

	<parent>
        <artifactId>com.ajc.demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
 
   <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!--thrift 相关资源-->
    <dependency>
        <groupId>org.apache.thrift</groupId>
        <artifactId>libthrift</artifactId>
        <version>0.9.3</version>
    </dependency>
     <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version><!--版本号自己选一个就行-->
        </dependency>
   </dependencies>

1.2.定义thrift文件

student.thrift:

//指明生成的代码在哪个包下
namespace java com.ajc.thrift.server.model

//讲shrift的数据类型格式转为java习惯的格式
typedef i16 short
typedef i32 int
typedef i64 long
typedef string String
typedef bool boolean

/**
* 学生对象
**/
 struct Student{
    //姓名
    1:optional String name,
    //年龄
    2:optional int age,
    //地址
    3:optional String address
 }
 /**
 * 数据异常
**/
 exception DataException{
    //异常码
    1:optional int code,
    //异常信息
    2:optional String message
    //时间
    3:optional String dataTime

 }
 /**
 * 学生服务
**/
    service StudentService{
    //根据名称获取学生信息
    Student getStudentByName(1:required String name) throws (1:DataException dataException),
    //保存一个学生信息
    void save(1:required Student student) throws (1:DataException dataException)
    }

在该文件下的终端执行命令

 thrift -gen java student.thrift

然后会生成对应的java文件,根据自己的文件目录进行分配。
注意:这里不要修改任何一个生成的文件
在这里插入图片描述

1.3.定义service实现类,完成业务逻辑

StudentServiceImpl:

@Service
@Slf4j
public class StudentServiceImpl implements StudentService.Iface {

    @Override
    public Student getStudentByName(String name) throws DataException, TException {
    log.info("服务端收到了客户端获取用户名的请求 name={}",name);
        Student student = new Student();
        student.setName("小李");
        student.setAge(18);
        student.setAddress("中国河南郑州");
        return student;

    }

    @Override
    public void save(Student student) throws DataException, TException {
            log.info("服务端收到了客户端保存学生信息的请求,{}",student);

            try{
                //模拟保存时间
                Thread.sleep(100);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            log.info("学生信息保存成功~");

    }
}

1.1.3.客户端配置文件

application.yml

server:
  port: 8081

spring:
  application:
    name: thrift-server


thrift:
  port: 8899 #监听的端口
  min-thread-pool: 100  #线程池最小线程数
  max-thread-pool: 1000 #线程池最大线程数

1.4.服务端配置类


@Component
@Slf4j
public class ThriftServer {

    //监听的端口
    @Value("${thrift.port}")
    private Integer port;

    //线程池最小线程数
    @Value("${thrift.min-thread-pool}")
    private Integer minThreadPool;

    //线程池最大线程数
    @Value("${thrift.max-thread-pool}")
    private Integer maxThreadPool;

    //业务服务对象
    @Autowired
    StudentServiceImpl studentService;

    @PostConstruct
    public void start() {
        try {
            /**
             * thrift支持的scoker有很多种
             * 这里采用非阻塞的socker
             */
            TNonblockingServerSocket socket = new TNonblockingServerSocket(port);

            /**
             * THsHaServer 一个高可用的server
             * minWorkerThreads 最小的工作线程2
             * maxWorkerThreads 最大的工作线程4
             * 如果这里Args不使用executorService指定线程池的话,创建THsHaServer会创建一个默认的LinkedBlockingQueue
             */
            THsHaServer.Args arg =
                    new THsHaServer.Args(socket).minWorkerThreads(minThreadPool).maxWorkerThreads(maxThreadPool);
            //可以自定义指定线程池
            //ExecutorService pool = Executors.newFixedThreadPool(minThreadPool);
            //arg.executorService(pool);


            /**
             * Processor处理区  用于处理业务逻辑
             * 泛型就是实现的业务
             */
            StudentService.Processor<StudentServiceImpl> processor = new StudentService.Processor<>(studentService);


            /**
             *---------------thrift传输协议------------------------------
             *  1. TBinaryProtocol      二进制传输协议
             *  2. TCompactProtocol     压缩协议 他是基于TBinaryProtocol二进制协议在进一步的压缩,使得体积更小
             *  3. TJSONProtocol        Json格式传输协议
             *  4. TSimpleJSONProtocol  简单JSON只写协议,生成的文件很容易通过脚本语言解析,实际开发中很少使用
             *  5. TDebugProtocol       简单易懂的可读协议,调试的时候用于方便追踪传输过程中的数据
             *-----------------------------------------------------------
             *
             *   设置工厂
             *   协议工厂 TCompactProtocol压缩工厂  二进制压缩协议
             */
            arg.protocolFactory(new TCompactProtocol.Factory());
            //---------------thrift传输格式------------------------------

            /**
             *  ---------------thrift数据传输方式------------------------------
             *             1. TSocker            阻塞式Scoker 相当于Java中的ServerSocket
             *             2. TFrameTransport    以frame为单位进行数据传输,非阻塞式服务中使用
             *             3. TFileTransport     以文件的形式进行传输
             *             4. TMemoryTransport   将内存用于IO,Java实现的时候内部实际上是使用了简单的ByteArrayOutputStream
             *             5. TZlibTransport     使用zlib进行压缩,与其他传世方式联合使用;java当前无实现所以无法使用
             *
             * 传输工厂 更加底层的概念
             */
            arg.transportFactory(new TFramedTransport.Factory());
            //arg.transportFactory(new TTransportFactory());
            //---------------thrift数据传输方式------------------------------

            //设置处理器(Processor)工厂
            arg.processorFactory(new TProcessorFactory(processor));

            /**
             *  ---------------thrift支持的服务模型------------------------------
             *             1.TSimpleServer  简单的单线程服务模型,用于测试
             *             2.TThreadPoolServer 多线程服务模型,使用的标准的阻塞式IO;运用了线程池,当线程池不够时会创建新的线程,当线程池出现大量空闲线程,线程池会对线程进行回收
             *             3.TNonBlockingServer 多线程服务模型,使用非阻塞式IO(需要使用TFramedTransport数据传输方式)
             *             4.THsHaServer YHsHa引入了线程池去处理(需要使用TFramedTransport数据传输方式),其模型把读写任务放到线程池去处理;Half-sync/Half-async(半同步半异步)的处理模式;Half-sync是在处理IO时间上(sccept/read/writr io),Half-async用于handler对RPC的同步处理
             *             ----------------------------
             *             根据参数实例化server
             *             半同步半异步的server
             */
            TServer server = new THsHaServer(arg);
            //---------------thrift支持的服务模型------------------------------
            log.info("shrift server started; port: {}", port);
            //启动server
            // 异步非阻塞的死循环
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        }
    }
}

1.5.启动服务端

在这里插入图片描述
看到以上日志内容,说明容器正常启动。

2.Thrift的客户端

2.1.引入依赖

	 <parent>
        <artifactId>com.ajc.demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
 
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!--thrift 相关资源-->
    <dependency>
        <groupId>org.apache.thrift</groupId>
        <artifactId>libthrift</artifactId>
        <version>0.9.3</version>
    </dependency>
	<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version><!--版本号自己选一个就行-->
        </dependency>
</dependencies>

2.2.生成对应的java文件并放在合适的包下。

具体操作,一般是服务端提供*.thrift文件或者java文件给客户端(maven依赖)。

2.3.客户端配置 application.yml

server:
  port: 8081

spring:
  application:
    name: thrift-server


thrift:
  port: 8899 #监听的端口
  min-thread-pool: 100  #线程池最小线程数
  max-thread-pool: 1000 #线程池最大线程数

2.4.客户端配置 ThriftClient


@Component
//每次请求实例化一个新的ThriftClient连接对象
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ThriftClient {

    @Value("${thrift.host}")
    private String host;

    @Value("${thrift.port}")
    private Integer port;

    private TTransport tTransport;

    private TProtocol tProtocol;

    private StudentService.Client client;

    @PostConstruct
    private void init() {
        tTransport = new TFramedTransport(new TSocket(host, port), 600);
        //协议对象 这里使用协议对象需要和服务器的一致
        tProtocol = new TCompactProtocol(tTransport);
        client = new StudentService.Client(tProtocol);
    }

    public StudentService.Client getService() {
        return client;
    }

    public void open() throws TTransportException {
        if (null != tTransport && !tTransport.isOpen()) {
            tTransport.open();
        }
    }

    public void close() {
        if (null != tTransport && tTransport.isOpen()) {
            tTransport.close();
        }
    }
}

2.5.Controller 接受web请求

@RestController
@RequestMapping("/thrift")
@Slf4j
public class ThriftTestController {


    @Autowired
    ThriftClient thriftClient;

    @RequestMapping("/get")
    public Student getStudentByName(String name){

        try{
         thriftClient.open();
         log.info("客户端请求用户名为: {}",name);
            StudentService.Client service = thriftClient.getService();
            System.out.println(service);
            Student student = thriftClient.getService().getStudentByName(name);
            log.info("学生信息: {}",student);
            return student;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            thriftClient.close();
        }
        return null;
    }
}

2.6.启动客户端工程,浏览器请求接口

在这里插入图片描述

到此 springBoot整合Thrift的基本流程已经完毕了,在日常开发中,client一般是由客户端进行封装,提供给客户端直接使用的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值