背景
场景:游戏房间服务
操作:对于房间中一些耗时操作,如申请语音资源,采取以下方式提升性能瓶颈:
- 先创建一个资源池,初始化一些用户
- 使用类似 HashMap 扩容机制,保持预申请的语音房间的比例
- 申请的数据异步落到 db
- 服务器关闭前注销资源
- 定时任务关闭达到一定时间的语音房间(如 20 小时)
其中“服务器关闭前注销资源”操作,需要远程调用语音资源服务。如果 dubbo 先被注销,将导致注销资源的远程调用失败。
dubbo 版本 2.6.X
ShutdownHook
一种方式是使用 java 提供的 Runtime.getRuntime().addShutdownHook()
方法:
1 | static { |
上面的代码就是 dubbo 在 AbstractConfig
类中 static 代码块中注册 shutdown hook 的方式。
另一种方式是使用 Spring 的 @PreDestroy
注解:
1 |
|
其本质也是在 Runtime 中添加了 shutdown hook。
编辑 Dubbo ShutdownHook
查看 Runtime
源码,发现其中 addShutdownHook(Thread hook)
与 removeShutdownHook(Thread hook)
方法都是单行道:无法指定 hook 进行加入或移除操作。故此,需要通过反射的方式来操作存储 hook 的 map,从中获得 dubbo 关闭的 hook:
1 | import com.alibaba.dubbo.config.AbstractConfig; |
需要注意的是,ShutdownHook 执行时长有限,需要控制其执行时间(如多线程执行,使用 CountDownLatch 控制等待时间)
再次强调:本示例中 dubbo 版本为 2.6.X ,之后 2.7.X 的版本尚未验证可行性。