通过Docker启动Solace,并在Spring Boot通过JMS整合Solace

news2024/11/25 14:31:27

1 简介

Solace是一个强大的实时性的事件驱动消息队列。本文将介绍如何在Spring中使用,虽然代码使用的是Spring Boot,但并没有使用相关starter,跟Spring的整合一样,可通用。JMS是通过的消息处理框架,可以深入学习一下,不同的MQ在JMS的整合上都是类似的。

2 通过Docker启动Solace

有两种方式试用Solace,一种是通过Docker来启动,另一种是使用Cloud版本,但Cloud版本有试用期限,我们使用Docker来启动吧。

先下载镜像:

$ docker pull solace/solace-pubsub-standard:9.13.0.16

然后通过以下命令启动:

$ docker run -d -p 8080:8080 -p 55554:55555 -p 8008:8008 -p 1883:1883 -p 8000:8000 -p 5672:5672 -p 9000:9000 -p 2222:2222 --shm-size=2g --env username_admin_globalaccesslevel=admin --env username_admin_password=admin --name=solace solace/solace-pubsub-standard:9.13.0.16

这里端口改为55554,是因为Mac的原因。

然后便可以访问来登陆管理界面:http://localhost:8080/

用户名密码为:admin/admin

登陆后可以看到如下界面,Solace按VPN来管理队列,VPN有点像分组,比如某个业务线使用某个VPN。

我们在default的VPN上创建一个Queue,名为pkslow-queue

其它设置如下:

接着在该Queue上创建Topic:

创建完成后,我们可以直接测试一下:

可以Publish到Topic或Queue,也可以从其中一个Subscribe。

完成以上设置后,我们就可以在Spring Boot中整合了。

3 Spring Boot JMS整合Solace

3.1 发送消息

我们是通过JmsTemplate来发送消息的,而JmsTemplate需要连接到MQ,就需要一个ConnectionFactory,这个Factory是带着MQ的一些连接信息。配置代码如下:

@Configuration
public class SolacePubConfig {

    private final SolaceProperties solaceProperties;

    public SolacePubConfig(SolaceProperties solaceProperties) {
        this.solaceProperties = solaceProperties;
    }

    @Bean("connectionFactory")
    public ConnectionFactory connectionFactory() throws Exception {
        Properties env = new Properties();
        env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "com.solacesystems.jndi.SolJNDIInitialContextFactory");
        env.put(InitialContext.PROVIDER_URL, solaceProperties.getBrokerUrl());
        env.put(SupportedProperty.SOLACE_JMS_VPN, solaceProperties.getVpn());
        env.put(InitialContext.SECURITY_PRINCIPAL, solaceProperties.getUsername());
        env.put(InitialContext.SECURITY_CREDENTIALS, solaceProperties.getPassword());
        return SolJmsUtility.createConnectionFactory(env);
    }

    @Bean
    public CachingConnectionFactory cachingConnectionFactory(ConnectionFactory connectionFactory) {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(connectionFactory);
        cachingConnectionFactory.setSessionCacheSize(10);
        return cachingConnectionFactory;
    }

    @Bean
    public JmsTemplate pubJmsTemplate(CachingConnectionFactory cachingConnectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);
        jmsTemplate.setPubSubDomain(true);
        jmsTemplate.setExplicitQosEnabled(true);
        jmsTemplate.setDeliveryPersistent(true);
        jmsTemplate.setDefaultDestinationName(solaceProperties.getDefaultPubDestinationName());
        return jmsTemplate;
    }

}

生成JmsTemplate后,就可以引用并发送消息了:

@RestController
@RequestMapping("/solace")
public class SolaceTestController {
    private final JmsTemplate pubJmsTemplate;
    private final SolaceProperties solaceProperties;

    public SolaceTestController(JmsTemplate pubJmsTemplate, SolaceProperties solaceProperties) {
        this.pubJmsTemplate = pubJmsTemplate;
        this.solaceProperties = solaceProperties;
    }

    @GetMapping
    public String send() {
        pubJmsTemplate.send(solaceProperties.getDefaultPubDestinationName(), session -> session.createTextMessage("www.pkslow.com"));
        pubJmsTemplate.send(session -> session.createTextMessage("Larry Deng"));
        return "OK";
    }
}

用到的属性配置如下:

server.port=8083

pkslow.solace.brokerUrl=smf://127.0.0.1:55554
pkslow.solace.vpn=default
pkslow.solace.username=default
pkslow.solace.password=default
pkslow.solace.defaultPubDestinationName=pkslow-topic
pkslow.solace.defaultSubDestinationName=pkslow-queue
@Configuration
@ConfigurationProperties(prefix = "pkslow.solace")
@Setter
@Getter
public class SolaceProperties {
    private String brokerUrl;
    private String vpn;
    private String username;
    private String password;
    private String defaultPubDestinationName;
    private String defaultSubDestinationName;
}

3.2 接收消息

我们通过MessageListenerContainer来接收消息,MessageListenerContainer也需要一个ConnectionFactory,也有MQ的连接信息。还需要一个MessageListener,用来定义如何处理消息。我们的配置如下:

@Configuration
@Slf4j
public class SolaceSubConfig {
    private final SolaceProperties solaceProperties;

    public SolaceSubConfig(SolaceProperties solaceProperties) {
        this.solaceProperties = solaceProperties;
    }

    @Bean
    public SingleConnectionFactory singleConnectionFactory(@Qualifier("connectionFactory") ConnectionFactory targetConnectionFactory) {
        return new SingleConnectionFactory(targetConnectionFactory);
    }

    @Bean
    public MessageListener messageListener() {
        return message -> {
            try {
                log.info("Received message " + ((TextMessage) message).getText() + " on destination: " +
                        message.getJMSDestination().toString());
            } catch (JMSException ex) {
                throw new RuntimeException(ex);
            }
        };
    }


    @Bean
    public MessageListenerContainer messageListenerContainer(SingleConnectionFactory singleConnectionFactory, MessageListener messageListener) {
        DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
        container.setConnectionFactory(singleConnectionFactory);
        container.setDestinationName(solaceProperties.getDefaultSubDestinationName());
        container.setMessageListener(messageListener);

        return container;
    }
}

这里@Qualifier("connectionFactory") ConnectionFactory targetConnectionFactory复用了在SolacePubConfig创建的对象。

3.3 测试

发送GET请求就可以触发发送了:

GET http://localhost:8083/solace

我发了三次,结果日志如下:

4 代码

代码请看GitHub: https://github.com/LarryDpk/pkslow-samples


References:

Docker available image tags

Docker Solace Guide

Spring Solace

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/168070.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

02.指针的进阶1.练习题

1.辨析 //数组指针是一种指针,指向数组的指针 //数组指针是指向数组地址的指针 //回调函数是调用函数指针指向函数 EG1:杨氏矩阵 有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中…

微服务间通讯负载均衡以及日志

2.通信 HTTP ResthttpJSONRPC远程过程调用二进制 1.使用 RestTemplate RestTemplate restTemplate new RestTemplate(); String forObject restTemplate.getForObject("http://localhot:8888/user", String.class);其负载均衡有问题其无法实现健康检查 2.使用Ri…

新年新气象,跨境电商助推出口再创新高

受疫情等多方面影响,2022年纯棉纱进口量及产量均出现一定幅度地下滑。由于库存增加,消费量下降,供需矛盾也不断加剧。 新年新气象,2023年据预计纯棉纱产量将小幅回升,初步预计将达到535万吨,同比增加5.6%。…

Allegro如何快速打开和关闭层面操作指导

Allegro如何快速打开和关闭层面操作指导 在做PCB设计的时候,打开和关闭某个层面是非常频繁的操作,尤其是丝印等等层面。 Allgeo升级到了172版本的时候,可以将常用的层面添加到Visibility菜单里,就不需要频繁打开颜色管理器打卡和关闭层面了,如下图 具体操作如下 打开颜色…

归纳一下软件测试中「安全测试工具」

大家好啊,我是大田。今天归纳一下安全测试工具,分别用这些工具做哪些工作。自动化测试人员、功能测试人员平常可能用的不多,但是面试时也需要准备,需要知道安全测试工具有什么,还要关注现在有哪些漏洞。本篇先归纳整理…

vue3学习笔记之样式穿透(:deep)及CSS 新特性(:soltted、:gloabl、v-bind、mouldCSS)

文章目录1. scoped的原理2. :deep()3. :slotted()4. :global()5. 动态css(v-bind)6. css module1. scoped的原理 vue中的 scoped 通过在DOM结构以及css样式上加唯一不重复的标记:data-v-hash的方式,以保证唯一(而这个工作是由过P…

如何使用极狐GitLab 机器人大幅提升研发效率

本文来自: 黄松 极狐GitLab 后端工程师 研发效率对互联网/科技类公司来说至关重要,效率高意味着你能用更低的人力、时间成本在市场试错,成功的概率也会更大。 而说到研发效率的常见阻碍,主要有两点: 1. 研发流程中需要…

基础二分查找总结

前言 由于我在学习二分查找的过程中处于会了忘,忘了复习的状态,因此总结一套适合自己记忆的模板。建议先看参考资料[1,2,3]^{[1,2,3]}[1,2,3],理解二分查找各种细节的由来。 二分查找又死循环了?【基础算法精讲 04】手把手带你撕出…

9656教程总结

9656 世界机器人大会青少年电子信息智能创新大赛官网少儿编程办学经验介绍机器人体验展馆体系课程知乎加盟介绍 知识点汇总 年龄 4-6岁 韩纳机器人主题体验馆 赛事 WRC世界机器人大赛, NOC全国中小学信息技术创新和实践大赛 5岁前:乐高积木,孩子年龄小只需对科特、编程…

事关网站数据安全,你真的了解https与SSL证书之间的关系吗?

虽然根据网上的建站教程,大多数站长都知道要给域名添加一个SSL证书,以此来开启https进而可以获得更好的用户体验以及提高网站的安全性。但是SSL证书为什么能使得网站https?你真的去细究过两者之间的关系吗?本文就来说说https与SSL…

python模拟三颗恒星的运动

文章目录随机三体三星问题随机三体 目前来说我们并不关心真实的物理对象,而只想看一下三个随机的点放在三个随机的位置,赋予三个随机的速度,那么这三个点会怎么走。所以其初始化过程为 import numpy as np m,x,y,u,v [np.random.rand(3) f…

【java入门系列四】java基础-数组

学习记录🤔数组引出动态初始化数组内的数据会自动转换类型注意事项数组赋值机制数组拷贝数组扩容append?多维数组trick生成随机数Math.random()讨论总结谢谢点赞交流!(❁◡❁)更多代码: Gitee主页:https://gitee.com/G…

如何进行复盘

复盘定义 复盘,原本是围棋术语,指下完一盘棋后,双方棋手把对弈过程重新摆一遍,看哪里下得好,哪里下得不好,哪些关键节点有不同甚至更好的下法,以检查对局中招法的优劣与得失,并从中…

深入理解可变参数列表

目录 1.前言 2.基本使用方法 1.引入 2.相关宏介绍 3.原理剖析 1.传参 2.va_list 3.va_start() 4.va_arg() 5.va_end() 4.注意事项 5.总结 1.前言 在C语言中,对于一般的函数而言,参数列表都是固定的,而且各个参数之间用逗号进行分开。而除…

面试,演讲为什么一说话就紧张? 的底层解读

信息存在损耗在说话中,说话者与接受者之间传递信息存在损耗。而且人表达情绪不管是说话,还有肢体语言,这使得增加了信息接受者的信息量。下面引入两个词语来说明。给予与流露的含义给予:别人评价你做的菜好吃。流露:别人眉头一皱。…

探讨下如何更好的使用缓存 —— Redis缓存的特殊用法以及与本地缓存一起构建多级缓存的实现

大家好,又见面了。 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面。如果感兴趣,欢迎关注以获取后续更新。 通过前面的文章,我们一起剖析了Guava Cache、Caf…

如何在线录屏?怎么录制网课

当我们需要学习特定知识时,可以在网络上寻找教学视频进行学习。一般情况下,视频会一直保留在网上,可以随时随地观看。那您知道我们平常观看的网络课程是如何录制的吗?如何进行在线录屏?今天小编教您如何在线录制视频网…

C语言——指针进阶(含例题及详细代码分析)

文章目录导语:思维导图:1.字符指针2.指针数组3.数组指针3.1 数组指针的定义3.2 &数组名和数组名3.3 数组指针的使用4.数组参数、指针参数4.1 一维数组传参4.2 二维数组传参4.3 一级指针传参4.4 二级指针传参5.函数指针6.函数指针数组7.指向函数指针数…

Django自定义认证系统原理及源码分析解读

疑问 Django在如何自定义用户登录认证系统的时候,大家都会里面立马说 自定义一个 或者多个backend,比如通过账号密码、邮箱密码,邮箱验证码、手机号短信验证码等等。 然后设置 在settings中配置一个 AUTHENTICATION_BACKENDS就行。 但是为什…

【尚硅谷】Java数据结构与算法笔记11 - 树结构的实际应用

文章目录一、堆排序1.1 堆排序基本介绍1.2 堆排序的基本思想1.3 堆排序步骤图解1.4 堆排序思路总结1.5 堆排序代码实现二、赫夫曼树2.1 基本介绍2.2 重要概念1.3 赫夫曼树构建思路图解1.4 赫夫曼树代码实现三、赫夫曼编码3.1 基本介绍3.2 原理剖析3.3 实践:数据压缩…