Thrift java 基于阻塞IO的服务端多线程通信

    xiaoxiao2021-04-14  82

    首先引用此链接作为参考

    此文章仅仅用于保存,以免遗忘。

    1.配置环境

    使用maven

    <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.8.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.1</version> </dependency> </dependencies> <!--这里用于打包测试插件--> <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <appendAssemblyId>false</appendAssemblyId> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.yamm.ThriftServer.AdditionServer</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>assembly</goal> </goals> </execution> </executions> </plugin> </plugins> </build>

    2.基本数据类型

    3.1 数据类型

    基本类型:

    bool: 布尔值,true 或 false,对应 Java 的 Boolean

    byte: 8 位有符号整数,对应 Java 的 byte

    i16:16 位有符号整数,对应 Java 的 short

    i32:32 位有符号整数,对应 Java 的 int

    i64:64 位有符号整数,对应 Java 的 long

    double:64 位浮点数,对应 Java 的 double

    string:utf-8编码的字符串,对应 Java 的 String

    结构体类型:

    Struct: 定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean

    容器类型:

    list:对应 Java 的 ArrayList

    set: 对应 Java 的 HashSet

    map: 对应 Java 的 HashMap

    异常类型:

    exception:对应 Java 的 Exception

    服务类型:

    service:对应服务的类

    枚举类型:

    3.例子

    1.首先下载thrift 0.8.0.exe(如果是linux,那么需要去官网下载tar.gz版本编译安装)

    2.然后按照上面的格式写出自己的.thrift文件,我这里是test.thrift

    namespace java com.yamm.ThriftServer // defines the namespace typedef i32 int //typedefs to get convenient names for your types service AdditionService { // defines the service to add two numbers int add(1:int n1, 2:int n2), //defines a method string getFile(1:string n1,2:string n2), }

    3.输入thrift.exe –gen java test.thrift就会在本地文件生成一个指定语言的客户端服务端文件。复制粘贴到java maven项目中.生成的文件内容较多–>我这里生成为AdditionService.java

    4.然后创建一个方法,实现此接口类:

    package com.yamm.ThriftServer; import org.apache.thrift.TException; public class AdditionServiceImp implements AdditionService.Iface{ public int add(int n1, int n2) throws TException { System.out.println("调用成功!"); while(true){ if(n1<0)break; } return n1+n2; } }

    编写服务端

    创建服务端类,这里服务端采用阻塞IO多线程方式:

    package com.yamm.ThriftServer; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TThreadPoolServer; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TTransportException; /* * Thrift经典的阻塞IO的多线程服务端 */ public class AdditionServer { public static final int SERVER_PORT=7777;//端口号传输 public static void main(String[] args) { System.out.println("start....."); try { TProcessor tprocessor = new AdditionService.Processor<AdditionService.Iface>(new AdditionServiceImp()); //阻塞IO TServerSocket transport = new TServerSocket(SERVER_PORT); //多线程服务模型 TThreadPoolServer.Args tnb_args = new TThreadPoolServer.Args(transport);//设置服务类型,TNonblocking是处理多线程比较好的 tnb_args.processor(tprocessor); // tnb_args.transportFactory(new TFramedTransport.Factory());使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式,二进制传输 //块传输协议,二进制协议 tnb_args.protocolFactory(new TCompactProtocol.Factory()); //start server TServer server = new TThreadPoolServer(tnb_args); System.out.println("start success port is : "+SERVER_PORT); server.serve(); } catch (TTransportException e) { e.printStackTrace(); } } }

    编写客户端

    1.你需要将之前生成的代码再拷贝一份到客户端处,保持服务端客户端的接口类一致 2.创建客户端类,调用服务端方法

    package com.yamm.Thrift_Client; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; public class AdditionClient { /* * 客户端 * * 定义地址 端口 连接超时时间 * */ private static final String SERVER_IP = "localhost"; private static final int PORT = 7777; private static final int TIME_OUT = 300000; public static void main(String[] args) { try{ //获取会话 TTransport transport = new TSocket(SERVER_IP,PORT,TIME_OUT); //选择会话协议,注意要和服务端一致,不然无法通信 TProtocol protocol = new TCompactProtocol(transport); AdditionService.Client client = new AdditionService.Client(protocol); //打开会话 transport.open(); //调用服务端方法,并返回 System.out.println(client.add(2, 3)); transport.close(); }catch (Exception e){ System.out.println(e); } } }

    在这里我们会发现,客户端调用时会阻塞,因为我在方法里面放置了while(true)。然后我们多线程多运行几次客户端,会发现服务端依次执行,所以可以确认服务端为多线程提供服务,一个阻塞会开启新线程。

    结果实验

    可以看到,客户端调用被阻塞,服务端开启新线程给客户端

    转载请注明原文地址: https://ju.6miu.com/read-670431.html

    最新回复(0)