扯淡:
短信发送的应用场景非常多,在较大的系统中,短信一般作为单独的服务独立运行,而短信发送任务的触发基本有两种方式。1、定时获取Redis中短信发送任务,2、消息中间件订阅短息任务队列。
个人学习总结:
链接:【springboot、springcloud、docker 等,学习目录】
需求:用户注册时输入手机号获取验证码。
RabbitMQ订阅短信:
短信微服务(springboot2_sms 文末下载源代码):
短信微服务为独立工程。将阿里大于SmsDemo抽取为工具类。
1、pom依赖:
<dependencies>
<!-- 阿里大于 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.6</version> <!-- 注:如提示报错,先升级基础包版,无法解决可联系技术支持 -->
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
<!-- RabbitMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
2、启动类:
@SpringBootApplication
public class SmsApplication {
public static void main(String[] args) {
SpringApplication.run(SmsApplication.class);
}
/**
* 短信队列
*/
@Bean
public Queue smsQueue(){
return new Queue("sms");
}
}
3、配置文件:
server:
port: 9009
spring:
application:
name: springboot2-sms # 微服务名称
# rabbitmq 配置
rabbitmq:
host: 192.168.25.133
port: 5672
username: guest
password: guest
aliyun:
sms:
accessKeyId: yourAccessKeyId
accessKeySecret: yourAccessKeySecret
template_code: SMS_1000000
sign_name: 云通
4、mq监听sms队列:
/**
* 短信监听类
*/
@Slf4j
@Component
@RabbitListener(queues = "sms")
public class SmsListener {
@Autowired
private SmsUtils smsUtils;
@Value("${aliyun.sms.template_code}")
private String template_code;//模板编号
@Value("${aliyun.sms.sign_name}")
private String sign_name;//签名
@RabbitHandler
public void sendSms(Map<String,String> map){
log.info("手机号:"+map.get("mobile"));
log.info("验证码:"+map.get("code"));
try {
// 模板格式根据自己的需求来做
String param = "{\"name\":\"Ron\", \"code\":\"" + map.get("code") + "\"}";
smsUtils.sendSms(map.get("mobile"),sign_name,template_code, param);
} catch (ClientException e) {
e.printStackTrace();
}
}
}
用户微服务(springboot2_user_sms 文末下载源代码):
添加用户注册功能。
1、添加pom依赖:
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- RabbitMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
2、添加RabbitMQ配置:
# rabbitmq 配置
spring:
rabbitmq:
host: 192.168.25.133
port: 5672
username: guest
password: guest
redis:
host: 127.0.0.1
port: 6379
database: 1
3、获取验证码接口
3.1、UserController:
/**
* 获取短信验证码
* @param mobile
*/
@RequestMapping(value="/sendsms/{mobile}",method= RequestMethod.POST)
public ApiResult sendsms(@PathVariable String mobile ){
userService.sendSms(mobile);
return ApiResult.ok();
}
3.2、UserService:
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendSms(String mobile) {
/**
* 1.生成6位短信验证码
* 阿帕奇 提供的工具类
*/
String code = RandomStringUtils.randomNumeric(6);
log.info(mobile + "收到验证码是:" + code);
/**
* 2.将验证码放入redis
* 此处将code 放入redis仅仅是为了用户输入验证码后,系统后台取出来检验
*/
redisTemplate.opsForValue().set("smscode_" + mobile, code+"" ,5, TimeUnit.MINUTES );//五分钟过期
//3.将验证码和手机号发动到rabbitMQ中
Map<String,String> map=new HashMap();
map.put("mobile", mobile);
map.put("code", code);
rabbitTemplate.convertAndSend("sms",map);
}
测试:
1、启动RabbitMQ、短信服务、用户服务。
2、请求接口:127.0.0.1:8090/user/sendsms/17671777777
从Redis获取短信发送任务:
1、用户请求获取验证码接口
2、生成随机验证码,可将手机号作为key,验证码作为value存入Redis。
3、短信服务定时获取Redis中数据,有数据就执行发送短信任务,并删除该缓存。
4、发送短信的任务建议做成异步的,并使用自定义线程池。
Redis、mq发现发送短信任务对比:
1、mq为实时监听订阅,有任务就立即触发发送短息。
2、Redis为定时获取任务,定时一般固定时间,发送短信可能不会立即响应。
代码地址:
短信微服务:
springboot-account2: 公众号 - Gitee.com
用户微服务:
springboot-account2: 公众号 - Gitee.com
个人学习分享
更多 springboot、springcloud、docker 文章,关注微信公众号吧: