二Dubbo设计基础--4Dubbo-URL

二Dubbo设计基础--4Dubbo-URL

2.4.1 Dubbo中的URL

一个标准的 URL 格式至多可以包含如下的几个部分

protocol://username:password@host:port/path?key=value&key=value

在 dubbo 中,也使用了类似的 URL,主要用于在各个扩展点之间传递数据,组成此 URL 对象的具体参数如下:

  • protocol:一般是 dubbo 中的各种协议 如:dubbo thrift http zk
  • username/password:用户名/密码
  • host/port:主机/端口
  • path:接口名称
  • parameters:参数键值对
public URL(String protocol, String username, String password, String host, int port, String path, Map<String, String> parameters) {
    if ((username == null || username.length() == 0) 
        && password != null && password.length() > 0) {
        throw new IllegalArgumentException("Invalid url, password without username!");
    }
    this.protocol = protocol;
    this.username = username;
    this.password = password;
    this.host = host;
    this.port = (port < 0 ? 0 : port);
    this.path = path;
    // trim the beginning "/"
    while(path != null && path.startsWith("/")) {
        path = path.substring(1);
    }
    if (parameters == null) {
        parameters = new HashMap<String, String>();
    } else {
        parameters = new HashMap<String, String>(parameters);
    }
    this.parameters = Collections.unmodifiableMap(parameters);
}

示例

描述一个 dubbo 协议的服务

dubbo://192.168.1.6:20880/moe.cnkirito.sample.HelloService?timeout=3000

描述一个 zookeeper 注册中心

zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=1214&qos.port=33333&timestamp=1545721981946

描述一个消费者

consumer://30.5.120.217/org.apache.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.0.2&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=1209&qos.port=33333&side=consumer&timestamp=1545721827784

URL的生命周期

  • 解析服务
  • 暴露服务
  • 引用服务

(1)解析服务

基于 dubbo.jar 内的 META-INF/spring.handlers 配置,Spring 在遇到 dubbo 名称空间时,会回调 DubboNamespaceHandler。

所有 dubbo 的标签,都统一用 DubboBeanDefinitionParser 进行解析,基于一对一属性映射,将 XML 标签解析为 Bean 对象。

在 ServiceConfig.export() 或 ReferenceConfig.get() 初始化时,将 Bean 对象转换 URL 格式,所有 Bean 属性转成 URL 的参数。

然后将 URL 传给协议扩展点,基于扩展点自适应机制,根据 URL 的协议头,进行不同协议的服务暴露或引用。

(2)暴露服务

\1. 只暴露服务端口:

在没有注册中心,直接暴露提供者的情况下,ServiceConfig 解析出的 URL 的格式为:dubbo://service-host/com.foo.FooService?version=1.0.0。

基于扩展点自适应机制,通过 URL 的 dubbo:// 协议头识别,直接调用 DubboProtocol的 export() 方法,打开服务端口。

\2. 向注册中心暴露服务:

在有注册中心,需要注册提供者地址的情况下,ServiceConfig 解析出的 URL 的格式为: registry://registry-host/org.apache.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0"),

基于扩展点自适应机制,通过 URL 的 registry:// 协议头识别,就会调用 RegistryProtocol 的 export() 方法,将 export 参数中的提供者 URL,先注册到注册中心。

再重新传给 Protocol 扩展点进行暴露: dubbo://service-host/com.foo.FooService?version=1.0.0,然后基于扩展点自适应机制,通过提供者 URL 的 dubbo:// 协议头识别,就会调用 DubboProtocol 的 export() 方法,打开服务端口

(3)引用服务

\1. 直连引用服务:

在没有注册中心,直连提供者的情况下,ReferenceConfig 解析出的 URL 的格式为:dubbo://service-host/com.foo.FooService?version=1.0.0。

基于扩展点自适应机制,通过 URL 的 dubbo:// 协议头识别,直接调用 DubboProtocol 的 refer() 方法,返回提供者引用。

\2. 从注册中心发现引用服务:

在有注册中心,通过注册中心发现提供者地址的情况下,ReferenceConfig 解析出的 URL 的格式为:registry://registry-host/org.apache.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")。

基于扩展点自适应机制,通过 URL 的 registry:// 协议头识别,就会调用 RegistryProtocol 的 refer() 方法,基于 refer 参数中的条件,查询提供者 URL,如: dubbo://service-host/com.foo.FooService?version=1.0.0。

基于扩展点自适应机制,通过提供者 URL 的 dubbo:// 协议头识别,就会调用 DubboProtocol 的 refer() 方法,得到提供者引用。

然后 RegistryProtocol 将多个提供者引用,通过 Cluster 扩展点,伪装成单个提供者引用返回。

URL 统一模型的意义

对于 dubbo 中的 URL,有人理解为配置总线,有人理解为统一配置模型,说法虽然不同,但都是在表达一个意思,这样的 URL 在 dubbo 中被当做是公共契约,所有扩展点参数都包含 URL 参数,URL 作为上下文信息贯穿整个扩展点设计体系。

2.4.2 override动态配置协议

动态配置override协议,可以让用户动态修改配置,并实时生效。该功能通常由监控中心或治理中心的页面完成。详细内容看官网:

RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&timeout=1000"));

注意上述url代表的内容:

  • override:// 表示数据采用覆盖方式,支持 overrideabsent,可扩展,必填
  • 0.0.0.0 表示对所有 IP 地址生效,如果只想覆盖某个 IP 的数据,请填入具体 IP,必填
  • com.foo.BarService 表示只对指定服务生效,必填
  • category=configurators 表示该数据为动态配置类型,必填
  • dynamic=false 表示该数据为持久数据,当注册方退出时,数据依然保存在注册中心,必填
  • enabled=true 覆盖规则是否生效,可不填,缺省生效。
  • application=foo 表示只对指定应用生效,可不填,表示对所有应用生效。
  • timeout=1000 表示将满足以上条件的 timeout 参数的值覆盖为 1000。如果想覆盖其它参数,直接加在 override 的 URL 参数上。

通过上面的override内参数定义的配置规则,可以实现如下的功能,例如:

  1. 禁用提供者:(通常用于临时踢除某台提供者机器,相似的,禁止消费者访问请使用路由规则)

    override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&disbaled=true
    
  2. 调整权重:(通常用于容量评估,缺省权重为 100)

    override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&weight=200
    
  3. 调整负载均衡策略:(缺省负载均衡策略为 random)

    override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&loadbalance=leastactive
    
  4. 服务降级:(通常用于临时屏蔽某个出错的非关键服务)

    override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null
    
posted @ 2023-03-13 14:36  LeasonXue  阅读(106)  评论(0编辑  收藏  举报