阿里云MNS Queue Rest API操作示例

简介: 阿里云消息服务(Message Service)是一种高效、可靠、安全、便捷、可弹性扩展的分布式消息服务。MNS能够帮助应用开发者在他们应用的分布式组件上自由的传递数据、通知消息,构建松耦合系统。本文主要介绍基于Java 语言实现Queue的创建、删除以及消息的发送及接受的Rest API操作。

作者:俏巴

签名验证工具

如果在使用过程中因为签名问题一直无法通过,建议直接使用签名验证工具进行快速的测试验证。

image.png

Code Sample

创建队列

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.StringEntity;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class CreateMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "********";//Access Key Secret
        String AccessKeyId = "********";//AccessKey ID
        String AccountId = "********";//Account ID

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        String body = "<?xml version=\"1.0\" encoding=\"UTF-8\"  ?>\n" +
                "    <Queue xmlns=\"http://mns.aliyuncs.com/doc/v1/\">\n" +
                "    <VisibilityTimeout >60</VisibilityTimeout>\n" +
                "    <MaximumMessageSize>1024</MaximumMessageSize>\n" +
                "    <MessageRetentionPeriod>120</MessageRetentionPeriod>\n" +
                "    <DelaySeconds>0</DelaySeconds>\n" +
                "    </Queue>";

        //构造签名String
        String SignString = "PUT\n" +
                "\n"+
                "application/xml"+
                "\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123");//在杭州区域
            URI uri = builder.build();
            HttpPut request = new HttpPut(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("Content-Type","application/xml");
            request.setHeader("x-mns-version","2015-06-06");

            // Request body
            StringEntity reqEntity = new StringEntity(body,"UTF-8");
            request.setEntity(reqEntity);

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

删除队列

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class DeleteMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "********";//Access Key Secret
        String AccessKeyId = "********";//AccessKey ID
        String AccountId = "********";

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        //构造签名String
        String SignString = "DELETE\n" +
                "\n"+"\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123");//在青岛区域创建Project
            URI uri = builder.build();
            HttpDelete request = new HttpDelete(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("x-mns-version","2015-06-06");

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

发送消息

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class SendMessageToMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "******";//Access Key Secret
        String AccessKeyId = "******";//AccessKey ID
        String AccountId = "********";

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        //延迟消息
        String body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "    <Message xmlns=\"http://mns.aliyuncs.com/doc/v1/\">\n" +
                "        <MessageBody>The Test Message!</MessageBody>\n" +
                "        <DelaySeconds>0</DelaySeconds>\n" +
                "        <Priority>1</Priority>\n" +
                "    </Message>";

        //构造签名String
        String SignString = "POST\n" +
                 "\n"+
                "text/xml;charset=utf-8"+
                "\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123/messages";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123/messages");
            URI uri = builder.build();
            HttpPost request = new HttpPost(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("Content-Type","text/xml;charset=utf-8");
            request.setHeader("x-mns-version","2015-06-06");

            // Request body
            StringEntity reqEntity = new StringEntity(body,"UTF-8");
            request.setEntity(reqEntity);

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

消费消息

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class GetMessageFromMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "********";//Access Key Secret
        String AccessKeyId = "********";//AccessKey ID
        String AccountId = "********";

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        //构造签名String
        String SignString = "GET\n" +
                 "\n"+
                "\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123/messages?waitseconds=30";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123/messages?waitseconds=30");
            URI uri = builder.build();
            HttpGet request = new HttpGet(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("x-mns-version","2015-06-06");

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

更多参考
签名验证工具
RESTfulAPI概述

备注: 示例代码仅供快速测试使用,未做冗余处理。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
5月前
|
API 微服务
阿里云微服务引擎 MSE 及 API 网关 2025 年 9 月产品动态
阿里云微服务引擎 MSE 及 API 网关 2025 年 9 月产品动态。
503 49
|
6月前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2025 年 9 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要。
554 142
|
6月前
|
人工智能 自然语言处理 安全
探索 API 的无限可能:阿里云的卓越引领
API是数字化时代的“万能钥匙”,阿里云凭借云控制API、API网关、OpenAPI Explorer等产品,构建全方位API生态,助力企业高效集成、安全管控与创新升级,推动电商、制造等行业智能化转型,引领未来科技浪潮。
248 10
|
6月前
|
人工智能 运维 监控
阿里云 API 聚合实战:破解接口碎片化难题,3 类场景方案让业务响应提速 60%
API聚合破解接口碎片化困局,助力开发者降本增效。通过统一中间层整合微服务、第三方接口与AI模型,实现调用次数减少60%、响应提速70%。阿里云实测:APISIX+函数计算+ARMS监控组合,支撑百万级并发,故障定位效率提升90%。
508 0
|
8月前
|
消息中间件 数据管理 Serverless
阿里云消息队列 Apache RocketMQ 创新论文入选顶会 ACM FSE 2025
阿里云消息团队基于 Apache RocketMQ 构建 Serverless 消息系统,适配多种主流消息协议(如 RabbitMQ、MQTT 和 Kafka),成功解决了传统中间件在可伸缩性、成本及元数据管理等方面的难题,并据此实现 ApsaraMQ 全系列产品 Serverless 化,助力企业提效降本。
|
6月前
|
消息中间件 Java Kafka
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
本文深入解析了 Kafka 和 RabbitMQ 两大主流消息队列在 Spring 微服务中的应用与对比。内容涵盖消息队列的基本原理、Kafka 与 RabbitMQ 的核心概念、各自优势及典型用例,并结合 Spring 生态的集成方式,帮助开发者根据实际需求选择合适的消息中间件,提升系统解耦、可扩展性与可靠性。
434 1
消息队列比较:Spring 微服务中的 Kafka 与 RabbitMQ
|
消息中间件 JSON Java
开发者如何使用轻量消息队列MNS
【10月更文挑战第19天】开发者如何使用轻量消息队列MNS
993 92
|
消息中间件 安全 Java
云消息队列RabbitMQ实践解决方案评测
一文带你详细了解云消息队列RabbitMQ实践的解决方案优与劣
477 93
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
消息中间件
解决方案 | 云消息队列RabbitMQ实践获奖名单公布!
云消息队列RabbitMQ实践获奖名单公布!
245 1