一个task项目,应用里边都是一些定时任务。我和新入职的高开商定程序部署不依赖于tomcat。

计划赶不上变化,任务开发完成还没等上线呢,哥们要离职了。工作交接时大概说了一下上线怎么部署。

结果呢,当我在linux测试服务器上部署时,可费了一些周折。之前都是把应用部署到tomcat下面的。那位高开说过,不依赖tomcat容器的部署方式已经不是新概念了。漫长的解决过程中,有同事建议我放弃,沿用tomcat吧。我觉得有必要坚持下来,最终也坚持下来了。

一.先介绍一下项目

工程如下图。assembly/bin下有一个emax-paycenter-task.sh文件,主要是通过nohup命令来运行LauncherMain。高开说了,部署时将该shell文件放到应用的根目录下,通过执行它来启动程序。

emax-paycenter-task.sh文件里是如下命令,start用的是nohup命令:

LauncherMain.java里是一个main方法,用来初始化环境:

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.context.support.XmlWebApplicationContext; import java.net.URL;
import java.util.concurrent.Semaphore; /**
* Description 启动方法
* Date 2018/2/8 上午10:01
*/
public class LauncherMain { private static Logger logger= LoggerFactory.getLogger(LauncherMain.class);
public static void main(String[] args) throws Exception { logger.info("init @Prop");
Semaphore sp = new Semaphore(0);
XmlWebApplicationContext xmlWeb = new XmlWebApplicationContext();
xmlWeb.setConfigLocation("classpath*:*spring/spring-applicationContext.xml");
String logbackCfg = "logback.xml";
URL logURL = new ClassPathResource(logbackCfg).getURL(); ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
LoggerContext loggerContext = (LoggerContext) loggerFactory; JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(loggerContext);
configurator.doConfigure(logURL); xmlWeb.refresh();
xmlWeb.start();
sp.acquire();
} }

项目中涉及到的定时任务采用Spring的@Scheduled来实现:

@Component
public class AgentPayTask { @Autowired
private LimitConfigDataHolder limitConfigDataHolder; @Autowired
private AgentPayTaskService agentPayTaskService; private static Logger logger = LoggerFactory.getLogger(AgentPayTask.class); @Scheduled(cron ="0/5 * * * * ?")
public void process() {
System.out.println("AgentPayTask111");
logger.info("AgentPayTask");
Map<String, RateLimiterConfig> LimiterMap = limitConfigDataHolder.getAgentPayLimiter();
agentPayTaskService.distributeTask(LimiterMap);
} }

二.linux部署

我在本地直接运行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

同时,日志文件里存在类似问题:spring context初始化时出现了异常。项目中一个类“AgentPayTaskQueryServiceImpl”通过@Autowired依赖注入了另一个bean“IPayCenterFacade”。

而在spring context里找不到“IPayCenterFacade”这个依赖(NoSuchBeanDefinitionException),从而导致spring context创建AgentPayTaskQueryServiceImpl实例“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

最后,将spring applicationContext里对dubbo配置文件的import由

<import resource="classpath*:*spring/dubbo-applicationContext.xml"/>

改成

<import resource="classpath:spring/dubbo-applicationContext.xml"/>

就可以了。

												

部署一个不依赖tomcat容器的应用的更多相关文章

  1. springboot项目打包部署在指定的tomcat容器中

    1.首先需要修改项目的打包方式,将package改为war <packaging>war</packaging> 2.移除spring boot web中的嵌入式tomcat ...

  2. SpringBoot项目部署在同一个tomcat容器报错

    在一个Tomcat容器中部署了两个springboot的应用,在启动时发现一直都是第一个启动的项目能启动成功,第二个项目启动报错,错误信息如下: 2018-01-30 15:49:27.810 ERR ...

  3. Docker实战之创建一个tomcat容器

    一.Docker与虚拟机的区别 二.Docker学习步骤 2.1:安装宿主操作系统 在VMVare中安装了Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic ...

  4. 给tomcat容器配置SSL的记录,包含项目完整部署过程

    给tomcat容器配置SSL(https) 昨天公司有一个旧的项目要部署, 服务器(OS是windows 10) 数据库都是新买的, 写个博客记录一下 1, 下载证书(以阿里云为例子) 参考链接: h ...

  5. 多个Spring Boot项目部署在一个Tomcat容器无法启动

    转自https://www.cnblogs.com/tomxin7/p/9434085.html 业务介绍 最近用Spring Boot开发了一个翻译的小项目,但是服务器上还跑着其他项目,包括一个同样 ...

  6. 探秘Tomcat——一个简易的Servlet容器

    即便再简陋的服务器也是服务器,今天就来循着书本的第二章来看看如何实现一个servlet容器. 背景知识 既然说到servlet容器这个名词,我们首先要了解它到底是什么. servlet 相比你或多或少 ...

  7. 如何在tomcat前部署一个nginx

    在tomcat应用已经发布后,如何在tomcat前部署一个nginx,可以正常访问jsp,静态资源(html,css,js) 这里tomcat的端口号是8888 upstream morris { s ...

  8. spring 在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property

    spring  在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property

  9. eclipse配置tomcat,并部署一个Java web项目到tomcat上

    引用链接:https://blog.csdn.net/cincoutcin/article/details/79408484 eclipse配置tomcat 1.windows——preference ...

随机推荐

  1. 使用Entity Framework Core需要注意的一个全表查询问题

    .NET Core 迁移工作如火如荼,今天在使用 Entity Frameowork Core(又名EF Core)时写了下面这样的 LINQ 查询表达式: .Where(u => u.Id = ...

  2. [No0000EE]主要的宏观经济指标查询

    主要的宏观经济指标查询 国内:东财>经济数据 _ 数据中心:http://data.eastmoney.com/center/macro.html东财>经济数据 :http://data. ...

  3. CountDownLatch简单使用

    CountDownLatch介绍 CountDownLatch是JAVA提供在java.util.concurrent包下的一个辅助类,可以把它看成是一个计数器,其内部维护着一个count计数,只不过 ...

  4. SQLServer 查询数据死锁语句

    SQLServer 查询数据死锁语句   我们可以通过以下SQL 语句用来查询,当前数据中存在的死锁语句,定位数据库出现死锁的根本原因.   --每秒死锁数量 SELECT * FROM sys.dm ...

  5. [development][C] linux 设置线程名称

    两个API, 都是linux的. 不是POSIX, 是GNU?  傻傻搞不清楚. 1. pthread_setname_np / pthread_setname_np 2. ptctl 带 PR_GE ...

  6. [math][mathematica] mathematica入门

    快速入门手册: 只找到了个中文的快速入门: https://www.wolfram.com/language/fast-introduction-for-programmers/zh/?source= ...

  7. linux配置IP访问权限

    允许访问vi /etc/hosts.allow添加(可以添加多行,其中“:allow”可以省率)sshd:192.168.81.*:allow                     #表示192.1 ...

  8. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

  9. 洛谷P3193 [HNOI2008]GT考试 kmp+dp

    正解:kmp+dp+矩阵优化 解题报告: 传送门! 啊刚说想做矩阵优化dp的字符串题就找到辣QwQ虽然不是AC自动机的但都差不多嘛QwQ 首先显然可以想到一个dp式?就f[i][j]:凑出i位了,在s ...

  10. es分页搜索

    1.es分页语法GET /_search?from=起始数&size=页面显示条数例如:GET /test_index/test_type/_search?from=0&size=3 ...