基于 Thrift + Spring Boot 的微服务开发
整个项目源码参见 https://github.com/henryhyn/thrift-server
博客站点原文: https://kaiyuanshuwu.com/articles/153
先决条件
$ brew install thrift
$ thrift -version
Thrift version 0.11.0
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/16ebe5f1843e6cb54856311ff0f676be53007329/Formula/thrift.rb
创建 Maven 项目
创建 Maven 项目 thrift-server
, 包含两个模块 thrift-api
和thrift-service
, 前者定义 API 接口, 后者是具体的实现.
父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>thrift-server</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>thrift-api</module>
<module>thrift-service</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
接口子项目
API 接口子项目 thrift-api
的 POM 文件主要定义
<build>
<plugins>
<plugin>
<groupId>org.apache.thrift</groupId>
<artifactId>thrift-maven-plugin</artifactId>
<version>0.10.0</version>
<configuration>
<thriftExecutable>/usr/local/bin/thrift</thriftExecutable>
</configuration>
<executions>
<execution>
<id>thrift-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>thrift-test-sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
</dependencies>
注意, 这里使用的是 thrift-maven-plugin
插件, 而不是 maven-thrift-plugin
, 该插件将在编译之前, 将 thrift 文件生成 Java 代码.
新建文件 thrift-api/src/main/thrift/service.thrift
, 内容如下
namespace java com.example.thrift.api
service HelloService {
string greet(1:string name)
}
实现子项目
服务实现子项目 thrift-service
的 POM 文件主要定义
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>thrift-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
新建入口类文件 thrift-service/src/main/java/com/example/Application.java
, 内容如下
@Slf4j
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
创建 HelloService.Iface
的实现类com.example.service.HelloServiceImpl
, 内容如下
@Service("helloService")
public class HelloServiceImpl implements HelloService.Iface {
@Override
public String greet(String para) throws TException {
return String.format("Hello %s!", para);
}
}
编写抽象测试类 com.example.AbstractTest
, 内容如下
@RunWith(SpringRunner.class)
@SpringBootTest
public abstract class AbstractTest {
}
创建服务测试类 com.example.service.HelloServiceTest
, 首先测试本地调用
@Autowired
private HelloService.Iface helloService;
@Test
public void testLocal() {
try {
log.info("本地调用服务...{}", helloService.greet("Local"));
} catch (TException e) {
log.error("本地调用异常.", e);
}
}
执行测试输出 本地调用服务...Hello Local!
, 说明接口实现没有问题.
远程调用
服务端
在 Application.java
的 main
方法中增加如下逻辑
try {
TProcessor tprocessor = new HelloService.Processor<>(new HelloServiceImpl());
TServerSocket serverTransport = new TServerSocket(9898);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
log.info("服务端开启....");
} catch (TTransportException e) {
log.error("服务端开启异常.", e);
}
将项目构建打包 mvn clean package
, 将生成的 thrift-service-1.0-SNAPSHOT.jar
可执行 jar 包移到项目以外, 比如 /tmp
目录, 然后用 java -jar xxx.jar
启动服务端.
客户端
在测试类 HelloServiceTest
中增加远程调用测试
@Test
public void testRemote() {
try (TTransport transport = new TSocket("localhost", 9898, 30000)) {
TProtocol protocol = new TBinaryProtocol(transport);
HelloService.Client helloService = new HelloService.Client(protocol);
transport.open();
log.info("远程调用服务...{}", helloService.greet("Remote"));
} catch (TException e) {
log.error("远程调用异常.", e);
}
}
执行测试输出 远程调用服务...Hello Remote!
, 说明远程调用服务也没有问题. 以上我们就构建了一个简单的单线程微服务模型.
参考文献
更多推荐
所有评论(0)