내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
머신이 오프라인 상태가 되면 많은 문제에 직면하게 됩니다. 등록 센터에서 머신을 오프라인으로 전환하는 방법은 무엇입니까? 리소스를 정리하고 해제하는 방법은 무엇입니까? 클라이언트는 서비스 목록을 가져올 때 로컬 캐시도 사용합니다. 로컬 캐시를 적시에 업데이트하는 방법은 무엇입니까?
서버 시스템을 정상적으로 종료하려면 ShutdownHook을 사용해야 하며 이는 종료 후크를 추가하는 것과 동일합니다. 이 후크는 JVM이 종료될 때(즉, 프로그램이 종료될 때) 호출되어 리소스를 정리하고 정상적으로 종료하세요.
- 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();
- }));
- }
후크 스레드에서는 아래와 같이 등록 센터에서 노드를 삭제하는 로직을 작성해야 합니다.
- // 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());
- }
등록 센터 ZK에서 노드를 삭제한 후 스레드 풀 리소스를 해제해야 합니다.
- 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();
- }
- });
- }
스레드 풀을 닫는 논리를 사용자 정의하면 스레드 풀 리소스의 해제를 보다 우아하게 실현할 수 있습니다. 특정 대기 시간 내에 새로운 작업 수락을 중단하고 제출된 작업을 계속 실행할 수 있습니다. 대기 시간이 초과되면 스레드 풀이 강제 종료됩니다.