informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Ketika sebuah mesin offline, ia menghadapi banyak masalah: Bagaimana cara menjadikannya offline dari pusat registrasi? Bagaimana cara membersihkan dan melepaskan sumber daya? Klien juga menggunakan cache lokal ketika menarik daftar layanan. Bagaimana cara memperbarui cache lokal tepat waktu?
Mematikan mesin server dengan baik memerlukan penggunaan ShutdownHook, yang setara dengan menambahkan hook shutdown. Hook ini adalah thread yang dipanggil ketika JVM dimatikan (yaitu, ketika program berakhir) untuk membersihkan sumber daya dan ditutup dengan anggun.
- public void clearAll() {
- log.info("addShutdownHook for clearAll");
- // 添加了一个关闭钩子,这个钩子是一个线程,它在JVM关闭时(即程序结束时)被调用,清理资源,优雅下机
- Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- try {
- InetSocketAddress inetSocketAddress = new InetSocketAddress(InetAddress.getLocalHost().getHostAddress(), NettyRpcServer.PORT);
- CuratorUtils.clearRegistry(CuratorUtils.getZkClient(), inetSocketAddress);
- } catch (UnknownHostException ignored) {
- }
- // 操作完整、优雅,便于释放连接资源,便于自定义清理逻辑
- ThreadPoolFactoryUtil.shutDownAllThreadPool();
- }));
- }
Di thread hook, Anda perlu menulis logika untuk menghapus node dari pusat registrasi, seperti yang ditunjukkan di bawah ini:
- // RPC Server端 本机所注册服务的缓存
- private static final Set<String> REGISTERED_PATH_SET = ConcurrentHashMap.newKeySet();
-
- public static void clearRegistry(CuratorFramework zkClient, InetSocketAddress inetSocketAddress) {
- REGISTERED_PATH_SET.stream().parallel().forEach(p -> {
- try {
- // 是本机在ZK注册的节点
- if (p.endsWith(inetSocketAddress.toString())) {
- // 根据路径名删除节点
- zkClient.delete().forPath(p);
- }
- } catch (Exception e) {
- log.error("clear registry for path [{}] fail", p);
- }
- });
- log.info("All registered services on the server are cleared:[{}]", REGISTERED_PATH_SET.toString());
- }
Setelah menghapus node di pusat pendaftaran ZK, sumber daya kumpulan thread harus dilepaskan:
- public static void shutDownAllThreadPool() {
- log.info("call shutDownAllThreadPool method");
- THREAD_POOLS.entrySet().parallelStream().forEach(entry -> {
- ExecutorService executorService = entry.getValue();
- // 停止接收新的任务,但已提交的任务会继续执行
- executorService.shutdown();
- log.info("shut down thread pool [{}] [{}]", entry.getKey(), executorService.isTerminated());
- try {
- // 等待线程池中的任务在指定的时间内完成。如果在指定时间内线程池未能终止,会抛出 InterruptedException
- executorService.awaitTermination(10, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- log.error("Thread pool never terminated");
- // 指定时间内线程池未能终止,立即停止所有正在执行的任务
- executorService.shutdownNow();
- }
- });
- }
Menyesuaikan logika penutupan kumpulan thread dapat mewujudkan pelepasan sumber daya kumpulan thread dengan lebih elegan. Itu dapat berhenti menerima tugas baru dan terus menjalankan tugas yang diserahkan dalam rentang waktu tunggu tertentu. Jika waktu tunggu terlampaui, kumpulan thread akan dihentikan secara paksa.