天道酬勤

天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣。

0%

大家有没有想过,调用方调用一个方法,服务端是怎么找到对应方法并处理的?

很多RPC里是通过反射实现的,但是thrift里用的是另一种方式。

阅读全文 »

(1) thrift Server 作用

Server将 thrift 所有功能整合到一起:

1、创建一个 Transport;
2、创建 Transport 使用的 I/O Protocol;
3、为 I/O Protocol 创建 Processor;
4、启动服务,等待客户端的连接;

thrift不同语言实现提供的服务器端的模式不一样

thrift Java版本为服务器端提供了多种模式: TSimpleServer 、 TThreadPoolServer 、 TNonblockingServer 、 THsHaServer 、 TThreadedSelectorServer

Thrift Go版本为服务器端提供了 TSimpleServer

IO模型 Java Go 特点
阻塞IO TSimpleServer - 只有一个工作线程,循环监听新请求的到来并完成对请求的处理,一次只能接收和处理一个socket连接,效率比较低。
阻塞IO TThreadPoolServer TSimpleServer
IO多路复用 TNonblockingServer - TNonblockingServer 单线程工作,采用NIO的方式,所有的socket都被注册到selector中
阅读全文 »

设计

TClient ,
TStandardClient、WrappedTClient 实现了TClient接口的Call方法

demo

https://github.com/weikeqin/thrift-tutorial-go-demo

以client调用add方法为例

调用下游Add()方法代码

func main() {
	// 创建thrift client
	thriftClient := getThriftClient()
	// 创建 calculatorClient   tutorial是由idl生成的
	calculatorClient := tutorial.NewCalculatorClient(thriftClient)
	// 调用Add方法
	sum, _ := calculatorClient.Add(defaultCtx, 1, 2)
	fmt.Print("1+2=", sum, "\n")
}
// 获取一个thriftClient
func getThriftClient() *thrift.TStandardClient {

	addr := flag.String("addr", "localhost:9090", "Address to listen to")

	var transportFactory thrift.TTransportFactory
	transportFactory = thrift.NewTTransportFactory()

	cfg := &thrift.TConfiguration{
		TLSConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	// 传输方式
	var transport thrift.TTransport
	transport = thrift.NewTSocketConf(*addr, cfg)
	// 传输方式增强
	transport, err := transportFactory.GetTransport(transport)
	if err != nil {
		fmt.Println(err)
	}

	//defer transport.Close()
	if err := transport.Open(); err != nil {
		fmt.Println(err)
	}

	// 协议工厂
	var protocolFactory thrift.TProtocolFactory
	protocolFactory = thrift.NewTBinaryProtocolFactoryConf(nil)

	iprot := protocolFactory.GetProtocol(transport)
	oprot := protocolFactory.GetProtocol(transport)

	// 创建thrift client,
	// 这个client使用TStandardClient类型,  TStandardClient 实现了 TClient 接口
	thriftClient := thrift.NewTStandardClient(iprot, oprot)
	return thriftClient
}
阅读全文 »

(1) 传输方式(Transport)作用

传输方式(Transport)作为rpc框架接收报文的入口,提供各种底层实现如socket创建、读写、接收连接等。
同时实现各种复写传输层包括http、framed、buffered、压缩传输等。

(1.1) 支持的传输方式

thrift支持多种传输方式

传输方式 特点
TSocket 阻塞型 socket,用于客户端,采用系统函数 read 和 write 进行读写数据。
TServerSocket 非阻塞型 socket,用于服务器端,accecpt 到的 socket 类型都是 TSocket(即阻塞型 socket)。
TBufferedTransport
TFramedTransport
TMemoryBuffer
TFileTransport
TFDTransport
TSimpleFileTransport
TZlibTransport
TSSLSocket
TSSLServerSocket
阅读全文 »

Thrift是一个轻量、支持多语言、可扩展、高性能的远程服务调用框架。
提供了数据传输、序列化、应用层处理的清晰抽象。

The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

(1) thrift架构分层

thrift-layers

分层 职责
服务调用层 (客户端/服务端) 客户端、服务端调用。
协议层 消息解析
传输层包装 功能增强,实现各种复写传输层包括http、framed、buffered、压缩传输等
低级传输层 靠近网络层、作为rpc框架接收报文的入口,提供各种底层实现如socket创建、读写、接收连接等。
语言层 thrift采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发
操作系统层 由编程语言提供各种操作系统的支持
阅读全文 »

 协议大家平时都会遇到,只是没有特别注意。
 像平时大家阅读文章的时候都是从上到下、从左往右 按行阅读,这可以看做一种阅读协议。 ( 备注: 古人在竹简上写的文字则是从上往下、从右往左 按列阅读。)
 更详细的规则比如:作文的第一行是标题,段首要空两格的是一个自然段,遇到一个句号是一句话。

详细的标点符号用法(通信协议)参考教育部的规范 标点符号用法 - 教育部

在计算机远程方法调用时,传输的都是二进制的01,调用方(写数据)和被调用方(读数据)怎么约定通信协议的?

(1) 协议(TProtocol)的作用

协议的作用就类似于文字中的符号,作为应用拆解请求消息的边界,保证二进制数据经过网络传输后,还能被正确地还原语义。

具体点就是从二进制数据中解析出协议版本方法名消息类型序列Id序列化方式消息长度协议体等内容。

thrift-protocol-message

阅读全文 »

Kafka是一个消息队列。被大家用在分布式消息队列或者流数据处理场景。
有几个问题,大家不知道思考过没有?
1、Kafka有哪些组件,作用分别是什么,为什么这么设计?
2、Kafka是怎么保证高性能、高并发、高可用的呢?

阅读全文 »

  经常会遇到的一个问题是数据库如何保证不丢数据? 同样的Redis如何保证不丢数据?

MySQL里有 redo log、bin log、undo log
Redis包含 rdb log、aof log

阅读全文 »

  在原来coding pages服务和github pages服务都可以免费试用时,在域名解析时配置 国内访问coding pages部署的博客静态文件,国外访问github pages部署的静态文件。国内国外访问速度都基本都在200ms内。

  自从 coding.net 停止免费的pages服务后,只有github pages可以免费试用,国内访问博客只能访问github pages服务,导致访问速度很慢。被人吐槽了一次,所以想优化一下。

优化思路比较简单,
1、国内ip访问国内的博客服务 比如gitee pages服务
2、通过缓存加快访问速度 比如CDN缓存

阅读全文 »

  在做系统稳定性-下游用户接口的兜底时,当时有2种方案:
  第一种是只校验用户uid(18位数字 long类型 8字节)是否合法,这种方案实现简单,但有安全风险;
  另一种方案是缓存一份用户信息(uid、城市、运营单元、收货地址id、身份 等) 数据,用户接口异常时用缓存数据校验,这种方案实现稍微复杂点,但是没有安全风险。

 当时有2亿多用户,别的组的同学缓存过全量(20多个字段)用户数据,用了200G内存。 由于占用内存太多,收益不高,他们很快就放弃缓存用户数据了。

 由于我们并不需要缓存用户的20多个字段,只需要缓存6个字段,想自己计算一下+实验下看需要多大内存,如果占用内存少可以使用方案二。

(1) redis整体存储结构

 redis整体数据存储结构

阅读全文 »