public void shutdown() {
    logger.info("Shutting down RestServer");
    long shutdownBeginTime = System.currentTimeMillis();
    try {
      //ordering is important.
      restServerState.markServiceDown();
      logger.info("Service marked as down ");

      nettyInternalMetrics.stop();
      logger.info("NettyInternalMetrics stops");

      nioServer.shutdown();
      long nioServerShutdownTime = System.currentTimeMillis();
      long elapsedTime = nioServerShutdownTime - shutdownBeginTime;
      logger.info("NIO server shutdown took {} ms", elapsedTime);
      restServerMetrics.nioServerShutdownTimeInMs.update(elapsedTime);

      restRequestHandler.shutdown();
      long requestHandlerShutdownTime = System.currentTimeMillis();
      elapsedTime = requestHandlerShutdownTime - nioServerShutdownTime;
      logger.info("Request handler shutdown took {} ms", elapsedTime);
      restServerMetrics.restRequestHandlerShutdownTimeInMs.update(elapsedTime);

      restRequestService.shutdown();
      long restRequestServiceShutdownTime = System.currentTimeMillis();
      elapsedTime = restRequestServiceShutdownTime - requestHandlerShutdownTime;
      logger.info("Rest request service shutdown took {} ms", elapsedTime);
      restServerMetrics.restRequestServiceShutdownTimeInMs.update(elapsedTime);

      restResponseHandler.shutdown();
      long responseHandlerShutdownTime = System.currentTimeMillis();
      elapsedTime = responseHandlerShutdownTime - restRequestServiceShutdownTime;
      logger.info("Response handler shutdown took {} ms", elapsedTime);
      restServerMetrics.restResponseHandlerShutdownTimeInMs.update(elapsedTime);

      router.close();
      long routerCloseTime = System.currentTimeMillis();
      elapsedTime = routerCloseTime - responseHandlerShutdownTime;
      logger.info("Router close took {} ms", elapsedTime);
      restServerMetrics.routerCloseTimeInMs.update(elapsedTime);

      accountService.close();
      long accountServiceCloseTime = System.currentTimeMillis();
      elapsedTime = accountServiceCloseTime - routerCloseTime;
      logger.info("Account service close took {} ms", elapsedTime);
      restServerMetrics.accountServiceCloseTimeInMs.update(elapsedTime);

      long notificationSystemCloseTime;
      try {
        notificationSystem.close();
      } catch (IOException e) {
        logger.error("Error while closing notification system.", e);
      } finally {
        notificationSystemCloseTime = System.currentTimeMillis();
        elapsedTime = notificationSystemCloseTime - accountServiceCloseTime;
        logger.info("Notification system close took {} ms", elapsedTime);
        restServerMetrics.notificationSystemCloseTimeInMs.update(elapsedTime);
      }

      reporter.stop();
      elapsedTime = System.currentTimeMillis() - notificationSystemCloseTime;
      logger.info("JMX reporter shutdown took {} ms", elapsedTime);
      restServerMetrics.jmxReporterShutdownTimeInMs.update(elapsedTime);
    } catch (IOException e) {
      logger.error("Exception during shutdown", e);
    } finally {
      long shutdownTime = System.currentTimeMillis() - shutdownBeginTime;
      logger.info("RestServer shutdown took {} ms", shutdownTime);
      restServerMetrics.restServerShutdownTimeInMs.update(shutdownTime);
      shutdownLatch.countDown();
    }
  }
Shuts down all the components. Returns when shutdown is FULLY complete.
This method is expected to be called in the exit path as long as the RestServer instance construction was
successful. This is expected to be called even if {@link #start()} did not succeed.
ambry-rest/src/main/java/com/github/ambry/rest/RestServer.java