SpringMVC处理请求的过程:
1、用户发送请求,dispatchersevlet捕获;
2、dispatchersevlet进行解析得到请求资源标志符,然后调用HandlerMapping获得该Handler配置的所有相关对象(包括Handler对象和对应的拦截器),最后以HandlerExcutionChain形式返回;
3、根据获得的Handler选择一个合适得HandlerAdapter(如果成功获取HandlerAdapter后,将会执行拦截器的preHandler方法);
4、提取request中的模型数据,填充Handler入参,开始执行Handler。在填充Handler的入参过程中,根据配置spring将做一些额外工作;
5、handler执行完成后,将向dispatcherservlet返回一个modelAndView对象;
6、根据返回的modelAndView选择一个合适得视图解析器,返回给dispatcherServlet;
7,视图解析器(viewResolver)结合modelAndView,进行视图渲染
8、将渲染结果返回给客户端;
springboot自动配置原理:
在spring程序中的main方法中添加@SpringBootApplication或者EnableAutoConfiguration,Spring会自动去maven中读取每个starter中的spring.factories文件,该文件配置了所有需要被创建的spring容器的bean
springcloud如何实现服务的注册与发现?
服务发布时,指定对应的服务名,将服务注册到Euraka,这一过程是springcloud自动实现的,只需要在服务的main方法上添加@EnableDiscoveryClient,同一个服务修改端口就可实现启动多个实例
调用方法:传递服务名,通过注册中心获取所有的可用实例,通过负载均衡策略调用(ribbon和feign)对应的服务
ribbon和feign的区别
ribbon添加maven依赖spring-starter-ribbon,使用@RibbonClient(value=“服务名”)使用RestTemplate调用远程服务对应的方法
feign添加maven依赖spring-starter-feign,服务提供方提供对外接口,调用方在接口上使用@FeignClient(“服务名”)
1、启动类注解不同,@RibbonClient,@FeignClient
2、服务指定的位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明
3、调用方式不同,Ribbon需要构建自己的http请求,模拟http请求然后使用RestTemplate发送给其他服务,相较繁琐;Feign则只需要将调用其他服务的方法定义为抽象方法即可,不需要构建自己的http请求。不过要注意抽象方法的注解和方法签名要和提供服务的方法完全一致
springcloud断路器的作用
当一个服务调用另一个服务时,由于网络原因,调用者会等待被调用者的响应,当更多的请求到达这些资源的时候,导致更多的等待,这样容易发生连锁效应,断路器就是为了解决这一问题。
spring的运行原理:
IOC:spring利用反射原理(在运行期间进行动态创建),让对象操作者不必再手动创建对象,spring将自动创建对象,将对象的创建和业务逻辑代码剥离开来。
AOP:面向切面编程,为某一对象或者方法进行监督和控制(在调用此方法前后调用指定的其他方法或模块),从而达到一个模块扩充的功能
目的:让对象和对象之间的关系没有通过代码相互关联,都是通过配置类进行管理
redis内存不够怎么处理:
redis内存模型【数据区,进程本身所需内存,缓冲内存,内存碎片】
处理方式:1、增加内存;2、使用内存淘汰策略;3、redis集群
内存淘汰策略:LRU(least recentlyUsed)最近最少使用算法【随机抽取三个键,删除其中使用最少的键】
集群处理:
redis仅支持单实例,内存一般在20G左右,当需缓存数据量过大时,就需要通过集群进行配置
集群方式【客户端分片,代理分片,rediscluster】
客户端分片:
通过业务代码自定义路由(优势:可以控制分片算法,性能比代理好;劣势:维护成本高,扩容运维等需要自己研发)
代理分片:
代理根据业务程序的请求,根据路由规则,将这些请求分发给正确的redis实例并返回给业务程序,类似使用wemproxy,codis等中间件(优势:运维方便,程序不关心如何连接redis;劣势:会带来性能消耗,无法平滑扩容,需要脚本迁移数据,不方便)
redis cluster:
官方集群解决方案(优势:无中心节点,和客户端直连,性能较好;劣势:方案太重,无法平滑扩容,需要执行相应的脚本)
redis服务器挂掉后怎么恢复数据:
先停止,在复制,在启动
RDB方式(默认):数据库出问题期间,RDB将不再进行,所以会造成一部分数据丢失;
AOF方式:类似日志记录等方式,将redis收到的每一条命令通过write函数追加到文件中,redis重启后通过重新执行文件中保存的命令进行数据重建;
redis和memcache有什么区别:
1、memcached还可以存储图片,视频等
2、redis不仅支持K/V形式,同时也支持list set hash等数据结构
3、虚拟内存技术(当内存用完时,可以将一些很久没有使用的value交换到硬盘)
4、过期策略不同,memcached在set时指定,redis还可以通过expire命令指定
5、分布式方式,memcached利用magent一主多从,redis可自实现一主多从
6、数据安全,服务挂掉后,memcached数据丢失,redis可以恢复
7、redis支持数据备份
8、使用场景:redis(nosql,消息队列,数据堆栈,数据缓存);memcached(缓存sql语句,数据集,用户临时数据,延迟查询数据,session)
redis为什么这么快:
1、基于内存操作
2、数据结构简单,操作也相对简单
3、单线程,不用考虑线程竞争,锁机制,避免上下文切换和互相竞争
4、使用多路I/O复用,非阻塞IO
5、底层实现VM,避免调用系统函数
spring bean的生命周期:
bean实例化(构造方法,工厂方法,反射)---setter注入(依赖注入)---根据实现接口,执行不同的方法---传递bean实例给前置处理器---调用初始化方法---将bean实例传递给后置处理器---使用---销毁
springbean的作用域:
singleton:IOC只会存在一个共享的bean实例【创建容器的同时自动创建一个bean对象,不管使用与否,均存在,且每次调用与返回都是同一个对象,是spring的缺省作用域】
prototype:表示一个bean定义对应多个对象实例【每次对该bean进行请求时,都会创建一个新的bean对象;原形类型,创建容器的时候并没有实例化,而是每次调用的时候进行实例化,且每次获取的bean对象都不是同一个】
request:表示在一次http请求中都有自己的bean实例【仅在当前的http request内有效,可以放心更改当前bean实例的属性和内部状态】
session:在一个http session对应一个实例【同样可以放心更改此实例的内部状态】
global session:在一个全局的http session中,一个bean对应一个实例【只有在基于portel的web应用才有效,类似于http session】
注:request,session global session 都仅在基于web的spring applicationcontext情形下才有效
springMVC处理请求的过程:
dispatcherservlet接受请求---handlerMapping找到相应的handlerAdapter---处理功能请求,返回modelAndView---viewResolver解析具体视图【视图渲染】---返回到前端
MySQL和Oracle的区别:
1、Oracle没有自增主键,需要创建sequence,在insert的时候进行调用
2、语法层面(Oracle没有limit,翻页处理较为繁琐;Oracle自带树状图函数connect )
3、字符串比较函数instr(字段名,‘字符串’)>0可以代替%like%
外键的作用:
1、表达参照的完整性;2、简单直观;3、确保数据有效性
多服务怎么实现session共享:
1、通过数据库实现session共享
2、通过cookie实现session共享
3、通过服务器数据同步实现
4、通过NFS【网络文件服务器】(专门的session服务器)实现
5、通过memcached和redis实现
springcloud怎么实现负载均衡:
zuul