今天认识下Dubbo,按套路来先看看为啥整个这个技术,看看官网,官网说背景里说分布式架构RPC是关键,然后在需求里说了一大堆,总结下来就是说需要注册中心、监控中心、调度中心,用过Eureka、Nacos这些注册中心的都知道,注册中心就是RPC实现的一种形式,通过注册中心解决分布式服务之间的远程调用,那啥是RPC(远程过程调用),对于java来说,RPC就是我本地没有这个方法的实现但是我还想调用这个方法,目的搞清楚了,接下来看看怎么跑起来,为了读源码方便,直接不基于Spring编写。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.5</version>
</dependency>
//服务接口
public interface GreetingsService {
String sayHi(String name);
}
//服务提供者服务接口实现
public class GreetingsServiceImpl implements GreetingsService {
@Override
public String sayHi(String name) {
return "hi, " + name;
}
}
//服务提供者提供服务
public static void main(String[] args) throws InterruptedException {
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
service.setApplication(new ApplicationConfig("first-dubbo-provider"));
service.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
service.setInterface(GreetingsService.class);
service.setRef(new GreetingsServiceImpl());
service.export();
System.out.println("dubbo service started");
new CountDownLatch(1).await();
}
//服务消费者消费
public static void main(String[] args) {
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
reference.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
reference.setInterface(GreetingsService.class);
GreetingsService service = reference.get();
String message = service.sayHi("dubbo");
System.out.println(message);
}
GreetingsService以公共API的jar包形式提供给消费者和提供者,提供者实现该接口,并把服务暴露出去,消费者通过该公共API进行调用,提供者和消费者费别处于不同的项目,这样在消费端就看见hi dubbo了。那是不是应该看看咋跑起来的了,先不急,Dubbo的源码复杂到不是看不懂,就是长啊,看着容易没耐心,今天先大致说一下吧,先说说几个抽象吧。
1、Invoker
package com.alibaba.dubbo.rpc;
public interface Invoker<T> extends Node {
Class<T> getInterface();
Result invoke(Invocation invocation) throws RpcException;
}
package com.alibaba.dubbo.common;
public interface Node {
URL getUrl();
boolean isAvailable();
void destroy();
}
这就是Dubbo源码调用者,调用者很简单的抽象,调用者调用调用器返回结果,即invoke方法,再看看Invocation。
package com.alibaba.dubbo.rpc;
public interface Invocation {
String getMethodName();
Class<?>[] getParameterTypes();
Object[] getArguments();
Map<String, String> getAttachments();
String getAttachment(String key);
String getAttachment(String key, String defaultValue);
Invoker<?> getInvoker();
}
这就是调用器源码,调用器是java方法的信息抽象(没想到合适的称谓,从这个接口可以知道方法名、方法参数类型、方法参数,以及调用者),那整这2个抽象干啥呢,我们不妨先猜测一下,RPC在java里就是远程方法调用,那要调用远程方法得知道哪个接口的哪个方法啊、方法都有啥参数啊,参数类型都是啥啊,那我们猜测这两个抽象应该就是搞这个用的,接下来再看看Protocol。
package com.alibaba.dubbo.rpc;
@SPI("dubbo")
public interface Protocol {
int getDefaultPort();
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
void destroy();
}
这里我们看到协议抽象最重要的就是调用者导出,即export方法,这里也可以先猜测一下,导出的目的是啥啊,不是说RPC嘛,那可能就是给别人用的呗,再看看Registry。
package com.alibaba.dubbo.registry;
public interface Registry extends Node, RegistryService {}
package com.alibaba.dubbo.registry;
public interface RegistryService {
void register(URL url);
void unregister(URL url);
void subscribe(URL url, NotifyListener listener);
List<URL> lookup(URL url);
}
可以看到RegistryService就是注册url,也就是说把服务的url给注册了,然后呢还有个lookup方法能找到一堆url,那这个干啥用的,先猜猜注册了url,还能根据url找到一堆url,这好像就是个注册中心啊,再看看Server。
package com.alibaba.dubbo.remoting;
public interface Server extends Endpoint, Resetable {
boolean isBound();
Collection<Channel> getChannels();
Channel getChannel(InetSocketAddress remoteAddress);
@Deprecated
void reset(com.alibaba.dubbo.common.Parameters parameters);
}
package com.alibaba.dubbo.remoting;
public interface Endpoint {
URL getUrl();
ChannelHandler getChannelHandler();
InetSocketAddress getLocalAddress();
void send(Object message) throws RemotingException;
void send(Object message, boolean sent) throws RemotingException;
void close();
void close(int timeout);
void startClose();
boolean isClosed();
}
那server就是一个服务器能发消息,这个也不太明了啊,看看实现类都有啥。
看到NettyServer好像能知道点东西了,就是一个通信的服务器,搞个这个东西干啥啊,这个猜不太出来,先不管以后再说;那回顾一下前面的几个接口Invoker、Protocol、Registry,联系一下,可能是这样我们本地有个服务实现封装成Invoker,然后通过Protocol导出,导出到Registry,谁要用呢管我们的Registry要,再看看官方的架构图。
看图好像猜的像那么回事,今天先说到这,后边继续,保存下官网框架设计Dubbo框架设计地址。