diamond源码分析(一)之diamond-server

1. diamond-service启动时,通过spring注解@PostConstruct 标注NotifyService的loadNodes方法来获取所有node.properties里配置的节点信息。

2. @RequestMapping(params = "method=login", method = RequestMethod.POST),通过params="method=xxx"来指定某个url访问到controller的方法,例如xxx.do?method=login是访问Controller的login方法,是通过applicationContext.xml的org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter配置实现。

3. 用户登录:在AdminService这个类初始化时候load了user.properties到properties对象中,然后通过登录时提交的用户名和密码与properties对象中的用户名和密码比较。

4. 用户管理:都是对user.properties的增删改查。

5. 添加配置信息:对应的AdminController的postConfig方法,保存顺序:数据库->更新md5cache->本地磁盘->通知其他节点更新;md5cache是用ConcurrentHashMap<String, String>存储的,key是group/dataId,value是content的md5字符串,MD5类是单例的,对数据进行md5的算法加了锁。通知其他节点更新的方式:首先获取node.properties保存的地址,然后通过http方式。调用NotifyController的notifyConfigInfo方法来保存配置信息到磁盘,值得一提是DiskService的saveToDisk方法使用了ConcurrentHashMap的putIfAbsent来进行并发写入的控制,类似于memcache的cas原子操作。

6. 更新配置信息:更新的方式同添加,区别只是入库的操作由insert->update。

7. 预览的方法是调用了一个servlet,ConfigServlet,为什么预览操作用了最传统的servlet而非springmvc的controller呢,肯定是为了效率,servlet直接由tomcat处理请求,框架还要多包一层,况且这个servlet不光后台用到,在client端同步数据的时候也用到了。预览的操作走的是doGet方法,读取的是本地config-data目录下的对应文件,ConfigServlet中有个doPost方法是client端同步数据时调用的。

8. 保存磁盘:该方法调用的就是更新配置信息时最后一步调用的通知其他节点更新的controller。

9. 删除配置信息:顺序是先根据配置信息的数据库的主键id查找ConfigInfo->删除对应的本地磁盘文件->清除对应的md5cache->删除数据库中相应数据->通知其他节点更新,同样的删除对应的本地磁盘文件时也使用了ConcurrentHashMap的putIfAbsent来进行并发写入的控制,删除文件时group这级目录是会保留的,只是删除了对应dataId的文件。

10. server端的定时任务:TimerTaskService这个类被spring容器初始化完成时会启动一个单线程的定时器,定时器的目的是每间隔一段时间将数据库中几乎所有数据从数据库中dump到磁盘。并更新md5cache,定时任务的间隔时间是从system.properties中获取的,单位为秒。在启动定时器之前会先dump一次数据。

问题来了:TimerTaskService中注解了@PreDestroy的方法什么时候执行呢? 实际上是在调用了WebApplicationContext的close方法时候,正常的close掉tomcat(运行shutdown脚本,eclipse的话点击tomcat的stop)。

通知其他节点更新操作:这个操作上次没有说清楚,实际操作是获取diamond-server事先配置的node.properties,我在本地做的实验如下,搭建两个centos虚拟机,每个服务器下部署一个tomcat,然后将主机的diamond-server的node.properties配置成如下:当有写入操作时就如之前分析会远程调用对应地址diamond-server的NotifyController的notifyConfigInfo方法来保存配置信息到磁盘,这就是通知机制的实现,至此diamond-server分析完毕!

#ip\:port=

#第一个虚拟机ip地址

10.100.17.62\:8080 

#第二个虚拟机ip地址

10.100.17.40\:8080



你可能感兴趣的:(源码分析,diamond)