Dubbo提供者本地缓存配置源码解析
2018-06-15 14:19
603 查看
问题
![](http://dubbo.apache.org/images//dubbo-architecture.png)
根据官方图,dubbo调用者需要通过注册中心(例如:ZK)注册信息,获取提供者,但是如果频繁往ZK获取信息,肯定会存在单点故障问题,所以dubbo提供了将提供者信息缓存在本地的方法。
Dubbo调用者在连接ZK后,提供者列表是如何进行本地缓存的?
源码
com.alibaba.dubbo.registry.support.AbstractRegistry类读取配置:
public AbstractRegistry(URL url) { setUrl(url); // Start file save timer //<------------------------此处用于配置是否将提供者缓存到本地,如果不配置,则默认为false syncSaveFile = url.getParameter(Constants.REGISTRY_FILESAVE_SYNC_KEY, false); String filename = url.getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/.dubbo/dubbo-registry-" + url.getParameter(Constants.APPLICATION_KEY) + "-" + url.getAddress() + ".cache"); File file = null; if (ConfigUtils.isNotEmpty(filename)) { file = new File(filename); if (!file.exists() && file.getParentFile() != null && !file.getParentFile().exists()) { if (!file.getParentFile().mkdirs()) { throw new IllegalArgumentException("Invalid registry store file " + file + ", cause: Failed to create directory " + file.getParentFile() + "!"); } } } this.file = file; loadProperties(); notify(url.getBackupUrls()); } .......省略很多代码 private void saveProperties(URL url) { if (file == null) { return; } try { StringBuilder buf = new StringBuilder(); Map<String, List<URL>> categoryNotified = notified.get(url); if (categoryNotified != null) { for (List<URL> us : categoryNotified.values()) { for (URL u : us) { if (buf.length() > 0) { buf.append(URL_SEPARATOR); } buf.append(u.toFullString()); } } } properties.setProperty(url.getServiceKey(), buf.toString()); long version = lastCacheChanged.incrementAndGet(); //<-----------如果开启了缓存,将会调用保存方法 if (syncSaveFile) { doSaveProperties(version); } else { registryCacheExecutor.execute(new SaveProperties(version)); } } catch (Throwable t) { logger.warn(t.getMessage(), t); } } public void doSaveProperties(long version) { if (version < lastCacheChanged.get()) { return; } if (file == null) { return; } // Save try { File lockfile = new File(file.getAbsolutePath() + ".lock"); if (!lockfile.exists()) { lockfile.createNewFile(); } RandomAccessFile raf = new RandomAccessFile(lockfile, "rw"); try { FileChannel channel = raf.getChannel(); try { FileLock lock = channel.tryLock(); if (lock == null) { throw new IOException("Can not lock the registry cache file " + file.getAbsolutePath() + ", ignore and retry later, maybe multi java process use the file, please config: dubbo.registry.file=xxx.properties"); } // Save try { if (!file.exists()) { file.createNewFile(); } FileOutputStream outputFile = new FileOutputStream(file); try { properties.store(outputFile, "Dubbo Registry Cache"); } finally { outputFile.close(); } } finally { lock.release(); } } finally { channel.close(); } } finally { raf.close(); } } catch (Throwable e) { if (version < lastCacheChanged.get()) { return; } else { registryCacheExecutor.execute(new SaveProperties(lastCacheChanged.incrementAndGet())); } logger.warn("Failed to save registry store file, cause: " + e.getMessage(), e); } }
Constants常量类中,定义了很多dubbo中配置需要的参数名信息。
Constants.REGISTRY_FILESAVE_SYNC_KEY 源码
public static final String REGISTRY_FILESAVE_SYNC_KEY = "save.file";
默认配置文件本地缓存路径,代码如下:
String filename = url.getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/.dubbo/dubbo-registry-" + url.getParameter(Constants.APPLICATION_KEY) + "-" + url.getAddress() + ".cache"); File file = null; if (ConfigUtils.isNotEmpty(filename)) { file = new File(filename); if (!file.exists() && file.getParentFile() != null && !file.getParentFile().exists()) { if (!file.getParentFile().mkdirs()) { throw new IllegalArgumentException("Invalid registry store file " + file + ", cause: Failed to create directory " + file.getParentFile() + "!"); } } } this.file = file;
上面配置文件读取的常量Key:
Constants.FILE_KEY = "file";
doSaveProperties 方法中通过在本地利用文件锁实现配置信息占用的问题,所以如果本地有多个dubbo实例,使用默认值会出现冲突的情况。此时需要在dubbo配置中添加不同的dubbo.registry.file进行区分;否则会有如下日志提示:
Can not lock the registry cache file " + file.getAbsolutePath() + ", ignore and retry later, maybe multi java process use the file, please config: dubbo.registry.file=xxx.properties
相关文章推荐
- dubbo本地缓存提供者信息配置问题
- Dubbo源码解析之配置解析篇
- dubbo源码解析(六) dubbo服务发布过程及本地暴露
- dubbo源码:配置文件加载自定义标签解析
- Dubbo源码解析之服务提供者篇
- 4、Volley解析(二),源码的深入分析一,缓存线程和网络请求线程
- Dubbo源码解析 —— zookeeper连接
- 【Spring实战】----源码解析Spring Security4.1.3中的过滤器Filter配置
- 聊聊Dubbo - Dubbo可扩展机制源码解析
- GlusterFS源码解析 —— GlusterFS 配置
- dubbo参数配置解析
- Dubbo源码解析 —— 服务暴露总结
- Dubbo项目配置文件解析
- NGINX----源码阅读---配置文件解析
- Dnsmasq安装与配置-搭建本地DNS服务器 更干净更快无广告DNS解析
- 【MyBatis源码分析】plugins解析属性配置元素详述
- 【Spring Boot】SpringBoot-自动配置源码解析
- 配置dubbo 源码
- Dubbo源码解析 —— 逻辑层设计之服务降级
- dubbo源码解析(九) dubbo中的zookeeper使用