Skip to content

fyupeng/crop-multi-api

Repository files navigation

植物鉴别博客多端管理项目

介绍

提供植物鉴别功能、含有 Android、网页端、手机移动网页端多端兼容 api 后端服务项目

软件架构

软件架构说明

项目架构:

基于vue的植物识别博客系统

接口文档:http://localhost:8083/swagger-ui.html

数据映射url:http://localhost:9001/crop_multi_data/

后端数据存储采用两台服务器支持,一台作为mysql和reids缓存和基本类型数据存储,另一台作为大数据文章类型存储。

数据库支持:MySQL、Redis、MongoDB

数据处理

  • MySQL 处理关系型数据

MySQL对于处理关系型数据是最合适的,它在POJOPO之间数据的映射是一对一的,所以在开发的时候可以使用逆向工具快速生成对应的POJO类,缩短开发时间和开发成本。

  • MongoDB 处理非关系型数据

对于非关系型数据存储,采用MongoDB是比较合适的,比如本项目的评论和文章都采用这种方式存储,它们不仅支持k-v形式、文档形式、图片形式,还容易扩展,数据没有耦合性。

  • Redis 处理缓存数据

对于可以使用弱一致性的,比如CSDN它的文章阅读量是每天中午会更新,不要求即时更新,就可以使用Redis来缓存数据,而且我在Redis数据库前面做了一层类似于布隆过滤器,先是过滤了敏感和没有营养的词汇,然后才可能会去查询数据库,如果关键字没有被Redis采录,它会写入到Redis中,以维护热度搜索,然后依次按照文章类名、标题、简述、内容去匹配,前面匹配到了,就停止去匹配后面的字段,就直接将匹配的文章查询出来。

日后改进

  • 分布式事务

由于使用了MySQLMongoDB的业务上耦合,但单机MongoDB不支持事务,使得业务耦合可能造成事务结果的不一致性

解决方案

  1. 使用分布式事务解决;
  2. 使用MQ消息队列,先把消息发MQ,确定消息落盘后,MySQL执行事务,提交/回滚,都给MQ发通知。接着MQ收到通知,再把消息退给MongoDBMongoDB事务必须保证成功,如果失败,就人工处理,手动补偿。

架构交互

项目的云部署采用两台服务器,将前端项目接口暴露,后台关键接口放到另一台服务器,再通过反向代理接口去访问后端服务,能起到隐藏真实服务地址,起到保护的作用,而之所以把MongoDB放到前端暴露的接口,是考虑到服务器的抗压能力,当然还有其他成本因素包含在里面。

  • 请求过程

用户发起请求 → 云服务器1 → 前端端口 → nginx反向代理 → 代理调用api接口 → 云服务器2 → 真实服务端口 → Redis(缓冲层) → MySQL/MongoDB(持久层)

之所以在前端与后端端口交互之间加了一层代理层,是起到代理后端服务的作用,能够直接屏蔽掉后端的地址,保证后端服务的安全。

  • 高可用服务

目前项目后端接口服务只使用了一个端口,在该环境下,还可以启动多端口的接口服务,如果要搭建高可用服务,可以直接到nginx中配置后端代理点,让这个代理点去代理多个服务接口,如果某一个springboot挂了(高请求导致),可利用Nginx来搭建负载均衡

使用nginx搭建反向代理和负载均衡:

前端项目所在机器:

http {
    // 使用的负载均衡策略
    upstream cropServer {
        server [后端ip]:[port] weight=10;
        server [后端ip]:[port] weight=10;
    }
    // 服务代理
    server {
        listen    9001;
        server_name localhost;
        # Reverse proxy backend server
        // 负载均衡方式
        location / {
            proxy_pass http://cropServer;
        }
        // 直连方式
        location / {
            proxy_pass http://[ip]:[port];
        }
        location /crop_multi_data/ {
            proxy_pass http://[后端ip]:9001;
            index index.html index.htm index.jsp;
        }
    
    }
}

后端服务所在机器 代理静态文件

http {
    server {
        listen          9001;
        server_name     127.0.0.1;
        
        location /crop_multi_data/ {
            root /**/***/;
            autoindex on;
        }
    }
}

上面代理静态文件是通过前台机器代理到后台的代理,再由后台代理映射到本地文件

  • 代理层

代理层

项目亮点

  • 阅读定时同步

阅读量不会即时更新到 mongodb,但会及时更新到 redis 缓存起来 开启定时任务,使用合适的策略将数据同步到 mongodb 中。

实现

用户阅读一篇文章时,在所调用的 api接口获取该请求所在的ip地址和 文章id,这样下一步就可以做到将该ip和文章id保存到Redis中,能够避免短时间内重复阅读同一篇文章而额外去执行一次 数据库IO操作,可以在Redis设置该key存活时间为 1 小时。

这样,我们就实现了即时将数据暂存到了Redis中,接着我们只需开启一个子线程获取Redis中每篇文章的id值和阅读数,将其同步到MongoDB就可以了,实现可以参考ScheduledExecutorServicescheduleAtFixedRate()方法。

  • 热度搜索

热度搜索利用的是 Redis的两大数据结构zSetHash来实现存储近期和搜索量的,从而实现热度搜索,当然搜索前必须得先对敏感关键字过滤,切忌让敏感关键字作为了热搜词汇,导致出现敏感文章被顶推上热搜。

实现

热度搜索需要在前端做一个搜索,接着调用api将用户的搜索词汇放到Redis中,可以使用zSet,把时间戳当成zSet的权值,所以是有序的,可以获取近期的搜索,实现近期搜索(这里还可以将该关键字连同userId放到Redis做用户搜索记录),接着再使用RedisHash数据结构,将关键字作为keyvalue作为关键字搜索量,就能够做到近期热度搜索了。

历史更新

  • 2022/4/7
  1. 配合 nginx 的url 映射技术,新增浏览器 查阅后台日志文件
  • 2022/4/8
  1. 更新评论内容、管理员注册和登录;
  2. 修复发表评论时,父评论id和被回复用户id为空仍可以保存的bug;
  • 2022/4/8
  1. 更新标签功能;
  2. 修复标签为私有,其他人不可见;
  • 2022/4/9
  1. 增加删除文章功能;
  • 2022/4/12
  1. 修复了管理员对文章分类可重复新增的bug
  • 2022/4/13
  1. 修复了用户恶意在文章详情接口输入错误文章id导致空指针的情况,导致对redis数据库的访问失败
  2. 添加敏感信息过滤功能(使用DFA算法)
  3. 添加推荐和近期文章接口
  • 2022/4/14
  1. 一部分接口分页失效问题
  2. 更新热度文章获取接口,更新获取策略
  3. 支持一种新的标准时间格式
  4. 修复获取评论接口中toUser字段为空报错的情况
  • 2022/4/15
  1. 更新评论接口,新增时间排序功能
  • 2022/4/16
  1. 更新获取所有评论的接口,引用内容可见
  2. 修复获取评论接口字段查询错误
  • 2022/4/17
  1. 修复标记标签和重新标记标签出现的问题

About

基于植物鉴别博客管理系统

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages