【问题标题】:Is there an IPC transport implementation for Thrift ? or low latency SOA solutionsThrift 是否有 IPC 传输实现?或低延迟 SOA 解决方案
【发布时间】:2012-05-23 10:11:56
【问题描述】:

我想将 SOA 引入一个没有 TCP 通信开销的低延迟系统(即使在同一台机器上)。 Thirft 看起来很合适,因为我同时拥有 Java 和 php 进程。是否有用于 thrift 的 IPC 传输实现,或任何其他可以在这种情况下提供帮助的好主意?

【问题讨论】:

    标签: java php ipc soa thrift


    【解决方案1】:

    您可以使用 Thrift 序列化您的对象,然后使用您喜欢的 IPC 方法(命名管道、消息队列等)。 下面是一个使用管道的简单示例

    1. 我们有一个 Message 类型的对象,其中包含一些信息
    2. php 进程是消息的生产者
    3. Java 进程是消费者

    节俭模式

    struct Message {
      1: i32 uid,
      2: string information,
    }
    

    生成节俭资源

    thrift --gen java message.thrift
    thrift --gen php message.thrift
    

    PHP 生产者

    <?php
    $GLOBALS['THRIFT_ROOT'] = 'src';
    require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
    require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinarySerializer.php'; // this generates serialized string from our obect
    require_once $GLOBALS['THRIFT_ROOT'].'/packages/message/message_types.php'; //from generated thrift sources
    //create new message
    $message = new Message();
    $message->uid = '1';
    $message->information = 'Some info';
    var_dump($message);
    
    //serialize
    $serializer = new TBinarySerializer(); 
    $serialized_message = $serializer->serialize($message);
    var_dump($serialized_message);
    
    //write to a pipe
    if (pcntl_fork() == 0) {
    $namedPipe = '/tmp/pipe';
    if (! file_exists($namedPipe)) {
       posix_mkfifo($namedPipe, 0600);
    }
    
    $fifo = fopen($namedPipe, 'w');
    
    fwrite($fifo, $serialized_message);
    exit(0);
    }
    ?>
    

    Java 消费者

            //read from pipe
        FileInputStream fileInputStream = new FileInputStream(new File("/tmp/pipe"));
        int availableBytes = fileInputStream.available();
    
        byte[] b = new byte[availableBytes]; 
            fileInputStream.read(b , 0, availableBytes);
            //deserialize
        TDeserializer tDeserializer = new TDeserializer();
        Message deserMessage = new Message();
        tDeserializer.deserialize(deserMessage, b);
        System.out.println(deserMessage.getInformation());
        //prints "Some info"
    

    【讨论】:

    • 能否请您澄清您的评论“服务器方法路由”。
    • Thrift 提供的不仅仅是序列化,生成的代码允许您进行客户端调用,该调用将调用服务器上的远程过程。我宁愿避免自己做路由,即应该调用哪个方法。
    • Unix 管道是 1:1 连接(每个“服务器”只有一个客户端)。域套接字更像 Windows 命名管道,因为它们可以支持多个连接(客户端)。虽然上面的解决方案很巧妙,但它没有利用 Thrift 的强大功能及其分层架构。
    • 您的代码似乎假设您将从消息边界的管道中获取数据(我怀疑这在实践中会发生)。这只是为了简单的例子吗?
    【解决方案2】:

    See here 关于 Thrift C++ 库的跨平台管道传输。这应该可以直接移植到其他语言。如果你只需要支持*NIX,你可以使用TSocket已经支持的域套接字。只需将 (name) 而不是 (host, port) 传递给它的构造函数。

    【讨论】:

      猜你喜欢
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 2011-12-29
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      相关资源
      最近更新 更多