从源码全面解析 dubbo 服务端服务调用的来龙去脉
Dubbo是一款开源的分布式服务治理框架,具有高性能和高可靠性等特点,得到了越来越多的关注和使用。Dubbo中的服务调用涉及到客户端和服务器端,本篇文章主要介绍Dubbo服务器端服务调用的来龙去脉,带有详细的源码解析和注释。本篇文章主要分为以下几个部分:
1.服务注册Dubbo服务端将提供的服务注册到注册中心,以便客户端通过注册中心来查找可用的服务提供者。在Dubbo中,可用的注册中心包括Zookeeper、Redis等。
// Dubbo服务注册public class RegistryProtocol implements Protocol {
// 注册中心 private final RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
public
...
// 注册服务 final URL registryUrl = getRegistryUrl(originInvoker);
final Registry registry = registryFactory.getRegistry(registryUrl);
registry.register(registryUrl);
...
}
}
上面的代码片段从RegistryProtocol类中摘取,其中调用了registryFactory.getRegistry方法获取了一个注册中心,通过registry.register方法来进行服务注册。
2.服务提供Dubbo服务器端在服务启动时,可以将一些服务开放出去,等待客户端的调用。Dubbo提供了三种不同的服务提供方式:协议扩展、服务扩展和SPI扩展,本文介绍协议扩展方式。
// Dubbo服务提供public class DubboProtocol implements Protocol {
// 省略部分代码 public
...
// 开放服务 openServer(sockUrl);
...
}
// 开放服务 protected
// 获取绑定的端口 Collection
if (ExtensionLoader.getExtensionLoader(Dispatcher.class).hasExtension(url.getParameter(Constants.DISPATCHER_KEY, Constants.DEFAULT_DISPATCHER))) {
handlers.add(ExtensionLoader.getExtensionLoader(Dispatcher.class).getExtension(url.getParameter(Constants.DISPATCHER_KEY, Constants.DEFAULT_DISPATCHER)).dispatch(invoker, new RpcInvocation(invoker, invocation));
} else {
handlers.add(new ChannelHandlerAdapter());
}
NettyServer server = new NettyServer(url,handlers);
server.bind();
}
}
DubboProtocol类为Dubbo提供了一套默认实现。在DubboProtocol的export方法中,启动了一个服务,调用了openServer方法。openServer方法中首先获取了需要绑定的端口,并且添加了一个处理器handlers,通过handlers.add方法将该处理器进行了添加。然后将url和handlers作为参数来实现对NettyServer的创建,并且最后调用了start方法。
3.服务调用Dubbo客户端在调用提供者的服务时,需要经过以下几个步骤:选择服务端,连接服务端,发起请求,等待响应,进行结果处理。
// Dubbo服务调用public class ReferenceConfig
private static final long serialVersionUID = -6848935145304626324L;
// 省略部分代码 public T get() {
...
// 准备调用 Invoker
try {
// 调用 result = invoker.invoke(request);
} catch (Throwable e) {
...
}
...
}
}
在ReferenceConfig类的get方法中,先是调用proxyFactory.getInvoker方法获取一个Invoker对象,然后将该对象和request传入invoker.invoke方法之中进行调用。在该方法的内部,首先获取选择后的服务提供者,并且随后连接该服务提供者后,再将请求信息发送给该服务提供者等待响应。最后,根据相应结果进行对结果的处理。
以上就是Dubbo服务器端服务调用的来龙去脉。Dubbo在服务调用的过程中设计非常完整,除了上述几个步骤,还有诸如负载均衡、容错机制等等,使得Dubbo成为一款极其强大的分布式服务治理框架。