我有一个Spring Boot应用程序,该应用程序使用activeMQ来排队邮件消息(POJO类)。队列部署在云的EC2实例下的云(单独的节点)中,该实例位于 tcp:// public_ip:61616 。当我在本地运行.jar时,我的应用程序可以正常工作。邮件排队并出队。
当我将相同的.jar上传到AWS Elastic Beanstalk Java Platform时,出现问题。当从云中执行.jar(以前在本地执行)时,消息将进入“ activeMQ.DLQ”队列。消息已排队但未出队。我的问题是,为什么我的Spring Boot应用程序部署在云中时不会使消息出队?
这是我的pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxxxxx</groupId>
<artifactId>xxxxxxx</artifactId>
<version>0.0.1-snAPSHOT</version>
<packaging>jar</packaging>
<name>xxxxxxProject</name>
<description>xxxxx</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JMS -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Spring Mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--Json Web Token-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>1.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-5 -->
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-5</artifactId>
<version>2.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-hibernate5 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>2.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.133</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
我的App.Properties文件:
#SpringFrameworkVersion: 4.3.13.RELEASE
#SSL Properties:
server.port=8083
server.use-forward-headers=true
#server.tomcat.remote_ip_header=x-forwarded-for
#DataBase Properties:
app.db.user=xxx
app.db.password=xxx
app.db.host=xxxxxxxxxx.us-east-1.rds.amazonaws.com
#app.db.host=localhost
app.db.port=3306
app.db.scheme=xxxxxkBD
spring.activemq.user=admin
spring.activemq.password=admin
spring.activemq.broker-url=tcp://public_ip:61616?jms.redeliveryPolicy.maximumRedeliveries=1
spring.jackson.default-property-inclusion=non_empty
spring.mvc.dispatch-options-request=true
amazonS3Properties.endpointUrlBase=https://s3.amazonaws.com
amazonS3Properties.bucketName=zzzzz.com
amazonS3Properties.region=us-east-1
#Recordar que faltan las propiedades de llave para conectarse a AWS S3
amazonS3Properties.accessKey=xx
amazonS3Properties.secretKey=xx
spring.http.multipart.max-file-size=4MB
spring.http.multipart.max-request-size=10MB
我的配置Spring Boot Bean:
@Configuration
@EnableJms
public class JavaMessageServiceConfiguration {
@Bean
public JmsListenerContainerFactory<?> myFactory( ConnectionFactory connectionFactory,DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory,connectionFactory);
return factory;
}
// Serialize message content to json using TextMessage
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
我的生产者班级:
@Component
public class Mail implements ApplicationListener<GenericEvent>{
@Autowired
private JmsTemplate jmsTemplate;
@Override
public void onApplicationEvent(GenericEvent event) {
if (event instanceof UserRegistrationEvent) {
UserRegistrationEvent registrationEvent = (UserRegistrationEvent) event;
createUserRegistrationEmailMessage(registrationEvent.getId(),registrationEvent.getEmail(),registrationEvent.getName(),registrationEvent.getappUrl());
}
}
@Transactional
private void createUserRegistrationEmailMessage(int id,String to,String name,String appUrl) {
EmailMessage emailMessage = new EmailMessage(env.getProperty("support.email"),to,subject,body.toString());
jmsTemplate.convertAndSend("mailbox",emailMessage);
}
}
我的消费者阶层:
@Component
public class MailSender {
@Autowired
private JavaMailSender mailSender;
@Async
@JmsListener(destination = "mailbox",containerFactory = "myFactory")
public void sendEmail(EmailMessage emailMessage) throws MessagingException {
System.out.println("Dequeue e-mail");
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,true);
helper.setfrom(emailMessage.getFrom());
helper.setTo(emailMessage.getTo());
helper.setSubject(emailMessage.getSubject());
helper.setText(emailMessage.getBody(),true);
mailSender.send(message);
}
}
更新:
请牢记行为的逻辑,以便他们可以更好地了解发生的情况:
当我在本地运行.jar时,该应用程序可以正常运行。现在,我在本地停止.jar,接下来我对该同一个.jar进行AWS Elastic Beanstalk部署,但是消息将发送到“ activeMQ.DLQ”。
然后,如果我再次在本地运行.jar,应用程序将停止工作(消息将进入“ activeMQ.DLQ”,原因与图中所示的相同)。
要使其在本地再次运行,我必须运行本地.jar并同时在AWS Elastic Beanstalk上重新部署相同的.jar。这样,本地.jar开始再次使消息出队,而不会出现问题。显然,在部署时,将重新启动与队列的连接,并且与本地.jar的连接将再次起作用。这是我仍然无法理解的最奇怪的行为