ActiveMQ–异步发邮件 点对点
技术点
1. ActiveMQ 发布信息到队列
2. ActiveMQ 队列消息获取
3. 邮件SMTP服务开启
4. Java发送邮件
遇到的问题
1. AOP 除了spring框架里的API,还要几个()
2. QQ邮箱必须开启邮箱独立密码然后才能开启SMTP服务,而且SMTP必须要验证
3. Java发送邮件的时候 QQ邮箱默认端口 28是不能用的,用587,其外一个也有问题
4. 邮箱密码是生成的验证码,修改邮箱独立密码会导致验证码失效,需要重新生成。
ActiveMQ 管理界面
1. name :消息队列名字
2. Number of Pending Messages :队列中消息数
3. Number of Consumers :消费者数
4. Message Enqueued :累计入队的消息数
5. Message Dequeued :累计出队的消息数
ActiveMQ 发布消息到队列
- Java代码
@Autowired
private JmsTemplate jmsTemplate;
jmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(JSONObject.toJSONString(mailParam));
}
});
<!--jmsTemplate 根据配置文件由spring自动注入 Autowired 默认按照类型装配-->
<!--createTextMessage内传入Json格式字符串-->
- 配置文件
<!--连接工厂-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!--ActiveMQ服务地址-->
<property name="brokerURL" value="${mq.brokerURL}"/>
<property name="userName" value="${mq.userName}"/>
<property name="password" value="${mq.password}"/>
</bean>
<!--池化-->
<!--ActiveMQ 提供PooledConnectionFactory将连接工厂 Connection,Session,MessageProduce池化,可以减少资源消耗-->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="targetConnectionFactory"/>
<property name="maxConnections" value="${mq.pool.maxConnections}"/>
</bean>
<!--spring与MQ集成 spring 提供用于管理真正的ConnectionFactory的类 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="pooledConnectionFactory"/>
</bean>
<!--spring提供的JMS工具类,可以进行消息发送接收-->
<!--队列模板-->
<bean id="activeMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestinationName" value="${queueName}"/>
</bean>
- 依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.13.3</version>
</dependency>
ActiveMQ 队列消息获取
- Java 代码
自定义监听 对目标队列进行监听
/**
* 自定义监听器
* @Author: duhongjiang
* @Date: Created in 2017/11/26
*/
@Component
public class ConsumerSessionAwareMessageListener implements SessionAwareMessageListener {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private Destination sessionAwareQueue;
@Autowired
private MailBiz mailBiz;
public synchronized void onMessage(Message message, Session session) throws JMSException {
try{
ActiveMQTextMessage msg=(ActiveMQTextMessage) message;
final String ms =msg.getText();
MailParam mailParam= JSONObject.parseObject(ms,MailParam.class);
if(mailParam==null){
return;
}
try{
mailBiz.mailSend(mailParam);
}catch (Exception e){
jmsTemplate.send(sessionAwareQueue, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(ms);
}
});
}
}catch (Exception e){
System.out.println(e);
}
}
}
- 配置文件
除了和发送的一样的还保含以下
<!--sessionAwareQueue的目的地 目标队列-->
<bean id="sessionAwareQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>${queueName}</value>
</constructor-arg>
</bean>
<bean id="consumerSessionAwareMessageListener" class="com.du.sm.ConsumerSessionAwareMessageListener"/>
<bean id="sessionAwareMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="sessionAwareQueue"/>
<property name="messageListener" ref="consumerSessionAwareMessageListener"/>
</bean>
邮件SMTP服务开启
Java发送邮件
- Java代码
@Autowired
private JavaMailSender mailSender;
@Autowired
private SimpleMailMessage mailMessage;
@Autowired
private ThreadPoolTaskExecutor threadPool;
public void mailSend(final MailParam mailParam) {
threadPool.execute(new Runnable() {
public void run() {
try{
mailMessage.setFrom(mailMessage.getFrom());
mailMessage.setTo(mailParam.getTo());
mailMessage.setSubject(mailParam.getSubject());
mailMessage.setText(mailParam.getContent());
mailSender.send(mailMessage);
}catch (MailException e){
System.out.println(e);
throw e;
}
}
});
}
- 配置文件
<!--spring提供发送电子邮件的高级抽象类-->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}"/>
<property name="port" value="${mail.port}"/>
<property name="username" value="${mail.name}"/>
<property name="password" value="${mail.password}"/>
<property name="defaultEncoding" value="${mail.default.Encoding}"/>
<property name="javaMailProperties" >
<props>
<prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
<prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop>
</props>
</property>
</bean>
<bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from">
<value>${mail.default.from}</value>
</property>
</bean>
<!--配置线程池-->
<bean id="threadPool" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="${pool.corePoolSize}"/>
<property name="keepAliveSeconds" value="${pool.keepAliveSeconds}"/>
<property name="maxPoolSize" value="${pool.maxPoolSize}"/>
<property name="queueCapacity" value="${pool.queueCapacity}"/>
</bean>
## SMTP服务配置
mail.host=smtp.qq.com
mail.port=587
mail.name=1324937864@qq.com
#mail.password邮箱验证码
mail.password=biwfxmikyscwiibb
mail.smtp.auth=true
mail.smtp.timeout=30000
mail.default.from=1324937864@qq.com
mail.default.Encoding=UTF-8
#线程池
#维护线程最少数量
pool.corePoolSize=5
#维护线程允许的空闲时间
pool.keepAliveSeconds=30000
#维护线程最大数量
pool.maxPoolSize=50
#缓冲队列
pool.queueCapacity=100
## MQ
mq.brokerURL=tcp\://192.168.0.106\:61616
mq.userName=admin
mq.password=
mq.pool.maxConnections=10
# queueName
queueName=du.edu.mqtest.v1