在读取ActiveMQ队列时,如何防止Spring JmsTemplate单元测试阻塞?
当试图从队列在读取ActiveMQ队列时,如何防止Spring JmsTemplate单元测试阻塞?,spring,testing,activemq,spring-jms,jmstemplate,Spring,Testing,Activemq,Spring Jms,Jmstemplate,当试图从队列Person.queue读取Person对象时,如何防止单元测试sendanderecieveperson()阻塞 该测试创建一个Person对象,将其发送到队列Person.queue(这还应创建包含该队列的嵌入式代理),然后尝试从同一队列读取该对象 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {MessagingConfiguration.class}) public class
Person.queue
读取Person
对象时,如何防止单元测试sendanderecieveperson()
阻塞
该测试创建一个Person
对象,将其发送到队列Person.queue
(这还应创建包含该队列的嵌入式代理),然后尝试从同一队列读取该对象
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MessagingConfiguration.class})
public class PersonMessengerTest {
@Autowired
private PersonMessenger personMessenger;
@Test
public void sendAndReceivePerson() {
final Person person = new Person();
final UUID id = UUID.randomUUID();
person.setId(id);
person.setFirstName("Derek");
person.setLastName("Mahar");
personMessenger.sendPersion(person);
final Person receivedPersion = personMessenger.receivePersion();
assertEquals(id, receivedPersion.getId());
}
}
public class PersonMessenger {
private final JmsOperations jmsOperations;
public PersonMessenger(JmsOperations jmsOperations) {
this.jmsOperations = jmsOperations;
}
public void sendPersion(final Person person) {
this.jmsOperations.convertAndSend(person);
}
public Person receivePersion() {
return (Person) this.jmsOperations.receiveAndConvert();
}
}
@Configuration
@Import({CommonConfiguration.class})
public class MessagingConfiguration {
public static final String PERSON_QUEUE = "person.queue";
@Autowired
private ApplicationEnvironment applicationEnvironment;
@Bean
public ConnectionFactory jmsConnectionFactory() {
final ActiveMQConnectionFactory activeMqConnectionFactory = new ActiveMQConnectionFactory(
this.applicationEnvironment.getJmsBrokerUrl());
activeMqConnectionFactory.setTrustAllPackages(true);
return activeMqConnectionFactory;
}
@Bean
public JmsOperations jmsTemplate(ConnectionFactory connectionFactory) {
final JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setDefaultDestinationName(PERSON_QUEUE);
return jmsTemplate;
}
@Bean
public PersonMessenger personMessenger(JmsOperations jmsOperations) {
return new PersonMessenger(jmsOperations);
}
@Bean(name = PERSON_QUEUE)
public Queue personQueue() {
return new ActiveMQQueue(PERSON_QUEUE);
}
}
@Configuration
@PropertySource("classpath:application.properties")
public class CommonConfiguration {
@Autowired
private Environment applicationEnvironment;
@Bean
public ApplicationEnvironment applicationEnvironment() {
return new ApplicationEnvironment(this.applicationEnvironment);
}
}
application.properties:
jms.brokerUrl=vm://test?async=false&broker.persistent=false&broker.useJmx=false
请注意,在尝试从队列中读取Person
对象时,测试块:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.opessoftware.example.spring.messenger.PersonMessengerTest
2017-02-15 15:30:33,736|WARN|main|o.a.activemq.broker.BrokerService|49670|
org.apache.activemq.broker.BrokerService.checkMemorySystemUsageLimits(BrokerService.java:2142)
Memory Usage for the Broker (1024mb) is more than the maximum available for the JVM: 955 mb - resetting to 70% of maximum available: 668 mb
2017-02-15 15:30:33,993|WARN|main|o.a.activemq.broker.BrokerService|49927|
org.apache.activemq.broker.BrokerService.checkMemorySystemUsageLimits(BrokerService.java:2142)
Memory Usage for the Broker (1024mb) is more than the maximum available for the JVM: 955 mb - resetting to 70% of maximum available: 668 mb
receiveAndConvert()
调用是在创建第二个嵌入式代理,还是在从其他队列读取?在使用嵌入式代理进行测试时,这是一个臭名昭著的问题
操作之间的连接已关闭,如果没有持久性,数据将丢失
尝试将连接工厂包装在CachingConnectionFactory
中,以便连接保持打开状态(因此代理保持打开状态)
无论如何,出于性能原因,您应该将CachingConnectionFactory
与JmsTemplate
一起使用,但在单元测试中尤其糟糕。As,为了防止每个JMS操作关闭连接并丢弃队列中的Person
消息以及嵌入式代理,方法jmsConnectionFactory()
在configuration类MessagingConfiguration
中,现在将(实现的)包装在:
下面请注意,测试只通过并输出一个BrokerService
内存警告,这意味着测试只创建一个所有JMS操作都使用的嵌入式代理
------------------------------------------------------------------------
Building spring-hibernate-jpa 1.0.0-SNAPSHOT
------------------------------------------------------------------------
--- maven-surefire-plugin:2.10:test (default-cli) @ spring-hibernate-jpa ---
Surefire report directory: /home/derek/Projects/spring-hibernate-jpa/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.opessoftware.example.spring.messenger.PersonMessengerTest
2017-02-16 10:14:03,743|WARN|main|o.a.activemq.broker.BrokerService|1579|
org.apache.activemq.broker.BrokerService.checkMemorySystemUsageLimits(BrokerService.java:2142)
Memory Usage for the Broker (1024mb) is more than the maximum available for the JVM: 955 mb - resetting to 70% of maximum available: 668 mb
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.929 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 4.190s
Finished at: Thu Feb 16 10:14:04 EST 2017
Final Memory: 8M/60M
------------------------------------------------------------------------
你完全正确!我在Github上偶然发现了一个例子,它将
ConnectionFactory
包装在CachingConnectionFactory
中,通过了这个更改,我的测试通过并只输出了一个BrokerService
内存警告。现在,为了解决这个警告,我找到了一个示例,演示了如何在CachingConnectionFactory
中包装ConnectionFactory
。
------------------------------------------------------------------------
Building spring-hibernate-jpa 1.0.0-SNAPSHOT
------------------------------------------------------------------------
--- maven-surefire-plugin:2.10:test (default-cli) @ spring-hibernate-jpa ---
Surefire report directory: /home/derek/Projects/spring-hibernate-jpa/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.opessoftware.example.spring.messenger.PersonMessengerTest
2017-02-16 10:14:03,743|WARN|main|o.a.activemq.broker.BrokerService|1579|
org.apache.activemq.broker.BrokerService.checkMemorySystemUsageLimits(BrokerService.java:2142)
Memory Usage for the Broker (1024mb) is more than the maximum available for the JVM: 955 mb - resetting to 70% of maximum available: 668 mb
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.929 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 4.190s
Finished at: Thu Feb 16 10:14:04 EST 2017
Final Memory: 8M/60M
------------------------------------------------------------------------