public void shutdown() {
    long startTime = SystemTime.getInstance().milliseconds();
    try {
      logger.info("shutdown started");
      if (nettyInternalMetrics != null) {
        nettyInternalMetrics.stop();
      }
      if (consistencyCheckerTask != null) {
        consistencyCheckerTask.cancel(false);
      }
      if (clusterParticipants != null) {
        clusterParticipants.forEach(ClusterParticipant::close);
      }
      if (consistencyCheckerScheduler != null) {
        shutDownExecutorService(consistencyCheckerScheduler, 5, TimeUnit.MINUTES);
      }
      if (scheduler != null) {
        shutDownExecutorService(scheduler, 5, TimeUnit.MINUTES);
      }
      if (statsManager != null) {
        statsManager.shutdown();
      }
      if (networkServer != null) {
        networkServer.shutdown();
      }
      if (nettyHttp2Server != null) {
        nettyHttp2Server.shutdown();
      }
      if (requestHandlerPoolForHttp2 != null) {
        requestHandlerPoolForHttp2.shutdown();
      }
      if (requestHandlerPool != null) {
        requestHandlerPool.shutdown();
      }
      if (repairRequestsSender != null) {
        repairRequestsSender.shutdown();
      }
      if (repairHandlerPool != null) {
        repairHandlerPool.shutdown();
      }
      if (repairThread != null) {
        repairThread.join();
      }
      if (repairRequestsDb != null) {
        repairRequestsDb.close();
      }

      if (localChannel != null) {
        localChannel.shutdown();
      }
      if (backupIntegrityMonitor != null) {
        backupIntegrityMonitor.shutdown();
      }
      if (recoveryManager != null) {
        recoveryManager.shutdown();
      }
      if (replicationManager != null) {
        replicationManager.shutdown();
      }
      if (storageManager != null) {
        storageManager.shutdown();
      }
      if (fileCopyBasedReplicationManager != null) {
       fileCopyBasedReplicationManager.shutdown();
      }
      if(prioritizationManager != null){
        prioritizationManager.shutdown();
      }
      if (connectionPool != null) {
        connectionPool.shutdown();
      }
      if (reporter != null) {
        reporter.stop();
      }
      if (notificationSystem != null) {
        try {
          notificationSystem.close();
        } catch (IOException e) {
          logger.error("Error while closing notification system.", e);
        }
      }
      if (clusterMap != null) {
        clusterMap.close();
      }
      if (serverSecurityService != null) {
        serverSecurityService.close();
      }

      if (replicationPrioritizationManager != null) {
        replicationPrioritizationManager.shutdown();
      }

      logger.info("shutdown completed");
    } catch (Exception e) {
      logger.error("Error while shutting down server", e);
    } finally {
      shutdownLatch.countDown();
      long processingTime = SystemTime.getInstance().milliseconds() - startTime;
      metrics.serverShutdownTimeInMs.update(processingTime);
      logger.info("Server shutdown time in Ms {}", processingTime);
    }
  }
This method is expected to be called in the exit path as long as the AmbryServer instance construction was
successful. This is expected to be called even if {@link #startup()} did not succeed.
ambry-server/src/main/java/com/github/ambry/server/AmbryServer.java