问题描述
||
我创建了一个生产者,该生产者正在使用
com.rabbitmq.client.connectionFactory
,并在100秒内发送了1,000,000条消息(40字节)。
但是现在我想要春天抽象。我无法使用com.rabbitmq.client.connectionFactory
,而不得不使用org.springframework.amqp.rabbit.connection.SingleConnectionFactory
。使用此连接工厂,在100秒内仅100,000消息(40字节)被发送到代理。
是否有人有经验为什么性能会降低很多(大约90%)。
使用“导入com.rabbitmq.client.ConnectionFactory; \”的代码是->
package Multiple_queues_multiple_consumers;
import java.io.IOException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Producer {
private static Connection myConnection;
private static Channel myChannel;
public static String myQueueName;
public static void main(String[] args) throws IOException {
long startTime=0;
int count=0;
ConnectionFactory myFactory=new ConnectionFactory();
myFactory.setHost(\"localhost\");
try {
myConnection = myFactory.newConnection();
myChannel = myConnection.createChannel();
String myExchange = \"wxyzabc\";
String myBody = \"This is a message : message numberxxxxxx\";
String myRoutingKey = \"RoutingKey\";
myQueueName = \"new_Queue\";
myChannel.exchangeDeclare(myExchange,\"direct\",true,false,null);
myChannel.queueDeclare(myQueueName,null);
myChannel.queueBind(myQueueName,myExchange,myRoutingKey);
startTime=System.currentTimeMillis();
AMQP.BasicProperties properties = new AMQP.BasicProperties();
properties.setDeliveryMode(2);
startTime=System.currentTimeMillis();
while(count++<=10000){
myChannel.basicpublish(myExchange,myRoutingKey,properties,myBody.getBytes() );
}
System.out.println(System.currentTimeMillis()-startTime);
} catch (Exception e){
System.exit(0);
}
}
}
使用SpringFramework的代码是:->
Producer1.java
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
public class Producer1 {
public static void main(String[] args) {
ConfigurableApplicationContext context = new ClasspathXmlApplicationContext(\"Producer1.xml\");
AmqpAdmin amqpAdmin = context.getBean(RabbitAdmin.class);
Queue queue = new Queue(\"sampleQueue\");
DirectExchange exchange = new DirectExchange(\"myExchange\");
Binding binding = new Binding(queue,exchange,\"\");
amqpAdmin.declareQueue(queue);
amqpAdmin.declareExchange(exchange);
amqpAdmin.declareBinding(binding);
RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
String routingKey = \"\";
String myBody = \"This is a message : message numberxxxxxx\";
Message Msg = new Message(myBody.getBytes(),null);
int count=0;
long CurrTime = System.currentTimeMillis();
while(count++<=10000){
rabbitTemplate.send(routingKey,Msg);
//System.out.println(\"Message Sent\");
}
System.out.println(System.currentTimeMillis()-CurrTime);
}
}
Producer1.xml
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<beans xmlns=\"http://www.springframework.org/schema/beans\"
xmlns:p=\"http://www.springframework.org/schema/p\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:context=\"http://www.springframework.org/schema/context\"
xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd\">
<!-- Define a connectionFactory -->
<bean id=\"rabbitConnectionFactory\" class=\"com.rabbitmq.client.ConnectionFactory\">
<property name=\"host\" value=\"localhost\" />
</bean>
<bean id=\"connectionFactory\" class=\"org.springframework.amqp.rabbit.connection.SingleConnectionFactory\">
<constructor-arg ref=\"rabbitConnectionFactory\"/>
</bean>
<!-- Tell the Admin bean about that connectionFactory and initialize it,create a queue and an exchange on Rabbit broker using the RabbitTemplate provided by Spring framework-Rabbit APIs -->
<bean id=\"Admin\" class=\"org.springframework.amqp.rabbit.core.RabbitAdmin\">
<constructor-arg ref=\"connectionFactory\" />
</bean>
<bean id=\"rabbitTemplate\" class=\"org.springframework.amqp.rabbit.core.RabbitTemplate\"
p:connectionFactory-ref=\"connectionFactory\"
p:routingKey=\"myRoutingKey\"
p:exchange=\"myExchange\" />
</beans>
解决方法
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<beans xmlns=\"http://www.springframework.org/schema/beans\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:p=\"http://www.springframework.org/schema/p\"
xsi:schemaLocation=\"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\">
<!-- Define a connectionFactory -->
<bean id=\"connectionFactory\" class=\"com.rabbitmq.client.connectionFactory\">
<constructor-arg value=\"localhost\" />
<property name=\"username\" value=\"guest\" />
<property name=\"password\" value=\"guest\" />
</bean>
<bean id=\"Admin\" class=\"org.springframework.amqp.rabbit.core.RabbitAdmin\">
<constructor-arg ref=\"connectionFactory\" />
</bean>
</beans>
使用此xml文件时,出现错误,提示org.springframework.amqp.rabbit.core.RabbitAdmin无法为connectionfactory bean强制转换com.rabbitmq.client.connectionFactory。
确切的错误是:\“嵌套异常是java.lang.IllegalStateException:无法将类型[com.rabbitmq.client.ConnectionFactory]的值转换为所需类型[org.springframework.amqp.rabbit.core.RabbitTemplate]:没有匹配的编辑器或找到转换策略\“。
因此,我必须使用bean:
<bean id=\"connectionFactory\"
class=\"org.springframework.amqp.rabbit.connection.SingleConnectionFactory\">
</bean>
, 您确定使用相同的Rabbit MQ代理吗?您可以在其他服务器上使用代理,还是在RabbitMQ的升级/降级版本中使用代理?
另一件事要看的是您的jvm。您是否可能没有配置足够的内存,而现在垃圾收集器正在崩溃?运行top
,查看jvm \的内存使用量是否接近配置的内存大小。
您是否在使用旧版本的RabbitMQ。许多Linux发行版都包含RabbitMQ 1.7.2,它是一个存在大量消息问题的旧版本。大是很难定义的,因为它取决于您的RAM,但是RabbitMQ不喜欢使用超过40%的RAM,因为它需要复制一个持久性事务日志以便对其进行处理并清理它以进行日志翻转。这可能会导致RabbitMQ崩溃,并且,当然,处理庞大的日志会降低它的速度。 RabbitMQ 2.4.1以较小的块更好地处理了持久性日志,并且还具有更快得多的消息路由代码。
在我看来,这仍然像Java问题一样,要么Spring只是一头猪,效率极低,要么您没有给jvm足够的RAM来避免频繁的gc运行。您为-Xmx使用什么设置?