`
一条路一个人
  • 浏览: 26261 次
  • 性别: Icon_minigender_1
  • 来自: 定州市
社区版块
存档分类
最新评论

Thrift初步了解

阅读更多

Thrift是一个可伸缩的跨语言的服务开发框架,对它的介绍就不google再复制了。
当我们在做web开发时,前端可能采用php,python,ruby等脚本语言做用户的交互页面,那业务和数据库的部分不少就用Java来开发了,毕竟做Java开发的程序员的数量还是占大多数的。这时,我们网站或系统的架构就可以页面用php写,业务程序用Java来写(对web开发都熟悉的mvc来说,就是把controller层和service、dao层分开,用不同的语言来写),那不同语言之间的数据交互怎么实现呢(php如何调用java的一个service的方法)?webservice,thrift,avro等框架和技术就可以拿来使用了~
好,直接写demo示例(thrift所用版本为0.9.1):


一、Java
thrift接口定义文件:UserService.thrift

namespace php tService
namespace java tService

service UserService {
    string getUserNameById(1:i32 userId);
}

 

server代码:ServerDemo.java

public class ServerDemo {
    public static void main(String[] args) {
        try {
            UserService.Processor processor = new UserService.Processor(new UserServiceImpl());
            TServerTransport transport = new TServerSocket(9090);
            TServer server = new TSimpleServer(new TServer.Args(transport).processor(processor));
            System.out.println("Starting the simple server...");
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        }
    }
}

 

client代码:ClientDemo.java

public class ClientDemo {
    public static void main(String[] args) {
        try {
            TTransport transport = new TSocket("localhost", 9090);
            TProtocol protocol = new TBinaryProtocol(transport);
            UserService.Client client = new UserService.Client(protocol);
            transport.open();
            System.out.println(client.getUserNameById(24));
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

定义的thrift接口文件,通过`thrift --gen java UserService.thrift`就可以得到java的接口类,在windows下运行“thrift.exe"可执行文件。thrift的安装文件,到官网下载然后安装。

在下载的thrift-0.9.1.tar.gz包下的tutorial文件夹下有各种常用语言的demo例子,拿来学习是很不错的资料。在java的例子中除了SimpleServer的例子还有一个secure的例子。

 

二、PHP

client代码:ClientDemo.php

<?php
error_reporting(E_ALL);

require_once __DIR__ . "/thrift/lib/Thrift/ClassLoader/ThriftClassLoader.php";
use Thrift\ClassLoader\ThriftClassLoader;

$GEN_DIR = realpath(dirname(__FILE__) . "/gen-php");

$loader = new ThriftClassLoader();
$loader->registerNamespace("Thrift", __DIR__ . "/thrift/lib");
$loader->registerDefinition("tService", $GEN_DIR);
$loader->register();

use Thrift\Transport\TSocket;
use Thrift\Transport\TBufferedTransport;
use Thrift\Protocol\TBinaryProtocol;

try {
    $socket = new TSocket('localhost', 9090);
    $transport = new TBufferedTransport($socket);
    $protocol = new TBinaryProtocol($transport);
    $client = new \tService\UserServiceClient($protocol);

    $transport->open();

    $userName = $client->getUserNameById(24);
    echo $userName;
    $transport->close();
} catch (Exception $e) {
    echo $e->getMessage();
}

 server端的代码,在thrift的tutorial中有一个例子,但是生成的php接口类文件中没有“UserServiceProcessor”类,因为默认执行`thrift --gen php UserService.thrift`生成的php文件中是不包含server端的实现的,要使用php写server程序,需添加参数":server",执行`thrift --gen php:server UserService.thrift`命令生产的php接口类中才会有server的实现。不过看server的代码,并是用到socket的类,所以php的server是有些特殊的,它需要apache的支持。

 

php server代码:ServerDemo.php

<?php
error_reporting(E_ALL);

require_once __DIR__ . '/thrift/lib/Thrift/ClassLoader/ThriftClassLoader.php';

use Thrift\ClassLoader\ThriftClassLoader;

$GEN_DIR = realpath(dirname(__FILE__)) . '/gen-php';

$loader = new ThriftClassLoader();
$loader->registerNamespace('Thrift', __DIR__ . '/thrift/lib');
$loader->registerDefinition("tService", $GEN_DIR);
$loader->register();

use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TPhpStream;
use Thrift\Transport\TBufferedTransport;

class UserServiceHandler implements \tService\UserServiceIf
{
    public function getUserNameById($userId)
    {
        return "hello, user(id:" . $userId . ")";;
    }
}
header('Content-Type', 'application/x-thrift');
if (php_sapi_name() == 'cli') {
    echo "\r\n";
}

$userService = new UserServiceHandler();
$processor = new \tService\UserServiceProcessor($userService);

$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
$protocol = new TBinaryProtocol($transport, true, true);

$transport->open();
$processor->process($protocol, $protocol);
$transport->close();

 把程序包放到apache配置的web目录,我本机环境为ubuntu12.04,所以把项目拷贝到"/var/www/“目录,ServerDemo.php在项目包ThriftDemo根目录下,所以client端的代码要修改为:

 

<?php
error_reporting(E_ALL);

require_once __DIR__ . "/thrift/lib/Thrift/ClassLoader/ThriftClassLoader.php";
use Thrift\ClassLoader\ThriftClassLoader;

$GEN_DIR = realpath(dirname(__FILE__) . "/gen-php");

$loader = new ThriftClassLoader();
$loader->registerNamespace("Thrift", __DIR__ . "/thrift/lib");
$loader->registerDefinition("tService", $GEN_DIR);
$loader->register();

use Thrift\Transport\TSocket;
use Thrift\Transport\TBufferedTransport;
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\THttpClient;

try {
    $socket = new THttpClient('localhost', 80, '/ThriftDemo/ServerDemo.php');
    $transport = new TBufferedTransport($socket);
    $protocol = new TBinaryProtocol($transport);
    $client = new \tService\UserServiceClient($protocol);

    $transport->open();
    $userName = $client->getUserNameById(24);
    echo $userName;
    $transport->close();
} catch (Exception $e) {
    echo $e->getMessage();
}

 这个时候,运行client的脚本,就可以访问php的thrift server实现类了。第一个的client可以访问java的server,所以php的server不是通过`php ServerDemo.php`来运行脚本的,client端是通过访问apache下的server脚本文件调用服务的。(php的server比java和ruby、python、perl等要繁琐一些,估计也很少用php写thrift的服务端代码)

 

好的,下个语言!

 

三、Ruby

server代码:server_demo.rb

require '../lib/thrift'
require '../thrift-demo/gen-rb/user_service'

class UserServiceHandler
  def getUserNameById(userId)
      return "hello, user(id: #{userId})"
  end
end

handler = UserServiceHandler.new()
processor = UserService::Processor.new(handler)
transport = Thrift::ServerSocket.new('localhost', 9090)
transportFactory = Thrift::BufferedTransportFactory.new()
server = Thrift::SimpleServer.new(processor, transport, transportFactory)

puts "Starting the server..."
server.serve()

 client代码:client_demo.rb

require '../lib/thrift'
require '../thrift-demo/gen-rb/user_service'

begin
  transport = Thrift::BufferedTransport.new(Thrift::Socket.new("localhost", 9090))
  protocol = Thrift::BinaryProtocol.new(transport)
  client = UserService::Client.new(protocol)

  transport.open()
  puts client.getUserNameById(24)
  transport.close()
rescue Thrift::Exception => tx
  puts 'Thrift.Exception: ', tx.message
end

 ruby还是很简洁的,执行`thrift --gen rb UserService.thrift`生成ruby的接口类文件,然后依次运行server脚本和client脚本。

 

四、Python

server代码:ServerDemo.py

__author__ = 'petric'

import sys
sys.path.append('./gen-py')

from UserService import UserService

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

class UserServiceHandler:
    def getUserNameById(self, id):
        return "hello, user(id:%d)" %id

handler = UserServiceHandler()
processor = UserService.Processor(handler)
transport = TSocket.TServerSocket(port=9090)
tFactory = TTransport.TBufferedTransportFactory()
pFactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TSimpleServer(processor, transport, tFactory, pFactory)

print "starting py server..."
server.serve()

 

client代码:ClientDemo.py

__author__ = 'petric'

import sys
sys.path.append('./gen-py')

from UserService import UserService

from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

try:
    transport = TSocket.TSocket('localhost', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = UserService.Client(protocol)
    
    transport.open()
    print client.getUserNameById(2)
    transport.close()
except Thrift.TException, tx:
    print '%s' % (tx.message)

执行`thrift --gen py UserService.thrift`生成ruby的接口类文件,然后依次运行server脚本和client脚本。

 

但是,这里面还有一个问题,先说java,在pom.xml中加入thrift的依赖配置就可以,这就不说了;php中,在下载的thrift-0.9.1.tar.gz包下的lib目录下有各个语言的thrift的工具包,php下有lib工具包,ruby下也有lib工具包,拿到自己的项目中就行;不过,python和php和ruby不同,它的lib目录下面没有,不过多了个“setup.py“文件,哦,对用python做开发的同学就不用说了,不过对想玩一玩python例子的其它程序员-google一下也就清楚了,执行`sudo python setup.py install`就可以给python添加thrift支持包了。

好,再写一个例子,就当自己也了解一下其它语言的特点了

 

五、Perl

对perl不是很了解,工作中也还没有用到过,先写client试一试

client代码:ClientDemo.pl

#!/usr/bin/env perl

use strict;
use warnings;

use lib '../lib';
use lib '../gen-perl';

use Thrift;
use Thrift::BinaryProtocol;
use Thrift::Socket;
use Thrift::BufferedTransport;

use UserService;

my $socket = new Thrift::Socket('localhost', 9090);
my $transport = new Thrift::BufferedTransport($socket, 1024, 1024);
my $protocol = new Thrift::BinaryProtocol($transport);
my $client = new UserServiceClient($protocol);

eval{
    $transport->open();

    print 'connection open...';
    my $name = $client->getUserNameById(3);
    print "$name\n";

    $transport->close();
}; if($@){
    warn(Dumper($@));
}

 访问java,python,ruby的server端没有问题,

server代码:ServerDemo.pl

#!/usr/bin/env perl

use strict;
use warnings;

use lib '../lib';
use lib '../gen-perl';
use Thrift;
use Thrift::Socket;
use Thrift::Server;
use UserService;

package UserServiceHandler;
use base qw(UserServiceIf);

sub new {
    my $classname = shift;
    my $self      = {};
    return bless($self,$classname);
}

sub getUserNameById
{
    my($self, $userId) = @_;
    return ("hello, user(id:$userId)\n");
}


eval {
    my $handler = new UserServiceHandler;
    my $processor = new UserServiceProcessor($handler);
    my $serversocket = new Thrift::ServerSocket(9090);
    my $forkingserver = new Thrift::ForkingServer($processor, $serversocket);
    print "Starting perl server...\n";
    $forkingserver->serve();
}; if($@) {
    if ($@ =~ m/TException/ and exists $@->{message}) {
        my $message = $@->{message};
        my $code    = $@->{code};
        my $out     = $code . ':' . $message;
        die $out;
    } else {
        die $@;
    }
}

 我的系统自带的perl的版本是5.14.2,不过和python差不多也得安装一下环境,但不是python那样安装python的thrift工具包,perl也是把它的lib目录拷贝到自己的项目就可以。运行脚本报了一些错误,一些类啊文件什么的好像没有,google一下,下载了Class-Accessor-0.34.tar.gz,然后安装上(解压,make install),又执行`sudo apt-get install libbit-vector-perl`,把perl的lib下的文件也跑了一下`perl Makefile.PL`和 `make install`。这样perl脚本的server和client都可以跑了,测试正常输出结果。

 

六、js

在tutorial中还有js的例子,js不能访问通常的server的,都是通过socket创建的,只能通过ajax访问通过JSON protocol 和 HTTP transport开启的服务,照着tutorial的例子写了一遍,server用java写的,用到apache的httpcomponents包,启动一个http的server,指定自己的html(包含js的client端)文件所在的目录为webapp,通过设定的端口访问自己的html页面,如“http://localhost:8088/Client_Html.html“,这样js就可以访问thrift的接口服务了!哇~,这个例子最麻烦了,代码就不拷贝过来了。由于js的ajax通常情况下是跨不了域的,所以js的client端和server端需在一个域名下,例子中使用的HttpService相当与模拟了一个web server(apache,tomcat等),那js请求的是一个url,如“/UserService/getUserNameById“,server端遇到该url会通过Processor调用实现类返回结果,其它的文件url就直接返回文件了。简单点就可以理解为:js要想访问thrift的service服务需通过web server这样一个中间层。

分享到:
评论

相关推荐

    thrift初步了解

    不要认为thrift能在*.thrift文件中定义调度之类的工作 thrift通过IDL(接口描述语言)来生成各种语言需要的接口代码。 执行thrift文件命令: java:thrift-0.9.1.exe --gen java test.thrift java:thrift-0.9.1.exe ...

    thrift实现http协议案例

    首先,让我们了解一下Thrift的基本工作原理。Thrift基于接口描述语言(IDL),开发者可以在IDL文件中定义服务接口和数据类型。例如: ```thrift service MyService { string echo(1: string msg) } ``` 这个服务...

    使用wireshark抓取thrift协议接口调用

    1. **了解Thrift协议** Thrift基于二进制协议,它定义了服务接口、数据结构(如结构体、枚举)和通信机制。Thrift文件(.thrift)是接口定义语言(IDL),用于描述服务和数据类型。生成的代码支持多种编程语言,如...

    thrift-0.13.0.zip

    在使用thrift-0.13.0.zip之前,你需要先了解Thrift的基本概念和工作流程: 1. **Thrift IDL**:Thrift IDL文件以`.thrift`为扩展名,用于定义服务、结构体、枚举、常量等。这些定义会被Thrift编译器转换为各种目标...

    thrift样例操作实例

    在"thrift样例操作实例"中,我们可以了解到Thrift的基本用法和工作流程。 首先,`Thrift简介.docx`可能是关于Thrift的入门文档,介绍了Thrift的概念、特点和用途。Thrift的主要特点包括高效、类型安全以及支持多种...

    thrift安装

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年开源,现在由Apache软件基金会维护。它的主要功能是定义数据结构和服务接口,然后自动生成多种编程语言的代码,实现这些接口,使得不同语言之间可以进行...

    Thrift-java学习小结

    Thrift是Facebook开源的一款高性能、跨语言的服务框架,它的设计目标是高效地在不同编程语言之间进行通信。本文将基于Thrift的Java实现,总结学习过程中的一些关键知识点,旨在帮助理解Thrift的工作原理以及如何在...

    thrift_sasl-0.3.0.tar.gz

    在深入探讨Thrift SASL 0.3.0 的知识点之前,我们先来了解一下Thrift和SASL的基本概念。 Thrift 是由Facebook开发的一种软件框架,旨在解决大规模分布式系统中的通信问题。它允许程序员在不同的编程语言之间创建和...

    qt 实现thrift的一个例子

    在IT行业中,Thrift是一种高性能、可扩展的跨语言服务开发框架,由Facebook开源,用于构建分布式服务。它通过定义一种中间表示(IDL,接口定义语言)来描述服务,然后自动生成不同编程语言的代码,使得不同语言之间...

    Windows下QT使用Thrift的样例

    总之,这个样例项目提供了一个很好的起点,帮助开发者了解如何在Windows上用QT与Thrift协同工作,同时利用Boost库增强功能。通过实践,你可以更好地理解和掌握这些技术,为你的项目带来高效、跨平台的解决方案。

    thrift官方代码+与dubbo集成支持原生thrift协议

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年设计并发布,其目的是为了在各种编程语言之间提供高效的、轻量级的通信机制。Thrift通过定义一种中间表示(IDL,Interface Definition Language)来描述...

    netty+thrift高并发高性能

    ### Netty+Thrift 实现高并发高性能的关键技术解析 #### 一、引言 在当前互联网技术高速发展的背景下,高性能、高并发的服务框架成为众多企业和开发者追求的目标。Netty作为一款高性能、异步事件驱动的网络应用...

    maven-thrift-server

    【 Maven-Thrift-Server:构建Thrift服务的Maven实践】 在软件开发中,Thrift是一种高效的跨语言服务开发框架,由Facebook开发并开源。它允许定义数据类型和服务接口,然后自动生成各种编程语言的代码,使得不同...

    C++(Qt)下的thrift的使用示例

    而Thrift则是一种开源的软件框架,用于构建可伸缩的服务,它支持多种编程语言,包括C++,并且允许不同语言之间进行高效的数据交换。在这个“C++(Qt)下的thrift的使用示例”中,我们将探讨如何在Qt项目中集成和使用...

    thrift-0.10.0.exe

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

    maven ant thrift0.9.0

    标题 "maven ant thrift0.9.0" 涉及到的是三个关键的软件开发工具:Thrift 0.9.0、Apache Ant 和 Apache ...在实际操作中,开发者需要了解每个工具的用法,编写或修改相应的构建脚本,以便在项目中顺利集成Thrift服务。

    thrift-delphi实例

    Thrift Delphi实例详解 Thrift,全称为“Transportation Layer Security”,是由Facebook开源的一款高性能、跨语言的服务框架。它最初设计的目的是解决大规模分布式系统中的数据通信问题,通过定义一种中间表示...

    thrift环境配置方法

    Thrift 环境配置方法 Thrift 是一个跨语言的 RPC 框架,由 Facebook 开发,用于建立高性能的服务之间的远程过程调用。为了使用 Thrift,需要配置好相关的环境,这篇文章将介绍 Thrift 环境配置的方法。 Thrift ...

    mac thrift 0.9.3安装

    mac 想安装低版本thrift 0.9.3太难了,高版本比较简单 直接执行 brew install thrift.rb 即可安装

    thrift环境搭建(内附thrift运行环境可执行程序、搭建说明文本)

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年创建,并于2008年贡献给了Apache基金会。它通过定义一种中间语言(IDL,Interface Definition Language)来描述服务接口,允许开发者在不同的编程语言之间...

Global site tag (gtag.js) - Google Analytics