分布式部署(下篇)

前言

代理服务和用户服务搭建完毕后,我们继续搭建剩下的服务:笔记服务和日志服务。

笔记服务 Note

笔记服务负责与笔记本相关的所有业务逻辑处理,也就是本项目中的主要业务功能,在代码上基本不需要做修改,只用配置好 Consul 即可。

代码结构
  • controller
    • ErrorController.java:全局异常处理
    • NoteController.java:笔记接口
    • NotesController.java:笔记本接口
  • entity
    • NoteInfo.java:笔记实体类
    • NotesInfo.java:笔记本实体类
  • mapper
    • NoteMapper.java:笔记持久类
    • NotesMapper.java:笔记本持久类
  • service
    • NoteService.java:笔记业务逻辑类
    • NotesService.java:笔记本业务逻辑类
  • NoterApplicatiion.java:服务启动类
获取笔记本列表

代码逻辑中唯一需要修改的地方是获取笔记本列表。原来的逻辑是在用户注册成功后,自动创建默认笔记本。当业务分离后,用户注册和创建笔记本是两个互不相干的业务,因此将创建默认笔记本的逻辑放在获取笔记本列表中。当发现用户没有笔记本时,创建一个默认笔记本并返回,这也就进一步做到了业务的解耦,代码如下:

/**
 * 获取用户的笔记本列表,如果用户没有笔记本,创建默认笔记本
 * @param userId
 * @return
 */
public ResultData getListByUser(int userId){
    NotesInfo notesInfo = new NotesInfo();
    notesInfo.setUserId(userId);
    notesInfo.setBaseKyleUseASC(true);
    List<NotesInfo> list = mapper.baseSelectList(notesInfo);

    if(list == null || list.size() < 1){
        notesInfo = insertDefaultNotes(userId);
        list.add(notesInfo);
    }
    return ResultData.success(list);
}

日志服务 Log

日志服务作为独立的一个组件,只负责所有日志的读写操作。通过接收 RabbitMQ 传递过来的数据进行写操作、通过 RESTFul 接口提供读服务。

将原项目中日志相关的操作移过来,没有太大的变化。

代码结构
  • controller
    • AdminController.java:管理员访问的接口
    • EmailLogController.java:邮件发送日志相关
    • ErrorController.java:全局异常处理
  • handler
    • RabbitHandler.java:RabbitMQ 消息处理类
  • mapper
    • EmailLogMapper.java:邮件发送日志持久类
    • ErrorLogMapper.java:错误日志持久类
    • LoginLogMapper.java:用户登录日志持久类
    • RegisterLogMapper.java:用户注册日志持久类
  • service
    • EmailLogService.java:邮件发送日志业务逻辑类
    • LoginLogService.java: 用户登录日志业务逻辑类
    • RegisterLogService.java:用户注册日志业务逻辑类
  • LogApplication.java:服务启动类
处理 RabbitMQ 消息

接收 RabbitMQ 传递的消息,通过 JSON 反序列化成实体对象,并记录在数据库中:

@Component
public class RabbitHandler {

    @Resource
    private EmailLogMapper emailLogMapper;
        // 记录邮件发送日志
    @RabbitListener(queues = MqConstants.EMAIL_LOG)
    public void emailLog(String content){
        Console.info("emailLog",content);
        EmailLog log = JSON.parseObject(content,EmailLog.class);
        emailLogMapper.baseInsertAndReturnKey(log);
    }

    @Resource
    private ErrorLogMapper errorLogMapper;
        // 记录异常日志
    @RabbitListener(queues = MqConstants.ERROR_LOG)
    public void errorLog(String content){
        Console.info("errorLog",content);
        ErrorLog log = JSON.parseObject(content,ErrorLog.class);
        errorLogMapper.baseInsertAndReturnKey(log);
    }

    @Resource
    private LoginLogMapper loginLogMapper;
        // 记录用户登录日志
    @RabbitListener(queues = MqConstants.LOGON_LOG)
    public void loginLog(String content){
        Console.info("loginLog",content);
        LoginLog log = JSON.parseObject(content,LoginLog.class);
        loginLogMapper.baseInsertAndReturnKey(log);
    }

    @Resource
    private RegisterLogMapper registerLogMapper;
        // 记录用户注册日志
    @RabbitListener(queues = MqConstants.REGISTER_LOG)
    public void registerLog(String content){
        Console.info("registerLog",content);
        RegisterLog log = JSON.parseObject(content,RegisterLog.class);
        registerLogMapper.baseInsertAndReturnKey(log);
    }
}
管理员接口

AdminController.java 中是原项目中管理员查看日志相关的操作:

@RestController
@RequestMapping(Constants.adminMapping)
public class AdminController {
    @Resource
    private LoginLogService loginLogService;

    @Resource
    private RegisterLogService registerLogService;

    @GetMapping("/loginLogByDay")
    public ResponseEntity getLoginLogByDay(String startDate, String endDate){
        if(ObjectUtils.isEmpty(startDate)){
            return Response.badRequest();
        }
        return Response.ok(loginLogService.getCountByDay(startDate,endDate));
    }

    @GetMapping("/loginLogByMonth")
    public ResponseEntity getLoginLogByMonth(String startDate,String endDate){
        if(ObjectUtils.isEmpty(startDate)){
            return Response.badRequest();
        }
        return Response.ok(loginLogService.getCountByMonth(startDate,endDate));
    }



    @GetMapping("/registerLogByDay")
    public ResponseEntity getRegisterLogByDay(String startDate, String endDate){
        if(ObjectUtils.isEmpty(startDate)){
            return Response.badRequest();
        }
        return Response.ok(registerLogService.getCountByDay(startDate,endDate));
    }

    @GetMapping("/registerLogByMonth")
    public ResponseEntity getRegisterLogByMonth(String startDate,String endDate){
        if(ObjectUtils.isEmpty(startDate)){
            return Response.badRequest();
        }
        return Response.ok(registerLogService.getCountByMonth(startDate,endDate));
    }
}
邮件发送记录查询
@RestController
@RequestMapping("/emailLog")
public class EmailLogController {

    @Resource
    private EmailLogService service;

    @GetMapping
    public ResponseEntity checkCode(String email,String code,Integer type){
        if(ObjectUtils.isEmpty(email,code,type)){
            return Response.badRequest();
        }
        return Response.ok(service.checkCode(email, code, type));
    }

}

至此,所有服务搭建完毕。

效果测试

注意在配置文件中为不同的服务设置不同的启动端口,所有服务启动完毕后,在 Consul 中能看到如下的记录:

在这里插入图片描述

注意

  • 从单体服务到分布式服务,对于客户端来说是无感知的,在客户端只需要配置代理服务的访问地址即可
  • 但由于请求的方式发生变化,需要在访问接口中添加 service Header 并指定相应的服务名称,也就是修改 Vue 项目中的 api.js 中各个接口

源码地址

本篇完整的源码地址:

https://github.com/tianlanlandelan/KellerNotes

小结

至此,项目的分布式部署完成。如果需要使用缓存,添加对 Redis 的支持即可。这里推荐一个 Redis 的可视化工具,支持 Windows 和 MacOS。

地址:

https://github.com/qishibo/AnotherRedisDesktopManager

界面如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值