minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Quando uma máquina fica off-line, ela enfrenta muitos problemas: Como colocá-la off-line na central de registro? Como limpar e liberar recursos? O cliente também usa o cache local ao extrair a lista de serviços. Como atualizar o cache local a tempo?
O desligamento normal da máquina servidora requer o uso de ShutdownHook, que equivale a adicionar um gancho de desligamento. Esse gancho é um thread que é chamado quando a JVM é encerrada (ou seja, quando o programa termina) para limpar recursos e. desligue graciosamente.
- 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();
- }));
- }
No thread do gancho, você precisa escrever a lógica para excluir nós do centro de registro, conforme mostrado abaixo:
- // 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());
- }
Após excluir o nó no centro de registro ZK, os recursos do pool de threads precisam ser liberados:
- 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();
- }
- });
- }
Personalizar a lógica de fechamento do pool de threads pode realizar a liberação dos recursos do pool de threads de maneira mais elegante. Ele pode parar de aceitar novas tarefas e continuar a executar as tarefas enviadas dentro de um determinado intervalo de tempo de espera. Se o tempo de espera for excedido, o pool de threads será encerrado à força.