Thrift服务(三):使用实战

本文详细介绍了如何在Windows环境下使用IntelliJ IDEA和Thrift 0.11.0构建Thrift服务端和客户端。通过创建Thrift项目,编译Thrift文件并打包成jar,接着开发Thrift服务端,包括创建Spring Boot项目、实现Thrift API接口、编写服务器端代码并启动。同时,还展示了如何创建Thrift客户端,完成RPC调用,最后进行了通信测试并展示成功结果。

实战环境

  • 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.youkuaiyun.com/u010900754/article/details/80172671
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值