山东小语种网站建设,天津有哪些互联网公司,phpcmsv9手机网站开发,申请个人网站RocketMQ 实战#xff1a;模拟电商网站场景综合案例#xff08;六#xff09;
一、RocketMQ 实战 #xff1a;项目公共类介绍
1、ID 生成器 #xff1a;IDWorker#xff1a;Twitter 雪花算法。
在 shop-common 工程模块中#xff0c;IDWorker.java 是 ID 生成器公共类…RocketMQ 实战模拟电商网站场景综合案例六
一、RocketMQ 实战 项目公共类介绍
1、ID 生成器 IDWorkerTwitter 雪花算法。
在 shop-common 工程模块中IDWorker.java 是 ID 生成器公共类运用 Twitter 雪花算法自动生成项目 ID而不会存在重复现象。 package com.itheima.utils;public class IDWorker {/*** 起始的时间戳*/private final static long START_STMP 1480166465631L;/*** 每一部分占用的位数*/private final static long SEQUENCE_BIT 12; //序列号占用的位数private final static long MACHINE_BIT 5; //机器标识占用的位数private final static long DATACENTER_BIT 5;//数据中心占用的位数/*** 每一部分的最大值*/private final static long MAX_DATACENTER_NUM -1L ^ (-1L DATACENTER_BIT);private final static long MAX_MACHINE_NUM -1L ^ (-1L MACHINE_BIT);private final static long MAX_SEQUENCE -1L ^ (-1L SEQUENCE_BIT);/*** 每一部分向左的位移*/private final static long MACHINE_LEFT SEQUENCE_BIT;private final static long DATACENTER_LEFT SEQUENCE_BIT MACHINE_BIT;private final static long TIMESTMP_LEFT DATACENTER_LEFT DATACENTER_BIT;private long datacenterId; //数据中心private long machineId; //机器标识private long sequence 0L; //序列号private long lastStmp -1L;//上一次时间戳public IDWorker(long datacenterId, long machineId) {if (datacenterId MAX_DATACENTER_NUM || datacenterId 0) {throw new IllegalArgumentException(datacenterId cant be greater than MAX_DATACENTER_NUM or less than 0);}if (machineId MAX_MACHINE_NUM || machineId 0) {throw new IllegalArgumentException(machineId cant be greater than MAX_MACHINE_NUM or less than 0);}this.datacenterId datacenterId;this.machineId machineId;}/*** 产生下一个ID** return*/public synchronized long nextId() {long currStmp getNewstmp();if (currStmp lastStmp) {throw new RuntimeException(Clock moved backwards. Refusing to generate id);}if (currStmp lastStmp) {//相同毫秒内序列号自增sequence (sequence 1) MAX_SEQUENCE;//同一毫秒的序列数已经达到最大if (sequence 0L) {currStmp getNextMill();}} else {//不同毫秒内序列号置为0sequence 0L;}lastStmp currStmp;return (currStmp - START_STMP) TIMESTMP_LEFT //时间戳部分| datacenterId DATACENTER_LEFT //数据中心部分| machineId MACHINE_LEFT //机器标识部分| sequence; //序列号部分}private long getNextMill() {long mill getNewstmp();while (mill lastStmp) {mill getNewstmp();}return mill;}private long getNewstmp() {return System.currentTimeMillis();}public static void main(String[] args) {IDWorker idWorker new IDWorker(2, 3);for (int i 0; i 10; i) {System.out.println(idWorker.nextId());}}} 2、异常处理类
在 shop-common 工程模块中 CustomerException.java 自定义异常公共类CastException.java 异常抛出公共类。
package com.itheima.exception;import com.itheima.constant.ShopCode;
import lombok.extern.slf4j.Slf4j;/*** 异常抛出类*/
Slf4j
public class CastException {public static void cast(ShopCode shopCode) {log.error(shopCode.toString());throw new CustomerException(shopCode);}
} package com.itheima.exception;import com.itheima.constant.ShopCode;/*** 自定义异常*/
public class CustomerException extends RuntimeException{private ShopCode shopCode;public CustomerException(ShopCode shopCode) {this.shopCode shopCode;}
}
3、常量类 ShopCode系统状态类
在 shop-common 工程模块中ShopCode.java 是系统状态公共类。 package com.itheima.constant;/*** author Think*/public enum ShopCode {//正确SHOP_SUCCESS(true, 1, 正确),//错误SHOP_FAIL(false, 0, 错误),//付款SHOP_USER_MONEY_PAID(true, 1, 付款),//退款SHOP_USER_MONEY_REFUND(true, 2, 退款),//订单未确认SHOP_ORDER_NO_CONFIRM(false, 0, 订单未确认),//订单已确认SHOP_ORDER_CONFIRM(true, 1, 订单已经确认),//订单已取消SHOP_ORDER_CANCEL(false, 2, 订单已取消),//订单已取消SHOP_ORDER_INVALID(false, 3, 订单无效),//订单已取消SHOP_ORDER_RETURNED(false, 4, 订单已退货),//订单已付款SHOP_ORDER_PAY_STATUS_NO_PAY(true,0,订单未付款),//订单已付款SHOP_ORDER_PAY_STATUS_PAYING(true,1,订单正在付款),//订单已付款SHOP_ORDER_PAY_STATUS_IS_PAY(true,2,订单已付款),//消息正在处理SHOP_MQ_MESSAGE_STATUS_PROCESSING(true, 0, 消息正在处理),//消息处理成功SHOP_MQ_MESSAGE_STATUS_SUCCESS(true, 1, 消息处理成功),//消息处理失败SHOP_MQ_MESSAGE_STATUS_FAIL(false, 2, 消息处理失败),//请求参数有误SHOP_REQUEST_PARAMETER_VALID(false, -1, 请求参数有误),//优惠券已经使用SHOP_COUPON_ISUSED(true, 1, 优惠券已经使用),//优惠券未使用SHOP_COUPON_UNUSED(false, 0, 优惠券未使用),//快递运费不正确SHOP_ORDER_STATUS_UPDATE_FAIL(false, 10001, 订单状态修改失败),//快递运费不正确SHOP_ORDER_SHIPPINGFEE_INVALID(false, 10002, 订单运费不正确),//订单总价格不合法SHOP_ORDERAMOUNT_INVALID(false, 10003, 订单总价格不正确),//订单保存失败SHOP_ORDER_SAVE_ERROR(false, 10004, 订单保存失败),//订单确认失败SHOP_ORDER_CONFIRM_FAIL(false, 10005, 订单确认失败),//商品不存在SHOP_GOODS_NO_EXIST(false, 20001, 商品不存在),//订单价格非法SHOP_GOODS_PRICE_INVALID(false, 20002, 商品价格非法),//商品库存不足SHOP_GOODS_NUM_NOT_ENOUGH(false, 20003, 商品库存不足),//扣减库存失败SHOP_REDUCE_GOODS_NUM_FAIL(false, 20004, 扣减库存失败),//库存记录为空SHOP_REDUCE_GOODS_NUM_EMPTY(false, 20005, 扣减库存失败),//用户账号不能为空SHOP_USER_IS_NULL(false, 30001, 用户账号不能为空),//用户信息不存在SHOP_USER_NO_EXIST(false, 30002, 用户不存在),//余额扣减失败SHOP_USER_MONEY_REDUCE_FAIL(false, 30003, 余额扣减失败),//已经退款SHOP_USER_MONEY_REFUND_ALREADY(true, 30004, 订单已经退过款),//优惠券不不存在SHOP_COUPON_NO_EXIST(false, 40001, 优惠券不存在),//优惠券不合法SHOP_COUPON_INVALIED(false, 40002, 优惠券不合法),//优惠券使用失败SHOP_COUPON_USE_FAIL(false, 40003, 优惠券使用失败),//余额不能小于0SHOP_MONEY_PAID_LESS_ZERO(false, 50001, 余额不能小于0),//余额非法SHOP_MONEY_PAID_INVALID(false, 50002, 余额非法),//Topic不能为空SHOP_MQ_TOPIC_IS_EMPTY(false, 60001, Topic不能为空),//消息体不能为空SHOP_MQ_MESSAGE_BODY_IS_EMPTY(false, 60002, 消息体不能为空),//消息发送失败SHOP_MQ_SEND_MESSAGE_FAIL(false,60003,消息发送失败),//支付订单未找到SHOP_PAYMENT_NOT_FOUND(false,70001,支付订单未找到),//支付订单已支付SHOP_PAYMENT_IS_PAID(false,70002,支付订单已支付),//订单付款失败SHOP_PAYMENT_PAY_ERROR(false,70002,订单支付失败);Boolean success;Integer code;String message;ShopCode() {}ShopCode(Boolean success, Integer code, String message) {this.success success;this.code code;this.message message;}public Boolean getSuccess() {return success;}public void setSuccess(Boolean success) {this.success success;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;}public String getMessage() {return message;}public void setMessage(String message) {this.message message;}Overridepublic String toString() {return ShopCode{ success success , code code , message message \ };}
}
4、响应实体类 Result封装响应状态和响应信息
在 shop-pojo 工程模块中Result.java 是封装响应状态和响应信息的公共类。
package com.itheima.entity;import java.io.Serializable;/*** 结果实体类*/
public class Result implements Serializable {private Boolean success;private String message;public Result() {}public Result(Boolean success, String message) {this.success success;this.message message;}public Boolean getSuccess() {return success;}public void setSuccess(Boolean success) {this.success success;}public String getMessage() {return message;}public void setMessage(String message) {this.message message;}Overridepublic String toString() {return Result{ success success , message message \ };}
}
二、RocketMQ 实战模拟电商网站场景综合案例 – 下单功能时序图 三、RocketMQ 实战下单接口定义和编码步骤分析
1、下单基本流程接口定义 IOrderService.java
在 shop-api 工程模块中创建 IOrderService.java 下单接口类。 package com.itheima.api;import com.itheima.entity.Result;
import com.itheima.shop.pojo.TradeOrder;public interface IOrderService {/*** 下单接口* param order* return*/public Result confirmOrder(TradeOrder order);}
2、下单基本流程业务类实现 OrderServiceImpl.java
在 shop-order-service 工程模块中创建 OrderServiceImpl.java 业务实现类。 基本框架如下 Slf4j
Component
Service(interfaceClass IOrderService.class)
public class OrderServiceImpl implements IOrderService {Overridepublic Result confirmOrder(TradeOrder order) {//1.校验订单//2.生成预订单try {//3.扣减库存//4.扣减优惠券//5.使用余额//6.确认订单//7.返回成功状态} catch (Exception e) {//1.确认订单失败,发送消息//2.返回失败状态}}
}四、RocketMQ 实战模拟电商网站场景综合案例–校验订单流程分析图 五、RocketMQ 实战模拟电商网站场景综合案例–校验订单实现
1、在 shop-order-service 工程模块中创建 OrderServiceImpl.java 下单业务类
完成 订单校验方法。 package com.itheima.shop.service;import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.itheima.api.ICouponService;
import com.itheima.api.IGoodsService;
import com.itheima.api.IOrderService;
import com.itheima.api.IUserService;
import com.itheima.constant.ShopCode;
import com.itheima.entity.MQEntity;
import com.itheima.entity.Result;
import com.itheima.exception.CastException;
import com.itheima.shop.mapper.TradeOrderMapper;
import com.itheima.shop.pojo.*;
import com.itheima.utils.IDWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.math.BigDecimal;
import java.util.Date;Slf4j
Component
Service(interfaceClass IOrderService.class)
public class OrderServiceImpl implements IOrderService {Referenceprivate IGoodsService goodsService;Referenceprivate IUserService userService;Overridepublic Result confirmOrder(TradeOrder order) {//1.校验订单checkOrder(order);//2.生成预订单try {//3.扣减库存//4.扣减优惠券//5.使用余额//6.确认订单//7.返回成功状态} catch (Exception e) {//1.确认订单失败,发送消息//2.返回订单确认失败消息return null;}}/*** 校验订单** param order*/private void checkOrder(TradeOrder order) {//1.校验订单是否存在if (order null) {CastException.cast(ShopCode.SHOP_ORDER_INVALID);}//2.校验订单中的商品是否存在TradeGoods goods goodsService.findOne(order.getGoodsId());if (goods null) {CastException.cast(ShopCode.SHOP_GOODS_NO_EXIST);}//3.校验下单用户是否存在TradeUser user userService.findOne(order.getUserId());if (user null) {CastException.cast(ShopCode.SHOP_USER_NO_EXIST);}//4.校验商品单价是否合法if (order.getGoodsPrice().compareTo(goods.getGoodsPrice()) ! 0) {CastException.cast(ShopCode.SHOP_GOODS_PRICE_INVALID);}//5.校验订单商品数量是否合法if (order.getGoodsNumber() goods.getGoodsNumber()) {CastException.cast(ShopCode.SHOP_GOODS_NUM_NOT_ENOUGH);}log.info(校验订单通过);}
}
2、在 shop-api 工程模块中创建 IGoodsService.java 接口类。 package com.itheima.api;import com.itheima.entity.Result;
import com.itheima.shop.pojo.TradeGoods;
import com.itheima.shop.pojo.TradeGoodsNumberLog;public interface IGoodsService {/*** 根据ID查询商品对象* param goodsId* return*/TradeGoods findOne(Long goodsId);}
3、在 shop-api 工程模块中创建 IUserService.java 接口类。 package com.itheima.api;import com.itheima.entity.Result;
import com.itheima.shop.pojo.TradeUser;
import com.itheima.shop.pojo.TradeUserMoneyLog;public interface IUserService {TradeUser findOne(Long userId);Result updateMoneyPaid(TradeUserMoneyLog userMoneyLog);
}
4、在 shop-user-service 工程模块中创建 UserServiceImpl.java 实现类。 package com.itheima.shop.service.impl;import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.api.IUserService;
import com.itheima.constant.ShopCode;
import com.itheima.entity.Result;
import com.itheima.exception.CastException;
import com.itheima.shop.mapper.TradeUserMapper;
import com.itheima.shop.mapper.TradeUserMoneyLogMapper;
import com.itheima.shop.pojo.TradeUser;
import com.itheima.shop.pojo.TradeUserMoneyLog;
import com.itheima.shop.pojo.TradeUserMoneyLogExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.math.BigDecimal;
import java.util.Date;Component
Service(interfaceClass IUserService.class)
public class UserServiceImpl implements IUserService{Autowiredprivate TradeUserMapper userMapper;Autowiredprivate TradeUserMoneyLogMapper userMoneyLogMapper;Overridepublic TradeUser findOne(Long userId) {if(userIdnull){CastException.cast(ShopCode.SHOP_REQUEST_PARAMETER_VALID);}return userMapper.selectByPrimaryKey(userId);}}
5、在 shop-goods-service 工程模块中创建 GoodsServiceImpl.java 实现类。 package com.itheima.shop.service.impl;import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.api.IGoodsService;
import com.itheima.constant.ShopCode;
import com.itheima.entity.Result;
import com.itheima.exception.CastException;
import com.itheima.shop.mapper.TradeGoodsMapper;
import com.itheima.shop.mapper.TradeGoodsNumberLogMapper;
import com.itheima.shop.pojo.TradeGoods;
import com.itheima.shop.pojo.TradeGoodsNumberLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Date;Component
Service(interfaceClass IGoodsService.class)
public class GoodsServiceImpl implements IGoodsService {Autowiredprivate TradeGoodsMapper goodsMapper;Autowiredprivate TradeGoodsNumberLogMapper goodsNumberLogMapper;Overridepublic TradeGoods findOne(Long goodsId) {if (goodsId null) {CastException.cast(ShopCode.SHOP_REQUEST_PARAMETER_VALID);}return goodsMapper.selectByPrimaryKey(goodsId);}}
上一节关联链接请点击 # RocketMQ 实战模拟电商网站场景综合案例五