SpringBoot基础重难点
1、SpringBoot
1.1 概念
Spring Boot是构建所有基于Spring的应⽤程序的起点。Spring Boot旨在尽可能快地启动和运⾏,只需最少的Spring前端配置。⾃⼰内部添加了单独tomcat服务器.要求项⽬尽可能独⽴运⾏.
Springboot⾃动装配解析:
1、@SpringBootApplication注解,表明该类是springboot的主配置类,包含了@SpringBootConfiguration、@ComponentScan和
@EnableAutoConfiguration注解;
2、看@SpringBootConfiguration的源码可知,它是⼀个@Configuration(配置类),因此@SpringBootApplication等同于
@Configuration+@ComponentScan+@EnableAutoConfiguration。
3、@EnableAutoConfiguration:⾃动配置的关键,加上此注解开启⾃动装配功能,spring会试图在你的classpath下到所有配置的bean然后进⾏装配。
4、@ComponentScan:表⽰将该类⾃动发现扫描组件。个⼈理解相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以⾃动收集所有的Spring组件,包括@Configuration类。我们经常使⽤@ComponentScan注解搜索beans,并结合@Autowired注解导⼊。可以⾃动收集所有的Spring组件,包括@Configuration类。我们经常使⽤@ComponentScan注解搜索beans,并结合@Autowired注解导⼊。如果没有配置的话,Spring Boot会扫描启动类所在包下以及⼦包下的使⽤了@Service,@Repository等注解的类。
5、@Configuration :相当于传统的xml配置⽂件,如果有些第三⽅库需要⽤到xml⽂件,建议仍然通过@Configuration类作为项⽬的配置主类——可以使⽤@ImportResource注解加载xml配置⽂件。等同于spring的XML配置⽂件;使⽤Java代码可以检查类型安全。
2、分布式
2.1分布式概念
将业务模块按照特定的规则进⾏拆分.分别部署到不同的服务器实现了架构的解耦.
传统项⽬:
  存在问题:
  1:模块之间耦合度太⾼,其中⼀个功能升级,其他的模块都得⼀起升级部署。
  2:开发困难,各个团队开发最后都要整合在⼀起.
  3:系统扩展性差
  4:不能灵活进⾏分布式部署
  解决⽅案:
  把模块才分成独⽴的⼯程,单节点运⾏,如果某⼀个节点压⼒⼤了可以单独对这个节点进⾏增加配置,其他节点不受影响。缺点就是系统之间交互
  需要额外的⼯作量来进⾏接⼝的开发。把系统拆分成多个⼯程,需要完成系统的⼯程需要多个⼯程协作完成,这种形式就叫做分布式。
分布式:
  把系统拆分成多个⼦系统.优点:
  1:把模块拆分,使⽤接⼝通信,降低模块之间的耦合度.
  2:把项⽬拆分成若⼲个⼦项⽬,不同的团队负责不同的⼦项⽬.
  3:增加功能时只需要再增加⼀个⼦项⽬,调⽤其他系统的接⼝就可以。
  4:可以灵活的进⾏分布式部署. 
  5:提⾼代码的复⽤性,⽐如service层,如果不采⽤分布式rest服务⽅式架构就会在⼿机wap商城,商城,pc,android,ios每个端都要写⼀个service层逻辑,开发量⼤,难以维护⼀起升级,这时候就可以采⽤分布式rest服务⽅式,公⽤⼀个service层。
  缺点:系统之间的交互要使⽤远程通信,接⼝开发增⼤⼯作量,但是利⼤于弊。
2.2分布式项⽬拆分
垂直拆分:
说明:按照项⽬的功能(业务)模块进⾏拆分.将不同的业务部署到不同的服务器中.
⽔平拆分:
场景:⼀个service可能3000⾏代码由⼀个⼈完成controller-Service-mapper任务繁重.这时需要多个⼈开发!!
概念:按照调⽤的层级进⾏拆分.
2.3分布式项⽬总结
分布式项⽬:对外统⼀,对内独⽴.实现了架构的解耦
2.3 分布式事务
1、分布式事务和分布式锁?
⽐如从⽀付宝转100元到余额宝,我们⼜两个⽅法1、⽀付宝减掉100,2、余额宝加上100。传统的在⼀个模块,⼀个服务,或者⼀个⽅法⾥⾯,我们就很好解决了,只需要注解⼀个事务就⾏了。
@Transactional(rollbackFor=Exception.class) 这样我们就可以保证两个⽅法数据的⼀致性了。但是显然,现在我们的项⽬中,为了满⾜性能要求,不可能还这样传统单机实现。我们做成了两个服务,在两个不同的模块 1、⽀付宝,2、余额宝这样就存在了我们提到的问题,分布式事务,这个时候如何解决呢?
通常来说呢实现⽅式有如下⼏种:
1、两阶段提交协议(Two-phase Commit,2PC):
架构图
简单来说,协调器先给A/B各发⼀条,准备的命令,等到都返回准备好了的命令的时候,再发起事务提交。这样来保证事务⼀致性,但是存在很多问题,就是通信上中断的情况,会导致事务⼀致⽆法提交,⽽可能使系统崩溃。这就可以使⽤第⼆种⽅案。
第⼆种⽅案:TCC补偿性,分为三个阶段TRYING-CONFIRMING-CANCELING。每个阶段做不同的处理。
TRYING:阶段主要是对业务系统进⾏检测及资源预留
CONFIRMING:阶段是做业务提交,通过TRYING阶段执⾏成功后,再执⾏该阶段。
(默认如果TRYING:阶段执⾏成功,CONFIRMING就⼀定能成功。)
CANCELING:阶段是回对业务做回滚,在TRYING阶段中,如果存在分⽀事务TRYING失败,则需要调⽤CANCELING将已预留的资源进⾏释放。
什么是分布式锁?
场景1:常规的我们多线程访问同⼀代码块的时候,为了保证同⼀时间只能
由⼀个线程访问,保证数据安全⼀致性,通常我们使⽤synchronized关键字来对⽅法加锁,以达到保证数据安全性。
场景2:现在越来越多的项⽬,为了追求性能与⾼并发,采⽤了soa架构,微服务架构,于是就会出现多个模块单独的服务。这个时候呢就会有⼀个问题,如何保证多个节点的现场同步执⾏呢?
这种情况呢,就会⽤到了分布式锁。
分布式锁的解决⽅案与实现有哪些呢?
1、数据库解决⽅案思路
a.数据库建⼀张表,字段⽅法名并且作为唯⼀性,当⼀个⽅法执⾏时插⼊,则相当于获得锁,其他线程将⽆法访问,⽅法执⾏完则释放锁。但是上⾯这种存在问题:
1、数据库单点,出现故障则将导致系统不可⽤。
2、没有失效时间,⼀旦操作⽅法异常,导致⼀直没有解锁,也将导致其他不可⽤⽤。
b.使⽤select * from user u where username = '' for update
来对记录加上排他锁。操作完成后使⽤commit命令释放锁。
2、基于缓存实现
通常有Memcached、Redis实现等,以下以Redis实现分布式锁为例
思路:主要⽤到的redis函数是setnx(),这个应该是实现分布式锁最主要的函数。⾸先是将某⼀任务标识名(这⾥⽤Lock:order作为标识名的例⼦)作为键存到redis⾥,并为其设个过期时间,如果是还有Lock:order请求过来,先是通过setnx()看看是否能将Lock:order插⼊到redis ⾥,可以的话就返回true,不可以就返回false
3.Zookeeper分布式锁
⼤致思路:每个客户端对某个⽅法加锁时,在zookeeper上的与该⽅法对应的指定节点的⽬录下,⽣成⼀个唯⼀的瞬时有序节点。
判断是否获取锁的⽅式很简单,只需要判断有序节点中序号最⼩的⼀个。
当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁⽆法释放,⽽产⽣的死锁问题。
ZK中创建和删除节点只能通过Leader服务器来执⾏,然后将数据同不到所有的Follower机器上,所以性能上不如基于缓存实现。
3、Ngnix
Nginx是⼀款轻量级的Web服务器/反向代理服务器及电⼦邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发⾏。其特点是占有内存少,并发能⼒强,事实上nginx的并发能⼒确实在同类型的⽹页服务器中表现较好,中国⼤陆使⽤nginx⽹站⽤户有:百度、京东、新浪、⽹易、腾讯、淘宝等。
3.1 Nginx配置⽂件介绍
server代表⼀个服务项
server {
listen      80; #监听端⼝
#server_name 表⽰拦截域名
server_name  localhost;
#拦截请求之后处理⽅式
location / {
#root 是关键字代表反向代理的⽂件夹名称
root  html;
#index 默认跳转页⾯
index  index.html index.htm;
}
}
如配置图⽚代理,并修改hosts⽂件
配置图⽚服务器
server {
listen 80;
server_name image.jt;
location / {
root D:/1-jt/image;
}
}
实现域名代理
后台管理服务器⽤户访问manage.jt时访问localhost:8091 server {
listen 80;
server_name manage.jt;
location / {
#代理路径
proxy_pass  localhost:8091;
}
nginx 配置文件}
3.2 实现负载均衡(Tomcat⾼可⽤)
设定负载均衡策略名称不要加"_"线 1.默认规则轮询
upstream jt-windows {
#ip_hash;
server 127.0.0.1:8091 max_fails=1 fail_timeout=60s;
server 127.0.0.1:8092 max_fails=1 fail_timeout=60s;
server 127.0.0.1:8093 max_fails=1 fail_timeout=60s;
}
#后台管理服务器⽤户访问manage.jt时访问localhost:8091
server {
listen 80;
server_name manage.jt;
location / {
#代理路径
proxy_pass  jt-windows;
#链接服务器超时
proxy_connect_timeout      2;
#读取服务器资源超时
proxy_read_timeout          2;
#向服务器发送数据超时
proxy_send_timeout          2;
}
}
}
3.3 常见⾯试题
1、请解释⼀下什么是Nginx?
Nginx是⼀个web服务器和⽅向代理服务器,⽤于HTTP、HTTPS、SMTP、POP3和IMAP协议。
2、请列举Nginx的⼀些特性。
Nginx服务器的特性包括:
反向代理/负载均衡器
嵌⼊式Perl解释器
动态⼆进制升级
可⽤于重新编写URL,具有⾮常好的PCRE⽀持
3、请列举Nginx和Apache 之间的不同点。
4、请解释Nginx如何处理HTTP请求。
Nginx使⽤反应器模式。主事件循环等待操作系统发出准备事件的信号,这样数据就可以从套接字读取,在该实例中读取到缓冲区并进⾏处理。单个线程可以提供数万个并发连接。
5、在Nginx中,如何使⽤未定义的服务器名称来阻⽌处理请求?
只需将请求删除的服务器就可以定义为:
Server {
listen 80;
server_name “ “ ;
return 444;
}
这⾥,服务器名被保留为⼀个空字符串,它将在没有“主机”头字段的情况下匹配请求,⽽⼀个特殊的Nginx的⾮标准代码444被返回,从⽽终⽌连接。
6、使⽤“反向代理服务器”的优点是什么?
反向代理服务器可以隐藏源服务器的存在和特征。它充当互联⽹云和web服务器之间的中间层。这对于安全⽅⾯来说是很好的,特别是当您使⽤web托管服务时。
7、请列举Nginx服务器的最佳⽤途。
Nginx服务器的最佳⽤法是在⽹络上部署动态HTTP内容,使⽤SCGI、WSGI应⽤程序服务器、⽤于脚本的FastCGI处理程序。它还可以作为负载均衡器。
8、请解释Nginx服务器上的Master和Worker进程分别是什么?
Master进程:读取及评估配置和维持
Worker进程:处理请求
9、请解释你如何通过不同于80的端⼝开启Nginx?
为了通过⼀个不同的端⼝开启Nginx,你必须进⼊/etc/Nginx/sites-enabled/,如果这是默认⽂件,那么你必须打开名为“default”的⽂件。编辑⽂件,并放置在你想要的端⼝:
Like server { listen 81; }
10、请解释是否有可能将Nginx的错误替换为502错误、503?
502 = 错误⽹关
503 = 服务器超载
有可能,但是您可以确保fastcgi_intercept_errors被设置为ON,并使⽤错误页⾯指令。
Location / {
fastcgi_pass 127.0.01:9001;
fastcgi_intercept_errors on;
error_page 502 =503/error_page.html;
11、在Nginx中,解释如何在URL中保留双斜线?
要在URL中保留双斜线,就必须使⽤merge_slashes_off;
语法:merge_slashes [on/off]
默认值: merge_slashes on
环境: http,server
12、请解释ngx_http_upstream_module的作⽤是什么?
ngx_http_upstream_module⽤于定义可通过fastcgi传递、proxy传递、uwsgi传递、memcached传递和scgi传递指令来引⽤的服务器组。13、请解释什么是C10K问题?
C10K问题是指⽆法同时处理⼤量客户端(10,000)的⽹络套接字。
14、请陈述stub_status和sub_filter指令的作⽤是什么?
Stub_status指令:该指令⽤于了解Nginx当前状态的当前状态,如当前的活动连接,接受和处理当前读/写/等待连接的总数
Sub_filter指令:它⽤于搜索和替换响应中的内容,并快速修复陈旧的数据
15、解释Nginx是否⽀持将请求压缩到上游?
您可以使⽤Nginx模块gunzip将请求压缩到上游。gunzip模块是⼀个过滤器,它可以对不⽀持“gzip”编码⽅法的客户机或服务器使⽤“内容编码:gzip”来解压缩响应。
16、解释如何在Nginx中获得当前的时间?
要获得Nginx的当前时间,必须使⽤SSI模块、$date_gmt和$date_local的变量。
Proxy_set_header THE-TIME $date_gmt;
17、⽤Nginx服务器解释-s的⽬的是什么?
⽤于运⾏Nginx -s参数的可执⾏⽂件。
18、解释如何在Nginx服务器上添加模块?
在编译过程中,必须选择Nginx模块,因为Nginx不⽀持模块的运⾏时间选择。
4、Linux
Linux是⼀套免费使⽤和⾃由传播的类Unix操作系统,是⼀个基于POSIX和UNIX的多⽤户、多任务、⽀持多线程和多CPU的操作系统。它能运⾏主要的UNIX⼯具软件、应⽤程序和⽹络协议。它⽀持32位和64位硬件。Linux继承了Unix以⽹络为核⼼的设计思想,是⼀个性能稳定的多⽤户⽹络操作系统。
Linux操作系统诞⽣于1991 年10 ⽉5 ⽇(这是第⼀次正式向外公布时间)。Linux存在着许多不同的Linux版本,但它们都使⽤了Linux内核。Linux可安装在各种计算机硬件设备中,⽐如⼿机、平板电脑、路由器、视频游戏控制台、台式计算机、⼤型机和超级计算机。
严格来讲,Linux这个词本⾝只表⽰Linux内核,但实际上⼈们已经习惯了⽤Linux来形容整个基于Linux内核,并且使⽤GNU⼯程各种⼯具和数据库的操作系统。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。