简介
Pigeon是一个分布式服务通信框架(RPC),在美团点评内部广泛使用,是美团点评最基础的底层框架之一
主要特色
除了支持spring schema等配置方式,也支持代码annotation方式发布服务、引用远程服务,并提供原生api接口的用法。
支持http协议,方便非java应用调用pigeon的服务。
序列化方式除了hessian,还支持thrift等。
提供了服务器单机控制台pigeon-console,包含单机服务测试工具。
创新的客户端路由策略,提供服务预热功能,解决线上流量大的service重启时大量超时的问题。
记录每个请求的对象大小、返回对象大小等监控信息。
服务端可对方法设置单独的线程池进行服务隔离,可配置客户端应用的最大并发数进行限流
github地址:https://github.com/dianping/pigeon
组成模块
1.pigeon-common
2.pigeon-config
3.pigeon-console
4.pigeon-extensions
5.pigeon-monitor
6.pigeon-registry
7.pigeon-remoting
pigeon-extensions模块
描述:包括pigeon多个子模块,比如注册中心聚合,zookeeper注册,http和netty通信
子模块如下:pigeon-registry-composite
pigeon-registry-zookeeper
pigeon-remoting-http
pigeon-remoting-netty
pigeon-registry-composite模块提供的主要功能如下:
1.读取配置中心的“pigeon.registry.prefer”配置项内容,决定注册中心(registry)的使用顺序
2.聚合并初始化mns注册中心和curator注册中心(todo:详细分析上述两个注册中心)
3.提供聚合注册中心变动通知(todo:详细分析RegistryNotifyListener):
3.1 是否需要通知
3.2 主机变动通知策略
-
跟指定的注册中心同名的注册中心通知直接转发
-
使用降级group转发
pigeon-registry-zookeeper模块实现与zookeeper通信的注册中心
架构图:
备注:pigeon内部使用curator框架与zookeeper通信
CuratorEventListener详解:CuratorEventListener实现CuratorListener接口监听zookeeper变更通知,根据WatchedEvent的path信息来区分通知类型
CuratorClient生命周期:
init流程如下:
-
初始化CuratorFramework类型的client对象(具体配置参数:zookeeper注册中心地址,会话超时时间,连接超时时间和重试策略)
-
client对象添加connectionstate和curatorevent listener(方便重连和curator事件广播)
-
client对象同步连接zookeeper注册中心
operation操作集:
pigeon-remoting-http模块提供Http协议适配器,http服务消费者及提供者(mock调用)相关实现
内容如下:
1.adapter (http协议适配) 2.Invoker (http协议服务消费者) 3.provider (http协议服务提供者)
adapter:
invoker:
provider:
HttpServerHandler描述:HttpServer 请求处理器
核心处理逻辑:
1.handle
pigeon-remoting-netty模块定制化使用netty框架实现服务消费者和提供者通信模型
channel:定制化实现NettyChannel
类图如下:
DefaultNettyChannel类说明:
属性:
private ReentrantLock connectLock = new ReentrantLock(); //连接锁
private int timeout; //连接超时时间
private volatile Channel channel;//内部channel
private ClientBootstrap bootstrap;//启动引导程序
private InetSocketAddress localAddress; //本地套接字地址
private InetSocketAddress remoteAddress; //远程套接字地址
private String remoteAddressString;
构造函数:
public DefaultNettyChannel(ClientBootstrap bootstrap, String remoteHost, int remotePort, int timeout) {
this.bootstrap = bootstrap;
this.remoteAddress = new InetSocketAddress(remoteHost, remotePort);
this.remoteAddressString = NetUtils.toAddress(remoteHost, remotePort);
this.timeout = timeout;
}
备注:初始化启动引导程序,远程套接字地址和超时时间
生命周期:
codec&&invoker&&provider:对netty传输的二进制流进行编解码和业务定制化处理
编解码:
Netty Rpc调用整体架构图:
NettyClientHandler核心功能:
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
CodecEvent codecEvent = (CodecEvent) e.getMessage();
if (codecEvent.isValid() && codecEvent.getInvocation() != null) {
client.processResponse((InvocationResponse) codecEvent.getInvocation());
}
}
通过适配Netty框架的SimpleChannelUpstreamHandler,实现messageReceived功能。调用流程图如下:
NettyServerHandler核心功能:
/**
* 服务器端接受到消息
*
* @see org.jboss.netty.channel.SimpleChannelUpstreamHandler#messageReceived(org.jboss.netty.channel.ChannelHandlerContext,
* org.jboss.netty.channel.MessageEvent)
*/
@SuppressWarnings("unchecked")
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent message) {
CodecEvent codecEvent = (CodecEvent) (message.getMessage());
if (!codecEvent.isValid() || codecEvent.getInvocation() == null) {
return;
}
InvocationRequest request = (InvocationRequest) codecEvent.getInvocation();
ProviderContext invocationContext = new DefaultProviderContext(request, new NettyServerChannel(ctx.getChannel()));
try {
this.server.processRequest(request, invocationContext);
} catch (Throwable e) {
String msg = "process request failed:" + request;
// 心跳消息只返回正常的, 异常不返回
if (request.getCallType() == Constants.CALLTYPE_REPLY
&& request.getMessageType() != Constants.MESSAGE_TYPE_HEART) {
ctx.getChannel().write(ProviderUtils.createFailResponse(request, e));
}
log.error(msg, e);
}
}
通过适配Netty框架的SimpleChannelUpstreamHandler,实现messageReceived功能。调用流程图如下:
pigeon-monitor模块内容包括:
1.监控加载器,监控事务和运行组件的实现
2.监控运行架构设计
pigeon-registry模块描述:
实现client端注册中心管理器。包装注册中心(比如pigeon-registry-zookeeper模块的CuratorRegistry)并保存以下数据:
-
服务与服务组的映射
-
引用服务与服务提供者主机组的映射
-
注册服务名称与服务的映射
RegistryManager类解析:
1.初始化过程
2.管理操作