一文学习Thrift RPC

Thrift RPC引言

Thrift RPC的特点

Thrift 是一个RPC的框架,和Hessian RPC有什么区别,最重要的区别是Thrift可以做异构系统开发。
什么是异构系统,服务的提供者和服务的调用者是用不同语言开发的。

为什么会当前系统会有异构系统的调用?
做大数据一般使用Python,数据存储又要使用Hbase(Java),这就是异构系统了。
另外,还有遗留系统额整合,一个公司的系统,是随着业务增长的,在不同的业务可能由不同的编程语言开发的,想要完成一个共同的目标,就要不同系统之间进行交互。不同的系统要传输数据,首先要构建一个统一的格式,和编程语言无关。

设计一个异构系统的RPC,解决的核心问题是什么?
只要双方用各自的编程语言,网络编程建立连接,进行通信即可。
但是有一些挑战:
1.得需要精通不同编程语言的网络IO线程技术。
2.通信数据的格式,尤其是二进制的格式,不同编程语言的二进制数据量大小不一样。
所以我们引入了Thrift帮我们解决异构系统的调用。

ThriftRPC框架

  1. 基本概念:是apache组织开源的一个顶级异构系统RPC框架,用于完成异构系统的RPC通信。
    多种编程语言 Java C++ PHP Phyton Ruby Node.jsp…
    2007 FaceBook Thrift 开源。
  2. 特点:
    1. 跨语言支持
    2. 开发快速
    3. 学习简单 IDL语言
    4. 稳定
  3. Thrift的设计思想
    1. 针对于不同的编程语言提供了一个库(jar)
      作用:网络通信的代码 协议(序列化)相关的内容 java libthrift
    2. IDL语言 中立语言 用于服务发布
    3. Thrift命令把IDL语言 自动转换成 你需要的编程语言。
      在这里插入图片描述

Thrift 命令的安装

安装什么?

安装的是将IDL语言转换为相应的编程语言。

如何安装

mac brew install thrift
windows http://www.apache.org/dyn/closer.cgi?path=/thrift/0.18.0/thrift-0.18.0.exe
https://blog.51cto.com/u_15854865/5810927

如何验证: thrift -help thrift --version

针对于不同的编程语言 安装库

这里用Java

   <dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.18.0</version></dependency>

IDL语法

IDEA 中 Thrift插件,插件目的提示 校验IDL语法。
IDL语法 必须 thrift

  • 注释

    #    单行注释
    //   单行注释
    /*
    *    多行注释 
    */
    
  • namespace

    namespace java com.liu
    namespace py com.liu指定编程语言,指定生成好的代码 包 
    
  • 基本类型

    1.  i8      有符号的8位整数   byte
    2.  i16     有符号的16位整数  short
    3.  i32     有符号的32位整数  int
    4.  i64     有符号的64位整数  long
    5.  double  64位浮点数       double
    6.  bool    布尔值          boolean
    7.  string  字符串 字符      "" ''  UTF-8
    
  • 集合类型

    list<T>   有序可重复    java.util.List 
    set<T>    无需不可重复  java.util.Set
    map<K,V>  k-v         java.util.Mapmap<i32,string> sex = {1:'female',2:'male'}
    list<i32> ages = [1,2,3,4]
    
  • struct 自定义对象

    struct User{1: string name ='sunshuai',2: optional i32 age,3: list<i32> ages = [1,2,3,4],4. required i32 hieght
    }1. struts 不能继承
    2. 成员与成员的分割,;
    3. 结构体里面的每一个字段 都要进行编号
    4. 变量类型 变量名
    5. optional 可选的 默认为每一个成员都加入的关键字代表这个字段在序列化过程中可选的。如果这个字段没有默认值,就不序列化,如果有默认值 就序列化.
    6. required 必选,有没有值都会序列化
    
  • 枚举 (enum)

    enum SEASON{SPRING = 1,SUMMERT = 2...
    }不支持嵌套,i32 
    
  • 异常 (Exception)

    exception MyException{1: i32 errorCode2: string message
    }
    
  • 服务 (Service)

    服务接口 
    service UserService{bool login(1:string name,2:string password)void register(1:User user) //User idl语言中的结构体 
    }注意:1. 异常service UserService{bool login(1:string name,2:string password) throws (1:MyException e,2:XXXException e)void register(1:User user) //User idl语言中的结构体 }2. oneway 表示客户端发起请求后不等待响应返回,只能和void 这种操作配合。service UserService{bool login(1:string name,2:string password) throws (1:MyException e,2:XXXException e)oneway void register(1:User user) //User idl语言中的结构体 }3. 继承service BaseService{void m1(1:string name)}service UserService extends BaseService{}
    
  • include

    作用:进行IDL模块化编程suns1.thriftstruct User{1:string name}
    suns2.thrift include "suns1.thrift"service UserService{void register(1:suns1.User user)}
    
  • Thrift把IDL生成对应代码的命令

    thrift --gen java xx.thrift 
    thrift --gen py xx.thriftthrift -r --gen java xx.thrift 
    

Thrift RPC的开发

环境搭建

1. 安装Thrift 作用:把IDL语言描述的接口内容,生成对应编程语言的代码,简化开发。
2. 引入依赖    作用:引入thrift针对于某一种编程语言的封装 (网络通信 协议【序列化】)<dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.13.0</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.32</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.9</version></dependency>

项目结构的定义

1. thrift-client  代表的是服务的调用者
2. thrift-server  代表的是服务的提供者
3. thrift-common  RPC编程共有的内容 1,实体类型 2,服务接口

Thrift核心对象

1. TTransport作用:底层封装网络通信TSocket 阻塞IO通信TNonblockdingTransport 非阻塞网络通信TFramedTransport 加入了封帧的操作 (压缩后 数据边界问题)  
2. TProtocol处理的协议 (序列化方式)TBinayProtocol 二进制进行序列化TCompactProtocol 压缩方式 处理二进制 TJSONProtocol  JSON进行序列化
3. TProcessor业务处理:把通信数据 和 业务功能整合在一起
4. TServer 服务端

thrift-common

1. 通过IDL语言 定义 client与服务端 共用的数据类型 和 服务接口 
2. client server端 引入 common模块

编写thrift文件:

namespace java com.liu
struct User{1:string name,2:string password
}service UserService{User queryUserByNamendPassword(1:string name,2:string password),void save(1:User user)
}

使用Thrift工具命令生成文件放在common模块中。
在这里插入图片描述

服务端

1. 实现服务接口 :idl语言生成的
2. 创建服务端代码

在这里插入图片描述
服务端实现之后,就要发布服务,如何发布服务?

public static void main1(String[] args) throws TTransportException {//TTransportTServerTransport tServerTransport =new TServerSocket(9002);//TBinaryProtocolTBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();//TProcessorUserService.Processor processor = new UserService.Processor(new UserServiceImpl());TSimpleServer.Args tArgs = new TSimpleServer.Args(tServerTransport);tArgs.protocolFactory(factory);tArgs.processor(processor);//TServer发布服务TServer tServer =new TSimpleServer(tArgs);tServer.serve();}

客户端

客户端要向本地方法那样 调用远端方法。 代理
 public static void main(String[] args) throws TException {//传输方式 基于Socket阻塞 也可以使用非阻塞方式TTransport transport=new TSocket("localhost",9002);//传输协议 TBinaryProtocol 二进制格式 TCompactProtocol 压缩格式 TJSONProtocol json格式TProtocol tProtocol =new TBinaryProtocol(transport);UserService.Client userService = new UserService.Client(tProtocol);transport.open();User user = userService.queryUserByNamendPassword("liusir", "123");System.out.println("user = " + user);}

启动服务端之后,然后运行客户端可以看到服务成功了。
在这里插入图片描述

实战开发中的思考

在实战开发中,往往服务端的功能 其实已经开发完成。1. 现有本地的功能 服务端的功能 写好了。2. 根据系统的功能,才有可能决定 这个服务发布成 RPC。所以在发布RPC业务实现 IFace接口,主要通过原有的Service方法的调用,进行实现。这样维护性更好,也是实战中使用的方式。

TServer服务的相关内容

  • TServer类型

    1. 代表的是Thrift开发中的服务器。
    2. 功能:服务的开启serve()   服务的关闭stop()
    3. 阻塞 非阻塞 有没有线程池 Reactor模式TSimpleServer:        阻塞 单线程的服务器 (没有实战价值,只是用于测试)TThreadPoolServer:     阻塞 线程池的服务器 TNonBlockingServer:    非阻塞单线程的服务器 TThreadSelectorServer: 实现了主从版的Reactor(类似Netty)
    
  • 分析TSimpleServer

    目的:1. 了解Thrift相关类型的作用(源码的分析)2. 核实SimpleServer是一个阻塞的 单线程的服务器
    

    在这里插入图片描述

  • TThreadPoolServer

    阻塞,引入了线程池 1. 如果使用,一定注意 默认的线程池 最大值 Integer.Max显然不成 需要maxWorkerThreads进行设置。
    2. 不能够让我们的线程复用,因为没有selector底层实现思路 把具体调用的Socket分配 WorkerProcess进行操作,而WorkerProcess从线程池中获得 线程资源。
    
  • TNonblockingServer

    底层连接 必须使用 TFreameTransport ,TCompactProtocol

    非阻塞  单线程Java NIO SocketChannel#configureBlocking
    ServerSocketChannel#configureBlockingselector
    
  • TThreadSelectorServer [主从版的Reactor模式的实现][实战中推荐]
    在这里插入图片描述

    • client

      public class TestClient1 {public static void main(String[] args) throws TException {//完成  与服务端 网络连接的连接TTransport tTransport = new TSocket("localhost", 9000);TFramedTransport tFramedTransport = new TFramedTransport(tTransport);tTransport.open();//创建协议TCompactProtocol tCompactProtocol = new TCompactProtocol(tFramedTransport);//创建代理  stub 存根 桩UserService.Client userService = new UserService.Client(tCompactProtocol);User user = userService.queryUserByNameAndPassword("xiaojr", "9090");System.out.println("user = " + user);}
      }
      
    • server

      public class TestServer1 {public static void main(String[] args) throws TTransportException {TNonblockingServerSocket tNonblockingServerSocket = new TNonblockingServerSocket(9000);TFramedTransport.Factory tFramedTransport = new TFramedTransport.Factory();TCompactProtocol.Factory factory = new TCompactProtocol.Factory();UserService.Processor processor = new UserService.Processor(new UserServiceImpl());TThreadedSelectorServer.Args arg = new TThreadedSelectorServer.Args(tNonblockingServerSocket);arg.transportFactory(tFramedTransport);arg.protocolFactory(factory);arg.processor(processor);TServer tServer = new TThreadedSelectorServer(arg);tServer.serve();}
      }
      
    • 1. client server thrift版本(maven) 一致
      2. client server通信的transport protocal 保持一致
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/647469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【WPF.NET开发】WPF 中的 Layout

本文内容 元素边界框布局系统测量和排列子元素面板元素和自定义布局行为布局性能注意事项子像素渲染和布局舍入 本主题介绍 Windows Presentation Foundation (WPF) 布局系统。 了解布局计算发生的方式和时间对于在 WPF 中创建用户界面非常重要。 1、元素边界框 在 WPF 中构…

Apollo Cyber RT:引领实时操作系统在自动驾驶领域的创新

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下…

深入理解旅游网站开发:Java+SpringBoot+Vue+MySQL的实战经验

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

ChatGPT 全域调教高手:成为人工智能交流专家

随着人工智能的快速发展&#xff0c;ChatGPT作为一种强大的文本生成模型&#xff0c;在各行各业中越来越受到重视和应用。想要利用ChatGPT实现更加智能、自然的交流&#xff0c;成为 ChatGPT 全域调教高手吗&#xff1f;本文将为您介绍如何通过优化ChatGPT的训练方法&#xff0…

jquery多选框

使用hbuilder <!DOCTYPE html> <html><head><meta charset"GBK"><title></title></head><body><table id"myTable"> <tr> <td>黄1</td> </tr> <tr> <td>…

JAVA泛型、泛型通配符、综合练习

作用&#xff1a; 是 jdk5 中引入的特性&#xff0c;可以在编译阶段 约束 操作的数据类型&#xff0c;并进行检查。 格式&#xff1a; <数据类型> 注意泛型只能支持引用数据类型&#xff0c;基本数据类型可转成对应的包装类。 问题&#xff1a; 在没有泛型的时候&…

UE使用C++添加FGameplayTag(游戏标签)

首先Ue会有一个UGameplayTagsManager类型的对象 游戏标签管理器(全局中就有一个) 我们直接通过 UGameplayTagsManager::Get()静态函数拿到 全局唯一的游戏标签管理器的实例 返回的是个左值引用 之后通过调用 AddNativeGameplayTag()函数就可添加游戏标签了 就这么简单 第…

按条件自动搜索文件

在计算机的某个文件夹中&#xff0c;假如有一大堆不同格式的文件&#xff0c;如下图&#xff1a; 我们的目的&#xff1a;快速查找出文件名中包含某文字内容的指定格式的文件&#xff0c;看看它们都放在哪里&#xff1f;通过分析&#xff0c;可能在当前文件夹中也可能在某个子…

核心类库ArrayList、hashMap等

八. 核心类库 1. ArrayList 数组缺点 ArrayList&#xff0c;它常常被用来替代数组 数组的缺点&#xff1a;不能自动扩容&#xff0c;比如已经创建了大小为 5 的数组&#xff0c;再想放入一个元素&#xff0c;就放不下了&#xff0c;需要创建更大的数组&#xff0c;还得把旧…

防御保护---防火墙(安全策略、NAT策略实验)

防御保护---防火墙&#xff08;安全策略、NAT策略实验&#xff09; 1.实验需求2.实验说明及思路3.实验配置3.1 配置IP地址以及VLAN3.2 配置防火墙IP地址及划分区域3.3 配置防火墙安全策略3.4 配置防火墙NAT策略 1.实验需求 1.生产区在工作时间内可以访问服务器区&#xff0c;仅…

【iOS ARKit】人脸追踪之挂载虚拟元素

人脸跟踪&#xff08;Face Tracking&#xff09;是指将人脸检测扩展到视频序列&#xff0c;跟踪同一张人脸在视频序列中的位置。是论上讲&#xff0c;任何出现在视频中的人险都可以被跟踪&#xff0c;也即是说&#xff0c;在连续视频帧中检测到的人脸可以被识别为同一个人。人脸…

ActiveMQ|01-ClassicArtemis功能介绍

接上篇-MQ消息队列主流消息服务规范及代表产品&#xff0c;ActiveMQ就是基于JMS消息服务规范的消息中间件组件&#xff0c;主要应用在分布式系统架构中&#xff0c;帮助构建高可用、 高性能、可伸缩的企业级面向消息服务的系统 本文速览&#xff1a; JMS对象模型ActiveMQ的功…

import tensorflow.contrib.slim as slim中contrib报红,显示没有导入contrib

本人环境&#xff1a; python 3.6 tensorflow 1.13 问题如下图&#xff1a; 解决方法&#xff1a; 找到包的位置&#xff0c;查看tensorflow中是否下载了contrib包&#xff0c;如果有的话&#xff0c;建议重新装一次TensorFlow 如果没有找找&#xff0c;可以在搜索栏搜一下…

【Web前端实操15】利用Grid布局完成九宫格

相关知识点&#xff1a; 创建多列 column-count 属性指定了需要分割的列数 列与列之间的间隙 column-gap 属性指定了列与列间的间隙 列边框 column-rule-style 属性指定了列与列间的边框样式 column-rule-width 属性指定了两列的边框厚度 column-rule-color 属性指定了…

【GitHub项目推荐--不错的Flutter项目】【转载】

01 可定制的图表库 FL Chart是一个高度可定制的 Flutter 图表库&#xff0c;支持折线图、条形图、饼图、散点图和雷达图 。 项目地址&#xff1a;https://github.com/imaNNeoFighT/fl_chart LineChart BarChart PieChart Sample1 Sample2 Sample3 …

哪吒汽车与经纬恒润合作升级,中央域控+区域域控将于2024年落地

近日&#xff0c;在2024哪吒汽车价值链大会上&#xff0c;哪吒汽车与经纬恒润联合宣布合作升级&#xff0c;就中央域控制器和区域域控制器展开合作&#xff0c;合作成果将在山海平台新一代车型上发布。 哪吒汽车首席技术官戴大力、经纬恒润副总裁李伟 经纬恒润在智能驾驶领域拥…

百度Apollo | 实车自动驾驶:感知、决策、执行的无缝融合

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下…

多维时序 | Matlab实现DBO-BiLSTM蜣螂算法优化双向长短期记忆神经网络多变量时间序列预测

多维时序 | Matlab实现DBO-BiLSTM蜣螂算法优化双向长短期记忆神经网络多变量时间序列预测 目录 多维时序 | Matlab实现DBO-BiLSTM蜣螂算法优化双向长短期记忆神经网络多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现DBO-BiLSTM多变量时间序…

Ubuntu 申请 SSL证书并搭建邮件服务器

文章目录 Log 一、域名连接到泰坦&#xff08;Titan&#xff09;电子邮件二、NameSilo Hosting 避坑三、Ubuntu 搭建邮件服务器1. 环境准备2. 域名配置3. 配置 Postfix 和 Dovecot① 安装 Nginx② 安装 Tomcat③ 申请 SSL 证书&#xff08;Lets Encrypt&#xff09;④ 配置 pos…

链表分割(新的错误:开头赋值)

1.单向链表&#xff1a;含有链表内容和下个链表的指针 2.双向链表&#xff1a;含有链表内容和上下两个链表的指针 3.带头和不带头&#xff1a;哨兵位的头结点&#xff08;不存储有效数据&#xff09;&#xff0c;主要区别在于链表为空时会存在一个哨兵位节点&#xff0c;优点…