简介:Docker安装RabbitMQ消息队列
#拉取镜像
docker pull rabbitmq:3.8.12-management-alpine
docker run -d --hostname rabbit_host1 --name xd_rabbit -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 rabbitmq:3.8.12-management-alpine
#介绍
-d 以守护进程方式在后台运行
-p 15672:15672 management 界面管理访问端口
-p 5672:5672 amqp 访问端口
--name:指定容器名
--hostname:设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts,作为容器主机IP的别名,并且将显示在容器的bash中
-e 参数
RABBITMQ_DEFAULT_USER 用户名
RABBITMQ_DEFAULT_PASS 密码
4369 erlang 发现口
5672 client 端通信口
15672 管理界面 ui 端口
25672 server 间内部通信口
访问管理界面
注意事项!!!!
CentOS 7 以上默认使用的是firewall作为防火墙
查看防火墙状态
firewall-cmd --state
停止firewall
systemctl stop firewalld.service
禁止firewall开机启动
systemctl disable firewalld.service
简介:讲解RabbitMQ的的死信队列+ TTL
简介:讲解RabbitMQ的延迟队列和应用场景
简介:项目整合RabbitMQ依赖和配置
<!--引入AMQP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
#消息队列
rabbitmq:
host: 8.129.113.233
port: 5672
virtual-host: /
password: password
username: admin
#开启手动确认消息
listener:
simple:
acknowledge-mode: manual
简介:商品下单锁定优惠券记录模块开发
/**
* 记录id
*/
private List<Long> lockCouponRecordIds;
/**
* 订单号
*/
private String orderOutTradeNo;
简介:优惠券微服务RabbitMQ延迟消息交换机和队列配置
#自定义消息队列配置,发送锁定库存消息-》延迟exchange-》lock.queue-》死信exchange-》release.queue
mqconfig:
#延迟队列,不能被监听消费
coupon_release_delay_queue: coupon.release.delay.queue
#延迟队列的消息过期后转发的队列
coupon_release_queue: coupon.release.queue
#交换机
coupon_event_exchange: coupon.event.exchange
#进入延迟队列的路由key
coupon_release_delay_routing_key: coupon.release.delay.routing.key
#消息过期,进入释放死信队列的key
coupon_release_routing_key: coupon.release.routing.key
#消息过期时间,毫秒,测试改为15秒
ttl: 15000
/**
* 交换机
*/
@Value("${mqconfig.coupon_event_exchange}")
private String eventExchange;
/**
* 第一个队列延迟队列,
*/
@Value("${mqconfig.coupon_release_delay_queue}")
private String couponReleaseDelayQueue;
/**
* 第一个队列的路由key
* 进入队列的路由key
*/
@Value("${mqconfig.coupon_release_delay_routing_key}")
private String couponReleaseDelayRoutingKey;
/**
* 第二个队列,被监听恢复库存的队列
*/
@Value("${mqconfig.coupon_release_queue}")
private String couponReleaseQueue;
/**
* 第二个队列的路由key
*
* 即进入死信队列的路由key
*/
@Value("${mqconfig.coupon_release_routing_key}")
private String couponReleaseRoutingKey;
/**
* 过期时间
*/
@Value("${mqconfig.ttl}")
private Integer ttl;
简介:延迟消息测试和注意事项
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CouponApplication.class)
@Slf4j
public class DemoApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void send(){
rabbitTemplate.convertAndSend("coupon.event.exchange","coupon.release.delay.routing.key","5qeqweqw");
}
}
简介:优惠券微服务发送延迟消息开发
@Data
public class CouponRecordMessage {
/**
* 消息队列id
*/
private Long messageId;
/**
* 订单号
*/
private String outTradeNo;
/**
* 库存锁定工作单id
*/
private Long taskId;
}
for(CouponTaskDO couponTaskDO : couponTaskDOList){
CouponRecordMessage couponRecordMessage = new CouponRecordMessage();
couponRecordMessage.setOutTradeNo(orderOutTradeNo);
couponRecordMessage.setTaskId(couponTaskDO.getId());
rabbitTemplate.convertAndSend(rabbitMQConfig.getEventExchange(),rabbitMQConfig.getCouponReleaseDelayRoutingKey(),couponRecordMessage);
log.info("优惠券锁定消息发送成功:{}",couponRecordMessage.toString());
}
简介:优惠券回收-延迟消息消费回收功能开发《上》
优惠券解锁记录场景
1、超时未支付,比如30分钟则订单失效关闭
2、下单成功,创建订单业务失败,订单回滚
库存解锁防止继续支付:
1、30分支付超时则无法支付订单
2、订单31分延迟消息(比订单超时大几分钟)
->查询订单状态-向第三方支付查询订单状态,只有未支付状态,且本地订单状态是NEW,才修改本地订单状态为取消CANCEL,其他业务才可以解锁对应的库存库存
3、商品、优惠券库存32分延迟消息(比订单超时大几分钟)
->查询订单状态-订单不存在,解锁库存
->查询订单状态
1)订单状态为取消CANCEL的情况,才可以解锁库存,确认消息接收;
2)订单状态为未支付NEW的情况,则不解锁库存,不修改订单状态,重新投递消息或者拒收;
(避免网络延迟到 导致订单关单消息,比库存解锁还慢,没更新订单状态)
3)如果是订单已经支付则修改库存task工作单状态,确认消息接收;
注意:延迟队列一定要开启手动的ack机制,防止解锁失败,消息丢失,也要防止多次解锁
解锁库存的时候:修改状态和修改对应库存task工作单状态应该是同个事务,防止其中一个失败
简介:订单微服务-查询订单支付状态接口开发
简介:优惠券回收-延迟消息消费回收功能开发《下》
INSERT INTO `product_order` (`id`, `out_trade_no`, `state`, `create_time`, `total_amount`, `pay_amount`, `pay_type`, `nickname`, `head_img`, `user_id`, `del`, `update_time`, `order_type`, `receiver_address`)
VALUES
(1, '123456abc', 'PAY', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL);
INSERT INTO `coupon_task` (`id`, `coupon_record_id`, `create_time`, `out_trade_no`, `lock_state`)
VALUES
(1, 1, '2021-02-27 16:05:11', '123456abc', 'LOCK');
愿景:“让编程不再难学,让技术与生活更加有趣”
简介:商品下单-锁定商品库存模块开发
@Data
public class LockProductRequest {
@JsonProperty("order_out_trade_no")
private String orderOutTradeNo;
@JsonProperty("order_item_list")
private List<OrderItemRequest> orderItemList;
}
@Data
public class OrderItemRequest{
@JsonProperty("product_id")
private long productId;
@JsonProperty("buy_num")
private int buyNum;
}
简介:商品微服务RabbitMQ延迟消息交换机和队列配置
#自定义消息队列配置,发送锁定库存消息-》延迟exchange-》lock.queue-》死信exchange-》release.queue
mqconfig:
#延迟队列,不能被监听消费
stock_release_delay_queue: stock.release.delay.queue
#延迟队列的消息过期后转发的队列
stock_release_queue: stock.release.queue
#交换机
stock_event_exchange: stock.event.exchange
#进入延迟队列的路由key
stock_release_delay_routing_key: stock.release.delay.routing.key
#消息过期,进入释放队列的key
stock_release_routing_key: stock.release.routing.key
#消息过期时间,毫秒,测试改为15秒
ttl: 15000
/**
* 交换机
*/
@Value("${mqconfig.stock_event_exchange}")
private String eventExchange;
/**
* 第一个队列延迟队列,
*/
@Value("${mqconfig.stock_release_delay_queue}")
private String stockReleaseDelayQueue;
/**
* 第一个队列的路由key
* 进入队列的路由key
*/
@Value("${mqconfig.stock_release_delay_routing_key}")
private String stockReleaseDelayRoutingKey;
/**
* 第二个队列,被监听恢复库存的队列
*/
@Value("${mqconfig.stock_release_queue}")
private String stockReleaseQueue;
/**
* 第二个队列的路由key
*
* 即进入死信队列的路由key
*/
@Value("${mqconfig.stock_release_routing_key}")
private String stockReleaseRoutingKey;
/**
* 过期时间
*/
@Value("${mqconfig.ttl}")
private Integer ttl;
简介:延迟消息测试和注意事项
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ProductApplication.class)
@Slf4j
public class DemoApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void send(){
rabbitTemplate.convertAndSend("stock.event.exchange","stock.release.delay.routing.key","23342342");
}
}
简介:商品微服务发送延迟消息开发
@Data
public class ProductMessage {
/**
* 消息队列id
*/
private Long messageId;
/**
* 订单号
*/
private String outTradeNo;
/**
* 库存锁定工作单id
*/
private Long taskId;
}
//发送MQ延迟消息 ,解锁商品库存 taskId TODO
ProductMessage productMessage = new ProductMessage();
productMessage.setTaskId(productTaskDO.getId());
productMessage.setOutTradeNo(orderOutTradeNo);
rabbitTemplate.convertAndSend(rabbitConfig.getEventExchange(),rabbitConfig.getStockReleaseDelayRoutingKey(),productMessage);
log.info("商品库存锁定信息发送成功:{}",productMessage);
简介:商品库存释放回收功能开发《上》
商品库存解锁记录场景
1、超时未支付,比如30分钟则订单失效关闭
2、下单成功,创建订单业务失败,订单回滚
库存解锁防止继续支付:
1、30分支付超时则无法支付订单
2、订单31分延迟消息(比订单超时大几分钟)
->查询订单状态-向第三方支付查询订单状态,只有未支付状态,且本地订单状态是NEW,才修改本地订单状态为取消CANCEL,其他业务才可以解锁对应的库存库存
3、商品、优惠券库存32分延迟消息(比订单超时大几分钟)
->查询订单状态-订单不存在,解锁库存
->查询订单状态
1)订单状态为取消CANCEL的情况,才可以解锁库存,确认消息接收;
2)订单状态为未支付NEW的情况,则不解锁库存,不修改订单状态,重新投递消息或者拒收;
(避免网络延迟到 导致订单关单消息,比库存解锁还慢,没更新订单状态)
3)如果是订单已经支付则修改库存task工作单状态,确认消息接收;
注意:延迟队列一定要开启手动的ack机制,防止解锁失败,消息丢失,也要防止多次解锁
解锁库存的时候:修改状态和修改对应库存task工作单状态应该是同个事务,防止其中一个失败
简介: 商品库存回收-延迟消息消费回收功能开发《下》
INSERT INTO `product_order` (`id`, `out_trade_no`, `state`, `create_time`, `total_amount`, `pay_amount`, `pay_type`, `nickname`, `head_img`, `user_id`, `del`, `update_time`, `order_type`, `receiver_address`)
VALUES
(1, '123456abc', 'PAY', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL);
INSERT INTO `product_task` (`id`, `product_id`, `buy_num`, `product_name`, `lock_state`, `out_trade_no`, `create_time`)
VALUES
(1, 1, 2, '杯子-小滴课堂', 'LOCK', '123456abc', '2021-02-28 16:01:52');
简介: 订单微服务-确认收货地址模块开发
简介: token令牌丢失原因分析和解决方案
@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor(){
return template -> {
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if(attributes!=null){
HttpServletRequest request = attributes.getRequest();
if (null == request){
return;
}
log.info(request.getHeaderNames().toString());
template.header("token", request.getHeader("token"));
}else {
log.warn("requestInterceptor获取Header空指针异常");
}
};
}
简介:订单微服务下单获取最新价格开发
/**
* 用于订单服务,确认订单,获取全部购物项
*
* 会清空购物车对应的商品
*
* @return
*/
@ApiOperation("下单清空购物项")
@RequestMapping("confirm_order_cart_items")
public JsonData confirmOrderCartItem(@ApiParam("商品id列表") @RequestBody List<Long> productIdList ){
List<CartItemVO> cartItemVOList = cartService.confirmOrderCartItem(productIdList);
return JsonData.buildSuccess(cartItemVOList);
}
{
"coupon_record_id":-1,
"product_ids":[1,2],
"pay_type":"ALIPAY",
"client_type":"H5",
"address_id":45,
"total_amount":10,
"real_pay_amount":10,
"token":"SbD5D4FLpUzemiuwSEytwGM9LLFGISDQ"
}
简介:下单-购物车清空已经下单商品逻辑作业设计
简介:商品验证价格和优惠券抵扣功能开发
简介:下单锁定优惠券和商品库存逻辑开发
简介:下单创建商品订单和订单项模块开发
简介:订单超时未支付-定时关单功能设计
简介:定时关单RabbitMQ延迟消息交换机和队列配置
#自定义消息队列配置,发送锁定库存消息-》延迟exchange-》lock.queue-》死信exchange-》release.queue
mqconfig:
#延迟队列,不能被监听消费
order_close_delay_queue: order.close.delay.queue
#延迟队列的消息过期后转发的队列
order_close_queue: order.close.queue
#交换机
order_event_exchange: order.event.exchange
#进入延迟队列的路由key
order_close_delay_routing_key: order.close.delay.routing.key
#消息过期,进入释放队列的key,进入死信队列的key
order_close_routing_key: order.close.routing.key
#消息过期时间,毫秒,测试改为15秒
ttl: 15000
/**
* 交换机
*/
@Value("${mqconfig.order_event_exchange}")
private String eventExchange;
/**
* 延迟队列
*/
@Value("${mqconfig.order_close_delay_queue}")
private String orderCloseDelayQueue;
/**
* 关单队列
*/
@Value("${mqconfig.order_close_queue}")
private String orderCloseQueue;
/**
* 进入延迟队列的路由key
*/
@Value("${mqconfig.order_close_delay_routing_key}")
private String orderCloseDelayRoutingKey;
/**
* 进入死信队列的路由key
*/
@Value("${mqconfig.order_close_routing_key}")
private String orderCloseRoutingKey;
/**
* 过期时间
*/
@Value("${mqconfig.ttl}")
private Integer ttl;
简介:延迟消息测试和注意事项
@RunWith(SpringRunner.class)
@SpringBootTest(classes = OrderApplication.class)
@Slf4j
public class DemoApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void send(){
rabbitTemplate.convertAndSend("order.event.exchange","order.close.delay.routing.key","23342342");
}
}
简介:用户下单发送定时关单消息开发
@Data
public class OrderMessage {
/**
* 消息队列id
*/
private Long messageId;
/**
* 订单号
*/
private String outTradeNo;
}
//MQ发送延迟队列 TODO,用于自动关单
OrderMessage orderMessage = new OrderMessage();
orderMessage.setOutTradeNo(orderOutTradeNo);
rabbitTemplate.convertAndSend(rabbitConfig.getEventExchange(), rabbitConfig.getOrderCloseDelayRoutingKey(), orderMessage);
简介:订单微服务-订单超时未支付关单消息监听处理