外卖点餐平台项目优化

在做外卖点餐平台项目时遇到的一些问题及解决方案,。。。浅浅记录一下


一、开发的系统可能存在的问题以及为什么要进行缓存优化?

问题:
移动端可以点击某一种菜品,然后页面发送一个请求给服务端,服务端返回数据展示到页面上。这样可能存在一个问题,如果移动端的用户比较多,它们都会请求系统,都要点餐。最终这些请求都会压到数据库上,这就造成用户数量多,系统访问量大,频繁访问数据库,系统性能下降,用户体验差。(页面加载的速度慢,点了一下需要好几秒才能显示相应的数据。)

解决思路:
通过缓存来解决(基于redis来进行缓存优化),也就是说用户点击某一个菜品的时候,在服务端并不是直接查数据库,而是看一下缓存里面有没有相应的数据,如果有数据的话,就不用再查数据库了,直接把数据返回给页面就可以了。因为很多缓存产品,其实本质上都是内存操作,相对于数据库查询操作来说,它的访问速度会快很多,所以可以通过缓存方面的优化,目的就是提高系统的响应性能,提高用户的体验度。

  1. 环境搭建:
    . 使用redis进行缓存优化呢,首先就需要导入一些maven坐标,配置文件、配置类等。

  2. 缓存短信验证码:
    之前的验证码是放在Httpsession里,现在要把短信验证码缓存到redis中,所以要进行代码改造。
    实现思路:
    2.1 在服务端UserController中注入RedisTemplate对象,用于操作Redis。
    2.2 在服务端UserController的sendMsg方法中,将随机生成的验证码缓存到Redis中,并设置有效期为5分钟。(redistemplate.get)
    2.3 在服务端UserController的login方法中,从Redis中获取缓存的验证码,如果登录成功则删除Redis中的验证码。(redistemplate.delete)

  3. 缓存菜品数据:
    用户会频繁的访问菜品数据,所以非常有必要把菜品数据缓存,把菜品数据缓存到redis中,来提高系统的查询性能。
    实现思路:
    3.1,改造DishController的list方法,先从Redis中获取菜品数据,如果有则直接返回,无需查询数据库;如果没有则查询数据库,并将查询的菜品数据放入Redis。
    3.2,改造DishController的save和update方法,加入清理缓存的逻辑。

  4. Spring Cache
    用Spring提供的Spring Cache技术来整合其他的一些缓存产品的框架,用了它之后,可以通过注解的方式来加缓存,从而简化我们的代码开发。

  5. 缓存套餐数据:套餐数据的缓存可以使用Spring Cache来实现。
    前面实现了移动端套餐查看功能,对应的服务端方法为SetmealController的list方法,此方法会根据前端提交的查询条件进行数据库查询操作。在高并发的情况下,频繁查询数据库会导致系统性能下降,服务响应时间增长。现在需要对此方法进行缓存优化,提高系统性能。
    具体实现思路如下:
    5.1, 导入Spring Cache和Redis相关maven坐标
    5.2, 在application.yml中配置缓存数据的过期时间
    5.3, 在启动类上加入@EnableCaching注解,开启缓存注解功能
    5.4, 在SetmealController的list方法上加入@Cacheble注解
    5.5, 在SetmealController的save和delete方法上加入CacheEvict注解

二、读写分离

目前系统还存在的问题:
1,当前系统只部署了一台服务器,读和写所有压力都由一台数据库承担,压力大。
· 答:实现主从复制,有多台数据库分摊压力。
2,数据库服务器磁盘损耗则数据丢失,单点故障。
· 答:多台数据库,主库的数据会实时同步到从库中,实现了主库数据的备份,就算主库损毁也有备份,安全性大大提高。

设置两个甚至多个数据库实现读写分离,
写操作(insert update delete)—>Master(主库)
读操作(select)—>(从库)

主从复制实际上就是将主库的数据同步到从库数据,通过Mysql主从复制就可以实现从库中的数据和主库中的数据一致。

  • mysql主从复制
    MySQL复制过程分为三步:
    • master将改变记录到二进制日志(binary log)
    • slave将master的binary log拷贝到它的中继日志(relay log)
    • slave重做中继日志中的时间,将改变应用到自己的数据库中

三、读写分离案例

面对日益增长的系统访问量,数据库吞吐量面临着巨大瓶颈。对于同一时刻有大量并发读操作和较少写操作类型的应用来说,将数据库拆分为主库和从库,主库就负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁(innodb引擎支持的就是行锁),使得整个系统的性能得到极大改善。

Sharding-JDBC介绍
Sharding-JDBC定位为轻量级java框架,在java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。
使用Sharding-JDBC可以在程序中轻松的实现数据库读写分离
· 适用于任何基于JDBC的ORM框架
· 支持任何第三方的数据库连接池
· 支持任意实现JDBC规范的数据库

四、前后端分离开发

如果前后端代码都在一个工程中,会存在一些问题:
· 开发人员同时负载前端和后端代码的开发,分工不明确
· 开发效率低
· 前后端代码混在一个工程中,不便于管理
· 对开发人员要求高,人员招聘困难
解决方案:前后端混合开发->前后端分离开发
在这里插入图片描述

开发流程

前后端分离开发后,面临一个问题,就是前端人员和后端人员如何进行配合来共同开发一个项目?
在这里插入图片描述
接口(API接口)就是一个http的请求地址,主要就是去定义:请求路径、请求方式、请求参数、响应数据等内容。
在这里插入图片描述

Swagger

使用Swagger你只需要按照它的规范去定义接口及接口相关的信息,再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,以及在线接口调试页面等等。
在这里插入图片描述

五,项目部署

部署架构

在这里插入图片描述
用户指的是后台系统的用户。
部署架构:
Mysql数据库、Redis、Tomcat服务器、Nginx服务器等
①,整个项目分成两个端:
后台管理端(餐厅内部人员使用):后台人员可以登录此系统来维护一些菜品,套餐等
微信端:未开发,微信开发可以使公众号、用小程序,一般属于前端开发,有专门的前端人员来开发这一块。微信主要是给消费者用户使用,主要访问的是点餐的页面。
②,用户通过联网可以访问到Ngix服务器
③,Nginx可以通过反向代理把请求转发到后端服务,后端服务基于Tomcat服务器运行的。
④,数据库端做了主从复制,有一个主库和一个从库,还用到了缓存,就需要Redis。

部署后端项目
第一步:在服务器B中安装jdk、git、maven、Mysql,使用git clone命令将git远程仓库代码克隆下来。
第二步:将资料中提供的reggieStart.sh文件上传到服务器B,通过Chmod命令设置执行权限。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐