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

首先引用此链接作为参考

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

1.配置环境

使用maven


  <dependencies>
    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.9version>
      <scope>testscope>
    dependency>

    <dependency>
      <groupId>org.apache.thriftgroupId>
      <artifactId>libthriftartifactId>
      <version>0.8.0version>
    dependency>
    <dependency>
      <groupId>org.slf4jgroupId>
      <artifactId>slf4j-log4j12artifactId>
      <version>1.6.1version>
    dependency>
  dependencies>

  
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-pluginartifactId>
                <configuration>
                    <appendAssemblyId>falseappendAssemblyId>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependenciesdescriptorRef>
                    descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.yamm.ThriftServer.AdditionServermainClass>
                        manifest>
                    archive>
                configuration>
                <executions>
                    <execution>
                        <id>make-assemblyid>
                        <phase>packagephase>
                        <goals>
                            <goal>assemblygoal>
                        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
    Thrift java 基于阻塞IO的服务端多线程通信_第1张图片

  • 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.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();
        }

    }
}

编写客户端

Thrift java 基于阻塞IO的服务端多线程通信_第2张图片

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)。然后我们多线程多运行几次客户端,会发现服务端依次执行,所以可以确认服务端为多线程提供服务,一个阻塞会开启新线程。

结果实验

Thrift java 基于阻塞IO的服务端多线程通信_第3张图片
Thrift java 基于阻塞IO的服务端多线程通信_第4张图片

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

你可能感兴趣的:(RPC)