Dubbo源码解析-Dubbo服务提供者_Injvm协议(一)

阅读: 评论:0

Dubbo源码解析-Dubbo服务提供者_Injvm协议(⼀)前⾔:
根据前⾯两篇⾃定义RPC框架的⽂章,我们带着问题来学习Dubbo。
学习Dubbo是如何解决这些服务调⽤、注册中⼼、序列化、集容错等问题。
本⽂主要集中在Dubbo服务端,使⽤最原始的API⽅式来构建⼀个可⽤服务。
原子核的能级1.使⽤API构建服务端
1public class ProviderApplication {
2    public static void main(String[] args) {
3        // 服务实现(⾃定义DemoService接⼝)
4        DemoService demoService = new DemoServiceImpl();
5
6        // 当前应⽤配置
7        ApplicationConfig application = new ApplicationConfig();
8        application.setName("provider");
9
10        // 连接注册中⼼配置
11        RegistryConfig registry = new RegistryConfig();
12        // 本地zookeeper作为配置中⼼
13        registry.setAddress("zookeeper://localhost:2181");
14
15        // 服务提供者协议配置
16        ProtocolConfig protocol = new ProtocolConfig();
17        // dubbo协议,并以20881端⼝暴露
18        protocol.setName("dubbo");
19        protocol.setPort(20881);
20
21        // 服务提供者暴露服务配置
22        ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
23        service.setApplication(application);
24        service.setRegistry(registry);
25        service.setProtocol(protocol);
26        service.setInterface(DemoService.class);
27        service.setRef(demoService);
28        service.setVersion("1.0.0");
29
30        // 暴露及注册服务
31        port();
32    }
33}
34
35// 接⼝
36public interface DemoService {
37    String sayHello(String name);
38}
我们使⽤最原始的这种⽅式来构造⼀个Dubbo provider。不建议在分析源码时使⽤spring-dubbo等⽅式,因为最终还是解析相关dubbo标签然后⽣成这样原始的bean的⽅式来发起dubbo服务的。
水半夏有些⽐较关键的配置类,我们⼀起来简单分析下。
1.1 ApplicationConfig解析
1// 应⽤相关信息
2public class ApplicationConfig extends AbstractConfig {
3    // 名称
4    private String name;
5    // 版本
6    private String version;
7
8    // Java字节码编译器,⽤于动态类的⽣成,可选:jdk或javassist
9    private String compiler;
10
11    // ⽇志输出⽅式,可选:slf4j,jcl,log4j,log4j2,jdk,默认为slf4j
12    private String logger;
13
14    // 配置参数
15    private Map<String, String> parameters;
16
17    // dubbo 2.5.8 新版本增加了 QOS 模块,提供了新的 telnet 命令⽀持
18    // 具体可参考/zh/docsv2.7/user/references/qos/
19    private Boolean qosEnable;
20    private String qosHost;
21    private Integer qosPort;
22    private Boolean qosAcceptForeignIp;
23
24    // 对应的注册中⼼信息
25    private List<RegistryConfig> registries;
26
27 // 对应的监控配置信息
28 private MonitorConfig monitor;
29
30 // 更多可参考:/zh/docsv2.7/user/references/xml/dubbo-application/
31 ...
王学左派
32}
ApplicationConfig主要描述了该服务端应⽤的配置信息。
1.2 RegistryConfig
1// 注册中⼼信息
2public class RegistryConfig extends AbstractConfig {
3
4    // 注册中⼼地址,如本地zookeeper,则address为zookeeper://localhost:2181
5    private String address;
6    private Integer port;
7
8    // 协议名称,⽀持dubbo, multicast, zookeeper, redis等
9    private String protocol;
10    // ⽹络传输⽅式,可选mina,netty
11    private String transporter;
12
13    // 更多配置可参考:/zh/docsv2.7/user/references/xml/dubbo-registry/
14    ...
15}
为什么需要注册中⼼,因为我们需要⼀个能够保存服务提供者信息的地⽅,需要能够动态的提醒消费者服务的上下线。
1.3 ProtocolConfig
Dubbo提供了很多种的协议实现⽅式,org.apache.dubbo.rpc.Protocol接⼝,所有的实现类即dubbo提供的协议。具体如下:
后续我们会仔细分析,本⽂我们先知道有这么多协议类型即可
1.4 ServiceConfig
1
// 协议配置2
public class ProtocolConfig extends AbstractConfig {3
4
// 协议名称,默认为dubbo 5
private String name;6
7
// 协议端⼝号,默认dubbo 协议为20880端⼝8
private Integer port;9
10
// 请求及响应数据包⼤⼩限制,默认为8M 11
private Integer payload;12
// 协议编码⽅式,默认为dubbo 13
private String codec;14
// 序列化⽅式,默认dubbo 为hessian215
private String serialization;16
17
// 服务提供者上下⽂路径,为服务path 的前缀18
private String contextpath;19
20
// 协议的消息派发⽅式,⽤于指定线程模型,⽐如:dubbo 协议的all, direct, message, execution, connection 等21
private String dispatcher;22
23
// ⽹络读写缓冲区⼤⼩,默认为8Kb 24
private Integer buffer;25
26
// 该协议的服务是否注册到注册中⼼27
private Boolean register;28
29
// ⽤户可⾃定义线程池信息,⽤于在接收请求时分配线程30
// ⽐较简单的参数定义,具体可直接看源码注释31
private String threadpool;32
private String threadname;33
private Integer corethreads;34
private Integer threads;35
private Integer iothreads;36
private Integer queues;37
38
// 更多协议配置信息可参考:/zh/docsv2.7/user/references/xml/dubbo-protocol/39
...40    41}
1public class ServiceConfig<T> extends ServiceConfigBase<T> {
2
3    // 主要属性如下
4    // 服务接⼝名
5    protected String interfaceName;
6    // 服务对象实现引⽤
7    protected T ref;
8    // 服务路径
9    protected String path;
10
11    // 远程服务调⽤超时时间(毫秒),默认为1秒
12    protected Integer timeout;
13    // 远程服务调⽤重试次数,不包括第⼀次调⽤,默认为2,则说明总共会调⽤3次
14    protected Integer retries;
15
16    // 服务是否动态注册,如果设为false,注册后将显⽰后disable状态,需⼈⼯启⽤,并且服务提供者停⽌时,也不会⾃动取消册,需⼈⼯禁⽤。
17    protected Boolean dynamic = true;麦肯锡
18
19    // 更多参数请参考/zh/docsv2.7/user/references/xml/dubbo-service/
20    ...
辽河油田华宇网21
22}
ServiceConfig本⾝并没有什么属性,主要就是⼀些⽅法。
我们使⽤ServiceConfig主要就是为了指定接⼝和实现类。
它的属性都在⽗类中提供,具体类结构图如下:
port()
上⾯所有的配置都是为了集成到ServiceConfig中,最重要的还是port()⽅法。
1public class ServiceConfig<T> extends ServiceConfigBase<T> {
2
3    public synchronized void export() {
4        ...
5        // ⽀持延时
6        if (shouldDelay()) {
7            DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);
8        } else {
阴阳互易9            // 交由doExport处理
10            doExport();
11        }
12
13        exported();
14    }
15
16 // doExport
17 protected synchronized void doExport() {
18        if (unexported) {
19            throw new IllegalStateException("The service " + Name() + " has already unexported!");
20        }
21        // 只能export⼀次
22        if (exported) {
23            return;
24        }
25        exported = true;
26
27        if (StringUtils.isEmpty(path)) {
28            path = interfaceName;
29        }
30        // 交由doExportUrls处理
31        doExportUrls();
32    }
33
34 // doExportUrls
35 private void doExportUrls() {
36        ...
37        List<URL> registryURLs = ConfigValidationUtils.loadRegistries(this, true);
38
39        // 这个protocols就是我们上⾯ServiceConfig添加的的ProtocolConfig对象,如果添加多个,则说明当前服务⽀持多协议暴露
40        for (ProtocolConfig protocolConfig : protocols) {
41            String pathKey = URL.buildKey(getContextPath(protocolConfig)
42                    .map(p -> p + "/" + path)
43                    .orElse(path), group, version);
44            isterService(pathKey, interfaceClass);
45            serviceMetadata.setServiceKey(pathKey);
46            // 重点在这⾥
47            doExportUrlsFor1Protocol(protocolConfig, registryURLs);
48        }
49    }
50
51 // 真正的暴露服务的⽅法
52 private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
53        String name = Name();
54        if (StringUtils.isEmpty(name)) {
55            name = DUBBO;
56        }
57
58        // 配置参数添加到map中
59        Map<String, String> map = new HashMap<String, String>();
60        map.put(SIDE_KEY, PROVIDER_SIDE);
61
62        ServiceConfig.appendRuntimeParameters(map);
63        ...
64        MetadataReportConfig metadataReportConfig = getMetadataReportConfig();
65        if (metadataReportConfig != null && metadataReportConfig.isValid()) {

本文发布于:2023-06-27 13:18:29,感谢您对本站的认可!

本文链接:https://patent.en369.cn/xueshu/137001.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:服务   协议   配置   注册   信息   服务提供者
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图