代码之家  ›  专栏  ›  技术社区  ›  Grim

优化持续部署(取消责任链)

  •  9
  • Grim  · 技术社区  · 7 年前

    我想改进连续交货。我用的是Tomcat8和Maven。

    我用 mvn tomcat:redeploy 部署webapp。

    tomcat documentation 我发现这部分:

    远程部署新的应用程序存档(war)

    如果安装和启动成功,您将收到(…)

    否则,响应将以失败开始,并包含一条错误消息。

    可能的原因 FAIL 一点是相互关联的:

    尝试启动新的Web应用程序时遇到异常。

    所以我想在启动时抛出一个异常,所以 web.xml 我写道:

    <启动时加载>1</启动时加载>

    org.springframework.web.servlet.DispatcherServlet servlet。然后我写了一首单曲:

    @Service
    public class AvoidStartupOnMissingDatabase implements SmartInitializingSingleton {
    
        @Override
        public void afterSingletonsInstantiated() {
            throw new RuntimeException("Do not deploy this app!");
        }
    }
    

    这将导致此stacktrace:

    java.lang.RuntimeException: Do not deploy this app!
            at xxx.AvoidStartupOnMissingDatabase.afterSingletonsInstantiated(AvoidStartupOnMissingDatabase.java:11)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
            at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:664)
            at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:630)
            at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:678)
            at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:549)
            at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:490)
            at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
            at javax.servlet.GenericServlet.init(GenericServlet.java:158)
            at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1144)
            at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1091)
            at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:983)
            at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4962)
            at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5274)
            at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
            at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3823)
            at org.apache.catalina.startup.HostConfig.reload(HostConfig.java:1410)
            at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1320)
            at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1648)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:497)
            at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
            at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
            at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
            at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1525)
            at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:773)
            at org.apache.catalina.manager.ManagerServlet.doPut(ManagerServlet.java:443)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:664)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
            at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
            at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:613)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
            at org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:486)
            at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
            at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
            at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
            at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)
    

    问题

    应用程序部署失败!

    Screenshot of ci

    问题

    初始化失败。我说了开始加载。Tomcat说如果不启动就失败。Tomcat说如果可以的话重新部署。

    因此,异常必须在部署中失败。对吗?

    编辑

    我测试了Tomcat-8.5.30和Tomcat-8.5.37,不幸的是两者都成功了。

    3 回复  |  直到 7 年前
        1
  •  4
  •   Grim    7 年前

    IV创建了 bug in Tomcat . 开发人员引导我找到解决方案 类似于亚历山德罗科乔卡鲁。

    我从servlet移动到serlvetContextListener,并成功地接收到部署的“失败”。

    在这种无效部署之后,旧应用程序很不幸 重新启动。但是对SVN的提交被成功取消,并且不会添加到SVN更改日志中!

        2
  •  0
  •   JRichardsz    7 年前

    Tomcat有两个部署战争文件的选项:

    • 将战争复制到webapps
    • HTTP Tomcat端点/管理器/文本/部署

    更多详细信息和配置 answer

    另外,tomcat:redeploy不用于回滚目的,只用于部署一个没有必要的现有战争或重新打包。

    我相信 mvn tomcat:deploy 插件使用 /管理器/文本/部署 用于部署战争文件的Tomcat端点。

    假设您使用一些持续集成服务器(Jenkins、Travis等)或只是一个简单的shell脚本来调用前面的步骤,我建议您使用以下方法执行回滚:

    回滚参数

    在流中添加一个新的输入参数,称为:rollback_tag或previous_version。

    使用maven回滚

    maven是编译和生成war或jar文件的最佳选项。但就部署而言,我认为这不是最佳选择。我不想在pom.xml(有或没有变量)中共享凭证或配置:

    <plugin>
       <groupId>org.codehaus.mojo</groupId>
       <artifactId>tomcat-maven-plugin</artifactId>
       <version>1.1</version>
       <configuration>
          <url>http://localhost:8080/manager/text</url>
          <server>TomcatServer</server>
          <path>/javaCodeGeeks</path>
       </configuration>
    </plugin>
    

    无论如何,如果你想使用Maven,你需要:

    • 搜索maven插件的源代码
    • 扩展它或添加新功能,如:
      • 从Tomcat部署捕获错误
      • 使用一些标记版本下载源代码
      • 出错时重新部署

    再次回滚下载

    步骤可以是:

    • (1)使用SVN下载源文件
    • (2)执行mvn clean包
    • (3)执行mvn-tomcat:deploy
      • 此命令必须返回退出代码
      • (3.1)如果退出代码==0,则表示部署成功。
      • (3.2)出口代码!=0,表示部署错误。继续(4)步骤
    • (4)使用SVN下载源,但在这种情况下,必须使用 rollback tag 参数化并重复步骤(2)和(3)

    使用一些工件存储库

    使用这个工具,我们只需要使用SVN下载一次源代码。编译和成功部署之后,必须 上传 具有特定版本(如1.0.0)的war或jar文件流中的下一步只需要下载war/jar文件。

    如果在1.0.1部署中出现错误,您只需要从工件存储库下载以前的稳定版本1.0.0。 步骤可以是:

    • (1)检测 支持向量机提交 开发人员的操作,使用持续集成服务器或shell脚本编译、测试和上传war文件到工件存储库。
    • (2)从工件存储库下载war文件
    • (3)执行curl命令上传和部署war文件。更多详细信息和配置如下:
    • (4)如果出现错误,请从工件存储库下载war文件,但在这种情况下,必须使用 以前的版本 参数并重复步骤(3)
        3
  •  0
  •   Alexandru Cojocaru    7 年前

    部署成功。您看到的堆栈跟踪是由应用程序运行时错误引起的,当Spring尝试加载 AvoidStartupOnMissingDatabase 豆类。此时,应用程序已经部署并运行。

    如果你想成为马文 redeploy 目标失败,您需要在部署过程中导致错误,而不是在应用程序运行时。您可以使用 wrong URL 例如,在maven-tomcat插件配置中。