一、pom引入
<!-- 阿里云mq -->
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>ons-client</artifactId>
<version>1.8.0.Final</version>
</dependency>
其它引入(可忽略)
<!-- 阿里云短信服务 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
<!-- rocketMq消息服务 -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-acl</artifactId>
<version>4.5.2</version>
</dependency>
二、生产者producer
2.1 封装producer(@Value注解引入的参数可自行在配置文件中配置)
import com.aliyun.openservices.ons.api.Consumer;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @author :cw
* @date :Created in 2020/8/27 上午11:10
* @description:
* @modified By:
* @version: $
*/
@Configuration
public class AliCloudProducerConfig {
@Value("${ali-cloud.accessKeyId}")
private String accessKeyId;
@Value("${ali-cloud.accessKeySecret}")
private String accessKeySecret;
@Value("${ali-cloud.autumnGroupId}")
private String autumnGroupId;
@Value("${ali-cloud.nameSrvAddr}")
private String nameSrvAddr;
@Bean
public Producer producer(){
Properties properties = new Properties();
// 您在控制台创建的 Group ID
properties.put(PropertyKeyConst.GROUP_ID, autumnGroupId);
// AccessKey 阿里云身份验证
properties.put(PropertyKeyConst.AccessKey, accessKeyId);
// SecretKey 阿里云身份验证
properties.put(PropertyKeyConst.SecretKey, accessKeySecret);
// 设置 TCP 接入域名,到控制台的实例基本信息中查看
properties.put(PropertyKeyConst.NAMESRV_ADDR, nameSrvAddr);
Producer producer = ONSFactory.createProducer(properties);
return producer;
}
}
2.2 生产消息封装(普通消息)
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.SendResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author :cw
* @date :Created in 2020/8/27 上午11:17
* @description:
* @modified By:
* @version: $
*/
@Component
@Slf4j
public class AliCloudTools {
private final Producer producer;
@Autowired
public AliCloudTools(Producer producer) {
this.producer = producer;
}
/**
* 生产短信消息
* @param phone
* @param type
* @return
*/
public boolean producerPhoneSms(String code,String phone,String type){
// 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可
producer.start();
Message msg = new Message( "phone_message", "TagA", (code+","+phone+","+type).getBytes());
msg.setKey("phone_"+phone);
try {
SendResult sendResult = producer.send(msg);
// 同步发送消息,只要不抛异常就是成功
if (sendResult != null) {
System.out.println(new Date() + " Send mq message success. Topic is:" + msg.getTopic() + " msgId is: " + sendResult.getMessageId());
}
}
catch (Exception e) {
System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic());
e.printStackTrace();
return false;
}
// 在应用退出前,销毁 Producer 对象
// 注意:如果不销毁也没有问题
producer.shutdown();
return true;
}
}
其它消息发送方式参考:https://www.cnblogs.com/laifw/p/11369000.html
2.3 使用方式
直接注入AliCloudTools后调用方法
三、消费者consumer
3.1 信息config配置
import com.aliyun.openservices.ons.api.Consumer;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @author :cw
* @date :Created in 2020/8/26 下午4:21
* @description:
* @modified By:
* @version: $
*/
@Configuration
public class ACSClientConfig {
@Value("${ali-cloud.product}")
private String product;
@Value("${ali-cloud.domain}")
private String domain;
@Value("${ali-cloud.accessKeyId}")
private String accessKeyId;
@Value("${ali-cloud.accessKeySecret}")
private String accessKeySecret;
@Value("${ali-cloud.autumnGroupId}")
private String autumnGroupId;
@Value("${ali-cloud.nameSrvAddr}")
private String nameSrvAddr;
/**
* 短信acs配置
**/
@Bean
public IAcsClient acsClient() throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou",accessKeyId,accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou",product,domain);
return new DefaultAcsClient(profile);
}
@Bean
public Consumer consumer(){
Properties properties = new Properties();
// 您在控制台创建的 Group ID
properties.put(PropertyKeyConst.GROUP_ID, autumnGroupId);
// AccessKey 阿里云身份验证
properties.put(PropertyKeyConst.AccessKey, accessKeyId);
// SecretKey 阿里云身份验证
properties.put(PropertyKeyConst.SecretKey, accessKeySecret);
// 设置 TCP 接入域名
properties.put(PropertyKeyConst.NAMESRV_ADDR, nameSrvAddr);
// 集群订阅方式(默认)
// properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING);
// 广播订阅方式
// properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING);
Consumer consumer = ONSFactory.createConsumer(properties);
return consumer;
}
}
3.2 发送短信工具配置
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @author :cw
* @date :Created in 2020/8/26 下午5:18
* @description:
* @modified By:
* @version: $
*/
@Component
@Slf4j
public class AliCloudTools {
private final IAcsClient iAcsClient;
@Autowired
public AliCloudTools(IAcsClient iAcsClient) {
this.iAcsClient = iAcsClient;
}
/**
* 发送短信
* @param code
* @param phoneNumber
* @param TemplateCode
* @return
*/
public SendSmsResponse sendSms(String code, String phoneNumber,String TemplateCode){
//组装请求对象
SendSmsRequest request = new SendSmsRequest();
//待发送手机号
request.setPhoneNumbers(phoneNumber);
//短信签名
request.setSignName("xxxx");
//短信模板
request.setTemplateCode(TemplateCode);
//模板参数 结合配置的模板信息
request.setTemplateParam("{\"codes\":\""+code+"\"}");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
try{
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = iAcsClient.getAcsResponse(request);
return sendSmsResponse;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
3.3 消费监听配置(部分)
public class ConsumerCenter {
private final DefaultMQPushConsumer consumer;
private final AliCloudTools aliCloudTools;
@Autowired
public ConsumerCenter(DefaultMQPushConsumer consumer, AliCloudTools aliCloudTools) {
this.consumer = consumer;
this.aliCloudTools = aliCloudTools;
}
@PostConstruct
public void init() throws MQClientException {
log.info("init sms consumer !");
this.phoneMessageConsumer();
log.info("init other consumer !");
// this.otherMessageConsumer();
consumer.start();
log.info("all consumer Started");
}
/**
* 初始化短信消费者
*/
private void phoneMessageConsumer() {
// 注册回调函数,处理消息
try{
consumer.subscribe("phone_message", "TagA||TagB");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
log.info("{} Receive New Messages:{}", Thread.currentThread().getName(), msgs);
for (MessageExt messageExt : msgs){
String dataBody = new String(messageExt.getBody());
String[] phoneMsgArrays = dataBody.split(",");
String templateName = phoneMsgArrays[2];
if(Constant.TX_TRANSFORM_NAME.VALUES().equals(templateName)){
templateName = Constant.TX_TEMPLATE_SMS.VALUES();
}else{
templateName = Constant.AQY_TEMPLATE_SMS.VALUES();
}
aliCloudTools.sendSms(phoneMsgArrays[0],phoneMsgArrays[1],templateName);
log.info("receive:"+phoneMsgArrays);
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 初始化其它消费者
*/
private void otherMessageConsumer() {
}
}
补充记录:使用过程中遇到各种问题,感觉还是自己搭建mq比较好一点可以根据需要进行配置,依托在平台上对接不出现问题还好,出现问题就很麻烦。除此之外,需要考虑消息丢失的情况及解决方式。自建mq注意端口的权限管控等