zRPC是经过生产环境千万日活实践检验的通用RPC框架,其底层依赖gRPC,内置完整的微服务治理能力。是一款简单、通用、高性能、可扩展的RPC框架。

框架特点

  • 通用性:依赖gRPC,支持跨语言的调用
  • 高性能:底层依赖HTTP2协议,序列化采用Protobuf序列化,保证了高性能
  • 可扩展:用户可根据不同的业务特点扩展功能如自定义拦截器等等
  • 功能完整:内建服务治理功能无需做任何配置,主要包括鉴权、日志记录、监控报警、数据统计、链路追踪、超时控制、自动熔断、自动降载等等,同时内置服务注册,服务发现,负载均衡等功能
  • 简单高效:只需几行代码即可创建服务,同时可配合goctl工具代码自动生成,用户只需要关注业务代码

优势

  • 轻松获得支撑千万日活服务的稳定性
  • 内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码
  • 微服务治理中间件可无缝集成到其它现有框架使用
  • 大量微服务治理和并发工具包

架构图

image-20210204013022985

自定义拦截器

zRPC底层依赖gRPC,gRPC提供了拦截器(interceptor)功能,包括客户端拦截器和服务端拦截器。zRPC框架内置了许多通用的拦截器,同时提供自定义拦截器功能以满足不同的业务需求。今天主要讲讲zRPC的自定义拦截器。

拦截器原理就是利用递归嵌套调用的方式,或前置,或后置,或前置和后置配合,将拦截函数按照加载的顺序加入事件处理队列。下面看个例子。

服务器端,zRPC实现的RPCServer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
func main() {
	cnf.InitEnvConfig()
	srv := zrpc.MustNewServer(cnf.EnvConfig.RPCServer, logic.RegisterFunc)
	// 添加服务器端的拦截器
	srv.AddUnaryInterceptors(logic.RateLimitInterceptor)
	srv.Start()
}

var limiter = rate.NewLimiter(rate.Limit(5), 5)

func RateLimitInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
	handler grpc.UnaryHandler) (resp interface{}, err error) {
	if !limiter.Allow() {
		log.Println("Request limited.")
		return nil, nil
	}
	return handler(ctx, req)
}

客户端,GoFast实现的WebServer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
func main() {
	cnf.InitEnvConfig()
	rpcConn := zrpc.MustNewClient(cnf.EnvConfig.EtcdServer, logic.ClientInterceptors...).Conn()
	logic.StartWeb(rpcConn)
}

// 客户端拦截器
var ClientInterceptors = []zrpc.ClientOption{zrpc.WithUnaryClientInterceptor(timeInterceptor)}

func timeInterceptor(ctx context.Context, method string, req, reply interface{}, 
	cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
	stymie := time.Now()
	err := invoker(ctx, method, req, reply, cc, opts...)
	if err != nil {
		return err
	}

	log.Printf("Call path [%s], Time: %v\n", method, time.Now().Sub(stymie))
	return nil
}

上面的代码只有一部分,没关系大家只需要看拦截器方法的实现和添加方式就好了。

(完)