引入
在dubbo中,URL是整个服务发布和调用流程的串联信息,它包含了服务的基本信息(服务名、服务方法、版本、分组),注册中心配置,应用配置等信息,并且通过URL可以实现扩展点自适应等。
它是在服务发布和注册的时候,进行生成的,即在 ServiceConfig.export() 或 ReferenceConfig.get() 初始化时,将 Bean 对象转换 URL 格式,所有 Bean 属性转成 URL 的参数。然后将 URL 传给 协议扩展点,基于扩展点的 扩展点自适应机制,根据 URL 的协议头,进行不同协议的服务暴露或引用。
演示
下面将以这个例子,来演示服务发布后生成的URL
public static void main(String[] args) throws IOException {
ServiceConfig<GreetingService> serviceConfig = new ServiceConfig<GreetingService>();
// 设置应用
serviceConfig.setApplication(new ApplicationConfig("first-dubbo-provider"));
// 设置注册中心
serviceConfig.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
// 设置服务接口
serviceConfig.setInterface(GreetingService.class);
serviceConfig.setRef(new GreetingServiceImpl());
// 设置服务具体方法,如这里设置服务超时时间为1000
MethodConfig methodConfig = new MethodConfig();
methodConfig.setName("sayHello");
methodConfig.setTimeout(1000);
serviceConfig.setMethods(Collections.singletonList(methodConfig));
// 发布服务
serviceConfig.export();
System.in.read();
}
可以看到生成的信息如下
dubbo://10.0.75.1:20880/com.wuhulala.dubbo.gateway.GreetingService?anyhost=true&application=first-dubbo-provider&default.deprecated=false&default.dynamic=false&default.register=true&deprecated=false&dubbo=2.0.2&dynamic=false&generic=false&interface=com.wuhulala.dubbo.gateway.GreetingService&methods=sayHello&pid=3272®ister=true&release=2.7.2-SNAPSHOT&sayHello.timeout=1000&side=provider×tamp=1554523631703
分析一下可以看到如
application=first-dubbo-provider
sayHello.timeout=1000
interface=com.wuhulala.dubbo.gateway.GreetingService
generic=false
那么具体是如何实现的呢
实现
ServiceConfig#doExportUrlsFor1Protocol
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
String name = protocolConfig.getName();
if (StringUtils.isEmpty(name)) {
name = Constants.DUBBO;
}
Map<String, String> map = new HashMap<String, String>();
// 设置为服务端
map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
// 设置运行时参数,dubbo-version、pid、release、timestamp
appendRuntimeParameters(map);
// 设置dubbo:application 信息,如应用名称、owner、organization等
appendParameters(map, application);
// 设置模块的信息
appendParameters(map, module);
// 设置默认的provider配置,具体指的就是dubbo:provider 的配置
appendParameters(map, provider, Constants.DEFAULT_KEY);
// 设置协议的信息 ,dubbo:protocol
appendParameters(map, protocolConfig);
// 设置dubbo:service 即服务自身的配置
appendParameters(map, this);
// 设置dubbo:method 的配置,
// 代码可以优化吧 ,这里应该抽出来一个方法吧,从而方便阅读
if (CollectionUtils.isNotEmpty(methods)) {
for (MethodConfig method : methods) {
appendParameters(map, method, method.getName());
String retryKey = method.getName() + ".retry"