视频课程项目之微信支付系统——整个项目的完整生命周期。
开发流程——数据库设计——接口设计——开发、编码、部署功能到阿里云服务器、域名备案、解析到服务器、通过域名进行访问。
项目核心功能:
列表展示、微信扫描登录、微信扫描支付。
面试题1:你在这个项目中充当什么角色?
我在该项目中主要做:支付和扫描登录这些。
为什么不进行账号密码登录?用微信登录这样更加安全。
一、项目的创建
开发工具:IDEA
二、开发的完整开发流程
三、需求分析架构设计
功能:
视频列表、微信扫码登录、下单微信支付。
架构设计:
前后端分离—>方案:node渲染
(选择这个)动静分离—>方案:静态资源如html,js放在cdn或者nginx服务器上
技术选择:
后端技术选择:IDEA + Springboot2.0 + redis4.0+ HttpClient + mysql + ActiveMQ消息队列前端技术选择:HTML5 + bootstrapt + jquery
测试要求:首页和视频详情页qps单机qps要求 2000+
将页面列表信息缓存到redis中去,这样减少对数据库的访问。
用户点击浏览器,前端发送AJAX请求到nginx里去,nginx再分发到后端服务器。
四、数据库设计
不关键的数据做缓存或者冗余,而不是做成实时的。
er图:
实体对象:矩形
属性:椭圆
关系:菱形
video表video_order表姡comment表chapter张episode节
字段冗余:
什么是字段冗余
冗余字段就是本存在一张表的字段,也出现在另一张表中。
什么时候选择字段冗余
看需求,如果影响不大,利于开发效率,可适当的增加冗余字段。
优点
不使用字段冗余,如果要查询所有数据,并用到其他表的一个字段,就要用join进行连接查询,那么当有很多表的时候,那么查询就很慢了。使用字段冗余,直接给表添加该字段就速度快多了。
缺点
如果对该字段进行增删改,对应也要对那个表的字段进行增删改,这时还要去了解所有表中的冗余字段,以防有些表中的字段没对应修改。
Mysql测试数据导入。
刚开始肯定不是设计的很全面的,要结合业务设计。
五、项目搭建、逆向工程构建、热部署、分层分包及资源文件处理、开源工具的选择/优缺点、接口配置文件自动映射到属性和实体类配置
项目依赖:
热部署。
项目目录结构:
pageHeper分页拦截器:
好处:开发方便,使用简单,使用aop方式进行分页,只需要引入相关依赖,然后PageHelper.startPage(page, size); 开启分页。
弊端:对于分库分表等情况下使用有问题,深度分页逻辑判断会复杂。
面试题2:写一个分页sql语句?
问面试官数据量有多大、表字段多不多,根据情况分为普通分页与深度分页:
如果表数据万级别的,如果id自增,那么不使用limit去查询,而是通过where id条件过滤或者特定的字段对前面无用的数据进行过滤然后进行查询,因为深度分页会牵扯磁盘IO操作,影响性能。
并且应该指定字段去查询,而不是用*去全部查询。
封装通用工具类,如缓存操作等、利于解耦,如切换缓存框架。
MySQL逆向工程。
接口配置文件自动映射到属性和实体类配置:
利用配置文件进行解耦。
使用@value注解配置文件自动映射到属性和实体类。
添加 @Component或者Configuration 注解。
使用 @PropertySource 注解指定配置文件位置:(属性名称规范: 大模块.子模块.属性名)
@PropertySource(value=“classpath:application.properties”)
必须 通过注入IOC对象Resource 进来 , 才能在类中使用获取的配置文件值。
六、视频列表接口开发
七、整合Mybatis访问数据库和阿里巴巴数据源
整合mysql 加入mybatis依赖,和加入alibaba druid数据源。
加入配置文件
八、使用Mybatis注解开发视频列表增删改查
1、控制台打印sql语句
#增加打印sql语句,一般用于本地开发测试
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
九、Vidoe相关接口完善和规范协议
十、动态Sql语句Mybaties SqlProvider
面试题3:如果一张表有很多字段,就只是单单的要更新几个属性,需要怎么实现?
面试题4:为什么包装类型的属性才能进行!null判断?
因为包装类型需要通过new在堆中分配内存,然后将对象放入堆中,而基本类型是直接将变量值放入栈中,两者的初始值不同,例如int初始值为0,而Integer的初始值为null,所以包装类型能够进行!null的判断。
十一、PageHelper分页插件使用
PageHelper分页大体流程:
SqlSessionFactory——>SqlSession——>executor—| 拦截器 |—>statement。
拦截器/Plugins-Interceptor:limit ?,? (ThreadLocal获取用户变量)
十二、JWT微服务下的用户登录权限校验
十三、单机和分布式应用的登录检验讲解
用户访问浏览器进行登录操作,登录成功后,浏览器会存储登录成功的凭证,如果是在负载均衡分发的多节点下,之前访问的节点1,当要访问节点2的时候,发现节点2没有存储sessionid,这样就得重新登录了。
解决方案一:tomcat开启session 共享,但是每个session都会占用内存,如果节点1的一百个用户都这样来访问节点2的话,那么节点1的所有session都要复制到节点2上。当用户数达到了百万级别以上的话,那么这种方式就不可行了。
解决方案二:redis集群存储登录token,用户登录成功后就生成一个token,可以是在节点中通过UUID来生成
一个64/128位的随机字符串,然后将该字符串保存到redis中去,浏览器访问服务器节点,服务器从redis中去拿token,然后用户第一次登录成功保存的token就和redis中token进行校验,如果校验存在就表示登录成功,如果不对就不成功。所以现在不管是在哪个节点下去访问,该节点只要从redis中去取,然后进行校验就可以了。不过这种方案也有缺点,那就是在高并发环境下会造成带宽的损失。
解决方案三:通过加解密算法生成token校验,用户登录成功,服务器拿到用户的id等关键信息,再通过密钥进行加密,然后返回给用户,后续用户访问就将保存的token传到服务器上,通过服务器上的解密算法进行逆向解密,然后进行比较,比较结果一样,那么表明用户曾经登录成功过。由于每个服务器的解密算法都是一样的,所以只要解密成功就算是登录过。
面试题5:session、cookie、token的区别?
session:
多个用户登录系统,系统为了辨别用户,就要为每个用户发一个标识session id ,这是一串随机字符串,用户越多,服务器的开销就越大。
此时就需要通过集群,但是如果是这样一种情况:例如登录是在服务器A上进行的,那么session id自然是在服务器A上的,这时候如果下一个请求被转发到服务器B上呢?服务器B可没有该session id啊。此时要怎么办?这个就是典型的分布式session一致性问题?如果没有解决这个问题,那么用户将出现频繁的登录操作。
如何保证分布式session的一致性呢?
参考链接:https://blog.csdn.net/u010028869/article/details/50773174?ref=myread#commentBox
cookie:
一个文本文件,保存在浏览器里的数据,也就是保存在客户端磁盘空间里,cookie保存着用户登录的数据,方便下一次访问浏览器,为确保不被恶意使用,通常会对cookie的数量进行限制。
cookie可以在本机进行修改,故没有比session安全。
token:
通过上面的解释我们大概能知道session是为了解决用户与服务器之间的验证问题:
对于验证还有另外一种很常用的解决方式:通过令牌token进行无状态的签名验证。
参考链接:https://www.cnblogs.com/moyand/p/9047978.html
十四、微服务下登录检验解决方案 JWT讲解
十五、登录检验JWT实战之封装通用方法