Springboot整合Thrift
编写thrift接口文件,并生成对应的服务端和客户端的代码
namespace java com.wdlm.thrift.code
namespace py py.com.wdlm.thrift.code
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 sex,
4:optional String address
}
exception DataException{1:optional int code,2:optional String messsage,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

服务端发布
创建一个maven的项目 thrift-server

在maven中添加对应的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.wdlm</groupId><artifactId>thrift-server</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version> <relativePath/> </parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.22.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies></project>
创建一个Service服务,实现StudentService.Iface接口
package com.wdlm.thrift.service;import com.wdlm.thrift.code.DataException;
import com.wdlm.thrift.code.Student;
import com.wdlm.thrift.code.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.springframework.stereotype.Service;@Service
@Slf4j
public class StudentServiceImpl implements StudentService.Iface {@Overridepublic Student getStudentByName(String name) throws DataException, TException{log.info("服务端收到客户端getStudentByName请求,name:" + name);Student student = new Student();student.setName("今天不coding");student.setAge(18);student.setSex("男");student.setAddress("北京");try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("服务端返回数据给客户端getStudentByName请求,student" + student);return student;}@Overridepublic void save(Student student) throws DataException, TException {log.info("服务端收到客户端saveStudent请求,student:" + student);try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("保存成功");}
}
配置服务端端口及线程池参数
server:thrift:port: 9001min-threads-pool: 100max-threads-pool: 1000
创建服务端对象
package com.wdlm.thrift.server;import com.wdlm.thrift.code.StudentService;
import com.wdlm.thrift.service.StudentServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.transport.layered.TFramedTransport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Slf4j
public class StudentServer {@Value("${server.thrift.port}")private Integer port;@Value("${server.thrift.min-threads-pool}")private Integer minThreadPool;@Value("${server.thrift.max-threads-pool}")private Integer maxThreadPool;@Autowiredprivate StudentServiceImpl studentService;public void start() {try {TNonblockingServerSocket socket = new TNonblockingServerSocket(port);THsHaServer.Args args = new THsHaServer.Args(socket).minWorkerThreads(minThreadPool).maxWorkerThreads(maxThreadPool);StudentService.Processor<StudentServiceImpl> processor = new StudentService.Processor<>(studentService);args.protocolFactory(new TCompactProtocol.Factory());args.transportFactory(new TFramedTransport.Factory());args.processorFactory(new TProcessorFactory(processor));THsHaServer server = new THsHaServer(args);server.serve();log.info("thrift server has been started, port:" + port);} catch (TTransportException e) {e.printStackTrace();}}
}
启动类中添加Server的启动配置
package com.wdlm.thrift.server;import com.wdlm.thrift.server.server.StudentServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class ServerApplication {public static void main(String[] args) {SpringApplication.run(ServerApplication.class, args);}@Beanpublic StudentServer studentServer(){StudentServer studentServer = new StudentServer();studentServer.start();return studentServer;}
}
调用端发布
创建一个maven项目 thrift-client

在maven中添加对应的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.wdlm</groupId><artifactId>thrift-client</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version> <relativePath/> </parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.22.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies></project>
配置远程服务端端口
server:port: 8001thrift:host: localhostport: 9001
创建客户端对象
package com.wdlm.thrift.client.client;import com.wdlm.thrift.client.code.StudentService;
import lombok.Setter;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.transport.layered.TFramedTransport;public class StudentClient {@Setterprivate String host;@Setterprivate Integer port;private TTransport transport;private TProtocol protocol;private StudentService.Client client;public void init() throws TTransportException {transport = new TFramedTransport(new TSocket(host, port), 600);protocol = new TCompactProtocol(transport);client = new StudentService.Client(protocol);}public StudentService.Client getService(){return client;}public void open() throws TTransportException {if (null != transport && !transport.isOpen()){transport.open();}}public void close() {if (null != transport && transport.isOpen()){transport.close();}}}
创建一个自动配置类,用于将客户端对象托管到spring容器
package com.wdlm.thrift.client.configuration;import com.wdlm.thrift.client.client.StudentClient;
import org.apache.thrift.transport.TTransportException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.web.context.WebApplicationContext;@Configuration
public class StudentClientConfig {@Value("${server.thrift.host}")private String host;@Value("${server.thrift.port}")private Integer port;@Bean@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)public StudentClient studentClient() throws TTransportException {StudentClient studentClient = new StudentClient();studentClient.setHost(host);studentClient.setPort(port);studentClient.init();return studentClient;}
}
定义Service接口
package com.wdlm.thrift.client.service;import com.wdlm.thrift.client.code.Student;public interface StudentService {Student getStudentByName(String name);void save(Student student);}
实现Service接口
package com.wdlm.thrift.client.service.impl;import com.wdlm.thrift.client.client.StudentClient;
import com.wdlm.thrift.client.code.Student;
import com.wdlm.thrift.client.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
@Slf4j
public class StudentServiceImpl implements StudentService {@Autowiredprivate StudentClient studentClient;@Overridepublic Student getStudentByName(String name) {try {studentClient.open();log.info("客户端根据学生姓名查询学生信息,name:" + name);return studentClient.getService().getStudentByName(name);} catch (Exception e) {log.error("客户端根据学生姓名查询学生信息报错" + e);throw new RuntimeException(e);} finally {studentClient.close();}}@Overridepublic void save(Student student) {try {studentClient.open();log.info("客户端保存学生信息请求" + student);studentClient.getService().save(student);} catch (Exception e) {log.error("客户端保存学生信息请求报错" + e);throw new RuntimeException(e);} finally {studentClient.close();}}
}
创建controller
package com.wdlm.thrift.client.controller;import com.wdlm.thrift.client.code.Student;
import com.wdlm.thrift.client.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/student")
public class StudentController {@Autowiredprivate StudentService studentService;@GetMapping("/getStudentByName")public Student getStudentByName(String name) {return studentService.getStudentByName(name);}@PostMapping("/save")public Student save(@RequestBody Student student) {studentService.save(student);return student;}}