RabbitMQ入门(5)

RabbitMQ入门(5)

摘要 RabbitMQ,RabbitMQ入门


主题(topic)

(使用Java客户端)

在先前的指南中我们改进了我们的日志系统。取代使用fanout类型的交易所,那个仅仅有能力实现哑的广播,我们使用一个direct类型的交易所,获得一个可以有选择性的接收日志。

虽然使用direct交易所类型已经改善了我们的系统,但它依旧有限制-它不能根据多个条件进行路由。

我们的日志系统中,我们可能想要订阅不仅仅基于严格的日志,同样基于发布日志的源码。你可能了解到syslog unix tool的概念,那个基于严格的(info/warn/crit…)和灵巧的(auth/cron/kern…)路由日志。

那个将会给我们许多灵活性-我们可能仅仅想监听来自于cron的关键性的错误和所有来自于kern的日志。

为了在我们日志系统中实现那个,我们需要学习更复杂的topic类型交易所。

topic类型交易所

发送到topic类型的交易所不能有任意的路由的关键字-它必须是一个关键字列表,由点分隔。这关键字可以是任意的,但是通常可以说明消息的基本的联系。几个合法的路由关键字例子:“stock.usd.nyse”,“nyse.vmw”,“quick.orange.rabbit”。可能有很多你想要的路由关键字,上限是255个字节。 
这绑定关键字必须也在这同样的表单里。topic交易所逻辑背后是与direct交易所类型类似-一个带特别的路由关键字的消息将会被传递到所有匹配绑定的关键字的队列。但是有两个特别重要的绑定关键字。

>* (星标) 能替代任意一个单词。 
># (哈希) 能代替零个或多个单词。

这个例子中是很容易解释的: 
python-five.png

在这个例子中,我们发送的消息都描述的是动物。被发送的消息的路由关键字是由三个单词(两个点)组成。路由关键字中第一个单词描述的是速度,第二个描述的是颜色,第三个是物种: 
“<速度>.<颜色>.<物种>“。

我们创建了三个绑定:Q1s是由绑定关键字”。orange.“所约束,Q2由”。rabbit"和"lazy.#“所约束。 
这些绑定可以概括为:

>Q1 是对orange颜色的动物感兴趣。 
>Q2 想了解关于兔子的所有信息和所有慢吞吞的动物信息。

一个路由关键字为"quick.orange.rabbit"消息将会被传递到所有队列。消息"lazy.orange.elephant"同样也传递到所有队列。另一方面"quick.orange.fox"仅进入第一队列,“lazy.brown.fox"仅进入第二个队列。“lazy.pink.rabbit"仅传递到第二个队列一次,即使它会匹配两个绑定。“quick.brown.fox"不符合任何绑定关键字,所以会被丢弃。

如果我们打破我们的约定,发送一个消息带一个或四个单词的关键字,像"orange"或"quick.orange.male.rabbit”,会发生什么呢?好吧,这些消息不会匹配任何绑定,将会丢失。 
另一方面"lazy.orange.male.rabbit”,即使它有四个单词,将会匹配最最后那个绑定,将消息传递到第二个队列。

topic类型交易所 
topic类型交易所是强大的,能表现的像其他的交易所。 
Topic exchange is powerful and can behave like other exchanges. 
当一个队列绑定到了”#“(哈希)绑定关键字-它会接收所有消息,不管路由关键字是什么-类似于fanout类型交易所 
topic类型交易所中没有使用像”*“(星标)和”#“(哈希)的特殊字符,它的行为类似于direct类型交易所

把所有放在一起

我们将会在我们的日志系统中使用topic类型交易所。我们假设我们的工作的日志消息的路由关键字是由两个单词组成,格式为:“ . “。 
这代码和先前的几乎一样: 
EmitLogTopic.java的代码:

public class EmitLogTopic {

    private static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] argv)
                  throws Exception {

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, "topic");

        String routingKey = getRouting(argv);
        String message = getMessage(argv);

        channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes());
        System.out.println(" [x] Sent '" + routingKey + "':'" + message + "'");

        connection.close();
    }
    //...
}

ReceiveLogsTopic.java的代码:

public class ReceiveLogsTopic {

    private static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] argv)
                  throws Exception {

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        String queueName = channel.queueDeclare().getQueue();

        if (argv.length < 1){
            System.err.println("Usage: ReceiveLogsTopic [binding_key]...");
            System.exit(1);
        }

        for(String bindingKey : argv){
            channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
        }

        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

        QueueingConsumer consumer = new QueueingConsumer(channel);
        channel.basicConsume(queueName, true, consumer);

        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            String routingKey = delivery.getEnvelope().getRoutingKey();

            System.out.println(" [x] Received '" + routingKey + "':'" + message + "'");
        }
    }
}

运行接下来的例子,在windows环境中,使用%CP%,包含指南一种的类路径。 
接收所有日志:

$ java -cp $CP ReceiveLogsTopic "#"

接收所有灵巧的kern日志:

$ java -cp $CP ReceiveLogsTopic "kern.*"

或者你仅仅想接收'critical'日志:

$ java -cp $CP ReceiveLogsTopic "*.critical"

你可以创建多个绑定:

$ java -cp $CP ReceiveLogsTopic "kern.*" "*.critical"

发出一个路由关键字为"kern.critical"的日志,输入:

$ java -cp $CP EmitLogTopic "kern.critical" "A critical kernel error"

跟这些程序玩的开心。注意代码没有对特定的路由和绑定关键字做臆断,你可以操作多于两个的路由关键字参数。

一些难题:

>““绑定会捕获路由关键字是空的消息吗? 
>“#.
“会捕获消息中关键字带”..“的吗?它会捕获一个单词的关键字吗? 
>“a.*.#和"a.#“之间有什么不同?

EmitLogTopic.java 和 ReceiveLogsTopic.java的源代码。

接下来,让我们在指南的第六部分,弄清当一个远端程序被调用,如何做一个一个往返的消息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值