乐檬商城笔记

乐檬商城是一个全品类的电商项目
项目主要采用分布式架构,dubbo+zookeeper整合ssm
主要技术有:springsecurity、elasticsearch、springdata-redis、rabbitmq、thymeleaf模板引擎、cas单点登录、分布式事务等
用到的第三方接口有:阿里云的OSS、阿里云的短信服务、微信的统一下单接口、查询接口等
前端技术有:vue、elementUI、vue-router、qrcode、axios等
数据库有:mysql、Redis、elasticsearch

主架构主要分层为:服务层、应用层、公共层

常用软件端口号
3306端口:MYSQL数据库端口
6379端口:Redis数据库端口
8080端口:(tomcat)TCP服务端默认端口
9200端口:Elasticsearch服务器端口
5601端口:kibana端口

RabbitMQ  端口号:4369 \ WEB  页面的端口15672
activeMQ的两个默认端口 8161是后台管理系统,61616是给java用的tcp端口。

应用层包就是面向用户的,
    主要包括:
        后台管理端,主要就是商品信息的维护,包括品牌、分类、模板、规格、参数、相册、商品等信息的维护,以及后端RBAC权限模型的集成
        用户中心,主要是面向用户的个人中心模块,在网站前台面向用户使用的,比如查看个人订单、物流信息、以及个人信息维护等
        网站前台,是网站的入口,这里主要包括了:首页、分类模块、轮播图模块、搜索、详情页、加入购物车、购物车信息维护、提交订单、支付、微信通知、支付成功通知跳转等模块
服务层是给应用层提供服务的,服务层面向数据库,提供数据支持,主要包括
    主要包括:
        商品服务,主要是给后台管理模块提供服务以及数据支持
        用户服务,主要是给前台用户提供注册、以及用户中心的信息维护
        短信服务,所有的发短信业务都在这里
        业务模块,轮播图、广告等相关业务在这里
        订单模块,主要是订单、购物车等前台模块的重要服务
        系统模块,主要是管理端菜单以及管理人员以及权限等的相关配置

1、前台首页模块,因为是面向用户的首页,所以数据加载速度是一个重要的要求,所以首页的分类、轮播图等信息都会缓存预热到redis中,在对应信息做出变化之后,同步修改缓存信息 

Redis相关面试题

1、Redis是基于C语言开发的key-value形式的nosql数据库,数据存储在内存中,有string hash list set zset 五种数据类型
2、由于数据存储在内存中,为防止服务器宕机数据丢失,支持RDB和 AOF 俩种持久化方式。
RDB: 默认开启,把内存快照的形式把内存中的数据持久化到本地磁盘文件。
AOF: 默认不开启,需要手动开启,设置appendonly 值为yes;aof是把写或删除的操作(命令)日志以追加的方式保存磁盘文件

2.说下对Redis缓存使用的了解

1、Redis缓存使用,首先查询数据时先从Redis缓存中查询,如果缓存中有数据,直接返回数据。如果查询不到,再去数据库中查询,查到数据添加到Redis缓存,返回查询的数据。

2、Redis缓存涉及到数据同步问题: 
当数据库数据发生变化时,Redis缓存中的数据也需要同步,否则导致数据不一致。
所以,数据新增、修改、删除时,把Redis缓存的数据清空。当再次查询时,先从数据库查询,然后把数据缓存到Redis中;这样就保证了数据的同步。
数据发生变化时,Redis缓存中的数据也需要同步,否则导致数据不一致。

3.介绍下Redis缓存雪崩?

缓存雪崩造成因素有2个:
1、Redis服务器宕机
2、同一时间Redis中缓存的数据大量过期,原本该去缓存查询的大量请求,有缓存出现问题,全都去数据查询,导致数据压力太大,系统崩溃。
解决方案:
可以给key的过期时间+随机数(让key的过期时间尽可能的分散)

4.介绍下Redis缓存穿透

缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库。

解决方案:
查询数据库如果没有,也要在Redis缓存一个空数据(key的value值:空字符串)。
但是有可能出现缓存同步问题:
解决方案: key设置一个很短的过期时间。key过期以后,Redis会清空这个key ,下次去查询时候,Redis中查不到,就会去查数据库,如果数据库查到值,就可以缓存到Redis,从而保证数据的同步。

5.Redis 过期策略

● 定时删除:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除
● 惰性删除:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null
● 定期删除:每隔一段时间执行一次删除过期key操作
Redis默认过期策略是:定期删除+惰性删除。


6.Redis缓存预热

缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据! 
缓存预热解决方案: 
(1)直接写个缓存刷新页面,上线时手工操作下; 
(2)数据量不大,可以在项目启动的时候自动进行加载; 


7.Redis缓存降级

当访问量剧增、服务出现问题,比如响应时间慢或不响应,或者非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有问题的服务。redis可以帮助系统实现数据降级载体,系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的


8.Redis缓存同步

mysql数据可能会发生变动,那么redis就要跟数据库的数据保持一致,我们实际去使用的时候,是在数据发生变动的地方,比如增删改的时候,新起一个线程,然后将变动的数据更新到redis中,根据不同的场景需求,也可以在数据变动时,把redis里的数据删掉,下一次用户查询的时候,发现redis中没有数据,就会重新去数据库加载一遍,这样也可以实现同步的效果


9.Redis 是单线程的么?线程安全么

redis 是单线程,线程安全。 
因为 Redis 是基于内存的操作,CPU 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器内存的大小或者网络带宽。 
redis 实际上是采用了线程封闭的观念,把任务封闭在一个线程,自然避免了线程安全问题
不过对于需要依赖多个 redis 操作的复合操作来说,依然需要锁,而且有可能是分布式锁

10.用什么操作redis
 现在用的是SpringDataRedis  之前用的是jedis 
  注解:RedisTemplate
 怎么操作:  配置文件 对应的依赖

11.redis基本类型:
 list   set  zset  hash   String
 为什么要用redis
 为了提升页面的加载速度,减轻数据库访问压力,我们将数据加载在缓存中

我们使用了thymeleaf完成首页广告轮播图渲染  和分类导航渲染

Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似JSP,Velocity,FreeMaker等, 它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。与其它模板引擎相比, Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用。 

ES相关面试题:

1、介绍一下ElasticSearch,以及在项目中的应用

​ Java开发的基于lucene分布式全文搜索引擎。基于restful Web接口。在检索领域相当优秀,在我们项目中主要是负责检索商品信息。商品信息构成是比较复杂的,并且数据量巨大,至少会有几十万,如果使用mysql做检索,效率会非常低,并且对mysql造成很大的压力。

在使用过程中主要需要做几件事:

1、Es服务的安装,中文分词器使用IK分词器,这个主要是运维负责;

2、在项目中集成springDataElasticSearch框架,用来操作ES;

3、创建实体类,标注了一个Document注解,这个注解里声明了这个索引库的名称以及它的类型,还有他的分片儿信息,还有他的副本信息。在这个类中创建所有跟商品相关的字段。同样会有一些注解去标识他的数据类型,他的比如说id字段会有一个id注解,其他字段用@Field注解标注在es中存储的数据类型,是否进行分词等,有些字段也可以不加任何注解,es会根据存储的数据去判断字段在es中存储的类型。等其他的字段都建好之后,然后又新添加了一个统一的搜索字段,我们给它定义的名称叫all,我们会把经常搜索的数据全部定义到这个字段里。比方说商品标题、副标题、品牌等;

4、初始全量数据导入

使用springboot测试类实现导入,分批从mysql中取出,组装数据到,保存到es中

5、修改、新增、删除等增量数据导入

使用rabbitMQ实现,商品上下架的时候发送Mq消息,搜索微服务以及静态页面微服务实现ES数据的同步和静态页面的数据同步操作

6、使用es实现搜索

  • 使用all进行分词查询,搜索时,按照matchQuery做的,这个方法的做法是会把输入的关键词分词之后,然后去匹配,匹配的规则我们设置的是and的方式匹配,就是分词之后每个词条都匹配才算匹配,我们在项目里设置了个all字段,会把所有可能被分词的字段都会放到这个里边,只对这一个字段设置分词,关键字搜索的时候,都会去匹配这个字段,
  • 使用规格参数聚合实现商品搜索规格参数的渲染
  • 使用分类和品牌聚合实现商品分类和品牌查询的渲染
  • 使用布尔查询实现规格参数、品牌、分类的过滤
  • 实现分页、排序等需求

2、为什么使用Es?

​ 因为在我们商城中的数据,将来会非常多,所以采用以往的模糊查询,模糊查询前置配置,会放弃索引,导致商品查询是全表扫面,在百万级别的数据库中,效率非常低下,而我们使用ES做一个全文索引,我们将经常查询的商品的某些字段,比如说商品名,描述、价格还有id这些字段我们放入我们索引库里,es内部有个倒排索引的机制,普通的索引的原理是通过id寻找数据,而倒排索引是通过数据寻找id,它的大概原理是把需要分词的数据通过ik分词器分词之后,记录出每个词条对应的文档id,在进行搜索的时候,将搜索关键字分词之后,找到每个词条的文档id,然后在进行通过id搜索操作,大大提高了全文检索的效率,这也是在全文检索方面最常用的技术。

3、 什么是桶(bucket)?什么是度量(metrics)?

,是按照某种方式对数据进行分组,每一组数据在ES中称为一个,例如我们根据国籍对人划分,可以得到中国桶英国桶日本桶……或者我们按照年龄段对人进行划分:010,1020,2030,3040等。分桶的方式有很多,比如按日期阶梯分组、按数值阶梯分组、按词条内容分组、按数值和日期范围分组等。

度量,分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在ES中称为度量。度量有求平均值、求最大最小值、求百分比、求和等。

4、es内部存储的存储结构

es内部默认就是分布式的存储结构,每当创建一个索引库的时候,我们需要指定当前索引库的分片数和副本数,分片数就是把数据分布式的存放在分片上,所有分片的数据加起来就是整个索引库的数据量,分片数越多,数据存放的越分散,搜索的时候,es会检索每个分片的伤的数据一起返回。副本数是指在数据进入索引库的时候,同时需要备份的数量,如果副本数量越多,那么需要消耗的存储空间就会越多,过多的话会造成空间浪费,一般生产中使用的时候都用的默认的配置,就是5个分片,2个副本。

5、描述一下Elasticsearch更新和删除文档的过程

1、删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更; 2、在文档被创建时,ES会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del 文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。删除同理

6、详细描述一下Elasticsearch搜索的过程

1、搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch; 2、在初始查询阶段时,查询会广播到每个索引的主分片或者副本分片。搜索并构建一个优先队列。 3、每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点来合并结果列表。 4、协调节点将结果列表中的ID对应的文档取回,返回结果给客户端。

7、在并发情况下,Elasticsearch如果保证读写一致

整体使用版本号机制的乐观锁来控制; 对于写操作,默认为只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,分片将会在一个不同的节点上重建直到成功。 对于读操作,可以设置副本为同步状态(默认),就是当主副分片都完成后才会返回;如果设置副本为异步时,也可以通过参数设置来只查询主分片,确查询最新数据。

8、Elasticsearch是如何实现Master选举的

1、ES的选主是 ZenDiscovery 模块负责,首先配置每个节点是否可能成为master节点,当ZenDiscovery 通过ping发现多数节点认为当前没有master的时候,发起选举 2、选举时,把所有能做master的节点根据节点id字典排序,选出第一个节点暂定为主节点 3、然后再发起投票,票数过半并且该节点自己也选举自己,那这个节点就是 master。

9.什么是倒排索引表:
1、将要搜索的文档内容分词,所有不重复的词组成分词列表。
2、将搜索的文档最终以Document方式存储起来。
3、每个词和docment都有关联。

10.ES中有什么分词器以及为什么要用:
Ik  分词器,默认对中文每个字进行分词,作为词条,显然不符合逻辑,他也可以分成自己想要的词条
IK分词器测试

11.ES   中String  类型的有什么 

text:

  • 会进行分词,分词后建立索引。
  • 支持模糊查询,支持准确查询。
  • 不支持聚合查询

keyword类型:

  • 不分词,直接建立索引。
  • 支持模糊查询,支持准确查询。
  • 支持聚合查询。

 对于字符串类型的字段,除特殊要求外,尽量使用keyword类型。

jdbc是干什么的?
1.jdbc用来连接我们的java应用程序和 数据库,用jdbc 我们能用java应用程序读取数据库里面的数据,还能够存储数据。

2.我们能通过jdbc连接到不同的数据库,像Oracle,Mysql 和sql Server 等数据库。

单点登录面试题:

单点登录:简称sso,用户只需要登录一次就可以访问所有相互信 任的应用系统
当我们访问其中一个前台系统需要登录才可以访问的页面时,
自动跳转到登录中心 进行登录,登录后再次跳转回该前台系统,该前台系统可以获取登录名。
实现单点登录有多种方案:
(1)    使用redis实现session共享 
比如A中的tomcat 有10  个session, B 中有5 个session,  tomcat  不存储,全部放到redis中,来判断是否登录
在tomcat 的内存中  比如: A和B  都存储这对方的 session。
缺点:浪费内存 、资源
spring-  session:  内存    redis  mysql  

(2)    使用开源的单点登录系统

CAS具有以下特点:

1.开源的企业级单点登录解决方案。
2.  跨语言   跨平台

 6、认证中心整个使用CAS做的单点登录,因为模块众多,不可能让用户访问不同模块的时候,重复登录,这里使用的是CAS,由CAS提供统一的登录认证服务,需要CAS的server端提供服务
    需要给CAS整合我们统一的登录页面,接入我们的数据库,并且指定bcrypt的加密策略,这样在登录的时候,就会使用我们项目的数据了,
    认证通过之后,然后由项目中springsecurity提供授权服务。

Spring Security 简介

Spring Security 是 Spring 家族中的一个安全管理框架,提供了一套 Web 应用安全性的完整解决方案。在用户认证方面,Spring Security 框架支持主流的认证方式。在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制
核心功能主要包括:
1、认证 (你是谁)
2、授权 (你能干什么)
3、攻击防护 

spring security 执行原理流程

● 首先是认证,即用户登陆,会被 AuthenticationProcessingFilter 拦截,调用认证管理器(AuthenticationManager )的实现类,认证管理器会调用 ProviderManager来获取用户验证信息,如果验证通过后会将用户的权限信息封装一个 User 放到 spring 的全局缓存 SecurityContextHolder 中,以备后面访问资源时使用。 
● 其次是授权,即访问资源,在访问 url 时,会通过 AbstractSecurityInterceptor 拦截器拦截,它会调用对应方法来获取被拦截url所需的全部权限,在调用授权管理器(AccessDecisionManager),这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取该url信息以及访问该 url 所需的全部权限,然后根据所配的策略(有:一票决定,一票否定,少数服从多数等),如果权限足够,则返回通过,权限不够则报错并调用权限不足页面

说一下密码加密的登录注册流程

1、用户注册的时候,对密码进行加盐加密处理之后,然后将盐值以及加密之后的密码等数据存入数据库,数据库不存储明文密码
2、在登录的时候,服务端接收到用户名密码之后,先根据用户名去数据库查询,如果查询到了,在把用户输入的密码结合查询出来的用户的盐值进行相同的加密处理,然后跟查询出来的密码进行对比,如果一致,则登录成功,否则登录失败

猜你喜欢

转载自blog.csdn.net/qq_46264836/article/details/122862887
今日推荐