RPC快速入门学习和java演示

2016-10-10 10:17:06来源:oschina作者:钟声已经敲响人点击

一.什么是RPC?

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。


RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

二.什么是Thrift?

hrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。


thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。

三.下载,安装,配置Thrift

1.下载:


下载地址:http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.3/thrift-0.9.3.tar.gz (目前最新0.9.3)


2.安装


安装有2种方法,都可以。


第一种:

1.安装boost库


sudo apt-get install libboost-dev libboost-dbg libboost-doc bcp libboost-*


2.安装其他相关工具包


sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev ant


如果需要支持java,需要安装jdk,配置java环境变量。


4.解压文件,进入目录thrift-0.8.0安装


./configure--with-cpp--with-boost--without-python--without-csharp --with-java --without-erlang --without-perl --with-php --without-php_extension --without-ruby --without-haskell--without-go


make


sudo make install


要支持java,需要编译生成jar包,到lib/java目录下,执行ant命令。将在lib/java/build目录下生成libthrift-0.9.3.jar和libthrift-0.9.3-javadoc.jar。编译过程中,可能出错,需要检查lib/java/build/tools/maven-ant-tasks-2.1.3.jar是否正确下载。


5.测试:


thrift -version


安装正确会出现Thrift version 0.9.3


或者用thrift自带的测试样例


进入thrift安装的tutorial文件夹,shared.thrift和tutorial.thrift是接口定义文件。


thrift -r --gen javatutorial.thrift


thirft -r --gen cpptutorial.thrift


执行这两条命令可以生成gen-java和gen-cpp两个文件夹,这些是thrift编译器自动生成的代码。

第二种:


官网教程:http://thrift.apache.org/docs/BuildingFromSource


Building from source

FirstmakesureyoursystemmeetsallnecessaryApache Thrift Requirements


Ifyouarebuildingfromthefirsttimeoutofthesourcerepository,youwillneedtogeneratetheconfigurescripts. (Thisisnotnecessaryifyoudownloadedareleasedtarball.)Fromthetopdirectory,do:


./bootstrap.sh

Once the configure scripts are generated, thrift can be configured. From the top directory, do:


./configure

Disable a language:


./configure --without-java

You may need to specify the location of the boost files explicitly. If you installed boost in /usr/local, you would run configure as follows:


./configure --with-boost=/usr/local

If you want to override the logic of the detection of the Java SDK, use the JAVAC environment variable:


./configure JAVAC=/usb/bin/javac

Note that by default the thrift C++ library is typically built with debugging symbols included. If you want to customize these options you should use the CXXFLAGS option in configure, as such:


./configure CXXFLAGS='-g -O2'
./configure CFLAGS='-g -O2'
./configure CPPFLAGS='-DDEBUG_MY_FEATURE'

To see other configuration options run


./configure --help

Once you have run configure you can build Thrift via make:


make

and run the test suite:


make check

and the cross language test suite:


sh test/test.sh

Issues while compiling

"compiler/cpp/thriftl.cc:2190: undefined reference to `yywrap'"

you need to install theFlex library(See alsoApache Thrift Requirements) and re-run the configuration script.


mv: cannot stat "'.deps/TBinaryProtocol.Tpo': No such file or directory" while building the Thrift Runtime Library

Re-reun configure with

--enable-libtool-lock

or by turning off parallel make by placing.NOTPARALLEL:in lib/cpp/Makefile or

make -j 1

Although the thrift compiler build appears to be compatible with parallel make without libtool lock, the thrift runtime build is not.

Installing

From the top directory, become superuser and do:


make install

Note that some language packages must be installed manually using build tools better suited to those languages (this applies to Java, Ruby, PHP).


Look for the README file in thelib//folder for more details on the installation of each language library package.

总结下来,第1步,先解压thrift-0.9.3.tar.gz,解压命令:


tar -xvf thrift-0.9.3.tar.gz

第2步,输入以下命令:


$cd thrift-0.9.3
$./configure
$make
#sudo make install

关于配置的问题可以查看命令:


./configure --help

可以关闭你不熟悉的语言,因为thrift支持的语言非常多,可以关闭一些用不到的,如python,gt4等;


关闭命令为:


./configure --without-qt4

在install的过程中如果报一些test方面的error可以忽略.


上面的步骤走完以后,可以在任意一个目录下输入如下命令进行测试:


~/workspace$ thrift -version
Thrift version 0.9.3 四.Thrift基本概念

和c语言很相似,但又有很大区别。也许正因为它什么都不是,它才有可能什么都是。


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:对应服务的类

2.服务端编码基本步骤:

实现服务处理接口impl
创建TProcessor
创建TServerTransport
创建TProtocol
创建TServer
启动Server

3.客户端编码基本步骤:

创建Transport
创建TProtocol
基于TTransport和TProtocol创建Client
调用Client的相应方法

4.数据传输协议

TBinaryProtocol : 二进制格式.
TCompactProtocol : 压缩格式
TJSONProtocol:JSON格式
TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

tips:客户端和服务端的协议要一致

五.Java实例

1.引入jar包


我这里用到的是maven进行管理jar包的,所以首先新建一个maven项目,然后在pom.xml中添加如下内容:



org.apache.thrift
libthrift
0.9.3


org.slf4j
slf4j-log4j12
1.5.8

2.创建Thrift文件


namespace java com.amos.thrift.demo
serviceHelloWorldService {
string sayHello(1:string username)
}

3.生成java文件:


thrift -r -gen java demoHello.thrift

文件目录如下:


tree
.
├── demoHello.thrift
└── gen-java
└── com
└── amos
└── thrift
└── demo
└── HelloWorldService.java

把生成的HelloWorldService.java文件拷贝到项目中去.


package com.amos;
public class HelloWorldImpl implements HelloWorldService.Iface {
public HelloWorldImpl() {
}
@Override
public String sayHello(String username) {
return "Hi," + username + " ,Welcome to the thrift's world !";
}
}

5.TSimpleServer服务端


简单的单线程服务模型,一般用于测试。


编写服务端server代码:HelloServerDemo.java


package com.amos;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;public class HelloServerDemo {
public static final int SERVER_PORT = 8090;
/**
* @param args
*/
public static void main(String[] args) {
HelloServerDemo server = new HelloServerDemo();
server.startServer();
}
public void startServer() {
try {
System.out.println("HelloWorld TSimpleServer start ....");
// TProcessor tprocessor = new HelloWorldService.Processor(newHelloWorldImpl());
HelloWorldService.Processor tprocessor = new HelloWorldService.Processor(new HelloWorldImpl());
// 简单的单线程服务模型,一般用于测试
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
// tArgs.protocolFactory(new TBinaryProtocol.Factory());
tArgs.protocolFactory(new TCompactProtocol.Factory());
// tArgs.protocolFactory(new TJSONProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
} catch (Exception e) {
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
}

6.编写客户端代码


package com.amos;import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;public class HelloClientDemo {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 8090;
public static final int TIMEOUT = 30000;
/**
* @param args
*/
public static void main(String[] args) {
HelloClientDemo client = new HelloClientDemo();
client.startClient("amosli");
}
/**
* @param userName
*/
public void startClient(String userName) {
TTransport transport = null;
try {
transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
// 协议要和服务端一致
// TProtocol protocol = new TBinaryProtocol(transport);
TProtocol protocol = new TCompactProtocol(transport);
// TProtocol protocol = new TJSONProtocol(transport);
HelloWorldService.Client client = new HelloWorldService.Client(
protocol);
transport.open();
String result = client.sayHello(userName);
System.out.println("Thrift client result =: " + result);
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
} finally {
if (null != transport) {
transport.close();
}
}
}
}

项目最终结构图:


7.最终运行效果


服务端:



客户端:


参考:


1.http://baike.baidu.com/view/1698865.htm?fr=aladdin


2.http://thrift.apache.org/docs/BuildingFromSource


3.http://www.cnblogs.com/amosli/p/3906177.html

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台