基于rocketmq的酒店后台系统(一) 登录系统

一 登录系统流程:
异步化登录流程:
在这里插入图片描述
代码实现:

先定义实体类:

package com.ruyuan.little.project.rocketmq.api.login.dto;

/**
 * @author <a href="mailto:little@163.com">little</a>
 * version: 1.0
 * Description:登录请求的dto
 **/
public class LoginRequestDTO {

    /**
     * 用户id
     */
    private Integer userId;

    /**
     * 用户名称
     */
    private String nickName;

    /**
     * 手机号
     */
    private String phoneNumber;

    /**
     * token
     */
    private String token;

    /**
     * 小程序id
     */
    private Integer beid;

第二步 核心Service类LoginServiceImpl

成员变量

/**
     * 日志组件
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class);
    //当一个接口有多个实现类时,在注入时除了使用Autowired,还要使用Qualifier
    @Autowired
    @Qualifier(value = "loginMqProducer")
    private DefaultMQProducer loginMqProducer;

    @Value("${rocketmq.login.topic}")
    private String loginTopic;

    /**
     * mysql dubbo api接口
     */
    @Reference(version = "1.0.0",
            interfaceClass = MysqlApi.class,
            cluster = "failfast")
    private MysqlApi mysqlApi;

    /**
     * redis dubbo服务
     */
    @Reference(version = "1.0.0",
            interfaceClass = RedisApi.class,
            cluster = "failfast")
    private RedisApi redisApi;

    @Override
    public void firstLoginDistributeCoupon(LoginRequestDTO loginRequestDTO) {
        if (!isFirstLogin(loginRequestDTO)) {
            // 不是第一次登陆 返回
            LOGGER.info("userId:{} not first login", loginRequestDTO.getUserId());
            return;
        }
        // 更新第一次登陆的标识位
        this.updateFirstLoginStatus(loginRequestDTO.getPhoneNumber(), FirstLoginStatusEnum.NO);

        // 发送第一次登陆成功的消息
        this.sendFirstLoginMessage(loginRequestDTO);
    }

方法:
1 直接和controller对接的方法 firstLoginDistributeCoupon

    public void firstLoginDistributeCoupon(LoginRequestDTO loginRequestDTO) {
        if (!isFirstLogin(loginRequestDTO)) {
            // 不是第一次登陆 返回
            LOGGER.info("userId:{} not first login", loginRequestDTO.getUserId());
            return;
        }
        // 更新第一次登陆的标识位
        this.updateFirstLoginStatus(loginRequestDTO.getPhoneNumber(), FirstLoginStatusEnum.NO);

        // 发送第一次登陆成功的消息
        this.sendFirstLoginMessage(loginRequestDTO);
    }

首先判断是不是第一次登录。方法细节: isFirstLogin(loginRequestDTO),去mysql查询是不是第一次登录,

private boolean isFirstLogin(LoginRequestDTO loginRequestDTO) {
        MysqlRequestDTO mysqlRequestDTO = new MysqlRequestDTO();
        mysqlRequestDTO.setSql("select first_login_status from t_member where id = ? ");
        ArrayList<Object> params = new ArrayList<>();
        params.add(loginRequestDTO.getUserId());
        mysqlRequestDTO.setParams(params);
        mysqlRequestDTO.setPhoneNumber(loginRequestDTO.getPhoneNumber());
        mysqlRequestDTO.setProjectTypeEnum(LittleProjectTypeEnum.ROCKETMQ);

        LOGGER.info("start query first login status param:{}", JSON.toJSONString(mysqlRequestDTO));
        CommonResponse<List<Map<String, Object>>> response = mysqlApi.query(mysqlRequestDTO);
        LOGGER.info("end query first login status param:{}, response:{}", JSON.toJSONString(mysqlRequestDTO), JSON.toJSONString(response));
        //注意这里要首先判断响应码是不是正确再去判断数据库中的值是不是第一次登录。
        if (Objects.equals(response.getCode(), ErrorCodeEnum.SUCCESS.getCode())
                && !CollectionUtils.isEmpty(response.getData())) {
            Map<String, Object> map = response.getData().get(0);
            return Objects.equals(Integer.valueOf(String.valueOf(map.get("first_login_status"))),
                    FirstLoginStatusEnum.YES.getStatus());
        }
        return false;
    }

如果不是第一次登录,就执行两个操作,第一,去数据库里修改值。updateFirstLoginStatus

    private void updateFirstLoginStatus(String phoneNumber, FirstLoginStatusEnum firstLoginStatusEnum) {
        MysqlRequestDTO mysqlRequestDTO = new MysqlRequestDTO();
        mysqlRequestDTO.setSql("update t_member set first_login_status = ? WHERE beid = 1563 and mobile = ?");
        ArrayList<Object> params = new ArrayList<>();
        params.add(firstLoginStatusEnum.getStatus());
        params.add(phoneNumber);
        mysqlRequestDTO.setParams(params);
        mysqlRequestDTO.setPhoneNumber(phoneNumber);
        mysqlRequestDTO.setProjectTypeEnum(LittleProjectTypeEnum.ROCKETMQ);

        LOGGER.info("start query first login status param:{}", JSON.toJSONString(mysqlRequestDTO));
        CommonResponse<Integer> response = mysqlApi.update(mysqlRequestDTO);
        LOGGER.info("end query first login status param:{}, response:{}", JSON.toJSONString(mysqlRequestDTO), JSON.toJSONString(response));
    }

第二,利用mq发送消息 sendFirstLoginMessage

    private void sendFirstLoginMessage(LoginRequestDTO loginRequestDTO) {
        // 场景一:性能提升  异步发送一个登录成功的消息到mq中
        Message message = new Message();
        message.setTopic(loginTopic);
        // 消息内容用户id
        //message发json字符串
        message.setBody(JSON.toJSONString(loginRequestDTO).getBytes(StandardCharsets.UTF_8));
        try {
            LOGGER.info("start send login success notify message");
            SendResult sendResult = loginMqProducer.send(message);
            LOGGER.info("end send login success notify message, sendResult:{}", JSON.toJSONString(sendResult));
        } catch (Exception e) {
            LOGGER.error("send login success notify message fail, error message:{}", e);
        }
    }

这里注意利用loginMqProducer发送消息,所以要提前@bean把这个producer注入到spring容器,利用LoginProducerConfiguration类注入producer

@Configuration
public class LoginProducerConfiguration {

    @Value("${rocketmq.namesrv.address}")
    private String namesrvAddress;

    @Value("${rocketmq.login.producer.group}")
    private String loginProducerGroup;

    /**
     * 登录生产者
     *
     * @return 登录消息rocketmq的生产者对象
     */
    @Bean(value = "loginMqProducer")
    public DefaultMQProducer loginMqProducer() throws MQClientException {
        DefaultMQProducer producer = new DefaultMQProducer(loginProducerGroup);
        //设置rocketmq的服务器地址
        producer.setNamesrvAddr(namesrvAddress);
        producer.start();
        return producer;
    }
}

scp到服务器 scp target/little-project-rocketmq.jar root@47.100.190.149:/home/admin/little-project-rocketmq/target,用脚本部署,查看日志测试成功。(也可以用postman测试)

2021-06-25 10:27:24.666 INFO 1949 — [nio-8088-exec-3]
c.r.l.p.r.a.l.c.LoginController : login success user info:

{“beid”:1563,“nickName”:“夏”,“phoneNumber”:“13132181205”,“token”:“322eb718e6a327b3263f35bdf0e00b06”,“userId”:14937}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值