springboot----数据层技术的选择+各种整合(缓存,消息队列)+定时任务+发邮件
Posted 你好牛蛙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot----数据层技术的选择+各种整合(缓存,消息队列)+定时任务+发邮件相关的知识,希望对你有一定的参考价值。
目录
数据层解决方案
内置的数据源
springboot如果我们不指定使用什么数据源(连接池),则默认使用springboot内嵌的hikariCP数据源,当然,若要使用数据源,则数据源相关的配置也必须配置上
springboot内嵌有三种数据源供我们选择使用
1.hikariCP
2.Tomcat提供的DataSource
3.Commons DBCP
数据源的配置
无论是内嵌的数据源还是我们自己选的比如druid数据源,他们的配置都大同小异,比如:
如果只这样配置:则默认使用hikariCP数据源
但是需要对hikariCP数据源进一步配置,则需要下面这样配置,和配置一般的数据源有点类似,但是,配置hikariCP需要注意一点,他的url得写在hikari同一级,不然会报错,这里注意
jdbcTemplate
JdbcTemplate是Spring对原始JDBC封装之后提供的一个操作数据库的工具类,是跟mybatis同一类的技术,操作数据库,实现持久化。
我们可以借助JdbcTemplate来完成所有数据库操作,比如:增删改查等
使用jdbcTemplate
使用jdbcTemplate需要先有dataSource对象,即数据源对象,即先配置好数据源(springboot项目启动的时候会根据配置产生对应的数据源对象)
然后:
- 需要导入对应的依赖
即jdbc的starter
- 自动装配上jdbcTemplate的对象
导入这个starter,从底层来说就等于有了jdbc启动器(starter),boot会自动加载,被spring容器管理,所以可以自动装配 - 使用
这里模拟一个查询操作
内置的数据库
springboot内置了三款数据库。
1.H2
2.HSQL
3.Derby
这些数据库都很小巧,是内嵌的,是内存级别的数据库,用来搞测试非常方便,所以这三款数据库多用于测试
三种,他们模式都差不多,所以以H2为例子
H2数据库
使用还是那几步
1.导入依赖包
2.做配置
3.使用
- 导入jar包
- 做配置和连接控制台
进入之后,根据提供的功能操作即可
第一次进入可能会报错,原因是springboot无对应的初始化数据,所以需要第一次也需要做一点配置,把上面连接界面的四个值告诉给springboot
可以在配置数据源的时候告诉springboot,第一次启动之后,这个就不需要了,注释掉也没问题
- 使用
直接使用即可,和mysql没啥区别,也是sql语句
NoSQL解决方案
这里学习整合三个常用的
1.Redis
2.Mongodb
3.ES
Redis
Redis是一款key-value存储结构的内存级NoSQL数据库
支持多种数据存储格式
支持持久化
支持集群
官方只提供linux版的Redis,windows版的由windows研发组维护这里以windows版本作为实例,整合springboot部分跟linux一样,这里以整合为主,并不是讲redis的,redis的知识后续再记录
安装和启动服务和可能出现的一个小BUG
windows版下载地址https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100
,这个地址进不去的话需要魔法,因为是在github上的
选择msi的话,则是安装包,只用于学习的话,安装全部下一步即可,自己选择安装路径
目录下是这样的: 里面的三个需要注意一下
使用redis前需要先启动服务,即上面的redis-service,可以在cmd中如下操作,或者直接在文件中双击对应的可执行程序
若出现这样的启动失败
这是windows版redis的小BUG,则可以这样解决:
一般是是安装包出现这样的问题,如果这样则先打开客户端,然后执行下面的命令,然后在启动服务就可以了
redis基础操作:
springboot整合redis
整合也就那三步,1.导依赖包 2.做配置 3.使用
- 导包
- 做配置
主要这几项:
这里是本机上的,只用配一个host和port,或者只一个url,但是其实啥配置也不用做,因为host和port有默认值
- 使用
如果使用redisTemplate,传入的是对象,则在客户端访问,则会返回一串类似这样的东西:"\\xac\\xed\\x00\\x05t\\x00\\x06747976"
,用上面说的StringRedisTemplate就能解决这个问题
切换springboot操作redis客户端的实现技术(jedis或lettuce)
lettcus与jedis区别:
jedis连接Redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案可以通过配置连接池使每个连接专用,这样整体性能就大受影响。
lettuce基于Netty框架进行与Redis服务器连接,底层设计中采用StatefulRedisConnection。StatefulRedisConnection自身是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用。当然lettcus也支持多连接实例一起工作。
- 导入依赖包
这玩意版本号也由springboot管控了 - 做配置
client-type用于设置使用什么技术,如下图
下面可以配置更详细的配置
- 直接使用,没啥区别,直接跟前面的一样使用即可
MongoDB
MongoDB的基本知识这里确实没写啥东西,因为我也不太会,但是整合部分的知识倒是没问题。MongoDB的使用可以找更详细的课程
MongoDB是一个开源、高性能、无模式的文档型数据库。NoSQL数据库产品中的一种,是最像关系型数据库的非关系型数据库
MongoDB多用于存储变动较快的数据
不常变动的一般用关系型数据库
安装和初始化
官网下载好像得注册账号,忘记之前咋下载的了,这里把我的安装包分享一下:
链接:链接:https://pan.baidu.com/s/1rrKB0UfbOwPWsBAbG-zJ4A 提取码:duay
版本是5.0.6
bin文件夹下
这里mongo.exe就是启动客户端的可执行程序
安装后之后,第一次使用需要初始化 启动服务也是这个命令
默认端口:27017
启动客户端,双击mongo.exe就行
安装mongodb的可视化工具Robo 3T
依然是之前保存的资源:
链接:链接:https://pan.baidu.com/s/1UjjsVokjYMEoTHBQF0AN8A 提取码:ynt2
版本是1.4.4
如果连接不上mongodb,那很可能是和mongobd的版本不符,但是我这俩版本不冲突
进来之后就这弔样,先连接,我这里已经连接过了,所以有记录
mongodb的详细使用可以参考对应的教程
整合
- 导入依赖包
NoSQL相关的包基本都是spring-boot-starter-data-*
- 做配置
- 使用
下面这个是查找
整合第三方技术
整合无非就那三步,导包,配置,使用
这里记录几个常用的
1.缓存 2.发邮件 3.消息队列
缓存
缓存是一种种介于数据永久存储介质与数据应用之间的数据临时存储介质
使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高系统性能
在软件中,因为两者对接而出现的一些问题,加一层能解决其中大部分的问题
缓存就是这样,若程序频繁访问数据库,则会极大的影响程序整体的性能
缓存就是在这两者之间加一层,缓存把常用的数据存储到内存中,然后程序去缓存中访问数据,这样就避免程序频繁访问数据库
缓存的作用不止是可以减低速数据读取过程的次数,还可以用于记录程序运行期间产生的一些无需进入数据库的数据,比如验证码
Spring提供的缓存技术除了提供默认的缓存方案,还可以对其他缓存技术进行整合,统接口,方便援存技术的开发与管理,有这么一些:
Generic
JCache
Ehcache
Hazelcast
Infinispan
Couchbase
Redis
Caffenine
Simple (默认)
还有一个技术memcache也挺常用,但是boot并未给整合,我们需要手动整合
这里记一下几个常用的缓存技术
1.Redis 2.Memcached 3.Ehcache
注意几点:
- springboot已经整合过的技术,下面关于这些技术的配置都是在spring级别下,比如redis,Simple,Ehcache,但是springboot并未整合memcache,他的配置后续到这部分了再讲
- 因为下面整合不同的缓存技术所使用的的例子都是一个业务,为了防止使用一个技术的时候和上一个技术相冲突,当从一项缓存技术切换到另一种缓存技术,则和上一种缓存技术相关的而且和当前切换到的缓存技术无关的部分需要注释掉
手动实现一个简单的缓存机制
随便搞一搞的话很简单
如果是验证码,则先获取验证码,然后存入Map,比对的时候从Map中取,这样这个数据就是只存在内存中的
springboot中默认的使用的缓存
springboot提供了自己默认的缓存技术
springboot中的缓存默认使用Simple
可以导入对应的依赖包后直接使用即可
然后三步:
启用缓存
设置进入缓存的数据
设置读取缓存的数据
实现一个简单的验证码业务
实验一个用缓存存储验证码的业务,作为后续用不同缓存技术的模板,这里先使用默认的Simple作为缓存技术
需求
输入手机号获取验证码,组织文档以短信形式发送给用户(页面模拟)
输入手机号和验证码验证结果
需求分析
提供controller, 传入手机号,业务层通过手机号计算出独有的6位验证码数据,存入缓存后返回此数据
提供controller, 传入手机号与验证码,业务层通过手机号从缓存中读取验证码与输入验证码进行比对,返回比对结果
service层:
对应产生验证码,和获取验证码的类,这里有一点很重要,需要注意
切换为Ehcache
三步
- 导入依赖包
- 做配置
Ehcache是spring体系外的技术,而且他有自己的配置,所以使用他的话,需要再搞一个属于他的配置文件。并放在resources路径下。
上面的配置文件也需要在配置中指定一下
- 使用
其实使用起来和前面的simple一模一样,这就是springboot的精妙之处,他给这些提供了一个统一的接口,我们直接调用即可。如果想换不同的实现,我们可以直接选择这些接口的实现就行了,不用变更使用方法
配置文件内容
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="D:\\ehcache" />
<!--默认缓存策略 -->
<!-- external:是否永久存在,设置为true则不会被清除,此时与timeout冲突,通常设置为false-->
<!-- diskPersistent:是否启用磁盘持久化-->
<!-- maxElementsInMemory:最大缓存数量-->
<!-- overflowToDisk:超过最大缓存数量是否持久化到磁盘-->
<!-- timeToIdleSeconds:最大不活动间隔,设置过长缓存容易溢出,设置过短无效果,可用于记录时效性数据,例如验证码-->
<!-- timeToLiveSeconds:最大存活时间-->
<!-- memoryStoreEvictionPolicy:缓存清除策略-->
<defaultCache
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU" />
<cache
name="smsCode"
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="10"
timeToLiveSeconds="10"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
切换为redis
三步:
- 导入依赖包并启动redis服务
- 做配置
下面这其中的注释比较重要
- 使用
前面已经说过了,springboot给这些提供了一个统一的接口,我们直接调用即可。如果想换不同的实现,我们可以直接选择这些接口的实现就行了,不用变更使用方法,就是说,使用方法跟之前一样,啥都不用该,就上面配置改一下,就等于换成了redis来实现缓存
切换为memcached
SpringBoot未提供对memcached的整合,所以这里也是相当于记录了如何整合springboot未整合的技术的模板
没有本地或者远程的服务的话,我们需要先在自己本机上下载对应的服务:地址https://www.runoob.com/memcached/window-install-memcached.html
然后以管理员身份进入cmd,再进入memcached安装目录,执行安装
启动和停止服务的命令:
都需要在memcached安装目录下执行
服务有了,使用这个服务我们需要选择客户端
啥意思呢?就像redis,他的bin目录下有redis-service(服务端),redis-cli(客户端)
就是说redis提供了客户端,所以不需要我们特意去找客户端,但是memcached没有提供,所以需要我们去选择使用
memcached客户端选择
Memcached Client for Java:最早期客户端,稳定可靠,用户群广
SpyMemcached: 效率更高
Xmemcached:并发处理更好
我们选择Xmemcached
但是SpringBoot未提供对memcached的整合,需要使用硬编码方式实现客户端初始化管理
其实还是那三步,但是在配置上差别稍微大一点:
- 导入客户端的依赖包
即Xmemcached
看这里带着版本号呢,因为springboot没给整合 - 做配置
因为pringboot没给整合,咱们在boot里这样整合,写一个配置类,然后在将所需的配置信息写在yml配置文件中,然后在封装到配置类的实体中,然后在需要使用配置信息的地方通过这个实体来获取即可,这就是我们自定义的配置信息,将其封装到对象中的操作
具体学习yml可以看这里:https://blog.csdn.net/qq_45821251/article/details/123188505?spm=1001.2014.3001.5501#yml_75
(哈哈,这个也是我的笔记)
配置类:
这里用到了lombok
lombok相关的看这里https://blog.csdn.net/qq_45821251/article/details/123188505?spm=1001.2014.3001.5501#lombok_206
(哈哈,还是我那篇笔记中的)
然后加载配置,得抛出异常
这里也是获取操作memcache客户端的对象,就像操作redis有redisTemplate一样,操作memcache有memcachedClient,通过这个类的实例来操作memcache客户端。就下面加了@Bean的那个方法,用来获取和配置memcachedClient的实例
- 使用
就是换一种缓存的实现方式,业务还是跟前面一样。
这里,第二个@Autowired那里,就是将上面获取的memcachedClient的对象注入进来
定时任务
企业开发中,总不免有些需要定时执行的任务,比如年度报表,缓存统计报告…
java提供的定时任务制作
java提供了一些api用于执行定时任务
使用quartz
Quartz是市面上比较流行的定时任务技术
Quartz将定时任务拆分又加了一些设定
quartz中有这么一些相关的概念
相关概念
工作 (Job) :用于定义具体执行的工作
工作明细 (JobDetail) :用于描述定时工作相关的信息
触发器 (Trigger) :用于描述触发工作的规则,通常使用cron表达式定义调度规则
调度器 (Scheduler) :描述了工作明细与触发器的对应关系
使用这个技术也是三步
- 导入依赖包
- 做配置
他需要的配置比较多,跟后面要讲的task比真的很繁杂
这里要做的工作就是实现这三个部分,工作明细 触发器 调度器
工作明细指定工作,然后触发器绑定工作明细,然后调度器描述触发器和工作明细的关系
就上面这东西,一听就知道很麻烦
先看看工作部分,即要执行的任务,这里有一个执行的任务:
这个任务要使用quartz的话,需要继承QuartzJobBean,并实现对应的方法,执行的任务就写在这个方法里面
这个方法提供了一个工作执行的上下文对象,即那个参数,通过这个上下文对象可以拿到很多具体的信息
注意这个类并没有定义为一个spring的bean,不需要
实现:工作明细指定工作,然后触发器绑定工作明细,然后调度器描述触发器和工作明细的关系
用配置类完成这样的配置
cron表达式一点基础知识看下面的目录 - 使用
哈哈哈,这里的使用其实和上面配置都融到一起了,上面已经完成所有工作了,直接运行即可
cron表达式一点基础知识
(“a b c d e f”)
一般有六项,从左到右分别代表,a:秒,b:分,c:时,d:日,e:月,f:星期几
他们的值设置为*
则表示任意,如"5 * * * * *"
表示任意分钟的5秒执行
一般d和f不会同时设定一个具体的值,比如不能这样设置"0 * * 1 * Monday"
这谁能确定1号就是星期1呢?所以一般是若一个设置为具体的值,则另一个需要设置为?
表示根据另一个值进行匹配,如"0 * * 1 * ?"
根据前面日子匹配星期
每一项有可以设定各种的值,如
"0/5 * * * * ?"
表示每隔5s执行一次
"0 5/5 * * * ?"
表示从每小时的第五分钟开始运行,每隔5分钟运行一次
"0,5,8,56 * * * * ?"
表示每分钟的0秒、5秒、8秒、56秒执行
更详细的可以去学习一下,网上一大堆,cron表达式生成器也一搜一大堆
使用task
由上面几个步骤,就知道这个quartz多让人难受了
还好,springboot给整了个简单方便的
只需简单的两步就能实现简单的定时任务
- 在项目中开启定时任务的功能在容器能扫描到的地方加上这个注解
@EnableScheduling
按照规范,我们一般加载启动类上,表示开启定时任务的功能
- 在需要执行定时的任务上加上注解
@Scheduled(cron = "")
cron的值是cron表达式,作用就是设置执行时间和频度等,这个类需要被标注为bean,交由spring管控
只这两步,就完成了定时任务
更详细的设定,可以通过配置文件来搞
整合JavaMail(发邮件)
关于收发电子邮件有三个协议
SMTP (Simple Mail Transfer Protocol) :简单邮件传输协议,用于发送电子邮件的传输协议
POP3 ( Post Office Protocol - Version 3) :用于接收电子邮件的标准协议
IMAP ( Internet Mail Access Protocol) :互联网消息协议,是POP3的替代协议
POP3协议因为同步问题,被IMAP替代了
发送简单邮件
三步
- 导入依赖包
- 配置
配置需要补充这几项
username就是我们的邮箱账户
host是为了区别邮件供应商,比如使用QQ邮箱,则host为smtp.qq.com,前缀smtp表示smtp协议。
password并不是邮箱账户的密码,是一个授权码,可以说是一个密码令牌,密码通行证
获取方式:
就类似于下面这样的:
- 使用
使用其实就是操作客户端,前面的整合技术中的操作原理也是操作客户端
具体的解释都在注释里了,实在不想再编辑一下图片了
上面定义的几个字符串类型的数据就对应着这里的这几项:
运行程序执行效果:
这就实现了简单邮件的发送
下面是可以包含链接,图片,文件等等信息的邮件发送
发送多部件邮件
多部件邮件其实就是邮件中能够包含多个部件的邮件
比如包含附件的邮件,甚至能够通过html格式解析邮件正文
发送这样的邮件的步骤和发送简单邮件的步骤一样
只是更换消息对象,和设置数据信息的方式
如果,要在正文中嵌入图片
如果图片是在网络上,则直接使用"<img src=‘网络资源的链接’/>",然后用开启html解析即可
如果是本地的图片,则需要换一个把戏
如下:这是如果图片是在本地的情况下
实现内嵌图片是靠下面标注出来的地方,注意下面标注出来的地方,在后面讲
- src=“cid:MUR” ?
cid: 全称是Content-ID
Content-ID头字段用于为"multipart/related" 组合消息中的内嵌资源指定一个唯一标识号,在HTML格式的正文中可以使用这个唯-标识号来引用该内嵌资源。例如,假设将一个表示内嵌图片的MIME消息的Content-ID头字段设置为如下形式:
Content-ID:MUR
那么,在HTML正文中就需要使用如下HTML语句来引用该图片资源:
<img src= “cid:MUR”>
注意,在引用Content-ID头字段标识的内嵌资源时,要在资源的唯一标识号前面加上"cid:" ,以说明要采用唯一标识号对资源进行引用。
在此处作用通俗点将就是作一个占位符,表示这里应该是一个标识号是MUR的内嵌资源 - File和FileSystemResourc ?
作用:创建一个内嵌资源,具体可以看上图中的文字说明 - helper.addInline ?
helper.addInline(内嵌资源标识符,内嵌资源的对象),用于为当前的消息对象添加一个内嵌资源,更形象点将,更应该叫做向指定地点位置插入一个内嵌资源。即将内嵌资源的对象(参数二)插入到内嵌资源标识符(参数一)所在的地方,跟上面src="cid:MUR"
相对应
为什么这样说,可以看一下官方文档:
注意下面警告那一部分
其实这里的原理:
看一下官方的这段话:
Multipart email允许添加附件和内嵌资源(inline resources)。内嵌资源可能是你在信件中希望使用的图像或样式表,但是又不想把它们作为附件。
就是说,这里潜入的内嵌资源也是附件,即也是多部件的一个部件,通过上面的操作,可以将这个附件不按照附件的形式来展示,而是通过内嵌的形式,潜入到邮件正文中
注意重要的一点:在下面这个地方,依然要增加第二个参数,并为其设置为true,因为这个内嵌的资源也是多部件的一种
看一下结果:
没啥意思,就想告诉大家,我是大帅比
中间件之消息队列
-
什么是中间件?
我也不是很明白,就是你好像知道,但是描述不出来,这说明了解的还是太少
百度百科:
中间件是一类连接软件组件和应用的计算机软件,它包括一组服务。以便于运行在一台或多台机器上的多个软件通过网络进行交互。该技术所提供的互操作性,推动了一致分布式体系架构的演进,该架构通常用于支持并简化那些复杂的分布式应用程序,它包括web服务器、事务监控器和消息队列软件。
IT界有句俗话说,所有问题都可以通过增加一层来解决。
中间件也是加一层,在两个服务之中加一层
比如redis,中间件的一种,他就是在程序和数据库之间加一层,当然redis不仅仅能用于存储数据库信息。再比如RabbitMQ,消息队列,就是在消息的发送方和接收方之间加一层,提高了极大的效率。
就这么回事
-
什么是消息?
百度百科:
“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。
很了然了,就是数据单位
消息有发送方和接收方
我们称为生产者和消费者
消息有同步消息和异步消息
同步消息:
生产者向消费者发送消息,只有得到消费者的回应后,生产者才会进行下一步的操作,这样的称为同步消息
异步消息:
生产者向消费者发送消息,无需得到消费者的回应,生产者即可进行下一步的操作,这样的称为异步消息
-
什么是消息队列?
百度百科:
“消息队列”是在消息的传输过程中保存消息的容器。
同步消息对我们的意义不是很大,消息队列的高并发靠的是异步消息
相关产品有RabbitMQ,ActiveMQ,RocketMQ… … -
企业级应用中广泛使用的三种异步消息传递技术:
JMS
AMQP
MQTT
这三组对应了又有若干个实现技术,比如消息队列中现在常用的
RabbitMQ,ActiveMQ,RocketMQ… …
JMS:
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。
AMQP:
JMS出来的要比AMQP早,JMS是一个规范,类似于JDBC,而且JMS定义的一些接口仅适用于Java平台,并不适用于其他语言,所以在这个基础上人们提出了一个协议
他将所有的消息种类规范为字节单位,主要就是靠这个实现跨平台的。消息模型注意direct和topic两个模型
百度百科:
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有RabbitMQ等。
他兼容JMS
AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。这使得实现了AMQP的provider天然性就是跨平台的。AQMP可以用http来进行类比,不关心实现的语言,只要大家都按照相应的数据格式去发送报文请求,不同语言的client均可以和不同语言的server链接。
AMQP跟JMS的关系可以类比于炒菜:AMQP规范了炒菜动作,JMS规范了放啥原料,炒菜动作都差不多,放啥原料要根据炒啥菜来放
MQTT
用于物联网
常用实现消息队列的技术有四个:
RabbitMQ
ActiveMQ
RocketMQ
Kafka:一种高吞吐量的分布式发布订阅消息系统,提供实时消息功能,可以实现消息队列的功能,但主要不使用用于做消息队列
这里记录两个常用的消息队列的整合
RabbitMQ
ActiveMQ
实现一个业务
先实现一个简单的业务,基于这个业务用于后续整合消息队列
业务功能:模仿订单处理其中的发短信功能(并不是真正的发短信)
两个类,一个表示类用于调用处理具体业务的具体实现(实际应该是这样做,这里是模拟,就意思意思一下),这里模拟的是发送短信,所以至少应该有一个实现具体发送短信的类吧,这里第二个类就是这个作用,当然就是具体意思意思,也不是真正的发送短信
调用处理具体业务的类:
一个实现具体发送短信业务的类:
按照开发流程,进行具体的发短信业务的类是消费消息,也应该对应一个视图层,不然里面的具体的发短信业务的那个方法无法调用
两个视图层:
切换为ActiveMQ
Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行。
市场使用量也很大
ActiveMQ的安装和启动
下载地址:https://activemq.apache.org/activemq-5016004-release
这个是5.16.4版本,5.17即往上需要jdk 11+
启动服务需要三个端口:5672,61613,1883,启动失败可以看看是哪个端口被占用:
比如这里,我启动active服务失败了,往下找到第一个报错的地方,可以看到是说5672的端口被占用
然后我们可以查找当前这个端口是被什么玩意给占了,把相关进程关了就行,一般我们能手动关闭的进程都是不重要的,不要担心因为手动关闭进程而导致电脑系统崩掉
根据端口关闭进程的方法后面再记录(往下找就能找到),这里直接接着上面写
这里就是因为我安装了RabbitMQ所需要的erlang语言,他的后台进程会占用5672端口,把它关闭了服务就能启动
启动服务
启动服务就是启动bin下的activemq.bat
直接点击或在cmd执行都可
这个样子:可以看到最下面,给了一个地址,这个是activeMQ给我们提供一个web端的控制台的地址
进入这个地址,会问你要密码和账户,初始默认都是admin,然后进入后这样:
点击那个Manage ActiveMQ broker
就能进入如下这样的相关的管理界面
windows下根据端口,关闭相关进程
分为两步:
- 查看端口被什么进程占用
在cmd下,这个命令用于查看占用对应端口号的进程信息
netstat -ano | findstr 端口号
显示的结果中每个值的含义:
1:协议 2:本地地址 3:外部地址 4:状态 5:PID
我们需要的只是最后面的PID值
根据PID值查看对应的进程信息:
tasklist|findstr PID值
- 关闭相关进程
有两种方法
第一是还在cmd下执行关闭命令:
taskkill -PID PID值 -F
这个权限不够高,可能无法生效
或者直接根据PID值在任务管理器中找到对应的进程,进行手动关闭:
这里建议,在详细信息中找到对应的进程信息后,在这里找到这个进程进行关闭
业务更换为activeMQ实现
三步
- 导入坐标
- 做配置
设置所连接的消息队列的地址
本机的话,格式是:tcp://localhost:服务的端口号
tcp是tcp协议,localhost表示本机的地址,后面的端口号是ActiveMQ服务所使用的端口号 - 使用接口操作
当向消息队列中存放消息的时候,需要为当前要发送的消息指定一个存储地址,因为消息队列也是一个大的容器,每次存放的消息应该分类划分进行存储,所以要在消息队列中指定一个位置,不然会报错
设置一个默认的存储路径:
然后通过postman测试:
测试结果如下:
消费消息:
通过postman通过设定的msgs路径进行调用:
这里,会从头取出第一个消息进行处理
但是,这里的存储空间的设定确实不妥,我们一般应该这样搞:
但是,在实际开发中,我们很少搞这种点一下才进行消费消息队列中的消息,我们一般都是消息过来,马上就消费
MQ中提供了一套这样的解决方案,设置一个监听器,来监听消息队列中对应的存储空间
一旦有消息
以上是关于springboot----数据层技术的选择+各种整合(缓存,消息队列)+定时任务+发邮件的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot数据访问 SpringBoot整合Mybatis