實戰環境
- win10
- IDEA 2018.1.6
- JDK 1.8
- thrift 0.11.0
- spring-boot 2.2.1
創建Thrift項目
- 創建Thrift項目
- 編譯thrift文件,導出成java文件,並將編譯導出的java文件打成jar包,作爲Thrift API
創建Thrift項目
新建一個maven項目,在src/main
包下創建thrift
文件夾和java
文件夾,在thrift文件夾下編寫RPCDateService.thrift
文件。我們可以編寫如下接口:
namespace java com.wl.thrift.api
service RPCDateService{
string getDate(1:string userName)
}
pom文件需要添加以下依賴和插件
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.thrift.tools</groupId>
<artifactId>maven-thrift-plugin</artifactId>
<version>0.1.11</version>
<configuration>
<!--<thriftExecutable>/usr/local/bin/thrift</thriftExecutable>-->
<!--<thriftSourceRoot>src/main/thrift</thriftSourceRoot>-->
<outputDirectory>src/main/java</outputDirectory>
<generator>java</generator>
</configuration>
<executions>
<execution>
<id>thrift-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
ps:
- thrift文件需要編譯,採用的是
maven-thrift-plugin
插件 libthrift
依賴的版本需要和本地安裝的Thrift服務版本相同,否則編譯報錯。安裝見上一篇文章maven-thrift-plugin
插件的執行compile
階段綁定generate-sources階段。
爲什麼要綁定在這個階段?而不是compile階段呢?因爲我們thrift插件的作用是生成java文件,而在maven執行compile階段時,java文件必鬚生成完畢才能進行編譯,因此,該插件的執行必須在compile之前,所以放在generate-sources階段比較合適。
thriftExecutable:指的是thrift編譯器的位置,如果我們配置了環境變量,可以不指定。驗證環境變量可以使用thrift --version命令。
thriftSourceRoot:thrift源文件的目錄,默認會從src/main/thrift下讀取。
outputDirectory:生成java文件的目錄。其實這個一般不需要配置,因爲java文件的包名是在.thrift文件以namespace的形式定義的。
編譯thrift文件,導出成java文件,並打成jar包
在IDEA底部的Terminal工具中輸入mvn clean install
命令進行打成jar包。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WdfmwNav-1574604513328)(/image/ThriftAPI.png)]
開發Thrift服務端
採用sprint-Boot編寫服務端
創建spring-boot項目
在pom文件
中導入依賴
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.wl</groupId>
<artifactId>ThriftAPI</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
</dependencies>
創建controller實現Thrift API接口
創建controller
文件夾,創建RPCDateServiceIml.java
文件,內容如下:
package com.wl.controller;
import com.wl.thrift.api.RPCDateService;
import org.apache.thrift.TException;
import org.springframework.stereotype.Controller;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class RPCDateServiceIml implements RPCDateService.Iface {
@Override
public String getDate(String userName) throws TException {
Date now = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("今天是"+"yyyy年MM月dd日 E kk點mm分");
String nowTime = simpleDateFormat.format(now);
return "Hello" + userName + "\n" + nowTime;
}
}
編寫Thrift Server端代碼,啓動Thrift Server
創建server
文件夾,創建RPCThriftServer.java
文件,內容如下:
package com.wl.server;
import com.wl.controller.RPCDateServiceIml;
import com.wl.thrift.api.RPCDateService;
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 RPCThriftServer {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${thrift.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 RPCDateServiceIml rpcDateService;
public void init(){
protocolFactory = new TBinaryProtocol.Factory();
transportFactory = new TTransportFactory();
}
public void start(){
RPCDateService.Processor processor = new RPCDateService.Processor<RPCDateService.Iface>(rpcDateService);
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);
logger.info("thrift服務啓動成功,端口={}",port);
server.serve();
}catch (Exception e){
logger.error("thrift服務啓動失敗");
}
}
}
修改SpringApplication啓動類
內容如下:
package com.wl;
import com.wl.server.RPCThriftServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class ThriftDemoApplication {
private static RPCThriftServer rpcThriftServer;
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(ThriftDemoApplication.class, args);
try {
rpcThriftServer = context.getBean(RPCThriftServer.class);
rpcThriftServer.start();
}catch (Exception e){
e.printStackTrace();
}
}
}
在application.properties中添加配置
thrift.port=6666
thrift.minWorkerThreads=10
thrift.maxWorkerThreads=100
啓動Thrift服務端
結果如下:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.1.RELEASE)
2019-11-21 21:21:41.304 INFO 56960 --- [ main] com.wl.ThriftDemoApplication : Starting ThriftDemoApplication on D-NJ0202188 with PID 56960 (C:\Users\lei.wang\IdeaProjects\thrift_demo\target\classes started by lei.wang in C:\Users\lei.wang\IdeaProjects\thrift_demo)
2019-11-21 21:21:41.307 INFO 56960 --- [ main] com.wl.ThriftDemoApplication : No active profile set, falling back to default profiles: default
2019-11-21 21:21:41.752 INFO 56960 --- [ main] com.wl.ThriftDemoApplication : Started ThriftDemoApplication in 0.899 seconds (JVM running for 2.119)
2019-11-21 21:21:41.757 INFO 56960 --- [ main] com.wl.server.RPCThriftServer : thrift服務啓動成功,端口=6666
創建Thrift客戶端
採用sprint-Boot編寫服務端
創建spring-boot項目
在pom文件
中導入依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.wl</groupId>
<artifactId>ThriftAPI</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
編寫RPCThriftClient:用於發出RPC調用
創建client文件夾
,編寫RPCThriftClient.java
類和RPCThriftClientConfig.java
類。
RPCThriftClient.java
類內容如下:
package com.wl.thrift_client_demo.client;
import com.wl.thrift.api.RPCDateService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransportException;
public class RPCThriftClient {
private RPCDateService.Client client;
private TBinaryProtocol protocol;
private TSocket transport;
private String host;
private int port;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public void init() {
transport = new TSocket(host, port);
protocol = new TBinaryProtocol(transport);
client = new RPCDateService.Client(protocol);
}
public RPCDateService.Client getRPCThriftService() {
return client;
}
public void open() throws TTransportException {
transport.open();
}
public void close() {
transport.close();
}
}
RPCThriftClientConfig.java
類,內容如下:
package com.wl.thrift_client_demo.client;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RPCThriftClientConfig {
@Value("${thrift.host}")
private String host;
@Value("${thrift.port}")
private int port;
@Bean(initMethod = "init")
public RPCThriftClient rpcThriftClient(){
RPCThriftClient rpcThriftClient = new RPCThriftClient();
rpcThriftClient.setHost(host);
rpcThriftClient.setPort(port);
return rpcThriftClient;
}
}
編寫controller作爲調用入口
創建RPCThriftContoller.java
類
內容如下:
package com.wl.thrift_client_demo.controller;
import com.wl.thrift_client_demo.client.RPCThriftClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/index")
public class RPCThriftContoller {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private RPCThriftClient rpcThriftClient;
@RequestMapping(value = "/thrift",method = RequestMethod.GET)
public String thriftTest(HttpServletRequest request, HttpServletResponse response){
try {
rpcThriftClient.open();
return rpcThriftClient.getRPCThriftService().getDate("XX");
}catch (Exception e){
logger.error("RPC調用失敗",e);
return "error";
}finally {
rpcThriftClient.close();
}
}
}
修改SpringBootApplication啓動類
package com.wl.thrift_client_demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ThriftClientDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ThriftClientDemoApplication.class, args);
}
}
修改配置文件application.properties
thrift.host=localhost
thrift.port=6666
server.port=9999
啓動Thrift客戶端
啓動結果如下:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.1.RELEASE)
2019-11-21 23:51:42.556 INFO 107628 --- [ restartedMain] c.w.t.ThriftClientDemoApplication : Starting ThriftClientDemoApplication on D-NJ0202188 with PID 107628 (C:\Users\lei.wang\IdeaProjects\thrift_client_demo\target\classes started by lei.wang in C:\Users\lei.wang\IdeaProjects\thrift_client_demo)
2019-11-21 23:51:42.566 INFO 107628 --- [ restartedMain] c.w.t.ThriftClientDemoApplication : No active profile set, falling back to default profiles: default
2019-11-21 23:51:42.686 INFO 107628 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2019-11-21 23:51:42.687 INFO 107628 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2019-11-21 23:51:44.197 INFO 107628 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9999 (http)
2019-11-21 23:51:44.210 INFO 107628 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-11-21 23:51:44.211 INFO 107628 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.27]
2019-11-21 23:51:44.336 INFO 107628 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-11-21 23:51:44.336 INFO 107628 --- [ restartedMain] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1649 ms
2019-11-21 23:51:44.611 INFO 107628 --- [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-11-21 23:51:44.791 INFO 107628 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2019-11-21 23:51:44.854 INFO 107628 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9999 (http) with context path ''
2019-11-21 23:51:44.858 INFO 107628 --- [ restartedMain] c.w.t.ThriftClientDemoApplication : Started ThriftClientDemoApplication in 3.013 seconds (JVM running for 5.185)
Thrift通信測試
在瀏覽器輸入url:http://localhost:9999/index/thrift
頁面打印如下結果:
HelloXX 今天是2019年11月21日 星期四 23點53分
參考:
- https://juejin.im/post/5afa19bf51882542653995b7#heading-6
- https://blog.csdn.net/u010900754/article/details/80172671