每个Java应用容器都要包含tomcat_部署一个不依赖tomcat容器的应用
一个task项目,应用里边都是一些定时任务。我和新入职的高开商定程序部署不依赖于tomcat。
计划赶不上变化,任务开发完成还没等上线呢,哥们要离职了。工作交接时大概说了一下上线怎么部署。
结果呢,当我在linux测试服务器上部署时,可费了一些周折。之前都是把应用部署到tomcat下面的。那位高开说过,不依赖tomcat容器的部署方式已经不是新概念了。漫长的解决过程中,有同事建议我放弃,沿用tomcat吧。我觉得有必要坚持下来,最终也坚持下来了。
一.先介绍一下项目
工程如下图。assembly/bin下有一个emax-paycenter-task.sh文件,主要是通过nohup命令来运行LauncherMain。高开说了,部署时将该shell文件放到应用的根目录下,通过执行它来启动程序。
emax-paycenter-task.sh文件里是如下命令,start用的是nohup命令:
LauncherMain.java里是一个main方法,用来初始化环境:
importch.qos.logback.classic.LoggerContext;importch.qos.logback.classic.joran.JoranConfigurator;importorg.slf4j.ILoggerFactory;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.core.io.ClassPathResource;importorg.springframework.web.context.support.XmlWebApplicationContext;importjava.net.URL;importjava.util.concurrent.Semaphore;/*** Description 启动方法
* Date 2018/2/8 上午10:01*/
public classLauncherMain {private static Logger logger= LoggerFactory.getLogger(LauncherMain.class);public static void main(String[] args) throwsException {
logger.info("init @Prop");
Semaphore sp= new Semaphore(0);
XmlWebApplicationContext xmlWeb= newXmlWebApplicationContext();
xmlWeb.setConfigLocation("classpath*:*spring/spring-applicationContext.xml");
String logbackCfg= "logback.xml";
URL logURL= newClassPathResource(logbackCfg).getURL();
ILoggerFactory loggerFactory=LoggerFactory.getILoggerFactory();
LoggerContext loggerContext=(LoggerContext) loggerFactory;
JoranConfigurator configurator= newJoranConfigurator();
configurator.setContext(loggerContext);
configurator.doConfigure(logURL);
xmlWeb.refresh();
xmlWeb.start();
sp.acquire();
}
}
项目中涉及到的定时任务采用Spring的@Scheduled来实现:
@Componentpublic classAgentPayTask {
@AutowiredprivateLimitConfigDataHolder limitConfigDataHolder;
@AutowiredprivateAgentPayTaskService agentPayTaskService;private static Logger logger = LoggerFactory.getLogger(AgentPayTask.class);
@Scheduled(cron="0/5 * * * * ?")public voidprocess() {
System.out.println("AgentPayTask111");
logger.info("AgentPayTask");
Map LimiterMap =limitConfigDataHolder.getAgentPayLimiter();
agentPayTaskService.distributeTask(LimiterMap);
}
}
二.linux部署
我在本地直接运行LauncherMain#main方法,程序是没问题的,里面的定时任务都可以正常跑。
将maven打包后的emax-paycenter-task-1.0.0-SNAPSHOT-assembly.tar.gz解压部署到测试服务器上。最终执行命令
./emax-paycenter-task.sh start &
查看生成的nohup.out文件,发现总是找不到class com.emax.paycenter.LauncherMain。
后来咨询运维,发现是没有给目录分配权限所致。
技能娴熟的运维又帮忙把emax-paycenter-task.sh里的命令修正了一下。最终如下:
再次按照上面命令启动程序,查看日志文件发现只有如下一条日志:
2018-03-21 15:11:45.381 [main] INFO [com.emax.paycenter.LauncherMain] - init @Prop
多次测试发现,程序执行到sp.acquire();这条语句时,就不动了;我在这条语句后加打印日志结果也没打印出来;定时任务也没执行。
了解了一下Semaphore信号量,把permits改成0或1或其他数字,都不行。
。。。。。一个小时。。。。
。。。。。两个小时。。。。
找同事帮助,无果。
。。。。。若干小时。。。。
灵感咋现!我将怀疑的焦点放到了spring context的设置这里,是不是压根都没有设置成功呢?
xmlWeb.setConfigLocation("classpath*:*spring/spring-applicationContext.xml");
莫非是各jar包里有同名的配置文件? 将路径参数"classpath*:*spring/spring-applicationContext.xml"改成"classpath:spring/spring-applicationContext.xml"后,查看nohup.out发现出现了新的问题:
[root@localhost emax-paycenter-task]# tail -f nohup.out
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:531)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:295)
... 11 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade]
found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:997)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:867)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:779)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:503)
... 13 more
同时,logback日志文件里也发现类似问题:spring context初始化时出现了异常。项目中一个类“AgentPayTaskQueryServiceImpl”通过@Autowired依赖注入了另一个type为“IPayCenterFacade”的bean,而在spring context里找不到这个类型为“IPayCenterFacade”的bean(NoSuchBeanDefinitionException),从而导致spring context创建bean “agentPayTaskQueryServiceImpl”失败(BeanCreationException异常)。
[root@localhost emax-paycenter-task]# tail -n200 -f logback-task/task_info.log
2018-03-21 16:16:37.174 [main] INFO [com.emax.paycenter.LauncherMain] - init @Prop
2018-03-21 16:16:39.397 [main] WARN [org.springframework.web.context.support.XmlWebApplicationContext] - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'agentPayTaskQueryServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.emax.paycenter.api.service.IPayCenterFacade com.emax.paycenter.service.impl.AgentPayTaskQueryServiceImpl.payCenterFacade; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1148) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:934) ~[spring-context-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) ~[spring-context-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at com.emax.paycenter.LauncherMain.main(LauncherMain.java:38) [emax-paycenter-task-1.0.0-SNAPSHOT.jar:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.emax.paycenter.api.service.IPayCenterFacade com.emax.paycenter.service.impl.AgentPayTaskQueryServiceImpl.payCenterFacade; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:531) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:295) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
... 11 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:997) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:867) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:779) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:503) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
... 13 common frames omitted
View Code
IPayCenterFacade定义在dubbo配置文件里。因此,将spring applicationContext里对dubbo配置文件的import由
改成
就可以了。
每个Java应用容器都要包含tomcat_部署一个不依赖tomcat容器的应用相关推荐
- 教你用Java的方式创建一个自己的Tomcat容器
当我们开始接触到SpringBoot项目的时候,我们特别惊讶,为什么没有了tomcat服务器,web项目还能跑起来.为什么只用了一个main方法就能讲一个web项目跑起来.学习了这篇文章你就能明白了. ...
- spring-boot项目打war包并部署到本地的tomcat容器
一.修改打包形式 在pom.xml里设置 <packaging>war</packaging> 二.移除springboot内嵌入式tomcat插件 在pom.xml里找到sp ...
- SpringBoot应用部署于外置Tomcat容器
来源:https://my.oschina.net/hansonwang99/blog/1824245 概述 SpringBoot平时我们用的爽歪歪,爽到它自己连Tomcat都自集成了,我们可以直接编 ...
- springboot容器化打包部署_SpringBoot应用部署于外置Tomcat容器的方法
0x01. 概述 SpringBoot平时我们用的爽歪歪,爽到它自己连Tomcat都自集成了,我们可以直接编写SBT启动类,然后一键开启内置的Tomcat容器服务,确实是很好上手.但考虑到实际的情形中 ...
- python需要依赖注入吗_是否需要使用依赖注入容器?
译文首发于 是否需要使用依赖注入容器?,转载请注明出处. 本文是依赖注入(Depeendency Injection)系列教程的第 2 篇文章,本系列教程主要讲解如何使用 PHP 实现一个轻量级服务容 ...
- tomcat + spring mvc原理(二):tomcat容器初始化加载和启动
tomcat + spring mvc原理(二):tomcat容器动态加载 容器通用生命周期标准 容器通用生命周期的实现 生命周期状态监听器的管理实现 生命周期方法实现 宏观来看各种容器生命周期的实际 ...
- Docker下载Tomcat镜像并运行Tomcat容器
1.上dockerhub官网 https://hub.docker.com/ 2.在dockerhub上搜索tomcat镜像 3.点击进入页面然后点击Tags页,查看关于tomcat镜像的各种版本信息 ...
- java 容器都有哪些?
目录 18.java 容器都有哪些? 19.Collection 和 Collections 有什么区别? 20.List.Set.Map 之间的区别是什么? 21.HashMap 和 Hashtab ...
- java servlet 部署到tomcat_如何把spring boot项目部署到tomcat容器中
把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改打包形式 在pom.xml里设置 war 二.移除嵌入式tomcat插件 在pom.xml里找到spring-bo ...
最新文章
- photoshop CS5 Dreamweaver CS5序列号及完美破解方法
- 第一届全国计算社会科学高端论坛在清华大学举行
- matlab“机器学习和深度学习”系列工具箱作用总结
- 使用springcloud gateway搭建网关(分流,限流,熔断)
- SAP OData batch request的并行处理实现原理
- Linux文件系统为,浅析Linux文件系统
- python使用logging模块记录日志
- 【Python】 Python数据类型
- oracle form lov 查询慢
- 2287: 【POJ Challenge】消失之物
- LINK : fatal error LNK1104: 无法打开文件“ucrtd.lib”
- Spring boot 拦截器(HandlerInterceptor) 与 自定义资源映射虚拟路径,WebMvcConfigurer
- 大二暑假假期周进度01
- 期待了1年多了《黑客攻防实战编程》终于面世了!
- 2010年最怪异的25个面试问题,你能回答吗?
- android视频播放异常,Android 播放视频常见问题小结
- 中国地区三级联动下拉菜单
- 关于“企业文化”的联想
- python 学习简记 《编程导论》 CH4CH5
- 基于8086单片机的PWM调光(带汇编)