1.使用 docker 下载 rabbitmq :
docker pull rabbitmq:management
2.使用 docker images 命令来查看下载的镜像:
$ docker images
3.使用 docker start 命令来启动rabbitmq:
docker start 9822b13b4f75
4.构建项目
5. umz-message-api 接口工程
1.api接口类RegisterServiceApi
#定义接口类
package com.microservice.soa.api.register;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import com.microservice.soa.bean.email.EmailRequestBean;
import com.microservice.soa.bean.email.EmailResponseBean;
public interface RegisterServiceApi {
/**
*
* @Title: queryOrderInfo
* @Description: TODO(注册发送邮件)
* @param @param emailRequestBean
* @param @return 参数
* @return String 返回类型
* @throws
*/
// @RequestMapping("sendEmail")
public EmailResponseBean sendMessage(@RequestBody EmailRequestBean emailRequestBean);
}
package com.microservice.soa.bean.email;
import java.io.Serializable;
/**
*
* @ClassName: EmailRequestBean
* @Description: TODO(邮箱请求实体类)
* @author MAOJIAJIE
* @date 2019年4月19日
*
*/
public class EmailRequestBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String uname;//收件人性名
private String upassword;//收件人密码
private String uregdate; //注册时间
private Integer ustate;//状态
private String fromAddress; //发件人
private String toAddress; //收件人
private String text; //邮件标题
private String content; //邮件内容
private String copyPerson; //抄送人
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpassword() {
return upassword;
}
public void setUpassword(String upassword) {
this.upassword = upassword;
}
public String getUregdate() {
return uregdate;
}
public void setUregdate(String uregdate) {
this.uregdate = uregdate;
}
public Integer getUstate() {
return ustate;
}
public void setUstate(Integer ustate) {
this.ustate = ustate;
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCopyPerson() {
return copyPerson;
}
public void setCopyPerson(String copyPerson) {
this.copyPerson = copyPerson;
}
@Override
public String toString() {
return "EmailRequestBean [uname=" + uname + ", upassword=" + upassword + ", uregdate=" + uregdate + ", ustate="
+ ustate + ", fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", text=" + text + ", content="
+ content + ", copyPerson=" + copyPerson + "]";
}
}
###########################################################################
package com.microservice.soa.bean.email;
import com.microservice.soa.bean.BaseRespBean;
/**
*
* @ClassName: EmailRequestBean
* @Description: TODO(邮箱返回实体类)
* @author MAOJIAJIE
* @date 2019年4月19日
*
*/
public class EmailResponseBean extends BaseRespBean {
private static final long serialVersionUID = 1L;
private String msg;
private String toAddress;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
@Override
public String toString() {
return "EmailResponseBean [msg=" + msg + ", toAddress=" + toAddress + "]";
}
}
6. umz-message工程
相关的配置
1.application.yml
#配置yml
# native
#应用端口及应用名称
server:
port: 8009
servlet:
context-path: /umz-message
#数据库配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/dumz_db?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 12345678
type: com.alibaba.druid.pool.DruidDataSource
tomcat:
initial-size: 1
max-wait: 60000
min-idle: 3
max-age: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
mvc:
view:
prefix: /WEB-INF/
suffix: .jsp
http:
encoding:
charset: UTF-8
enabled: true
force: true
#邮箱服务器
mail:
host: smtp.qq.com
#发送邮箱用户名
username: [email protected]
#此处为客户端授权密码
password: kmwptnlpeznjebaj
#编码集
default-encoding: UTF-8
#必须有!邮箱授权开启,不然报错
properties:
mail:
smtp:
auth: true
#服务器地址校正
localhost: smtp.qq.com
application:
name: umz-message #客户端服务名
# redis:
# database: 0 #Redis数据库索引(默认为0)依次递增
# host: 127.0.0.1 #Redis服务器地址
# port: 6379 #Redis服务器连接端口
# lettuce:
# pool:
# max-active: 8 #最大连接数
# max-wait: -1s #最大阻塞等待时间(负数表示没限制)
# max-idle: 8 #最大空闲数
# min-idle: 0 #最小空闲数
# timeout: 10000s #连接超时时间
# jedis: #springboot2.0 中直接使用jedis或者lettuce配置连接池
# pool:
# max-active: 10 #最大连接数 负数为不限制
# max-wait: -1s #连接池最大阻塞等待时间(使用负值表示没有限制) 等待可用连接的最大时间,负数为不限制
# max-idle: 8 #连接池中的最大空闲连接
# min-idle: 0 #连接池中的最小空闲连接
# timeout: 10000ms #设置连接超时时间
#消息队列
rabbitmq:
host: 127.0.0.1
port: 5672
username: admin
password: admin
### 地址
virtual-host: /
#注册信息
eureka:
instance:
hostname: localhost #eureka客户端主机实例名称
instance-id: umz-message:8762 #客户端实例名称
prefer-ip-address: true #显示IP
lease-renewal-interval-in-seconds: 1 #eureka 客户端向服务端发送心跳间隔时间 单位秒
lease-expiration-duration-in-seconds: 2 #eureka服务端收到最后一次等笔
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# 单机 defaultZone: http://localhost:2001/eureka #把服务注册到eureka注册中心
#defaultZone: http://eureka2001.java1234.com:2001/eureka/,http://eureka2002.java1234.com:2002/eureka/,http://eureka2003.java1234.com:2003/eureka/ # 集群
mybatis:
mapper-locations:
- classpath:com/microservice/soa/dao/*.xml
config-location: classpath:com/microservice/mybatis-config.xml
type-aliases-package: com.microservice.soa.model
# configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #可以指定相应的类
## 健康状态 http://localhost:9001/microConsumer/health
#info:
# app:
# name: "@project.artifactId@"
# encoding: "@project.build.sourceEncoding@"
# java:
# source: "@java.version@"
# target: "@java.version@"
#logging:
# config: classpath:log4j2.xml
2.RabbitConfig配置类
package com.microservice.soa.conf;
import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
//为了方便演示我都使用的public
//队列
public static final String EMAIL_QUEUE = "emailQueue";
//交换机
public static final String EXCHANGE_TOPIC_NAME = "testChange";
//#路由规则 匹配 email后面 所有的键
public static final String QUEUE_BING_ROUTINGKEY="email.#";
//# 提供者发送消息指定的 路由键(邮件)
public static final String PRODUCER_ROUTINGKEY="email.bar.test";
//声明队列
@Bean(EMAIL_QUEUE)
public Queue QUEUE_NEWS(){ //新闻的队列
return new Queue(EMAIL_QUEUE);
}
//声明交换机
@Bean(EXCHANGE_TOPIC_NAME)
public Exchange EXCHANGE_TOPIC_INFORM(){
//声明了一个Topic类型的交换机,durable是持久化(重启rabbitmq这个交换机不会被自动删除)
return ExchangeBuilder.topicExchange(EXCHANGE_TOPIC_NAME).durable(true).build();
}
//声明EMAIL_QUEUE队列和交换机绑定关系,并且指定RoutingKey
@Bean
public Binding NEWS_BINDING_TOPIC(@Qualifier(EMAIL_QUEUE) Queue queue,
@Qualifier(EXCHANGE_TOPIC_NAME) Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(QUEUE_BING_ROUTINGKEY).noargs();
}
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
3.消费监听
EmailMessageListener类
package com.microservice.soa.listener;
import java.io.IOException;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.microservice.soa.model.Email;
import com.microservice.soa.service.register.SendEmailService;
/**
* @RabbitListener 底层 使用Aop进行拦截,如果程序没有抛出异常,自动提交事务,
* 如果Aop使用异常通知拦截 获取异常信息的话,自动实现补偿机制,该消息会缓存到rabbitmq服务器存放,
* 会一直重试到不抛出异常为主。解决方式 修改重试机制策略 默认间隔5秒重试一次
*
*
*
* @ClassName: EmailMessageListener
* @Description: TODO(消息处理监听类 邮件发送类)
* @author MAOJIAJIE
* @date 2019年4月12日
*
*/
@Component
public class EmailMessageListener{
private static Logger log = LoggerFactory.getLogger(EmailMessageListener.class);
@Resource
private SendEmailService sendEmailService;
@RabbitListener(queues = {"emailQueue"})
public void onMessage(Message message) {
// TODO Auto-generated method stub
log.info("*************************开始邮件监听消息*************************");
String messageBody = new String(message.getBody());
ObjectMapper mapper = new ObjectMapper();
System.out.println(messageBody);
/**
* rabbitmq 默认情况下,如果消费者程序出现异常的情况下,会自动实现补偿机制 (重试机制)
* 队列服务器发送补尝请求
*/
// int i = 1/0;
try {
Jackson2JsonMessageConverter jackson2JsonMessageConverter =new Jackson2JsonMessageConverter();
Email email = (Email)jackson2JsonMessageConverter.fromMessage(message);
// Email email = mapper.readValue(messageBody, Email.class);
log.info("接收到邮件消息:【" + email + "】");
//发送邮件通知
//EmailUtil.sendEmail(email);
sendEmailService.sendMessage(email);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("发送邮件失败!:【" + e.toString() + "】");
}
}
}
4.接口请求类 RegisterAccess
package com.microservice.soa.access.register;
import java.util.Date;
import java.util.UUID;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.microservice.soa.api.register.RegisterServiceApi;
import com.microservice.soa.bean.email.EmailRequestBean;
import com.microservice.soa.bean.email.EmailResponseBean;
import com.microservice.soa.dao.user.UserDao;
import com.microservice.soa.model.Email;
import com.microservice.soa.model.User;
import com.microservice.soa.util.RespUtils;
import com.microservice.soa.util.UidUtils;
/**
*
* @ClassName: RegisterAccess
* @Description: TODO(邮件通知)
* @author MAOJIAJIE
* @date 2019年4月20日
*
*/
@RestController
public class RegisterAccess implements RegisterServiceApi {
private static Logger log = LoggerFactory.getLogger(RegisterAccess.class);
@Resource
private UserDao userDao;
@Resource
RabbitTemplate template;
@Override
@RequestMapping("sendEmail")
public EmailResponseBean sendMessage(EmailRequestBean emailRequestBean) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
Email email = new Email();
//发件人邮件地址
email.setFromAddress(emailRequestBean.getFromAddress());
//收件人邮件地址
email.setToAddress(emailRequestBean.getToAddress());
//邮件主题
email.setText("站点测试邮箱");
email.setContent("注册成功!");
//入库
User user = new User();
user.setUserId(UidUtils.createUtil());
user.setUserName(emailRequestBean.getUname());
user.setCreateTime(new Date());
user.setUserStart("01");
user.setOlineStart("01");
user.setUserEmail(emailRequestBean.getToAddress());
user.setUserPsw(emailRequestBean.getUpassword());
//插入表中
userDao.insert(user);
//测试注解事物
// System.out.println(1 / 0);
try {
//发送到消息队列中
// template.convertAndSend(email);
//指定交换机,指定routing key,发送消息的内容
template.convertAndSend("testChange","email.bar.test",email);
log.info("****************用户注册成功!");
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
log.info("用户注册失败:原因【"+e.toString()+"】");
return RespUtils.createBaseResp("1004", "用户注册失败:原因【"+e.toString()+"】", email.getToAddress());
}
return RespUtils.createBaseResp("000", "测试成功!", email.getToAddress());
}
}
6. 测试
项目下载地址:
https://download.csdn.net/download/qq_31987649/12374703