当前位置:实例文章 » C#开发实例» [文章]从源码全面解析 dubbo 服务端服务调用的来龙去脉

从源码全面解析 dubbo 服务端服务调用的来龙去脉

发布人:shili8 发布时间:2024-06-06 22:47 阅读次数:0

Dubbo是一款开源的分布式服务治理框架,具有高性能和高可靠性等特点,得到了越来越多的关注和使用。Dubbo中的服务调用涉及到客户端和服务器端,本篇文章主要介绍Dubbo服务器端服务调用的来龙去脉,带有详细的源码解析和注释。本篇文章主要分为以下几个部分:

1.服务注册Dubbo服务端将提供的服务注册到注册中心,以便客户端通过注册中心来查找可用的服务提供者。在Dubbo中,可用的注册中心包括Zookeeper、Redis等。

// Dubbo服务注册public class RegistryProtocol implements Protocol {

// 注册中心 private final RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();

public Exporter export(final Invoker originInvoker) throws RpcException {
...
// 注册服务 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 Expoter export(final Invoker originInvoker) throws RemotingException {
...
// 开放服务 openServer(sockUrl);
...
}

// 开放服务 protected void openServer(URL url) {
// 获取绑定的端口 Collection handlers = new ArrayList();
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 extends ServiceConfigBase {

private static final long serialVersionUID = -6848935145304626324L;

// 省略部分代码 public T get() {
...
// 准备调用 Invoker invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryUrl.addParameterAndEncoded(Constants.REFER_KEY, encodeIfNecessary(ref.getClass().getName())), new CouchdbServiceKey(interfaceName, group, version), rpcContext);
try {
// 调用 result = invoker.invoke(request);
} catch (Throwable e) {
...
}
...
}
}

在ReferenceConfig类的get方法中,先是调用proxyFactory.getInvoker方法获取一个Invoker对象,然后将该对象和request传入invoker.invoke方法之中进行调用。在该方法的内部,首先获取选择后的服务提供者,并且随后连接该服务提供者后,再将请求信息发送给该服务提供者等待响应。最后,根据相应结果进行对结果的处理。

以上就是Dubbo服务器端服务调用的来龙去脉。Dubbo在服务调用的过程中设计非常完整,除了上述几个步骤,还有诸如负载均衡、容错机制等等,使得Dubbo成为一款极其强大的分布式服务治理框架。

相关标签:c#linqdubbo
其他信息

其他资源

Top