docker 重新启动时无法清理 Jetty 工作目录

Unable to clean the Jetty working directory while docker is restarted

这是为了嵌入码头。我正在尝试清理在容器内的 /tmp 文件夹中自动创建的码头工作目录。我确实编写了以下方法 - “cleanJettyWorkingDirectory()”逻辑来清理工作目录并且它有效。这里的问题是,它不允许我现在创建一个工作目录,因为我认为我是从错误的地方调用这个方法的。每当我重新启动 docker 时,它都会清理整个工作目录 请协助。

public void cleanJettyWorkingDirectory(){
    final File folder = new File(JETTY_WORKING_DIRECTORY);
    final File[] files = folder.listFiles( new FilenameFilter() {
        @Override
        public boolean accept( final File dir,
                               final String name ) {
            return name.matches( "jetty-0_0_0_0-.*" );
        }
    } );

    for ( final File file : files ) {
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
           logger.info("Unable to delete the Jetty working directory");
        }
    }
}

Jetty Service Main class 文件如下:

public class JettyServer {

private final static Logger logger = Logger.getLogger(JettyServer.class.getName());
private static final int JETTY_PORT = 10000;
private static final String JETTY_REALM_PROPERTIES_FILE_NAME = "realm.properties";
private static final String JETTY_REALM_NAME = "myrealm";

private static final String JETTY_WORKING_DIRECTORY="tmp";

public static QueuedThreadPool threadPool;

public JettyServer() {

    try {
       
         cleanJettyWorkingDirectory(); // *Calling here*
        RolloverFileOutputStream os = new RolloverFileOutputStream(JETTY_STDOUT_LOG_FILE_NAME, true);
        PrintStream logStream = new PrintStream(os);
        System.setOut(logStream);
        System.setErr(logStream);

        Server server = new Server(JETTY_PORT);
        server.addBean(getLoginService());
      
            try {
                logger.info("Configuring Jetty SSL..");
                HttpConfiguration http_config = new HttpConfiguration();
                http_config.setSecureScheme("https");
                http_config.setSecurePort(JETTY_PORT);
                https.setPort(JETTY_PORT);
                server.setConnectors(new Connector[]{https});
                logger.info("Jetty SSL successfully configured..");
            } catch (Exception e){
                logger.severe("Error configuring Jetty SSL.."+e);
                throw e;
            }
        
        Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
        classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration",
                "org.eclipse.jetty.plus.webapp.EnvConfiguration",
                "org.eclipse.jetty.plus.webapp.PlusConfiguration");

        //register ui and service web apps
        HandlerCollection webAppHandlers = getWebAppHandlers();

        for (Connector c : server.getConnectors()) {
            c.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setRequestHeaderSize(MAX_REQUEST_HEADER_SIZE);
            c.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
        }

        threadPool = (QueuedThreadPool) server.getThreadPool();

        // request logs
        RequestLogHandler requestLogHandler = new RequestLogHandler();
        AsyncRequestLogWriter asyncRequestLogWriter = new AsyncRequestLogWriter(JETTY_REQUEST_LOG_FILE_NAME);
        asyncRequestLogWriter.setFilenameDateFormat(JETTY_REQUEST_LOG_FILE_NAME_DATE_FORMAT);
        asyncRequestLogWriter.setAppend(JETTY_REQUEST_LOG_FILE_APPEND);
        asyncRequestLogWriter.setRetainDays(JETTY_REQUEST_LOG_FILE_RETAIN_DAYS);
        asyncRequestLogWriter.setTimeZone(TimeZone.getDefault().getID());
        requestLogHandler.setRequestLog(new AppShellCustomRequestLog(asyncRequestLogWriter));
        webAppHandlers.addHandler(requestLogHandler);

        StatisticsHandler statisticsHandler = new StatisticsHandler();
        statisticsHandler.setHandler(new AppshellStatisticsHandler());
        webAppHandlers.addHandler(statisticsHandler);

        // set handler
        server.setHandler(webAppHandlers);

        //start jettyMetricsPsr
        JettyMetricStatistics.logJettyMetrics();

        // set error handler
        server.addBean(new CustomErrorHandler());

        // GZip Handler
        GzipHandler gzip = new GzipHandler();
        server.setHandler(gzip);
        gzip.setHandler(webAppHandlers);


        //setting server attribute for datasources
        server.setAttribute("fawappshellDS", new Resource(JNDI_NAME_FAWAPPSHELL, DatasourceUtil.getFawAppshellDatasource()));
        server.setAttribute("fawcommonDS", new Resource(JNDI_NAME_FAWCOMMON, DatasourceUtil.getCommonDatasource()));
        //new Resource(server, JNDI_NAME_FAWAPPSHELL, getFawAppshellDatasource());
        //new Resource(server, JNDI_NAME_FAWCOMMON, getFawCommonDatasource());
        
        server.start();
        server.join();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

private HandlerCollection getWebAppHandlers() throws SQLException, NamingException{
    //Setting the war and context path for the service layer: oaxservice
    WebAppContext serviceWebapp = new WebAppContext();
    serviceWebapp.setWar(APPSHELL_API_WAR_FILE_PATH);
    serviceWebapp.setContextPath(APPSHELL_API_CONTEXT_PATH);
    serviceWebapp.setPersistTempDirectory(false);

    //setting the war and context path for the UI layer: oaxui
    WebAppContext uiWebapp = new WebAppContext();
    uiWebapp.setWar(APPSHELL_UI_WAR_FILE_PATH);
    uiWebapp.setContextPath(APPSHELL_UI_CONTEXT_PATH);
    uiWebapp.setAllowNullPathInfo(true);
    uiWebapp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");

    //set error page handler for the UI context
    uiWebapp.setErrorHandler(new CustomErrorHandler());

    //handling the multiple war files using HandlerCollection.
    HandlerCollection handlerCollection = new HandlerCollection();
    handlerCollection.setHandlers(new Handler[]{serviceWebapp, uiWebapp});
    return handlerCollection;
}


public LoginService getLoginService() throws IOException {
    URL realmProps = JettyServer.class.getClassLoader().getResource(JETTY_REALM_PROPERTIES_FILE_NAME);

    if (realmProps == null)
        throw new FileNotFoundException("Unable to find " + JETTY_REALM_PROPERTIES_FILE_NAME);
    return new HashLoginService(JETTY_REALM_NAME, realmProps.toExternalForm());
}

public void cleanJettyWorkingDirectory(){
    final File folder = new File(JETTY_WORKING_DIRECTORY);
    final File[] files = folder.listFiles( new FilenameFilter() {
        @Override
        public boolean accept( final File dir,
                               final String name ) {
            return name.matches( "jetty-0_0_0_0-.*" );
        }
    } );

    for ( final File file : files ) {
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
           logger.info("Unable to delete the Jetty working directory");
        }
    }
}

public static void main(String[] args) {
    new JettyServer();
}

}

选项 1:使用 docker tmpfs

如果你想消除系统临时持久性,只需正确使用 docker 以避免它在重新启动之间这样做,不要在你的 java 应用程序中编写此自定义逻辑。

docker tmpfs 可能是更好的解决方案。

查看过去的答案:

选项 2:使用 linux systemd tmpfiles

您还可以使用 systemd-tmpfilessystemd-tmpfiles-clean 在 docker 图像的 Linux 环境中自动执行清理(定期)。

选项 3:为 Jetty 使用 non-standard 系统临时目录

为您的 Java 实例配置一个新的临时目录...

$ java -Djava.io.tmpdir=/var/run/jetty/work/ -jar start.jar

然后使用启动 Jetty 实例的 shell 脚本在执行 java 实例之前清除该唯一目录。

又名:

JETTY_WORK=/var/run/jetty/work
rm -rf $JETTY_WORK/*
java -Djava.io.tmpdir=$JETTY_WORK/ -jar start.jar

这种方法还可以从您的第 3 方库中捕获所有 Java 临时目录使用情况,而不仅仅是 Jetty 本身。