分布式服务框架学习笔记7.1 Thrift入门试用



Thrift是facebook开发,08年进入apache孵化器
官网地址 : https://thrift.apache.org

一、使用过程

1. 下载配置

新建Maven项目

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.whrsmart</groupId>
<artifactId>thrift-demo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>thrift-demo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.10.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>thrift-demo</finalName>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<version>3.0</version>
</configuration>
</plugin>
</plugins>
</build>
</project>

如果自己编译lib包

把下载的压缩包解压到X:盘,然后在X:\thrift-0.15.0\lib\java 目录下运行ant进行自动编译,会在X:\thrift-0.15.0\lib\java\build\ 目录下看到编译好的lib包:libthrift-0.15.0.jar

下载thrift-***.exe
​​​ https://thrift.apache.org/download​

2. thrift生成代码

在Thrift根目录 创建multiplication.thrift文件:

namespace java tutorial
namespace py tutorial

typedef i32 int // We can use typedef to get pretty names for the types we are using
service MultiplicationService
{
int multiply(1:int n1, 2:int n2),
}

把thrift-0.15.0.exe放到同一个目录下,运行:

thrift-0.15.0.exe -r --gen java multiplication.thrift

生成代码:
分布式服务框架学习笔记7.1 Thrift入门试用_apache

把生成的文件拷到项目里并新建类文件:
分布式服务框架学习笔记7.1 Thrift入门试用_分布式_02

MultiplicationClient

package test;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

import tutorial.MultiplicationService;

public class MultiplicationClient {
public static void main(String [] args) {


try {
TTransport transport;

transport = new TSocket(null, "localhost", 9090);
transport.open();

TProtocol protocol = new TBinaryProtocol(transport);
MultiplicationService.Client client = new MultiplicationService.Client(protocol);

perform(client);

transport.close();
} catch (TException x) {
x.printStackTrace();
}
}

private static void perform(MultiplicationService.Client client) throws TException
{

int product = client.multiply(3,5);
System.out.println("3*5=" + product);
}
}

MultiplicationHandler

package test;

import org.apache.thrift.TException;
import tutorial.MultiplicationService;

public class MultiplicationHandler implements MultiplicationService.Iface {

public int multiply(int n1, int n2) throws TException {
System.out.println("Multiply(" + n1 + "," + n2 + ")");
return n1 * n2;
}


}

MultiplicationServer

package test;

import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;

import tutorial.MultiplicationService;

public class MultiplicationServer {

public static MultiplicationHandler handler;

public static MultiplicationService.Processor processor;

public static void main(String [] args) {
try {
handler = new MultiplicationHandler();
processor = new MultiplicationService.Processor(handler);

Runnable simple = new Runnable() {
public void run() {
simple(processor);
}
};

new Thread(simple).start();
} catch (Exception x) {
x.printStackTrace();
}
}

public static void simple(MultiplicationService.Processor processor) {
try {
TServerTransport serverTransport = new TServerSocket(9090);
TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));

System.out.println("Starting the simple server...");
server.serve();
} catch (Exception e) {
e.printStackTrace();
}
}

}

其它问题处理

  • 在生成的MultiplicationService里,有些@Overide会提示不需要,要移除它们
  • 我这里生成的项目JDK版本不匹配,要调整一下这里:
    分布式服务框架学习笔记7.1 Thrift入门试用_框架_03

3. 测试运行

首先运行Server
分布式服务框架学习笔记7.1 Thrift入门试用_分布式_04

再运行Client
分布式服务框架学习笔记7.1 Thrift入门试用_apache_05

本文参考:
​​​ http://thrift-tutorial.readthedocs.io/en/latest/usage-example.html#a-simple-example-to-warm-up​

一些测试例子:
​​​ https://www.helplib.com/Java_API_Classes/article_70064​

二、ThinkPHP5 使用Thrift要点

1. 生成代码:

thrift -r --gen php tutorial.thrift

会生成gen-php/ ,把生成的文件放到Controller的某个目录
分布式服务框架学习笔记7.1 Thrift入门试用_apache_06
生成的 service文件把文件名改和文件里的类名一致。
然后给它的头加上命名空间:

namespace app\device\controller;

2. 把下载的thrift php库放到thinkphp的extend目录下:

分布式服务框架学习笔记7.1 Thrift入门试用_apache_07

3. 修改生成的client文件

new \

这样的代码里的\都删除。,开始的use 引用加上 \,如:

use \Thrift\Base\TBase;
use \Thrift\Type\TType;
use \Thrift\Type\TMessageType;
use \Thrift\Exception\TException;
use \Thrift\Exception\TProtocolException;
use \Thrift\Protocol\TProtocol;
use \Thrift\Protocol\TBinaryProtocolAccelerated;
use \Thrift\Exception\TApplicationException;

4. bridge负责调用thrift服务端,示例:

client

<?php
namespace app\device\controller;
use think\Controller;
use think\Request;
use app\index\controller\Common;


use \Thrift\ClassLoader\ThriftClassLoader;
use \Thrift\Protocol\TBinaryProtocol;
use \Thrift\Transport\TSocket;
use \Thrift\Transport\THttpClient;
use \Thrift\Transport\TBufferedTransport;
use \Thrift\Exception\TException;

class Bridge extends Common
{
public function add(){
try {

$socket = new TSocket('localhost', 9090);

$transport = new TBufferedTransport($socket, 1024, 1024);
$protocol = new TBinaryProtocol($transport);
$client = new MessageForwardsServiceClient($protocol);

$transport->open();

$client->myFunction();
$transport->close();

} catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}

}
}

参考网址:
​​​ http://thrift.apache.org/tutorial/php​