Thrift基本应用

https://www.jianshu.com/p/10b7cf0a384e
https://thrift.apache.org/tutorial/java
https://www.jianshu.com/p/397d7b278e65

Thrift创建步骤

  • 服务端编码基本步骤
    • 实现服务处理接口impl
    • 创建TProcessor
    • 创建TServerTransport
    • 创建TProtocol
    • 创建TServer
    • 启动Server
  • 客户端编码基本步骤
    • 创建Transport
    • 创建TProtocol
    • 基于TTransport和TProtocol创建Client
    • 调用Client的相应方法

Thrift服务类型

  • Thrift的Server类型有TSimpleServer、TNonblockingServer、THsHaServer、TThreadedSelectorServer、TThreadPoolServer
  • TSimpleServer是单线程阻塞IO的方式,仅用于demo
  • TNonblockingServer是单线程非阻塞IO的方式,通过java.nio.channels.Selector的select()接收连接请求,但是处理消息仍然是单线程,吞吐量有限不可用于生产
  • THsHaServer使用一个单独的线程处理IO,一个独立的worker线程池处理消息, 可以并行处理所有请求
  • TThreadPoolServer使用一个专用连接接收connection,一旦接收到请求就会放入ThreadPoolExecutor中的一个worker里处理,当请求处理完毕该worker释放并回到线程池中,可以配置线程最大值,当达到线程最大值时请求会被阻塞。TThreadPoolServer性能表现优异,代价是并发高时会创建大量线程
  • TThreadedSelectorServer是thrift 0.8引入的实现,处理IO也使用了线程池,比THsHaServer有更高的吞吐量和更低的时延,与TThreadPoolServer比性能相近且能应对网络IO较多的情况
  • 对于客户端较少的情况,TThreadPoolServer也有优异的性能表现,但是考虑到未来SOA可能的高并发,决定采用TThreadedSelectorServer

实现过程

  • 创建thrift文件
    thrift文件的功能是提供KV查询服务,接口中定义了四个方法如下,分别按照单key,多key查询value;也可以按照单key,多key设置value值
namespace java sc.leveldb
service KvService{
    string getValue(1: string key),
    list<string> mgetValues(1: list<string> keys),
    bool setValue(1: string key, 2: string value),
    bool msetValues(1: list<string> keys, 2: list<string> values)
}
  • 将thrift描述文件转成java接口
    在Mac上执行命令如下
    /usr/local/Cellar/thrift/0.10.0/bin/thrift -r –gen java ./kv.thrift
    将生成的KvService.java文件拷贝到相应的java工程中
  • 实现KvService接口
package sc.leveldb;
import org.apache.thrift.TException;

import java.util.ArrayList;
import java.util.List;

public class KvImpl implements KvService.Iface  {
    public KvImpl(){};
    @Override
    public String getValue(String key) throws TException{
        return key + ":super clocks";
    }
    @Override
    public java.util.List<String> mgetValues(java.util.List<String> keys) throws TException{
        List<String> r = new ArrayList<String>();
        for(int i = 0; i < keys.size(); i++){
            r.add(keys.get(i) + ":super clocks");
        }
        return null;
    }
    @Override
    public boolean setValue(String key, String value) throws TException{
        System.out.print(key + ":" + value + "\n");
        return true;
    }
    @Override
    public boolean msetValues(List<String> keys, java.util.List<String> values) throws TException{
        for(int i = 0; i < keys.size(); i++){
            System.out.print(keys.get(i) + ":" + values.get(i) + "\n");
        }
        return true;
    }
}
  • 定义服务端启动程序
    实现TSimpleServer和TThreadedSelectorServer
package sc.leveldb;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.transport.*;
/**
 * Created by zhongchao03 on 2018/1/20.
 */
public class ThriftServer {
    public void simpleServerStart(){
        TServerSocket serverTransport = null;
        try {
            System.out.println("Starting Thrift Server......");
            TProcessor processor = new KvService.Processor<KvService.Iface>(new KvImpl());
            serverTransport = new TServerSocket(8191);
            TTransportFactory transportFactory = new TFramedTransport.Factory();
            Factory factory = new TBinaryProtocol.Factory();
            TServer.Args tArgs = new TServer.Args(serverTransport);
            tArgs.protocolFactory(factory);
            tArgs.transportFactory(transportFactory);
            tArgs.processor(processor);
            // 简单的单线程服务模型,一般用于测试
            TServer server = new TSimpleServer(tArgs);
            server.serve();
        } catch (TTransportException e) {
            System.out.println("Starting Thrift Server......Error!!!");
            e.printStackTrace();
        } finally {
            serverTransport.close();
        }
    }

    public void threadedSelectorServerStart(){
        try {
            System.out.println("HelloWorld TNonblockingServer start ....");
            TNonblockingServerTransport serverSocket=new TNonblockingServerSocket(8888);
            TThreadedSelectorServer.Args serverParams=new TThreadedSelectorServer.Args(serverSocket);
            serverParams.protocolFactory(new TBinaryProtocol.Factory());
            serverParams.processor(new KvService.Processor<KvService.Iface>(new KvImpl()));
            TServer server=new TThreadedSelectorServer(serverParams); //简单的单线程服务模型,常用于测试
            server.serve();
        } catch (Exception e) {
            System.out.println("Server start error!!!");
            e.printStackTrace();
        }
    }
}
  • 客户端调用
    对应实现对TSimpleServer和TThreadedSelectorServer的调用
package sc.leveldb;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.*;
/**
 * Created by zhongchao03 on 2018/1/20.
 */
public class ThriftClient {
    public static void a()
    {
        try {
            TTransport transport = new TFramedTransport(new TSocket("127.0.0.1", 8191, 5000));
            // 协议要和服务端一致
            TProtocol protocol = new TBinaryProtocol(transport);
            KvService.Client client = new KvService.Client(protocol);
            transport.open();
            boolean string = client.setValue("fuck", "haha");
            System.out.println(string);
            transport.close();
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        }
    }
    public static void nonblockingSocket() throws Exception{
        TTransport transport = new TFramedTransport(new TSocket("localhost", 8888));
        TProtocol protocol = new TBinaryProtocol(transport);
        KvService.Client client = new KvService.Client(protocol);
        transport.open();
        int i = 5;
        while (i > 0) {
            System.out.println("client调用返回:" + client.getValue("张三"));
            i--;
        }
        transport.close();
    }
    public static void main(String[] args)throws Exception{
        nonblockingSocket();
    }
}

Thrift客户端连接池设计

Thrift连接池优化:http://blog.csdn.net/chen7253886/article/details/52779471
Thrift客户端连接池设计:http://blog.csdn.net/lansebolangcjl/article/details/52788198

基于Zookeeper服务的RPC服务发布订阅

https://www.jianshu.com/p/a378b2539a57

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值