All Products
Search
Document Center

ApsaraMQ for RabbitMQ:FAQ about SDKs

Last Updated:Sep 29, 2024

This topic provides answers to commonly asked questions when you use SDKs to send and receive messages.

Can open source RabbitMQ clients directly access Alibaba Cloud services?

Yes. ApsaraMQ for RabbitMQ is fully compatible with open source RabbitMQ. Open source RabbitMQ clients can directly access Alibaba Cloud services. You must generate a pair of static username and password in the ApsaraMQ for RabbitMQ console. Then, your client can use the pair of static username and password to directly access Alibaba Cloud services. For information about how to create a pair of static username and password, see Manage static usernames and passwords.

Which programming languages that open source RabbitMQ SDK supports are supported by ApsaraMQ for RabbitMQ?

ApsaraMQ for RabbitMQ SDKs support all programming languages or frameworks supported by open source RabbitMQ SDKs. For more information, see Programming languages and frameworks supported by open source RabbitMQ SDKs over AMQP.

If automatic acknowledgment (ACK) is enabled, can I call the Reject method to requeue a message?

No. You can call the basicReject method to reject and requeue a message or call the basicNack method to reject and requeue one or more messages.

  • Call the basicReject method to reject and requeue a message

    Parameter

    Description

    deliveryTag

    The unique identifier that is used to deliver messages in the channel.

    requeue

    Specifies whether to requeue the rejected message. If you set this parameter to true, the rejected message is requeued. If you set this parameter to false, the rejected message is discarded or sent to the dead-letter exchange. For more information, see Dead-letter exchanges.

  • Call the basicNack method to reject and requeue one or more messages

    Parameter

    Description

    deliveryTag

    The unique identifier that is used to deliver messages in the channel.

    multiple

    Specifies whether to reject multiple messages. If you set this parameter to true, the message with the specified delivery tag and unacknowledged messages before the specified delivery tag are rejected. If you set this parameter to false, only the message with the specified delivery tag is rejected.

    requeue

    Specifies whether to requeue the rejected message. If you set this parameter to true, the rejected message is requeued. If you set this parameter to false, the rejected message is discarded or sent to the dead-letter exchange. For more information, see Dead-letter exchanges.

    Sample code:

    channel.basicConsume("test", false, "consumertag", new DefaultConsumer(channel) {
       @Override
        public void handleDelivery(String consumerTag, Envelope envelope,
                          AMQP.BasicProperties properties, byte[] body)
                throws IOException {
            System.out.println("Rejected: " + new String(body, "UTF-8") + ", deliveryTag: " + envelope.getDeliveryTag() + ", messageId: " + properties.getMessageId());
            channel.basicNack(envelope.getDeliveryTag(), true, true);
        }
    });

How do I specify a message ID?

To track and identify messages, you can specify a unique ID for each message on the ApsaraMQ for RabbitMQ producer client. For more information about message IDs, see message ID.

To specify a message ID, you can configure the message-id parameter of the Basic.Properties field on the ApsaraMQ for RabbitMQ producer client. Sample code:

Note

A message ID cannot exceed 255 characters in length.

Java

AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().messageId("messageid").build(); 
channel.basicPublish("${ExchangeName}", "RoutingKey", true, props, ("Message body").getBytes(StandardCharsets.UTF_8));

Python

properties = pika.BasicProperties(app_id='example-publisher', content_type='application/json', message_id='messageid')

PHP

$msg = new AMQPMessage($msgBody, ['application_headers'=>$amqpTable,'content_type' => 'text/plain', 'delivery_mode' => 2,'message_id' => 'messageid',]);

Go

err = ch.Publish( "helloExchange", "hello", false, false, amqp.Publishing { ContentType: "text/plain", Body: []byte(body), MessageId: "messageId", })

Node.js

channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body);

How do I delete messages from a queue?

You can call the queuePurge method in the Java client library to delete all messages from a queue. Sample code:

channel.queuePurge("queue-name");

How do I configure encrypted transmission on an open source client?

In the following example, the default port 5672 for non-encyrpted transmission is used. If you want to use encrypted transmission, you must use port 5671 and configure

the SslProtocol parameter in com.rabbitmq.client.ConnectionFactory.

 private void setSSL(com.rabbitmq.client.ConnectionFactory factory) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init((KeyStore) null);
        
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
        
        factory.useSslProtocol(sslContext);
    }

What can I do if the memory usage and CPU utilization of each consumer greatly vary because the number of messages consumed by each consumer varies?

ApsaraMQ for RabbitMQ deploys server nodes in distributed mode. Multiple server nodes are deployed in the backend of ApsaraMQ for RabbitMQ and the polling mechanism is used by the gateway to establish connections to the server nodes. If client connections are unevenly distributed among server nodes, the number of messages pulled by each consumer may vary. For example, five clients establish five connections to three server nodes A, B, and C. Two connections are established to each of A and B, and one connection is established to C. In this case, the client that is connected to C can consume all messages pulled by C. The number of messages pulled by A, B, and C is the same because the backend of ApsaraMQ for RabbitMQ uses the storage-compute separation architecture. As a result, the client that is connected to C consumes more messages than the clients that are connected to A and B.

Solution: You can establish multiple connections for each client. For example, you can establish 50 connections for each client and evenly distribute the connections to the server nodes to make sure that each server node can pull the same number of messages. If Spring Boot is used on the client, you can configure the connection mode for message consumption.