第二十四章:Java基础面试题,Nginx使用,微服务配置。
本期主题:
7天掌握《Java编程与面试2024》的核心三章59问,即Java基础面试题篇19问,Nginx使用篇15问,微服务配置篇25问。
下面,先来介绍一下,以上三个篇章各自的核心问题:
1、Java语言,有哪些特点?
2、char类型变量,是否能保存一个汉字?
3、==和equals的区别?
4、final、finally、finalize的区别?
5、一个.java源文件中,是否可以包含多个类(不是内部类)呢?又有什么限制呢?
6、&与&&的区别?
7、JAVA中的保留字,都有什么?
8、Collection和Collections的区别?
9、如何去掉Vector集合中的重复元素?
10、ArrayList和Vector的区别?
11、HashMap和Hashtable的区别?
12、说说ArrayList,Vector,LinkedList三者的存储性能和特性?
13、HashMap与TreeMap的区别?
14、List、Map、Set三个接口,在存储元素时,各有什么特点?
15、在Java中,List是个接口,那实现List接口的类有哪些,它们又有什么区别?
16、判断下列语句是否正确,如果有错误,请指出错误所在?
17、A=10,B=20使得两值互换?
18、只移动一个数字,使62-63=1成立(不能移动符号)?
19、字符串面试的经典源码示例?
...
1、请解释一下,什么是Nginx?
2、为什么要用Nginx?
3、Nginx的优缺点?
4、Nginx应用场景?
5、使用“反向代理服务器”的优点是什么?
6、请列举Nginx服务器的最佳用途?
7、请解释下,Nginx是如何处理HTTP请求的?
8、在Nginx中,如何使用未定义的服务器名称,来阻止处理请求的?
9、在Nginx中,如何在URL中保留双斜线?
10、ngx_http_upstream_module的作用是什么?
11、fastcgi与cgi的区别?
12、Nginx常用命令?
13、Nginx常用配置?
14、请陈述stub_status和sub_filter指令的作用是什么?
15、主从Reactor多线程模型?
...
一、什么是SpringBoot?
二、SpringBoot常用的starter?
三、SpringBoot自动配置原理?
四、SpringBootstarter工作原理?
五、SpringBoot的优点?
六、SpringCloud解决了哪些问题?
七、SpringBoot与SpringCloud的关系?
八、微服务是如何调用的?
九、微服务调用的原理?
十、微服务如何实现负载均衡?
十一、配置详解?
十二、Eureka?
十三、Eureka的高可用配置?
十四、谈谈微服务?
十五、微服务和SOA的关系?
十六、SpringCoud是如何实现服务注册与发现的?
十七、Ribbon和Feign的区别?
十八、雪崩效应?
十九、熔断机制?
二十、Eureka的基础架构?
二十一、Eureka和Zookeeper都可以提供服务注册与发现的功能,而两者的区别是?
二十二、CAP理论?
二十三、Ribbon和Nginx的区别?
二十四、服务注册与发现?
二十五、微服务的负载均衡,为何用?怎么用?
......
1、Java语言,有哪些特点?
答:
简单性(Simple);
结构体系中立(ArchitectureNeutral);
面向对象(ObjectOriented);
易于移植(Portable);
分布式(Distributed);
高性能(HighPerformantce);
多线程(Multithreaded);
健壮性(Robust);
动态性(Dynamic);
安全性(Secure)。
...
2、char类型变量,是否能保存一个汉字?
答:可以。
在Java语言中,一个char类型变量占16位bit(即2个字节byte)的存储空间。
由于Java语言,使用Unicode字符集对字符进行编码...
因此,char类型变量可以存储任何字符;
这些字符,可以是英文字符、汉字、日文片断,以及其它国家的许多字符。
相关详细知识点:
在计算机中的存储单位,是以字节为单位的。
常见的磁盘大小和文件大小,分别以GB、MB、KB等来表示...
它们之间的换算单位是1GB=1024MB,1MB=1024KB,1KB=1024byte(即字节)。
每个字节的取值范围是-128到127,它可以保存一个英文字符,包括字母、数字和英文标点。
而汉字的存储,是由2个字节保存的。
因为汉字的数量太多,它的编码范围,远远超过一个字节的取值范围...
所以,必须要使用双字节来表示。在Java语言中...
使用Unicode字符集,对字符进行编码,可以存储65535个字符。
所以Java字符类型,被定义为双字节。
因此,在Java语言中,可以使用char类型变量,来存储汉字。
...
3、==和equals的区别?
答:有2点区别,即...
(1)==,是用于比较基本数据类型的值,以及比较引用数据类型,在内存中存放的地址。
(2)equals方法,在比较引用数据类型时...
如果没有覆盖Object类的equals方法,则同==一样,比较内存中的存放地址;
反之,则像String字符串等类的equals方法一样,去比较引用数据类型的内容了。
...
4、final、finally、finalize的区别?
答:
final,用于声明属性,方法和类...
分别表示属性不可变,方法不可覆盖,类不可继承。
\tfinally,是异常处理语句结构的一部分,表示总是执行。
finalize,是Object类的一个方法...
在垃圾收集器执行的时候,会调用被回收对象的此方法;
可以覆盖此方法,以提供垃圾收集时的其它资源回收,例如关闭文件等。
...
5、一个.java源文件中,是否可以包含多个类(不是内部类)呢?又有什么限制呢?
答:可以包含多个类。
但,只能有一个public类,且public的类名,必须与文件名一致。
...
6、&与&&的区别?
答:主要有点区别,即...
(1)&和&&都可以用作逻辑与(and)运算;
(2)&&还具有短路的功能;
(3)&还可以按位运算。
下面,详细说明下以上3点区别:
(1)&和&&用作逻辑与运算符
&和&&,都可以用作逻辑与的运算符,表示逻辑与(and)。
当运算符,两边表达式的结果,都为true时...
整个运算结果才为true;
否则,只要有一方为false,则结果为false。
(2)&&有短路功能
&&除了可作逻辑与运算符外,还具有短路的功能...
即如果第一个表达式为false,则不再计算第二个表达式。
例如,对于if(str!=null&&!str.equals(“”))表达式...
当str为null时,后面的表达式不会执行;
所以不会出现NullPointerException空指针异常。
而如果将&&改为&,此时则会抛出NullPointerException异常了。
在If(x==33&++y>0)中,y会增长;
而在If(x==33&&++y>0)中,则不会增长。
(3)&用作位运算符
&还可以用作位运算符。
当&操作符两边的表达式,不是boolean类型时...
&表示“按位与”操作。
我们通常使用0x0f,来与一个整数进行&运算...
来获取该整数的最低4个bit位。
例如,“0x31&0x0f”的结果为“0x01”。
...
7、JAVA中的保留字,都有什么?
答:goto,const。
关键字Keyword:
Java的关键字,对Java的编译器有特殊的意义...
它们用来表示一种数据类型,或者表示程序的结构等。
保留字Reservedword:
保留字,是为java预留的关键字。
它们虽然现在没有作为关键字,但在以后的升级版本中,有可能作为关键字。
...
8、Collection和Collections的区别?
答:主要2点区别,即...
(1)Collection是集合类的上级接口,继承于它的主要接口有List和Set;
(2)Collections是针对集合类的一个帮助类...
它提供了,一系列静态方法,以实现对各集合的搜索、排序、线程安全化等操作。
...
9、如何去掉Vector集合中的重复元素?
答:有两种方式可以去掉Vector集合中的重复元素。
下面,我来具体说说这两种方式...
方式一:
VectornewVector=newVector;
for(inti=0;i
Objectobj=vector.get(i);
if(!ntains(obj)){
newVector.add(obj);
}
}
方式二:
HashSetset=newHashSet(vector);
因为,HashSet集合中允许存在重复元素。
...
10、ArrayList和Vector的区别?
答:两者的同步性和数据增长不同。
一、同步性不同
Vector是线程安全的,也就是同步的。
而ArrayList,则是线程不安全的,不是同步。
二、数据增长不同
当需要增长时,Vector默认增长为原来的一倍。
而ArrayList,却是原来的一半。
...
11、HashMap和Hashtable的区别?
答:两者主要有三点区别,即...
一、历史来源不同
Hashtable,是基于陈旧的Dictionary类的。
而HashMap,则是Java1.2引进的Map接口的一个实现类。
二、同步性不同
Hashtable是线程安全的,也就是同步的。
而HashMap,不是线程安全的,不是同步的。
三、是否允许“空值”不同
只有HashMap,可以让你将一个空值,作为一个表条目的key或value。
...
12、说说ArrayList,Vector,LinkedList三者的存储性能和特性?
答:
ArrayList和Vector,都是使用数组方式存储数据...
此数组元素数,大于实际存储的数据,以便增加和插入元素。
它们都允许,直接按序号索引元素...
但插入元素,要涉及数组元素移动等内存操作;
所以,索引数据快,而插入数据慢。
Vector,由于使用了synchronized方法(线程安全)...
通常在性能上,较ArrayList差。
而LinkedList,是使用双向链表实现存储的...
按序号索引数据,需要进行前向或后向遍历;
但插入数据时,只需要记录本项的前后项即可,所以插入速度较快。
...
13、HashMap与TreeMap的区别?
答:
HashMap是通过hashcode,对其内容进行快速查找的。
而TreeMap中所有的元素,都保持着某种固定的顺序。
所以,如果你需要得到一个有序的结果...
那么,你就应该使用TreeMap。
因为,HashMap中元素的排列顺序,是不固定的。
...
14、List、Map、Set三个接口,在存储元素时,各有什么特点?
答:
1)List是有序的Collection…
使用此接口,能够精确的控制每个元素插入的位置。
用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素…
这类似于Java的数组。
2)Set是一种不包含重复的元素的Collection…
即任意的两个元素e1和e2都有e1.equals(e2)=false。
此外,Set最多有一个null元素。
3)Map接口…
请注意,Map没有继承Collection接口。
Map是提供了key到value的映射。
…
下面,让我来具体说说…
List、Map、Set,是Java中常用的三种集合接口。
它们在存储元素时,各自具有不同的特点:
1)List接口
具有5个特点,即有序性,可重复性,可变性,元素类型,操作方法。
有序性:
List集合中的元素,按照插入顺序进行存储…
可以通过索引,去访问和操作集合中的元素。
可重复性:
List集合中,允许存储重复的元素…
即同一个元素可以多次出现在集合中。
可变性:
List集合中的元素,可以随时增加、删除和修改,集合的大小可以动态改变。
元素类型:
在List集合中,可以存储任意类型的元素…
包括基本数据类型和引用类型。
操作方法:
List集合,提供了丰富的方法,来操作集合中的元素…
比如添加、删除、获取元素,查找元素等。
2)Map接口
具有5个特点,即键值对存储,键的唯一性,值的可重复性,键和值的类型,单向一对一关系。
键值对存储:
Map用于保存具有映射关系的数据…
即Key-Value对(双列元素)。
键的唯一性:
Map中的key不允许重复,每个key都唯一对应一个value。
值的可重复性:
Map中的value可以重复,即多个key可以对应相同的value。
键和值的类型:
Map中的key和value,可以是任何引用类型的数据。
单向一对一关系:
Map中key和value之间,存在单向一对一关系…
即通过指定的key,总能找到对应的value。
3)Set接口
具有5个特点,即无序性,元素的互异性,空集性质,元素类型,测试归属性。
无序性:
Set集合中的元素位置无顺序,元素之间是无序的。
元素的互异性:
Set集合不允许出现重复元素,每个元素只能出现一次。
空集性质:
空集是一切集合的子集,Set也可以表示空集。
元素类型:
Set集合中可以存储任意类型的元素。
测试归属性:
Set最常被用于测试归属性…
可以很容易地查询某个对象,是否在某个Set中。
综上所述:
List、Map、Set三种接口,在存储元素时的主要区别…
在于元素的顺序性、重复性、以及存储结构(List是有序列表,Map是键值对映射,Set是无序集合)。
所以,在实际使用中,我们可以根据需求…
去选择合适的集合类型,来存储和处理数据。
…
15、在Java中,List是个接口,那实现List接口的类有哪些,它们又有什么区别?
答:
在Java中,List确实是一个接口…
它属于Java的集合框架(JavaCollectionsFramework)。
List接口定义了一些基本的操作,比如添加、删除元素等。
有很多类实现了List接口,诸如ArrayList、LinkedList、Vector等等。
这些实现类之间的主要区别,在于三者的内部实现机制和性能特性:
1)ArrayLis
ArrayList内部基于数组实现…
因此它提供了,对元素的随机访问(即通过索引访问)的高效性。
当添加或删除元素时…
如果列表的大小,超过了其内部数组的大小,ArrayList会自动扩容;
这可能会涉及到数组元素的复制;
因此,在大量添加或删除元素时,可能会产生较高的开销。
在大部分情况下,ArrayList是List接口的首选实现…
特别是,当你需要频繁地,访问列表中的元素时。
2)LinkedLis
LinkedList内部基于链表实现…
因此它提供了,在列表开头和结尾,添加或删除元素的高效性。
对于随机访问元素…
LinkedList的性能较差,因为它需要从列表的一端开始遍历。
因此,如果你需要…
频繁地在列表的开头或结尾,添加或删除元素的话…
那么LinkedList,可能是一个更好的选择。
3)Vector
Vector和ArrayList类似…
也是基于数组实现的,但它提供了线程安全的操作。
这是通过在每个公共方法上,添加同步来实现的…
因此,它可能会比ArrayList慢。
在现代Java编程中,我们通常更倾向于使用并发集合(如ConcurrentHashMap)…
或者,显式地同步代码块;
而不是使用Vector,因为同步的开销可能会比较大。
此外…
还有其它一些类,也实现了List接口,例如CopyOnWriteArrayList…
它适用于读多写少的并发场景。
至于选择哪个实现类,则取决于你的具体需求,比如访问模式、线程安全性、性能要求等。
…
16、判断下列语句是否正确,如果有错误,请指出错误所在?
Lista=newArrayList;
a.add(5);
答:正确。
在Java中,你可以创建一个ArrayList,它存储的元素类型是Short。
Short是Java的一个包装类,用于表示基本数据类型short的值。
当你调用“a.add(5);”时…
Java会自动将基本数据类型“int的5”,转换成包装类型Short。
因为,5在short的范围内(即-32768到32767)。
所以,可以安全地转换为Short。
因此,这段代码会成功地向ArrayList中…
添加一个Short类型的对象,其值为5。
这是自动装箱(autoboxing)的一个例子…
它是Java5及以上版本,提供的一个特性;
允许在基本数据类型,和它们对应的包装类之间,进行自动转换。
…
17、A=10,B=20使得两值互换?
答:
1)中间变量:C=A;A=B;B=C
2)A=A-B;B=B+A;A=B-A
…
18、只移动一个数字,使62-63=1成立(不能移动符号)?
答:2的6次方-63=1。
注意:要从“移动一个数字”的思维中抽离出来,考虑次方实现。
…
19、字符串面试的经典源码示例?
答:具体代码示例如下…
packagecom.exam.prj.action.String;
/**
*@authorAARON
*/
publicclassStringTest{
\tpublicstaticvoidmain(String[]args){
\t\t//
\t\t//判断生成几个对象
\t\t//\t\
\t\t//生成2个对象.StringPool中生成一个对象“aaron”,Heap中生成一个对象“aaron”
\t\tStringstrA=newString(“aaron“);\t\
\t\t//未生成新对象.判断StringPool中是否存在“aaron”,存在则strB直接引用“aaron”对象
\t\tStringstrB=“aaron“;
\t\
\t\t//生成1个对象.在Heap中生成一个对象“aaron”
\t\tStringstrC=newString(“aaron“);
\t\
\t\tSystem.out.println(strA==strB);\t//\tfalse
\t\tSystem.out.println(strA==strC);\t//\tfalse
\t\tSystem.out.println(strB==strC);\t//\tfalse
\t\t//intern返回在StringPool中存在的地址
\t\tSystem.out.println(strA==strA.intern);\t//\tfalse
\t\tSystem.out.println(strB==strB.intern);\t//\ttrue
\t\tSystem.out.println(strA.intern==strC.intern);\t//\ttrue
\t\t//
\t\t//判断字符串变量的内存地址是否相等
\t\t//
\t\
\t\tStringaaron=“aaron“;
\t\tStringaa=“aa“;
\t\tStringron=“ron“;
\t\
\t\t//“aa“+“ron“,这是两个字符串常量相加,拼接结果为“aaron”,然后到StringPool中判断获得内存地址
\t\tSystem.out.println(aaron==“aa“+“ron“);//true
\t\
\t\t//“aa“+ron,这是字符串常量和变量相加,拼接结果为“aaron”,然后在Heap中创建一个“aaron”对象
\t\tSystem.out.println(aaron==“aa“+ron);//false
\t}
}
......
1、请解释一下,什么是Nginx?
Nginx,是一个Web服务器和反向代理服务器,用于HTTP、HTTPS、SMTP、POP3和IMAP协议。
目前是被使用最多的Web服务器,代理服务器...
像淘宝、新浪、网易、迅雷等,都在使用。
Nginx的主要功能如下:
(1)作为httpserver(代替Apache
对PHP需要FastCGI处理器支持)。
(2)FastCGI
Nginx本身不支持PHP等语言...
但是它,可以通过FastCGI来将请求,扔给某些语言或框架处理。
(3)反向代理服务器
(4)实现负载均衡
(5)虚拟主机
...
2、为什么要用Nginx?
因为Nginx具有:
跨平台,配置简单,反向代理,缓存服务,邮件代理服务器...
高并发连接数,内存消耗小,拥有健康检查功能...
节省宽带,稳定性高,接受请求异步等优秀的特性。
下面,就让我来具体说说Nginx的一些优秀特点吧!
高并发连接数:
Nginx处理2-3万并发连接数,官方监测能支持5万并发。
内存消耗小:
开启10个nginx,才占150M内存;
Nginx处理静态文件效果好,耗费内存少。
健康检查功能:
Nginx内置了健康检查功能;
当有一个服务器宕机时,就会做一个健康检查...
之后再发送的请求,就不会发送到宕机的服务器了;
而是,重新将请求,提交到其它的节点上。
节省宽带:
支持GZIP压缩,可以添加浏览器本地缓存。
稳定性高:
宕机的概率非常小。
接受请求异步:
即接收的用户请求,是异步的。
...
3、Nginx的优缺点?
优点:
占内存小,可实现高并发连接,处理响应快…
可实现http服务器、虚拟主机、方向代理、负载均衡。
Nginx的配置简单,还可以不暴露正式的服务器IP地址。
缺点:
动态处理差。
Nginx处理静态文件好,耗费内存少…
但是处理动态页面则很鸡肋,因为现在一般前端用Nginx作为反向代理抗住压力。
…
4、Nginx应用场景?
1)http服务器
Nginx是一个http服务,可以独立提供http服务。
可以做网页静态服务器。
2)虚拟主机
它可以实现,在一台服务器虚拟出多个网站,例如个人网站使用的虚拟机。
3)反向代理与负载均衡
当网站的访问量,达到一定程度后,单台服务器不能满足用户的请求时…
就需要用多台服务器集群,可以使用Nginx做反向代理。
并且多台服务器,可以平均分担负载…
不会因为某台服务器负载高而宕机。
4)Nginx中也可以配置安全管理
比如可以使用Nginx搭建API接口网关,对每个接口服务进行拦截。
…
5、使用“反向代理服务器”的优点是什么?
反向代理服务器,可以隐藏源服务器的存在和特征。
它充当互联网云和web服务器之间的中间层。
这对于安全方面来说是很好的,特别是当您使用web托管服务时。
…
6、请列举Nginx服务器的最佳用途?
Nginx服务器,是一种高性能的HTTP和反向代理服务器…
它具有丰富的功能和广泛的应用场景。
Nginx服务器的7个最佳用途…
即静态HTTP服务器,负载均衡,虚拟主机,邮件代理服务器,性能优化,安全性,高并发与高稳定性。
1)静态HTTP服务器
Nginx可以将服务器上的静态文件(如HTML、图片、CSS、JavaScript等)…
通过HTTP协议,高效地展现给客户端。
2)负载均衡
当网站访问量非常大时,可以将同一个应用部署在多台服务器上。
Nginx通过反向代理的方式,实现负载均衡…
将大量用户的请求,分配给多台机器处理。
这不仅可以提高网站的响应速度,还增强了系统的可用性和可靠性。
在负载均衡过程中,Nginx可以灵活配置各种负载均衡算法,来满足不同的业务需求。
3)虚拟主机
对于访问量较小的网站…
Nginx支持在同一台服务器上,部署多个网站,从而通过虚拟主机的方式,来节省成本。
4)邮件代理服务器
Nginx也是一个非常优秀的邮件代理服务器…
可以处理邮件相关的任务,如SMTP、POP3和IMAP等。
5)性能优化
Nginx提供了多种性能优化策略,如启用缓存、压缩响应、启用TCP缓冲、启用HTTP2等。
这些策略,可以显著提高网站的性能,减少网络传输数据量,加快页面响应速度。
6)安全性
尽管Nginx本身具有一些安全漏洞,但通过合理配置和更新,可以大大提高网站的安全性。
例如…
可以限制缓存文件的大小和时间,设置验证规则以验证数据是否被篡改,从而加强缓存安全。
7)高并发与高稳定性
Nginx以高速、高并发、高稳定性著称。
其内部的事件驱动架构,以及采用异步非阻塞方式,去处理客户端请求的特点…
使得在高并发请求下,Nginx依然能够保持稳定性。
这使得Nginx,成为了处理大量并发连接的理想选择…
尤其适用于,大型高负载的Web应用程序、云计算、物联网等领域。
总的来说:
Nginx服务器在Web服务、负载均衡、性能优化、安全性和稳定性等方面都有出色的表现。
Nginx是构建高效、可靠和安全的网络应用的理想选择。
然而,具体的最佳用途,可能因应用场景和需求的不同而有所差异。
因此在实际使用中,我们需要根据具体情况,去进行配置和优化。
…
7、请解释下,Nginx是如何处理HTTP请求的?
因为Nginx使用了“反应器模式”。
主事件循环,等待操作系统发出准备事件的信号…
这样数据就可以从套接字读取,在该实例中读取到缓冲区并进行处理。
且单个线程可以提供数万个并发连接。
下面,让我来具体说说…
实际上,Nginx处理HTTP请求的过程…
是一个复杂而高效的操作,它涉及到多个阶段和模块。
Nginx处理HTTP请求的“六部曲”,即…
接收请求,解析请求,访问URI,反向代理和负载均衡,处理动态请求,记录日志。
1)接收请求
Nginx使用监听器,来接收客户端发送的HTTP请求。
监听器会绑定到一个特定的端口上,并等待客户端的连接请求。
一旦有新的连接到达,监听器会创建一个连接对象…
并将这个连接对象,放入连接池中等待处理。
2)解析请求
当Nginx从连接池中,取出一个连接对象时…
它会开始读取,该连接对象中的请求数据。
这个过程包括解析请求行、请求头和请求体。
请求行,包含了HTTP方法(如GET、POST等)、请求的URI以及HTTP协议的版本信息。
请求头,则包含了客户端发送的各种元数据和请求参数。
请求体,通常用于POST请求,包含了客户端提交的数据。
3)访问URI
解析完请求后,Nginx会根据请求的URI,来决定如何处理这个请求。
如果请求的URI,对应的是静态文件…
Nginx会直接从文件系统中读取这个文件,并将其作为响应返回给客户端。
如果请求的URI,对应的是动态内容…
Nginx则需要将请求,转发给后端服务器进行处理。
4)反向代理和负载均衡
如果请求需要由后端服务器处理…
Nginx会作为反向代理服务器,将请求转发给后端服务器。
在这个过程中,Nginx还可以使用负载均衡算法…
将请求分发到多个后端服务器上;
以充分利用这些服务器的资源,提高系统的吞吐量和可靠性。
5)处理动态请求
对于需要动态生成内容的请求…
Nginx会将请求转发给后端服务器(如PHP、Python、Java等应用服务器)来处理。
后端服务器,会根据请求的内容,生成相应的响应,然后将响应返回给Nginx。
Nginx再将这个响应,封装成一个HTTP响应对象,发送给客户端。
6)记录日志
在处理完请求后,Nginx会记录相关的访问日志和错误日志。
这些日志,可以帮助管理员了解服务器的运行状态,以及分析和优化性能。
在整个处理过程中,Nginx使用了“事件驱动的模型”来同时处理多个请求。
这种模型,使得Nginx能够高效地处理并发请求,提供高性能的Web服务。
此外,Nginx还允许通过配置和扩展模块…
来支持更多的功能和优化策略,以满足不同的业务需求。
…
8、在Nginx中,如何使用未定义的服务器名称,来阻止处理请求的?
只需将请求删除的服务器就可以定义为:
Server{
listen80;
server_name““;
return444;
}
这里,服务器名被保留为一个空字符串…
它将在没有“主机”头字段的情况下,匹配请求。
而一个特殊的Nginx的非标准代码444,被返回,从而终止连接。
…
9、在Nginx中,如何在URL中保留双斜线?
要在URL中保留双斜线,就必须使用“merge_slashes_off;”。
语法:merge_slashes[onoff];
默认值:merge_slasheson;
环境:http,server
…
10、ngx_http_upstream_module的作用是什么?
ngx_http_upstream_module用于定义可通过fastcgi传递、proxy传递、uwsgi传递、memcached传递和scgi传递指令,来引用的服务器组。
…
11、fastcgi与cgi的区别?
1)cgi
web服务器会根据请求的内容,然后会fork一个新进程来运行外部c程序(或perl脚本…)。
这个进程,会把处理完的数据,返回给web服务器。
最后web服务器,把内容发送给用户,刚才fork的进程,也随之退出。
如果下次用户还请求改动态脚本…
那么web服务器,又再次fork一个新进程,周而复始的进行。
2)fastcgi
web服务器收到一个请求时,他不会重新fork一个进程(因为这个进程在web服务器启动时就开启了,而且不会退出)。
web服务器,直接把内容传递给这个进程(进程间通信,但fastcgi使用了别的方式,tcp方式通信)。
这个进程收到请求后进行处理,把结果返回给web服务器…
最后自己接着等待下一个请求的到来,而不是退出。
综上所述,fastcgi与cgi的差别,就在于是否重复fork进程,处理请求。
…
12、Nginx常用命令?
启动nginx。
停止nginx-sstop或nginx-squit。
重载配置.sbinnginx-sreload(平滑重启)或servicenginxreload。
重载指定配置文件.nginx-cusrlocanf。
查看nginx版本nginx-v。
检查配置文件是否正确nginx-t。
显示帮助信息nginx-h。
…
13、Nginx常用配置?
worker_processes8;#工作进程个数
worker_connections65535;#每个工作进程能并发处理(发起)的最大连接数(包含所有连接数)
error_logdatalogsnginxerror.log;#错误日志打印地址
access_logdatalogsnginxaccess.log;#进入日志打印地址
log_formatmain'$remote_addr$request''$status$upstream_addr
$request_time';#进入日志格式
##如果未使用fastcgi功能的,可以无视
fastcgi_connect_timeout=300;#连接到后端fastcgi超时时间
fastcgi_send_timeout=300;#向fastcgi请求超时时间(这个指定值,已经完成两次握手后,向fastcgi传送请求的超时时间)
fastcgi_rend_timeout=300;#接收fastcgi应答超时时间,同理也是2次握手后
fastcgi_buffer_size=64k;#读取fastcgi应答第一部分需要多大缓冲区,该值表示使用1个64kb的缓冲区读取应答第一部分(应答头)…
可以设置为fastcgi_buffers选项缓冲区大小
fastcgi_buffers464k;#指定本地需要多少和多大的缓冲区来缓冲fastcgi应答请求…
假设一个php或java脚本所产生页面大小为256kb,那么会为其分配4个64kb的缓冲来缓存
fastcgi_cacheTEST;#开启fastcgi缓存并为其指定为TEST名称,降低cpu负载,防止502错误发生
listen80;#监听端口
server_namerrc.test.;#允许域名
rootdatareleaserrcweb;#项目根目录
indexindex.phpindex.htmlindex.htm;#访问根文件
…
14、请陈述stub_status和sub_filter指令的作用是什么?
(1)Stub_status指令
该指令用于了解Nginx当前状态的当前状态…
如当前的活动连接,接受和处理当前读写等待连接的总数。
(2)Sub_filter指令
它用于搜索和替换响应中的内容,并快速修复陈旧的数据。
…
15、主从Reactor多线程模型?
服务端用于接收客户端连接的,不再是个1个单独的NIO线程…
而是一个独立的NIO线程池。
Acceptor接收到客户端TCP连接请求,处理完成后(可能包含接入认证等)…
将新创建的SocketChannel,注册到IO线程池(subreactor线程池)的某个IO线程上;
由它负责SocketChannel的读写和编解码工作。
Acceptor线程池,仅仅只用于客户端的登陆、握手和安全认证…
一旦链路建立成功,就将链路注册到后端subReactor线程池的IO线程上;
由IO线程负责后续的IO操作。
......
一、什么是SpringBoot?
1、用来简化spring初始搭建,以及开发过程中使用特定的方式,进行配置(properties或者yml文件)。
2、创建独立的Spring应用程序main方法运行。
3、嵌入Tomcat无需部署war包,直接打成jar包,用nohupjava-jar–&启动就好。
4、简化了maven的配置。
5、自动配置Spring添加对应的starter自动化配置。
...
下面,让我来具体说说…
SpringBoot是由Pivotal团队提供的全新框架…
旨在简化新Spring应用的初始搭建,以及开发过程。
从根本上讲,SpringBoot是一个基于Spring框架的开源框架…
它提供了一套开发工具和约定,使得构建独立、可执行的、生产级别的Spring应用,变得更加容易。
SpringBoot具有4大核心特性,即自动化配置,外部化配置,内嵌容器,健康检查和监控。
1、自动化配置
通过自动配置机制,根据项目中引入的依赖和约定…
自动配置应用程序中的各种组件和功能。
这减少了开发者,手动编写大量XML或注解配置的工作量,降低了出错的可能性。
2、外部化配置
支持将配置信息从代码中分离出来,使开发者能够在不同环境下…
灵活切换配置参数,例如使用不同的数据库或消息队列。
3、内嵌容器
支持内置的Servlet容器(如Tomcat、Jetty、Undertow等)…
这意味着,你可以将应用程序,打包为一个可执行的JAR文件…
并直接运行,无需单独安装和配置外部容器。
4、健康检查和监控
提供了健康检查和监控功能,可以监控应用程序的运行状态和性能指标…
确保应用程序的稳定性和可靠性。
此外…
SpringBoot还致力于提供快速的应用开发体验,并使得开发者…
能够更专注于业务逻辑的实现,而不是花费大量时间在配置和部署上。
因此…
无论是Web应用、RESTful服务还是批处理作业,SpringBoot都能帮助开发者…
更快速、更便捷地构建及部署Java应用程序,提高开发效率和项目的可维护性。
划重点:
最新版本的SpringBoot(截至2024年4月)是3.2.x系列,提供了更多的特性和改进…
如系统要求提升、安全性增强、虚拟线程支持以及JakartaEE迁移等。
这些新特性和改进,使得SpringBoot在构建现代、高效和安全的Java应用程序方面,更加强大和灵活。
…
二、SpringBoot常用的starter?
1、spring-boot-starter-web(嵌入Tomcat和web开发需要的servlet和jsp支持)
2、spring-boot-starter-data-jpa(数据库支持)
3、spring-boot-starter-data-Redis(Redis支持)
4、spring-boot-starter-data-solr(solr搜索应用框架支持)
5、mybatis-spring-boot-starter(第三方mybatis集成starter)
…
三、SpringBoot自动配置原理?
1、@EnableAutoConfiguration这个注解会“猜“你将如何配置spring,前提是你已经添加了jar依赖项。
如果spring-boot-starter-web已经添加Tomcat和SpringMVC…
这个注释,就会自动假设您在开发一个web应用程序,并添加相应的Spring配置;
会自动去maven中读取每个starter中的spring.factories文件;
该文件里,配置了所有需要被创建spring容器中bean。
2、在main方法中,加上注解@SpringBootApplication和@EnableAutoConfiguration。
…
四、SpringBootstarter工作原理?
1、SpringBoot在启动时,扫描项目依赖的jar包,寻找包含spring.factories文件的jar。
2、根据spring.factories,配置加载AutoConfigure。
3、根据@Conditional注解的条件,进行自动配置,并将bean注入到SpringContext。
…
五、SpringBoot的优点?
1、减少开发、测试时间和努力。
2、使用JavaConfig有助于避免使用XML。
3、避免大量的maven导入和各种版本冲突。
4、提供意见发展方法,
5、通过提供默认值快速开始开发。
6、没有单独的web服务器需要...
这就意味着,不再需要启动Tomcat、Glassfish,或其它任何东西。
7、需要更少的配置,因为没有web.xml文件。
只需添加用@Configuration注释的类,然后添加用@Bean注释的方法…
Spring将自动加载对象,并像以前一样对其进行管理。
甚至可以将@Autowired添加到bean方法中,以使用Spring自动装入需要的依赖关系中。
…
六、SpringCloud解决了哪些问题?
配置管理(注册中心eureka、zk)…
服务发现、服务注册、断路器、路由策略、全局锁、分布式会话…
客户端调用、接口网关(zuul)、服务管理系统。
下面,让我来具体说说…
SpringCloud主要解决了,在构建微服务架构时,面临的一系列问题。
主要有6个,即服务注册与发现,配置管理,负载均衡,熔断与降级,服务拆分与治理,生态系统丰富。
具体来说,它提供了以下关键解决方案:
1、服务注册与发现
通过集成服务注册中心(如Eureka、Consul等)…
SpringCloud使得微服务之间,能够自动注册和发现彼此…
从而实现了服务之间的无缝通信。
这大大简化了,服务之间的调用过程,提高了系统的可维护性和可扩展性。
2、配置管理
SpringCloudConfig提供了集中式的配置管理功能…
使得开发者,可以方便地管理所有微服务的配置信息。
通过动态更新和版本控制,它确保了配置的一致性和可维护性,降低了因配置错误导致的问题。
3、负载均衡
SpringCloud提供了多种负载均衡器(如Ribbon、SpringCloudLoadBalancer等)…
能够在服务消费者之间分配请求,确保每个服务实例,都能得到合理的负载。
这有助于,提高系统的可用性和性能,避免单点故障。
4、熔断与降级
通过集成Hystrix等组件,SpringCloud实现了熔断和降级机制。
当某个服务,出现故障或响应过慢时…
熔断器会快速失败调用,避免整个系统崩溃。
同时,降级机制,可以在服务不可用时,提供备选方案,确保系统的稳定运行。
5、服务拆分与治理
SpringCloud支持微服务的细粒度拆分,使得开发者,能够更灵活地设计系统架构。
同时,它提供了服务治理功能,如流量控制、熔断隔离等等…
帮助开发者,更好地管理和维护微服务集群。
6、生态系统丰富
SpringCloud拥有庞大的生态系统,包括许多开源项目和第三方库。
这些库,可以帮助开发者,更容易地构建各种类型的微服务,如API网关、认证中心、监控中心等。
总的来说:
SpringCloud通过提供一系列工具和组件…
简化了微服务的开发、部署和管理过程,降低了构建分布式系统的复杂性。
这使得开发者,能够更专注于,业务逻辑的实现,提高开发效率和质量。
…
七、SpringBoot与SpringCloud的关系?
1、SpringBoot简化了xml配置,快速整合框架。
2、Springcloud是一套微服务解决方案—RPC远程调用。
3、关于SpringCloud依赖与SpringBoot(web组件用的SpringMVC),为什么Springcloud会依赖与SpringBoot?
因为SpringCloud写接口就是SpringMVC接口。
4、SpringBootproperties和yml中可以使用${random}设置一些随机值。
…
下面,让我来具体说说…
SpringBoot与SpringCloud的关系可以被视为一种相辅相成、互为补充的协作关系。
具体来说,它们之间的关系主要体现在3个方面,即基础与扩展,互补与协同,依赖与独立。
1、基础与扩展
SpringBoot为开发者,提供了快速构建Spring应用程序的基础能力…
它注重于简化配置、内嵌服务器以及自动配置等特性;
使得开发者,能够更快速地启动和运行单个Spring应用程序。
而SpringCloud,则是在SpringBoot的基础上…
提供了构建分布式系统和微服务架构所需的工具和框架,它关注于全局的微服务协调整理和治理。
2、互补与协同
SpringBoot虽然能够快速构建单个微服务…
但对于微服务之间的协调、配置管理、服务发现等问题,并未提供完整的解决方案。
而SpringCloud,则通过提供一系列的功能组件…
如配置中心、服务发现、断路器、路由等,来弥补SpringBoot在这些方面的不足。
这使得开发者,能够利用SpringBoot快速构建微服务个体…
再利用SpringCloud,将这些微服务整合并管理起来,形成一个完整的微服务架构。
3、依赖与独立
虽然SpringCloud依赖于SpringBoot作为其基础…
但SpringBoot本身并不需要SpringCloud就可以独立使用。
这意味着开发者,可以根据项目的实际需求,选择只使用SpringBoot来构建简单的Spring应用程序…
或者结合使用SpringBoot和SpringCloud来构建复杂的微服务架构。
综上所述:
SpringBoot与SpringCloud之间的关系是一种基础与扩展、互补与协同的关系。
它们各自具有独特的功能和优势,但又能够相互协作…
共同为开发者提供构建高效、稳定、可扩展的分布式系统,及微服务架构的能力。
…
八、微服务是如何调用的?
微服务的调用,主要依赖于服务之间的通信机制。
具体实现方式会根据,所选择的通信协议和框架有所不同,但大致流程是相似的。
微服务调用三步走如下:
首先…
服务消费者(即发起调用的微服务)会通过某种机制获取到服务提供者(即被调用的微服务)的地址信息。
这种机制可以是服务注册与发现中心…
如Eureka、Consul或Nacos等;
也可以是静态配置,如直接在配置文件中指定服务地址。
获取到服务地址后,服务消费者,会根据选定的通信协议和框架来构建请求。
常见的通信协议包括HTTP、gRPC、Thrift等,而框架则可能是SpringCloud、Dubbo等。
例如,如果使用HTTP协议和SpringCloud框架,服务消费者可能会使用RestTemplate或WebClient来构建HTTP请求。
接下来…
服务消费者,会发送请求到服务提供者。
这个过程可能涉及到网络传输、序列化与反序列化等步骤。
网络传输,负责将请求,从服务消费者发送到服务提供者…
而序列化与反序列化,则负责将请求对象,转换为可以在网络上传输的格式,并在接收端,恢复为原始对象。
服务提供者收到请求后,会进行相应的业务处理,并返回结果给服务消费者。
这个过程,同样涉及到网络传输、序列化与反序列化等步骤。
最后…
服务消费者,接收到服务提供者返回的结果,根据需要进行相应的处理。
这样,一个完整的微服务调用过程,就完成了。
在整个过程中,为了确保调用的可靠性和稳定性,可能还会涉及到一些额外的机制…
如超时处理、重试机制、熔断器等等。
这些机制可以在网络故障、服务不可用等情况下,提供一定的容错能力,保证系统的稳定性和可用性。
总的来说:
微服务的调用,是一个涉及到服务发现、通信协议、网络传输、序列化与反序列化等多个步骤的复杂过程。
在设计和实现微服务调用时,我们需要根据具体的业务需求和技术选型,来进行综合考虑和权衡。
…
九、微服务调用的原理?
微服务调用的原理,其实主要基于分布式系统的设计理念。
简单来说,每个微服务都是一个独立的、可独立部署的服务,它们之间通过轻量级的通信机制进行交互。
一、首先…
微服务之间需要有一种机制,来发现彼此的位置。
这通常通过服务注册与发现机制来实现的。
例如使用服务注册中心,如Consul、Eureka或Nacos等等。
服务提供方,会将自己的地址,注册到注册中心…
服务调用方,则通过注册中心,查找需要调用的服务的地址。
二、其次…
在微服务调用时,为了实现高可用性和水平扩展,通常会使用负载均衡技术。
负载均衡器,可以将请求分发到多个服务实例上,从而均衡负载,提高系统的吞吐量和稳定性。
在实际调用过程中,微服务之间通常通过HTTP、RPC或消息队列等轻量级通信协议进行通信。
这种通信方式,保证了服务之间的松耦合,使得服务可以独立地升级和扩展,而不会影响到其他服务。
三、此外…
为了保证数据的独立性和隔离性,每个微服务,通常会有自己的独立数据库或数据存储。
这样,当某个服务的数据结构或存储方式需要变更时…
只需要修改该服务即可,不会影响到其他服务。
四、最后…
自动化部署和运维也是微服务调用的重要一环。
通过容器化技术(如Docker)和自动化工具(如Kubernetes)…
可以实现微服务的快速部署和管理,提高了开发和运维的效率。
总的来说:
微服务调用的原理,就是通过服务注册与发现、负载均衡、轻量级通信、独立数据库以及自动化部署和运维等技术手段…
实现各个微服务之间的解耦、独立部署和扩展,从而构建出高效、稳定、灵活的分布式系统。
…
十、微服务如何实现负载均衡?
微服务实现负载均衡的方式是多种多样的,这主要取决于具体的业务场景和技术选型。
常见负载均衡实现方式有4种,即通过硬件负载均衡器实现,使用软件负载均衡器实现,基于服务注册与发现机制的负载均衡实现,通过容器编排工具实现。
下面,让我来具体说说…
一、通过硬件负载均衡器实现
硬件负载均衡器通常位于网络的前端,接收来自客户端的请求…
然后根据预设的策略,将请求分发到不同的微服务实例上。
这种方式,具有较高的性能和稳定性,但需要额外的硬件设备投入。
二、使用软件负载均衡器实现
软件负载均衡器,通常集成在微服务框架或中间件中,如Nginx、HAProxy等。
这些软件,可以通过配置,实现请求的分发和路由,支持更灵活的负载均衡策略。
三、基于服务注册与发现机制的负载均衡实现
这也是常见的实现方式。
服务提供者,将自己的地址注册到注册中心…
服务消费者,通过注册中心获取服务提供者的地址列表;
然后根据负载均衡策略,选择一个进行调用。
这种方式可以实现服务的动态发现和调用,对服务的扩展和容错处理具有较好的支持。
在具体实现上,负载均衡策略也是多种多样的。
常见的策略包括轮询、随机、最少连接数等。
1、轮询策略,将请求依次分发给各个服务实例;
2、随机策略,则随机选择一个服务实例进行调用;
3、最少连接数策略,则根据服务实例当前的连接数进行选择,以实现负载均衡。
四、通过容器编排工具实现
随着容器化技术的发展,容器编排工具如Kubernetes,也提供了强大的负载均衡能力。
通过Kubernetes的Service资源,可以方便地实现微服务的自动发现和负载均衡。
总的来说:
微服务实现负载均衡的方式是多种多样的…
我们需要根据具体的业务场景和技术选型进行选择和配置。
同时,负载均衡策略的选择,也需要根据实际需求和系统特性进行权衡和调整,以达到最佳的负载均衡效果。
…
十一、配置详解?
1、eureka.client.register-with-eureka:
是否向注册中心注册自己,注册为true反之为false。
2、eureka.client.fetch-registry:
是否需要去检索服务,检索为true反之为false。
3、eureka.client.serviceUrl.defaultZone:
指定服务注册中心的地址。
...
十二、Eureka?
1、Eureka可分为三个角色:
服务发现者、服务注册者、注册发现中心。
但是这三个角色,并不和实际部署的模型,是一对一的关系。
2、所有的网络通信,都是基于http(s)协议的。
3、Eureka和AWS是紧密结合的,无论是配置还是源码...
比如Region、zone…...
Region可以通过配置文件进行配置,如果不配置默认使用us-east-1。
同样Zone也可以配置,若不配置默认使用defaultZone。
...
十三、Eureka的高可用配置?
EurekaServer的高可用,实际上就是将自己作为服务向其它服务注册中心注册自己。
这样就可以形成一组互相注册的服务注册中心...
以实现服务清单的互相同步,达到高可用效果。
...
十四、谈谈微服务?
以前所有的代码,都放在同一个工程中,部署在同一个服务器,这就造成了同一项目的不同模块、不同功能互相抢占资源...
微服务,就是将工程根据不同的业务规则,拆分成微服务,部署在不同的服务器上,实现服务之间相互调用。
实现Java微服务的有Dubbo(只能用来做微服务)...
SpringCloud(提供了服务的发现、断路器等)。
微服务的7个特点:
1、按业务划分为一个独立运行的程序,即服务单元;
2、服务之间通过HTTP协议相互通信;
3、自动化部署;
4、可以用不同的编程语言;
5、可以用不同的存储技术;
6、服务集中化管理;
7、微服务是一个分布式系统。
微服务的6点优势:
1、将一个复杂的业务拆分为若干小的业务,将复杂的业务简单化。
新人只需要了解它所接管的服务的代码,这就减少了新人的学习成本。
2、由于微服务是分布式服务,服务于服务之间没有任何耦合。
微服务系统的微服务单元,具有很强的横向拓展能力。
3、服务与服务之间,采用HTTP网络通信协议来通信...
单个服务内部高度耦合,服务与服务之间完全独立,无耦合。
这使得微服务,可以采用任何的开发语言和技术来实现,提高开发效率、降低开发成本。
4、微服务是按照业务进行拆分的,并有坚实的服务边界...
若要重写某一业务代码,不需了解所以业务,重写简单。
5、微服务的每个服务单元是独立部署的...
即独立运行在某个进程中,微服务的修改和部署,对其它服务没有影响。
6、微服务在CAP理论中,采用的AP架构,具有高可用分区容错特点。
高可用主要体现在系统7x24不间断服务...
它要求系统有大量的服务器集群,从而提高系统的负载能力。
分区容错也使得系统更加健壮。
微服务的4点不足:
1、微服务的复杂度
构建一个微服务比较复杂,服务与服务之间,通过HTTP协议或其它消息传递机制通信。
开发者要选出最佳的通信机制,并解决网络服务差时,带来的风险。
2、分布式事物
将事物分成多阶段提交,如果一阶段某一节点失败,仍会导致数据不正确。
如果事物涉及的节点很多,某一节点的网络出现异常...
会导致整个事务处于阻塞状态,大大降低数据库的性能。
3、服务划分
将一个完整的系统,拆分成很多个服务,是一件非常困难的事...
因为这涉及了具体的业务场景。
4、服务部署
最佳部署容器Docker。
...
十五、微服务和SOA的关系?
微服务相对于和ESB联系在一起的SOA,轻便敏捷得多...
微服务,将复杂的业务组件化,也是一种面向服务思想的体现。
对于微服务来说,它是SOA的一种体现,但是它比ESB实现的SOA,更加轻便、敏捷和简单。
...
十六、SpringCoud是如何实现服务注册与发现的?
服务发布时,指定对应的服务名(IP地址和端口号),将服务注册到注册中心(eureka和zookeeper)...
但是这一切是SpringCloud自动实现的;
只需要在SpringBoot的启动类上,加上@EnableDisscoveryClient注解。
同一服务修改端口,就可以启动多个实例调用方法:
传递服务名称,通过注册中心获取所有的可用实例...
通过负载均衡策略(Ribbon和Feign)调用对应的服务。
...
十七、Ribbon和Feign的区别?
两者有3点具体区别,即启动类使用的注解不同,服务的指定位置不同,调用方式不同。
Ribbon添加的maven依赖是spring-starter-ribbon。
使用@RibbonClient(value=“服务名称”),使用RestTemplate调用远程服务对应的方法。
Feign添加的maven依赖是spring-starter-feign...
服务提供方提供对外接口,调用方使用,在接口上使用FeignClient(“指定服务名”)。
3点具体区别:
1、启动类使用的注解不同
Ribbon使用的是@RibbonClient,Feign使用的是@EnableFeignClients。
2、服务的指定位置不同
Ribbon是在@RibbonClient注解上声明。
Feign则是在定义抽象方法的接口中使用@FeignClient声明。
3、调用方式不同
Ribbon需要自己构建http请求,模拟http请求...
然后使用RestTemplate发送给其它服务,步骤比较繁琐。
而Feign,则是在Ribbon的基础上进行了一次改进,采用接口调用的方式...
将需要调用的其它服务的方法,定义成抽象方法即可...
不需要自己构建http请求。
不过要注意的是,抽象方法的注解、方法签名,要和提供方的完全一致。
...
十八、雪崩效应?
分布式系统中的服务通信,依赖于网络...
网络不好,必然会对分布式系统带来很大的影响。
在分布式系统中,服务之间相互依赖,即...
如果一个服务之间出现了故障或者网络延迟,在高并发的情况下...
会导致线程阻塞,在很短的时间内,该服务的线程资源会消耗殆尽,最终使得该服务不可用。
由于服务的相互依赖,可能会导致整个系统的不可用,这就是“雪崩效应”。
为了防止此类事件的发生,分布式系统必然要采取相应的措施,如熔断机制(SpringCloud采用的是Hystrix)。
...
十九、熔断机制?
1、服务故障则开启熔断器
当一个服务出现故障时,请求失败次数超过设定的阀值(默认50)之后...
该服务就会开启熔断器,之后该服务就不进行任何业务逻辑操作,执行快速失败,直接返回请求失败的信息。
其它依赖于该服务的服务,就不会因为得不到响应而造成线程阻塞。
这是除了该服务,以及依赖于该服务的部分功能不可用外,其它功能正常。
2、熔断器的自我修复机制
当一个服务熔断后,经过一段时间(5s)半打开熔断器。
半打开的熔断器,会检查一部分请求(只能有一个请求)是否正常...
其它请求执行快速失败;
检查的请求如果响应成功,则可判断该服务正常了,就可关闭该服务的熔断器,反之则继续打开熔断器。
这种自我熔断机制和自我修复机制...
可以使程序更加健壮,也可以为开发和运维,减少很多不必要的工作。
3、熔断组件提供监控
熔断组件往往会提供一系列的监控...
比如服务可用与否、熔断器是否被打开、目前的吞吐量、网络延迟状态的监控等等。
从而,可以让开发人员和运维人员去了解服务的状况。
...
二十、Eureka的基础架构?
Eureka的基础架构的组成部分是...
1、服务注册中心(失效剔除、自我保护);
2、服务提供者(服务注册、服务同步、服务续约);
3、服务消费者(获取服务、服务调用、服务下线)。
...
下面,就来说下具体内容吧!
1、服务注册中心
Eureka提供的服务端,提供服务注册与发现的功能。
1.1、失效剔除
对于那些非正常下线的服务实例(内存溢出、网络故障导致的)...
服务注册中心,不能收到“服务下线”的请求,为了将这些无法提供服务的实例从服务列表中剔除...
EurekaServer在启动的时候,会创建一个定时任务...
默认每隔一段时间(默认60s),将当前清单中超时(默认90s)没有续约的服务,剔除出去。
1.2、自我保护
EurekaServer在运行期间,会统计心跳失败的比例,在15分钟之内是否低于85%...
如果出现低于的情况(生产环境由于网络不稳定会导致)...
EurekaServer会将当前的实例注册信息保护起来,让这些实例不过期,尽可能保护这些注册信息。
但是在这保护期间内,实例出现问题...
那么客户端,就很容易拿到实际上已经不存在的服务实例,会出现调用失败的情况。
所以客户端必须有容错机制,比如可以使用请求重试、断路器等机制。
在本地进行开发时,可以使用eureka.server.enable-self-preseervation=false参数...
来关闭保护机制,以确保注册中心,可以将不可用的实例剔除。
2、服务提供者
提供服务的应用,可以是SpringBoot应用,也可以是其它的技术平台,且遵循Eureka通信机制的应用。
它将自己提供的服务,注册到Eureka,以供其它应用发现(如service层)。
2.1、服务注册
服务提供者,在启动的时候,会通过发送Rest请求的方式...
将自己注册到EurekaServer(服务注册中心)中,同时带上自身服务的一些元数据;
EurekaServer接收到这个Rest请求后,将元数据存储在一个双层结构Map中;
第一层的key是服务名,第二层key是具体服务的实例名。
2.2、服务同步
若有两个或两个以上的EurekaServer(服务注册中心)时...
它们之间是互相注册的。
当服务提供者,发送注册请求到一个服务注册中心时...
它会将该请求,转发到集群中相连的其它注册中心;
从而实现,注册中心间的服务同步,这样服务提供者的服务信息,可以通过任意一台服务中心获取到。
2.3、服务续约
在注册完服务之后,服务提供者会维护一个心跳,来持续告诉EurekaServer:“我还活着”...
以防止EurekaServer的“剔除任务”将该服务实例,从服务列表中排除出去。
配置:eureka.instance.lease-renewal-in-seconds=30(续约任务的调用间隔时间,默认30秒,也就是每隔30秒向服务端发送一次心跳,证明自己依然存活)。
eureka.instance.lease-expiration-duration-in-seconds=90(服务失效时间,默认90秒,也就是告诉服务端,如果90秒之内没有给你发送心跳就证明我“死”了,将我剔除)。
3、服务消费者
消费者应用,从服务注册中心获取服务列表...
从而使消费者,可以知道去何处调用其所需要的服务。
比如Ribbon实现消费方式,Feign实现消费方式。
3.1、获取服务
当启动服务消费者时,它会发送一个Rest请求给注册中心...
获取上面注册的服务清单;
EurekaServer会维护一份只读的服务清单,来返回给客户端,并且每三十秒更新一次。
3.2、服务调用
在服务消费者获取到服务清单后,通过服务名...
可以获得具体提供服务的实例名和该实例的元信息,采用Ribbon实现负载均衡。
3.3、服务下线
当服务实例,进行正常的关闭操作时...
它会触发一个服务下线的Rest请求,给EurekaServer,告诉服务注册中心“我要下线了”。
服务端接收到请求之后,将该服务状态设置为下线,并把下线时间传播出去。
...
二十一、Eureka和Zookeeper都可以提供服务注册与发现的功能,而两者的区别是?
简单来说,Zookeeper保证了CP(C:一致性,P:分区容错性);
Eureka保证了AP(A:高可用,P:分区容错)。
1、Zookeeper
当向注册中心查询服务列表时...
我们可以容忍,注册中心返回的是几分钟以前的信息;
但不能容忍直接down掉,不可用的。
也就是说,服务注册功能对高可用性要求比较高。
但是Zookeeper会出现这样的一种情况...
当master节点,因为网络故障与其它节点失去联系时...
剩余的节点,会重新选leader。
问题在于,选取leader的时间过长(30~120s),且选取期间Zookeeper集群都不可用...
这样就会导致,选取期间注册服务瘫痪。
在云部署的环境下,因网络问题...
使得Zookeeper集群,失去master节点,是较大概率会发生的事。
虽然服务最终恢复,但是漫长的选择时间,导致的注册长期不可用,是不能容忍的。
2、Eureka
它则看明白这一点,因此在设计上优先保证了高可用性。
Eureka各个节点都是平等的,几个节点挂掉,不会影响到正常节点的工作...
剩余的节点,依然可以提供注册和查询服务。
而Eureka的客户端,再向某个Eureka注册时...
如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在...
就能保证注册服务的可用(保证可用性),只不过查到的信息,可能不是最新的(不保证一致性)。
除此之外,Eureka还有一种自我保护机制...
如果在15分钟内,超过85%的节点都没有正常心跳...
那么Eureka,就认为客户端与注册中心出现了网络故障。
而此时,就会出现以下几种情况:
2.1、Eureka不再从注册列表移除,因为长时间没收到心跳,而应该过期的服务;
2.2、Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(保证当前节点可用);
2.3、当网络稳定时,当前实例新的注册信息,会被同步到其它节点中。
Eureka还有客户端缓存功能(Eureka分为客户端程序和服务器端程序两个部分,客户端程序负责向外提供注册与发现服务接口)。
所以,即便Eureka集群中所有节点都失效,或者发生网络分隔故障,导致客户端不能访问任何一台Eureka服务器。
Eureka服务的消费者,任然可以通过Eureka客户端缓存,来获取所有的服务注册信息。
甚至最极端的环境下,所有正常的Eureka节点,都不对请求产生响应...
也没有更好的服务器解决方案,来解决这种问题。
得益于Eureka的客户端缓存技术,消费者服务...
仍然可以通过Eureka客户端,查询与获取注册服务信息,这点很重要;
因此Eureka,可以很好的应对网络故障,导致部分节点失去联系的情况。
而不像Zookeeper那样,使整个注册服务瘫痪。
...
二十二、CAP理论?
1、Consistency
指数据的强一致性。
如果写入某个数据成功,之后读取,读到的都是新写入的数据;
如果写入失败,读到的都不是写入失败的数据。
2、Availability
指服务的可用性。
3、Partition-tolerance
指分区容错。
...
二十三、Ribbon和Nginx的区别?
1、Nginx性能好,但Ribbon可以剔除不健康节点,Nginx剔除比较麻烦。
2、Ribbon是客户端负载均衡,Nginx是服务端负载均衡。
...
二十四、服务注册与发现?
服务注册,就是向服务注册中心,注册一个服务实例...
服务提供者将自己的服务信息(服务名、IP地址等)告知注册中心。
服务发现,是服务消费另一个服务时,注册中心将服务的实例,返回给服务消费者...
一个服务,既是服务提供者又是服务消费者。
服务注册中心健康检查机制...
当一个服务实例注册成功以后,会定时向注册中心,发送一个心跳证明自己可用;
若停止发送心跳,证明服务不可用将会别剔除;
若过段时间继续向注册中心提供心跳,将会重新加入服务注册中心列表中。
...
二十五、微服务的负载均衡,为何用?怎么用?
1、为什么要用?
微服务是将业务代码拆分为很多小的服务单元...
服务之间的相互调用通过HTTP协议来调用,为了保证服务的高可用,服务单元往往都是集群化部署的。
2、消费者该调用,哪个服务提供者的实例呢?
服务消费者集成负载均衡组件,该组件会向服务消费者...
获取服务注册列表信息,并隔一段时间重新刷新获取列表。
当服务消费者消费服务时,负载均衡组件,获取服务提供者所有实例的注册信息...
并通过一定的负载均衡策略(可以自己配置)选择一个服务提供者实例;
向该实例进行服务消费,这样就实现了负载均衡。
……
以上,就是今天的分享啦!
希望,对你的求职面试,编程工作有那么一点点、一丢丢、一戳戳地帮助哈~
喜欢我分享的,就一键三连于我,可好?!
7天掌握《Java编程与面试2024》的核心三章59问,即Java基础面试题篇19问,Nginx使用篇15问,微服务配置篇25问。
下面,先来介绍一下,以上三个篇章各自的核心问题:
1、Java语言,有哪些特点?
2、char类型变量,是否能保存一个汉字?
3、==和equals的区别?
4、final、finally、finalize的区别?
5、一个.java源文件中,是否可以包含多个类(不是内部类)呢?又有什么限制呢?
6、&与&&的区别?
7、JAVA中的保留字,都有什么?
8、Collection和Collections的区别?
9、如何去掉Vector集合中的重复元素?
10、ArrayList和Vector的区别?
11、HashMap和Hashtable的区别?
12、说说ArrayList,Vector,LinkedList三者的存储性能和特性?
13、HashMap与TreeMap的区别?
14、List、Map、Set三个接口,在存储元素时,各有什么特点?
15、在Java中,List是个接口,那实现List接口的类有哪些,它们又有什么区别?
16、判断下列语句是否正确,如果有错误,请指出错误所在?
17、A=10,B=20使得两值互换?
18、只移动一个数字,使62-63=1成立(不能移动符号)?
19、字符串面试的经典源码示例?
...
1、请解释一下,什么是Nginx?
2、为什么要用Nginx?
3、Nginx的优缺点?
4、Nginx应用场景?
5、使用“反向代理服务器”的优点是什么?
6、请列举Nginx服务器的最佳用途?
7、请解释下,Nginx是如何处理HTTP请求的?
8、在Nginx中,如何使用未定义的服务器名称,来阻止处理请求的?
9、在Nginx中,如何在URL中保留双斜线?
10、ngx_http_upstream_module的作用是什么?
11、fastcgi与cgi的区别?
12、Nginx常用命令?
13、Nginx常用配置?
14、请陈述stub_status和sub_filter指令的作用是什么?
15、主从Reactor多线程模型?
...
一、什么是SpringBoot?
二、SpringBoot常用的starter?
三、SpringBoot自动配置原理?
四、SpringBootstarter工作原理?
五、SpringBoot的优点?
六、SpringCloud解决了哪些问题?
七、SpringBoot与SpringCloud的关系?
八、微服务是如何调用的?
九、微服务调用的原理?
十、微服务如何实现负载均衡?
十一、配置详解?
十二、Eureka?
十三、Eureka的高可用配置?
十四、谈谈微服务?
十五、微服务和SOA的关系?
十六、SpringCoud是如何实现服务注册与发现的?
十七、Ribbon和Feign的区别?
十八、雪崩效应?
十九、熔断机制?
二十、Eureka的基础架构?
二十一、Eureka和Zookeeper都可以提供服务注册与发现的功能,而两者的区别是?
二十二、CAP理论?
二十三、Ribbon和Nginx的区别?
二十四、服务注册与发现?
二十五、微服务的负载均衡,为何用?怎么用?
......
1、Java语言,有哪些特点?
答:
简单性(Simple);
结构体系中立(ArchitectureNeutral);
面向对象(ObjectOriented);
易于移植(Portable);
分布式(Distributed);
高性能(HighPerformantce);
多线程(Multithreaded);
健壮性(Robust);
动态性(Dynamic);
安全性(Secure)。
...
2、char类型变量,是否能保存一个汉字?
答:可以。
在Java语言中,一个char类型变量占16位bit(即2个字节byte)的存储空间。
由于Java语言,使用Unicode字符集对字符进行编码...
因此,char类型变量可以存储任何字符;
这些字符,可以是英文字符、汉字、日文片断,以及其它国家的许多字符。
相关详细知识点:
在计算机中的存储单位,是以字节为单位的。
常见的磁盘大小和文件大小,分别以GB、MB、KB等来表示...
它们之间的换算单位是1GB=1024MB,1MB=1024KB,1KB=1024byte(即字节)。
每个字节的取值范围是-128到127,它可以保存一个英文字符,包括字母、数字和英文标点。
而汉字的存储,是由2个字节保存的。
因为汉字的数量太多,它的编码范围,远远超过一个字节的取值范围...
所以,必须要使用双字节来表示。在Java语言中...
使用Unicode字符集,对字符进行编码,可以存储65535个字符。
所以Java字符类型,被定义为双字节。
因此,在Java语言中,可以使用char类型变量,来存储汉字。
...
3、==和equals的区别?
答:有2点区别,即...
(1)==,是用于比较基本数据类型的值,以及比较引用数据类型,在内存中存放的地址。
(2)equals方法,在比较引用数据类型时...
如果没有覆盖Object类的equals方法,则同==一样,比较内存中的存放地址;
反之,则像String字符串等类的equals方法一样,去比较引用数据类型的内容了。
...
4、final、finally、finalize的区别?
答:
final,用于声明属性,方法和类...
分别表示属性不可变,方法不可覆盖,类不可继承。
\tfinally,是异常处理语句结构的一部分,表示总是执行。
finalize,是Object类的一个方法...
在垃圾收集器执行的时候,会调用被回收对象的此方法;
可以覆盖此方法,以提供垃圾收集时的其它资源回收,例如关闭文件等。
...
5、一个.java源文件中,是否可以包含多个类(不是内部类)呢?又有什么限制呢?
答:可以包含多个类。
但,只能有一个public类,且public的类名,必须与文件名一致。
...
6、&与&&的区别?
答:主要有点区别,即...
(1)&和&&都可以用作逻辑与(and)运算;
(2)&&还具有短路的功能;
(3)&还可以按位运算。
下面,详细说明下以上3点区别:
(1)&和&&用作逻辑与运算符
&和&&,都可以用作逻辑与的运算符,表示逻辑与(and)。
当运算符,两边表达式的结果,都为true时...
整个运算结果才为true;
否则,只要有一方为false,则结果为false。
(2)&&有短路功能
&&除了可作逻辑与运算符外,还具有短路的功能...
即如果第一个表达式为false,则不再计算第二个表达式。
例如,对于if(str!=null&&!str.equals(“”))表达式...
当str为null时,后面的表达式不会执行;
所以不会出现NullPointerException空指针异常。
而如果将&&改为&,此时则会抛出NullPointerException异常了。
在If(x==33&++y>0)中,y会增长;
而在If(x==33&&++y>0)中,则不会增长。
(3)&用作位运算符
&还可以用作位运算符。
当&操作符两边的表达式,不是boolean类型时...
&表示“按位与”操作。
我们通常使用0x0f,来与一个整数进行&运算...
来获取该整数的最低4个bit位。
例如,“0x31&0x0f”的结果为“0x01”。
...
7、JAVA中的保留字,都有什么?
答:goto,const。
关键字Keyword:
Java的关键字,对Java的编译器有特殊的意义...
它们用来表示一种数据类型,或者表示程序的结构等。
保留字Reservedword:
保留字,是为java预留的关键字。
它们虽然现在没有作为关键字,但在以后的升级版本中,有可能作为关键字。
...
8、Collection和Collections的区别?
答:主要2点区别,即...
(1)Collection是集合类的上级接口,继承于它的主要接口有List和Set;
(2)Collections是针对集合类的一个帮助类...
它提供了,一系列静态方法,以实现对各集合的搜索、排序、线程安全化等操作。
...
9、如何去掉Vector集合中的重复元素?
答:有两种方式可以去掉Vector集合中的重复元素。
下面,我来具体说说这两种方式...
方式一:
VectornewVector=newVector;
for(inti=0;i
Objectobj=vector.get(i);
if(!ntains(obj)){
newVector.add(obj);
}
}
方式二:
HashSetset=newHashSet(vector);
因为,HashSet集合中允许存在重复元素。
...
10、ArrayList和Vector的区别?
答:两者的同步性和数据增长不同。
一、同步性不同
Vector是线程安全的,也就是同步的。
而ArrayList,则是线程不安全的,不是同步。
二、数据增长不同
当需要增长时,Vector默认增长为原来的一倍。
而ArrayList,却是原来的一半。
...
11、HashMap和Hashtable的区别?
答:两者主要有三点区别,即...
一、历史来源不同
Hashtable,是基于陈旧的Dictionary类的。
而HashMap,则是Java1.2引进的Map接口的一个实现类。
二、同步性不同
Hashtable是线程安全的,也就是同步的。
而HashMap,不是线程安全的,不是同步的。
三、是否允许“空值”不同
只有HashMap,可以让你将一个空值,作为一个表条目的key或value。
...
12、说说ArrayList,Vector,LinkedList三者的存储性能和特性?
答:
ArrayList和Vector,都是使用数组方式存储数据...
此数组元素数,大于实际存储的数据,以便增加和插入元素。
它们都允许,直接按序号索引元素...
但插入元素,要涉及数组元素移动等内存操作;
所以,索引数据快,而插入数据慢。
Vector,由于使用了synchronized方法(线程安全)...
通常在性能上,较ArrayList差。
而LinkedList,是使用双向链表实现存储的...
按序号索引数据,需要进行前向或后向遍历;
但插入数据时,只需要记录本项的前后项即可,所以插入速度较快。
...
13、HashMap与TreeMap的区别?
答:
HashMap是通过hashcode,对其内容进行快速查找的。
而TreeMap中所有的元素,都保持着某种固定的顺序。
所以,如果你需要得到一个有序的结果...
那么,你就应该使用TreeMap。
因为,HashMap中元素的排列顺序,是不固定的。
...
14、List、Map、Set三个接口,在存储元素时,各有什么特点?
答:
1)List是有序的Collection…
使用此接口,能够精确的控制每个元素插入的位置。
用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素…
这类似于Java的数组。
2)Set是一种不包含重复的元素的Collection…
即任意的两个元素e1和e2都有e1.equals(e2)=false。
此外,Set最多有一个null元素。
3)Map接口…
请注意,Map没有继承Collection接口。
Map是提供了key到value的映射。
…
下面,让我来具体说说…
List、Map、Set,是Java中常用的三种集合接口。
它们在存储元素时,各自具有不同的特点:
1)List接口
具有5个特点,即有序性,可重复性,可变性,元素类型,操作方法。
有序性:
List集合中的元素,按照插入顺序进行存储…
可以通过索引,去访问和操作集合中的元素。
可重复性:
List集合中,允许存储重复的元素…
即同一个元素可以多次出现在集合中。
可变性:
List集合中的元素,可以随时增加、删除和修改,集合的大小可以动态改变。
元素类型:
在List集合中,可以存储任意类型的元素…
包括基本数据类型和引用类型。
操作方法:
List集合,提供了丰富的方法,来操作集合中的元素…
比如添加、删除、获取元素,查找元素等。
2)Map接口
具有5个特点,即键值对存储,键的唯一性,值的可重复性,键和值的类型,单向一对一关系。
键值对存储:
Map用于保存具有映射关系的数据…
即Key-Value对(双列元素)。
键的唯一性:
Map中的key不允许重复,每个key都唯一对应一个value。
值的可重复性:
Map中的value可以重复,即多个key可以对应相同的value。
键和值的类型:
Map中的key和value,可以是任何引用类型的数据。
单向一对一关系:
Map中key和value之间,存在单向一对一关系…
即通过指定的key,总能找到对应的value。
3)Set接口
具有5个特点,即无序性,元素的互异性,空集性质,元素类型,测试归属性。
无序性:
Set集合中的元素位置无顺序,元素之间是无序的。
元素的互异性:
Set集合不允许出现重复元素,每个元素只能出现一次。
空集性质:
空集是一切集合的子集,Set也可以表示空集。
元素类型:
Set集合中可以存储任意类型的元素。
测试归属性:
Set最常被用于测试归属性…
可以很容易地查询某个对象,是否在某个Set中。
综上所述:
List、Map、Set三种接口,在存储元素时的主要区别…
在于元素的顺序性、重复性、以及存储结构(List是有序列表,Map是键值对映射,Set是无序集合)。
所以,在实际使用中,我们可以根据需求…
去选择合适的集合类型,来存储和处理数据。
…
15、在Java中,List是个接口,那实现List接口的类有哪些,它们又有什么区别?
答:
在Java中,List确实是一个接口…
它属于Java的集合框架(JavaCollectionsFramework)。
List接口定义了一些基本的操作,比如添加、删除元素等。
有很多类实现了List接口,诸如ArrayList、LinkedList、Vector等等。
这些实现类之间的主要区别,在于三者的内部实现机制和性能特性:
1)ArrayLis
ArrayList内部基于数组实现…
因此它提供了,对元素的随机访问(即通过索引访问)的高效性。
当添加或删除元素时…
如果列表的大小,超过了其内部数组的大小,ArrayList会自动扩容;
这可能会涉及到数组元素的复制;
因此,在大量添加或删除元素时,可能会产生较高的开销。
在大部分情况下,ArrayList是List接口的首选实现…
特别是,当你需要频繁地,访问列表中的元素时。
2)LinkedLis
LinkedList内部基于链表实现…
因此它提供了,在列表开头和结尾,添加或删除元素的高效性。
对于随机访问元素…
LinkedList的性能较差,因为它需要从列表的一端开始遍历。
因此,如果你需要…
频繁地在列表的开头或结尾,添加或删除元素的话…
那么LinkedList,可能是一个更好的选择。
3)Vector
Vector和ArrayList类似…
也是基于数组实现的,但它提供了线程安全的操作。
这是通过在每个公共方法上,添加同步来实现的…
因此,它可能会比ArrayList慢。
在现代Java编程中,我们通常更倾向于使用并发集合(如ConcurrentHashMap)…
或者,显式地同步代码块;
而不是使用Vector,因为同步的开销可能会比较大。
此外…
还有其它一些类,也实现了List接口,例如CopyOnWriteArrayList…
它适用于读多写少的并发场景。
至于选择哪个实现类,则取决于你的具体需求,比如访问模式、线程安全性、性能要求等。
…
16、判断下列语句是否正确,如果有错误,请指出错误所在?
List
a.add(5);
答:正确。
在Java中,你可以创建一个ArrayList,它存储的元素类型是Short。
Short是Java的一个包装类,用于表示基本数据类型short的值。
当你调用“a.add(5);”时…
Java会自动将基本数据类型“int的5”,转换成包装类型Short。
因为,5在short的范围内(即-32768到32767)。
所以,可以安全地转换为Short。
因此,这段代码会成功地向ArrayList中…
添加一个Short类型的对象,其值为5。
这是自动装箱(autoboxing)的一个例子…
它是Java5及以上版本,提供的一个特性;
允许在基本数据类型,和它们对应的包装类之间,进行自动转换。
…
17、A=10,B=20使得两值互换?
答:
1)中间变量:C=A;A=B;B=C
2)A=A-B;B=B+A;A=B-A
…
18、只移动一个数字,使62-63=1成立(不能移动符号)?
答:2的6次方-63=1。
注意:要从“移动一个数字”的思维中抽离出来,考虑次方实现。
…
19、字符串面试的经典源码示例?
答:具体代码示例如下…
packagecom.exam.prj.action.String;
/**
*@authorAARON
*/
publicclassStringTest{
\tpublicstaticvoidmain(String[]args){
\t\t//
\t\t//判断生成几个对象
\t\t//\t\
\t\t//生成2个对象.StringPool中生成一个对象“aaron”,Heap中生成一个对象“aaron”
\t\tStringstrA=newString(“aaron“);\t\
\t\t//未生成新对象.判断StringPool中是否存在“aaron”,存在则strB直接引用“aaron”对象
\t\tStringstrB=“aaron“;
\t\
\t\t//生成1个对象.在Heap中生成一个对象“aaron”
\t\tStringstrC=newString(“aaron“);
\t\
\t\tSystem.out.println(strA==strB);\t//\tfalse
\t\tSystem.out.println(strA==strC);\t//\tfalse
\t\tSystem.out.println(strB==strC);\t//\tfalse
\t\t//intern返回在StringPool中存在的地址
\t\tSystem.out.println(strA==strA.intern);\t//\tfalse
\t\tSystem.out.println(strB==strB.intern);\t//\ttrue
\t\tSystem.out.println(strA.intern==strC.intern);\t//\ttrue
\t\t//
\t\t//判断字符串变量的内存地址是否相等
\t\t//
\t\
\t\tStringaaron=“aaron“;
\t\tStringaa=“aa“;
\t\tStringron=“ron“;
\t\
\t\t//“aa“+“ron“,这是两个字符串常量相加,拼接结果为“aaron”,然后到StringPool中判断获得内存地址
\t\tSystem.out.println(aaron==“aa“+“ron“);//true
\t\
\t\t//“aa“+ron,这是字符串常量和变量相加,拼接结果为“aaron”,然后在Heap中创建一个“aaron”对象
\t\tSystem.out.println(aaron==“aa“+ron);//false
\t}
}
......
1、请解释一下,什么是Nginx?
Nginx,是一个Web服务器和反向代理服务器,用于HTTP、HTTPS、SMTP、POP3和IMAP协议。
目前是被使用最多的Web服务器,代理服务器...
像淘宝、新浪、网易、迅雷等,都在使用。
Nginx的主要功能如下:
(1)作为httpserver(代替Apache
对PHP需要FastCGI处理器支持)。
(2)FastCGI
Nginx本身不支持PHP等语言...
但是它,可以通过FastCGI来将请求,扔给某些语言或框架处理。
(3)反向代理服务器
(4)实现负载均衡
(5)虚拟主机
...
2、为什么要用Nginx?
因为Nginx具有:
跨平台,配置简单,反向代理,缓存服务,邮件代理服务器...
高并发连接数,内存消耗小,拥有健康检查功能...
节省宽带,稳定性高,接受请求异步等优秀的特性。
下面,就让我来具体说说Nginx的一些优秀特点吧!
高并发连接数:
Nginx处理2-3万并发连接数,官方监测能支持5万并发。
内存消耗小:
开启10个nginx,才占150M内存;
Nginx处理静态文件效果好,耗费内存少。
健康检查功能:
Nginx内置了健康检查功能;
当有一个服务器宕机时,就会做一个健康检查...
之后再发送的请求,就不会发送到宕机的服务器了;
而是,重新将请求,提交到其它的节点上。
节省宽带:
支持GZIP压缩,可以添加浏览器本地缓存。
稳定性高:
宕机的概率非常小。
接受请求异步:
即接收的用户请求,是异步的。
...
3、Nginx的优缺点?
优点:
占内存小,可实现高并发连接,处理响应快…
可实现http服务器、虚拟主机、方向代理、负载均衡。
Nginx的配置简单,还可以不暴露正式的服务器IP地址。
缺点:
动态处理差。
Nginx处理静态文件好,耗费内存少…
但是处理动态页面则很鸡肋,因为现在一般前端用Nginx作为反向代理抗住压力。
…
4、Nginx应用场景?
1)http服务器
Nginx是一个http服务,可以独立提供http服务。
可以做网页静态服务器。
2)虚拟主机
它可以实现,在一台服务器虚拟出多个网站,例如个人网站使用的虚拟机。
3)反向代理与负载均衡
当网站的访问量,达到一定程度后,单台服务器不能满足用户的请求时…
就需要用多台服务器集群,可以使用Nginx做反向代理。
并且多台服务器,可以平均分担负载…
不会因为某台服务器负载高而宕机。
4)Nginx中也可以配置安全管理
比如可以使用Nginx搭建API接口网关,对每个接口服务进行拦截。
…
5、使用“反向代理服务器”的优点是什么?
反向代理服务器,可以隐藏源服务器的存在和特征。
它充当互联网云和web服务器之间的中间层。
这对于安全方面来说是很好的,特别是当您使用web托管服务时。
…
6、请列举Nginx服务器的最佳用途?
Nginx服务器,是一种高性能的HTTP和反向代理服务器…
它具有丰富的功能和广泛的应用场景。
Nginx服务器的7个最佳用途…
即静态HTTP服务器,负载均衡,虚拟主机,邮件代理服务器,性能优化,安全性,高并发与高稳定性。
1)静态HTTP服务器
Nginx可以将服务器上的静态文件(如HTML、图片、CSS、JavaScript等)…
通过HTTP协议,高效地展现给客户端。
2)负载均衡
当网站访问量非常大时,可以将同一个应用部署在多台服务器上。
Nginx通过反向代理的方式,实现负载均衡…
将大量用户的请求,分配给多台机器处理。
这不仅可以提高网站的响应速度,还增强了系统的可用性和可靠性。
在负载均衡过程中,Nginx可以灵活配置各种负载均衡算法,来满足不同的业务需求。
3)虚拟主机
对于访问量较小的网站…
Nginx支持在同一台服务器上,部署多个网站,从而通过虚拟主机的方式,来节省成本。
4)邮件代理服务器
Nginx也是一个非常优秀的邮件代理服务器…
可以处理邮件相关的任务,如SMTP、POP3和IMAP等。
5)性能优化
Nginx提供了多种性能优化策略,如启用缓存、压缩响应、启用TCP缓冲、启用HTTP2等。
这些策略,可以显著提高网站的性能,减少网络传输数据量,加快页面响应速度。
6)安全性
尽管Nginx本身具有一些安全漏洞,但通过合理配置和更新,可以大大提高网站的安全性。
例如…
可以限制缓存文件的大小和时间,设置验证规则以验证数据是否被篡改,从而加强缓存安全。
7)高并发与高稳定性
Nginx以高速、高并发、高稳定性著称。
其内部的事件驱动架构,以及采用异步非阻塞方式,去处理客户端请求的特点…
使得在高并发请求下,Nginx依然能够保持稳定性。
这使得Nginx,成为了处理大量并发连接的理想选择…
尤其适用于,大型高负载的Web应用程序、云计算、物联网等领域。
总的来说:
Nginx服务器在Web服务、负载均衡、性能优化、安全性和稳定性等方面都有出色的表现。
Nginx是构建高效、可靠和安全的网络应用的理想选择。
然而,具体的最佳用途,可能因应用场景和需求的不同而有所差异。
因此在实际使用中,我们需要根据具体情况,去进行配置和优化。
…
7、请解释下,Nginx是如何处理HTTP请求的?
因为Nginx使用了“反应器模式”。
主事件循环,等待操作系统发出准备事件的信号…
这样数据就可以从套接字读取,在该实例中读取到缓冲区并进行处理。
且单个线程可以提供数万个并发连接。
下面,让我来具体说说…
实际上,Nginx处理HTTP请求的过程…
是一个复杂而高效的操作,它涉及到多个阶段和模块。
Nginx处理HTTP请求的“六部曲”,即…
接收请求,解析请求,访问URI,反向代理和负载均衡,处理动态请求,记录日志。
1)接收请求
Nginx使用监听器,来接收客户端发送的HTTP请求。
监听器会绑定到一个特定的端口上,并等待客户端的连接请求。
一旦有新的连接到达,监听器会创建一个连接对象…
并将这个连接对象,放入连接池中等待处理。
2)解析请求
当Nginx从连接池中,取出一个连接对象时…
它会开始读取,该连接对象中的请求数据。
这个过程包括解析请求行、请求头和请求体。
请求行,包含了HTTP方法(如GET、POST等)、请求的URI以及HTTP协议的版本信息。
请求头,则包含了客户端发送的各种元数据和请求参数。
请求体,通常用于POST请求,包含了客户端提交的数据。
3)访问URI
解析完请求后,Nginx会根据请求的URI,来决定如何处理这个请求。
如果请求的URI,对应的是静态文件…
Nginx会直接从文件系统中读取这个文件,并将其作为响应返回给客户端。
如果请求的URI,对应的是动态内容…
Nginx则需要将请求,转发给后端服务器进行处理。
4)反向代理和负载均衡
如果请求需要由后端服务器处理…
Nginx会作为反向代理服务器,将请求转发给后端服务器。
在这个过程中,Nginx还可以使用负载均衡算法…
将请求分发到多个后端服务器上;
以充分利用这些服务器的资源,提高系统的吞吐量和可靠性。
5)处理动态请求
对于需要动态生成内容的请求…
Nginx会将请求转发给后端服务器(如PHP、Python、Java等应用服务器)来处理。
后端服务器,会根据请求的内容,生成相应的响应,然后将响应返回给Nginx。
Nginx再将这个响应,封装成一个HTTP响应对象,发送给客户端。
6)记录日志
在处理完请求后,Nginx会记录相关的访问日志和错误日志。
这些日志,可以帮助管理员了解服务器的运行状态,以及分析和优化性能。
在整个处理过程中,Nginx使用了“事件驱动的模型”来同时处理多个请求。
这种模型,使得Nginx能够高效地处理并发请求,提供高性能的Web服务。
此外,Nginx还允许通过配置和扩展模块…
来支持更多的功能和优化策略,以满足不同的业务需求。
…
8、在Nginx中,如何使用未定义的服务器名称,来阻止处理请求的?
只需将请求删除的服务器就可以定义为:
Server{
listen80;
server_name““;
return444;
}
这里,服务器名被保留为一个空字符串…
它将在没有“主机”头字段的情况下,匹配请求。
而一个特殊的Nginx的非标准代码444,被返回,从而终止连接。
…
9、在Nginx中,如何在URL中保留双斜线?
要在URL中保留双斜线,就必须使用“merge_slashes_off;”。
语法:merge_slashes[onoff];
默认值:merge_slasheson;
环境:http,server
…
10、ngx_http_upstream_module的作用是什么?
ngx_http_upstream_module用于定义可通过fastcgi传递、proxy传递、uwsgi传递、memcached传递和scgi传递指令,来引用的服务器组。
…
11、fastcgi与cgi的区别?
1)cgi
web服务器会根据请求的内容,然后会fork一个新进程来运行外部c程序(或perl脚本…)。
这个进程,会把处理完的数据,返回给web服务器。
最后web服务器,把内容发送给用户,刚才fork的进程,也随之退出。
如果下次用户还请求改动态脚本…
那么web服务器,又再次fork一个新进程,周而复始的进行。
2)fastcgi
web服务器收到一个请求时,他不会重新fork一个进程(因为这个进程在web服务器启动时就开启了,而且不会退出)。
web服务器,直接把内容传递给这个进程(进程间通信,但fastcgi使用了别的方式,tcp方式通信)。
这个进程收到请求后进行处理,把结果返回给web服务器…
最后自己接着等待下一个请求的到来,而不是退出。
综上所述,fastcgi与cgi的差别,就在于是否重复fork进程,处理请求。
…
12、Nginx常用命令?
启动nginx。
停止nginx-sstop或nginx-squit。
重载配置.sbinnginx-sreload(平滑重启)或servicenginxreload。
重载指定配置文件.nginx-cusrlocanf。
查看nginx版本nginx-v。
检查配置文件是否正确nginx-t。
显示帮助信息nginx-h。
…
13、Nginx常用配置?
worker_processes8;#工作进程个数
worker_connections65535;#每个工作进程能并发处理(发起)的最大连接数(包含所有连接数)
error_logdatalogsnginxerror.log;#错误日志打印地址
access_logdatalogsnginxaccess.log;#进入日志打印地址
log_formatmain'$remote_addr$request''$status$upstream_addr
$request_time';#进入日志格式
##如果未使用fastcgi功能的,可以无视
fastcgi_connect_timeout=300;#连接到后端fastcgi超时时间
fastcgi_send_timeout=300;#向fastcgi请求超时时间(这个指定值,已经完成两次握手后,向fastcgi传送请求的超时时间)
fastcgi_rend_timeout=300;#接收fastcgi应答超时时间,同理也是2次握手后
fastcgi_buffer_size=64k;#读取fastcgi应答第一部分需要多大缓冲区,该值表示使用1个64kb的缓冲区读取应答第一部分(应答头)…
可以设置为fastcgi_buffers选项缓冲区大小
fastcgi_buffers464k;#指定本地需要多少和多大的缓冲区来缓冲fastcgi应答请求…
假设一个php或java脚本所产生页面大小为256kb,那么会为其分配4个64kb的缓冲来缓存
fastcgi_cacheTEST;#开启fastcgi缓存并为其指定为TEST名称,降低cpu负载,防止502错误发生
listen80;#监听端口
server_namerrc.test.;#允许域名
rootdatareleaserrcweb;#项目根目录
indexindex.phpindex.htmlindex.htm;#访问根文件
…
14、请陈述stub_status和sub_filter指令的作用是什么?
(1)Stub_status指令
该指令用于了解Nginx当前状态的当前状态…
如当前的活动连接,接受和处理当前读写等待连接的总数。
(2)Sub_filter指令
它用于搜索和替换响应中的内容,并快速修复陈旧的数据。
…
15、主从Reactor多线程模型?
服务端用于接收客户端连接的,不再是个1个单独的NIO线程…
而是一个独立的NIO线程池。
Acceptor接收到客户端TCP连接请求,处理完成后(可能包含接入认证等)…
将新创建的SocketChannel,注册到IO线程池(subreactor线程池)的某个IO线程上;
由它负责SocketChannel的读写和编解码工作。
Acceptor线程池,仅仅只用于客户端的登陆、握手和安全认证…
一旦链路建立成功,就将链路注册到后端subReactor线程池的IO线程上;
由IO线程负责后续的IO操作。
......
一、什么是SpringBoot?
1、用来简化spring初始搭建,以及开发过程中使用特定的方式,进行配置(properties或者yml文件)。
2、创建独立的Spring应用程序main方法运行。
3、嵌入Tomcat无需部署war包,直接打成jar包,用nohupjava-jar–&启动就好。
4、简化了maven的配置。
5、自动配置Spring添加对应的starter自动化配置。
...
下面,让我来具体说说…
SpringBoot是由Pivotal团队提供的全新框架…
旨在简化新Spring应用的初始搭建,以及开发过程。
从根本上讲,SpringBoot是一个基于Spring框架的开源框架…
它提供了一套开发工具和约定,使得构建独立、可执行的、生产级别的Spring应用,变得更加容易。
SpringBoot具有4大核心特性,即自动化配置,外部化配置,内嵌容器,健康检查和监控。
1、自动化配置
通过自动配置机制,根据项目中引入的依赖和约定…
自动配置应用程序中的各种组件和功能。
这减少了开发者,手动编写大量XML或注解配置的工作量,降低了出错的可能性。
2、外部化配置
支持将配置信息从代码中分离出来,使开发者能够在不同环境下…
灵活切换配置参数,例如使用不同的数据库或消息队列。
3、内嵌容器
支持内置的Servlet容器(如Tomcat、Jetty、Undertow等)…
这意味着,你可以将应用程序,打包为一个可执行的JAR文件…
并直接运行,无需单独安装和配置外部容器。
4、健康检查和监控
提供了健康检查和监控功能,可以监控应用程序的运行状态和性能指标…
确保应用程序的稳定性和可靠性。
此外…
SpringBoot还致力于提供快速的应用开发体验,并使得开发者…
能够更专注于业务逻辑的实现,而不是花费大量时间在配置和部署上。
因此…
无论是Web应用、RESTful服务还是批处理作业,SpringBoot都能帮助开发者…
更快速、更便捷地构建及部署Java应用程序,提高开发效率和项目的可维护性。
划重点:
最新版本的SpringBoot(截至2024年4月)是3.2.x系列,提供了更多的特性和改进…
如系统要求提升、安全性增强、虚拟线程支持以及JakartaEE迁移等。
这些新特性和改进,使得SpringBoot在构建现代、高效和安全的Java应用程序方面,更加强大和灵活。
…
二、SpringBoot常用的starter?
1、spring-boot-starter-web(嵌入Tomcat和web开发需要的servlet和jsp支持)
2、spring-boot-starter-data-jpa(数据库支持)
3、spring-boot-starter-data-Redis(Redis支持)
4、spring-boot-starter-data-solr(solr搜索应用框架支持)
5、mybatis-spring-boot-starter(第三方mybatis集成starter)
…
三、SpringBoot自动配置原理?
1、@EnableAutoConfiguration这个注解会“猜“你将如何配置spring,前提是你已经添加了jar依赖项。
如果spring-boot-starter-web已经添加Tomcat和SpringMVC…
这个注释,就会自动假设您在开发一个web应用程序,并添加相应的Spring配置;
会自动去maven中读取每个starter中的spring.factories文件;
该文件里,配置了所有需要被创建spring容器中bean。
2、在main方法中,加上注解@SpringBootApplication和@EnableAutoConfiguration。
…
四、SpringBootstarter工作原理?
1、SpringBoot在启动时,扫描项目依赖的jar包,寻找包含spring.factories文件的jar。
2、根据spring.factories,配置加载AutoConfigure。
3、根据@Conditional注解的条件,进行自动配置,并将bean注入到SpringContext。
…
五、SpringBoot的优点?
1、减少开发、测试时间和努力。
2、使用JavaConfig有助于避免使用XML。
3、避免大量的maven导入和各种版本冲突。
4、提供意见发展方法,
5、通过提供默认值快速开始开发。
6、没有单独的web服务器需要...
这就意味着,不再需要启动Tomcat、Glassfish,或其它任何东西。
7、需要更少的配置,因为没有web.xml文件。
只需添加用@Configuration注释的类,然后添加用@Bean注释的方法…
Spring将自动加载对象,并像以前一样对其进行管理。
甚至可以将@Autowired添加到bean方法中,以使用Spring自动装入需要的依赖关系中。
…
六、SpringCloud解决了哪些问题?
配置管理(注册中心eureka、zk)…
服务发现、服务注册、断路器、路由策略、全局锁、分布式会话…
客户端调用、接口网关(zuul)、服务管理系统。
下面,让我来具体说说…
SpringCloud主要解决了,在构建微服务架构时,面临的一系列问题。
主要有6个,即服务注册与发现,配置管理,负载均衡,熔断与降级,服务拆分与治理,生态系统丰富。
具体来说,它提供了以下关键解决方案:
1、服务注册与发现
通过集成服务注册中心(如Eureka、Consul等)…
SpringCloud使得微服务之间,能够自动注册和发现彼此…
从而实现了服务之间的无缝通信。
这大大简化了,服务之间的调用过程,提高了系统的可维护性和可扩展性。
2、配置管理
SpringCloudConfig提供了集中式的配置管理功能…
使得开发者,可以方便地管理所有微服务的配置信息。
通过动态更新和版本控制,它确保了配置的一致性和可维护性,降低了因配置错误导致的问题。
3、负载均衡
SpringCloud提供了多种负载均衡器(如Ribbon、SpringCloudLoadBalancer等)…
能够在服务消费者之间分配请求,确保每个服务实例,都能得到合理的负载。
这有助于,提高系统的可用性和性能,避免单点故障。
4、熔断与降级
通过集成Hystrix等组件,SpringCloud实现了熔断和降级机制。
当某个服务,出现故障或响应过慢时…
熔断器会快速失败调用,避免整个系统崩溃。
同时,降级机制,可以在服务不可用时,提供备选方案,确保系统的稳定运行。
5、服务拆分与治理
SpringCloud支持微服务的细粒度拆分,使得开发者,能够更灵活地设计系统架构。
同时,它提供了服务治理功能,如流量控制、熔断隔离等等…
帮助开发者,更好地管理和维护微服务集群。
6、生态系统丰富
SpringCloud拥有庞大的生态系统,包括许多开源项目和第三方库。
这些库,可以帮助开发者,更容易地构建各种类型的微服务,如API网关、认证中心、监控中心等。
总的来说:
SpringCloud通过提供一系列工具和组件…
简化了微服务的开发、部署和管理过程,降低了构建分布式系统的复杂性。
这使得开发者,能够更专注于,业务逻辑的实现,提高开发效率和质量。
…
七、SpringBoot与SpringCloud的关系?
1、SpringBoot简化了xml配置,快速整合框架。
2、Springcloud是一套微服务解决方案—RPC远程调用。
3、关于SpringCloud依赖与SpringBoot(web组件用的SpringMVC),为什么Springcloud会依赖与SpringBoot?
因为SpringCloud写接口就是SpringMVC接口。
4、SpringBootproperties和yml中可以使用${random}设置一些随机值。
…
下面,让我来具体说说…
SpringBoot与SpringCloud的关系可以被视为一种相辅相成、互为补充的协作关系。
具体来说,它们之间的关系主要体现在3个方面,即基础与扩展,互补与协同,依赖与独立。
1、基础与扩展
SpringBoot为开发者,提供了快速构建Spring应用程序的基础能力…
它注重于简化配置、内嵌服务器以及自动配置等特性;
使得开发者,能够更快速地启动和运行单个Spring应用程序。
而SpringCloud,则是在SpringBoot的基础上…
提供了构建分布式系统和微服务架构所需的工具和框架,它关注于全局的微服务协调整理和治理。
2、互补与协同
SpringBoot虽然能够快速构建单个微服务…
但对于微服务之间的协调、配置管理、服务发现等问题,并未提供完整的解决方案。
而SpringCloud,则通过提供一系列的功能组件…
如配置中心、服务发现、断路器、路由等,来弥补SpringBoot在这些方面的不足。
这使得开发者,能够利用SpringBoot快速构建微服务个体…
再利用SpringCloud,将这些微服务整合并管理起来,形成一个完整的微服务架构。
3、依赖与独立
虽然SpringCloud依赖于SpringBoot作为其基础…
但SpringBoot本身并不需要SpringCloud就可以独立使用。
这意味着开发者,可以根据项目的实际需求,选择只使用SpringBoot来构建简单的Spring应用程序…
或者结合使用SpringBoot和SpringCloud来构建复杂的微服务架构。
综上所述:
SpringBoot与SpringCloud之间的关系是一种基础与扩展、互补与协同的关系。
它们各自具有独特的功能和优势,但又能够相互协作…
共同为开发者提供构建高效、稳定、可扩展的分布式系统,及微服务架构的能力。
…
八、微服务是如何调用的?
微服务的调用,主要依赖于服务之间的通信机制。
具体实现方式会根据,所选择的通信协议和框架有所不同,但大致流程是相似的。
微服务调用三步走如下:
首先…
服务消费者(即发起调用的微服务)会通过某种机制获取到服务提供者(即被调用的微服务)的地址信息。
这种机制可以是服务注册与发现中心…
如Eureka、Consul或Nacos等;
也可以是静态配置,如直接在配置文件中指定服务地址。
获取到服务地址后,服务消费者,会根据选定的通信协议和框架来构建请求。
常见的通信协议包括HTTP、gRPC、Thrift等,而框架则可能是SpringCloud、Dubbo等。
例如,如果使用HTTP协议和SpringCloud框架,服务消费者可能会使用RestTemplate或WebClient来构建HTTP请求。
接下来…
服务消费者,会发送请求到服务提供者。
这个过程可能涉及到网络传输、序列化与反序列化等步骤。
网络传输,负责将请求,从服务消费者发送到服务提供者…
而序列化与反序列化,则负责将请求对象,转换为可以在网络上传输的格式,并在接收端,恢复为原始对象。
服务提供者收到请求后,会进行相应的业务处理,并返回结果给服务消费者。
这个过程,同样涉及到网络传输、序列化与反序列化等步骤。
最后…
服务消费者,接收到服务提供者返回的结果,根据需要进行相应的处理。
这样,一个完整的微服务调用过程,就完成了。
在整个过程中,为了确保调用的可靠性和稳定性,可能还会涉及到一些额外的机制…
如超时处理、重试机制、熔断器等等。
这些机制可以在网络故障、服务不可用等情况下,提供一定的容错能力,保证系统的稳定性和可用性。
总的来说:
微服务的调用,是一个涉及到服务发现、通信协议、网络传输、序列化与反序列化等多个步骤的复杂过程。
在设计和实现微服务调用时,我们需要根据具体的业务需求和技术选型,来进行综合考虑和权衡。
…
九、微服务调用的原理?
微服务调用的原理,其实主要基于分布式系统的设计理念。
简单来说,每个微服务都是一个独立的、可独立部署的服务,它们之间通过轻量级的通信机制进行交互。
一、首先…
微服务之间需要有一种机制,来发现彼此的位置。
这通常通过服务注册与发现机制来实现的。
例如使用服务注册中心,如Consul、Eureka或Nacos等等。
服务提供方,会将自己的地址,注册到注册中心…
服务调用方,则通过注册中心,查找需要调用的服务的地址。
二、其次…
在微服务调用时,为了实现高可用性和水平扩展,通常会使用负载均衡技术。
负载均衡器,可以将请求分发到多个服务实例上,从而均衡负载,提高系统的吞吐量和稳定性。
在实际调用过程中,微服务之间通常通过HTTP、RPC或消息队列等轻量级通信协议进行通信。
这种通信方式,保证了服务之间的松耦合,使得服务可以独立地升级和扩展,而不会影响到其他服务。
三、此外…
为了保证数据的独立性和隔离性,每个微服务,通常会有自己的独立数据库或数据存储。
这样,当某个服务的数据结构或存储方式需要变更时…
只需要修改该服务即可,不会影响到其他服务。
四、最后…
自动化部署和运维也是微服务调用的重要一环。
通过容器化技术(如Docker)和自动化工具(如Kubernetes)…
可以实现微服务的快速部署和管理,提高了开发和运维的效率。
总的来说:
微服务调用的原理,就是通过服务注册与发现、负载均衡、轻量级通信、独立数据库以及自动化部署和运维等技术手段…
实现各个微服务之间的解耦、独立部署和扩展,从而构建出高效、稳定、灵活的分布式系统。
…
十、微服务如何实现负载均衡?
微服务实现负载均衡的方式是多种多样的,这主要取决于具体的业务场景和技术选型。
常见负载均衡实现方式有4种,即通过硬件负载均衡器实现,使用软件负载均衡器实现,基于服务注册与发现机制的负载均衡实现,通过容器编排工具实现。
下面,让我来具体说说…
一、通过硬件负载均衡器实现
硬件负载均衡器通常位于网络的前端,接收来自客户端的请求…
然后根据预设的策略,将请求分发到不同的微服务实例上。
这种方式,具有较高的性能和稳定性,但需要额外的硬件设备投入。
二、使用软件负载均衡器实现
软件负载均衡器,通常集成在微服务框架或中间件中,如Nginx、HAProxy等。
这些软件,可以通过配置,实现请求的分发和路由,支持更灵活的负载均衡策略。
三、基于服务注册与发现机制的负载均衡实现
这也是常见的实现方式。
服务提供者,将自己的地址注册到注册中心…
服务消费者,通过注册中心获取服务提供者的地址列表;
然后根据负载均衡策略,选择一个进行调用。
这种方式可以实现服务的动态发现和调用,对服务的扩展和容错处理具有较好的支持。
在具体实现上,负载均衡策略也是多种多样的。
常见的策略包括轮询、随机、最少连接数等。
1、轮询策略,将请求依次分发给各个服务实例;
2、随机策略,则随机选择一个服务实例进行调用;
3、最少连接数策略,则根据服务实例当前的连接数进行选择,以实现负载均衡。
四、通过容器编排工具实现
随着容器化技术的发展,容器编排工具如Kubernetes,也提供了强大的负载均衡能力。
通过Kubernetes的Service资源,可以方便地实现微服务的自动发现和负载均衡。
总的来说:
微服务实现负载均衡的方式是多种多样的…
我们需要根据具体的业务场景和技术选型进行选择和配置。
同时,负载均衡策略的选择,也需要根据实际需求和系统特性进行权衡和调整,以达到最佳的负载均衡效果。
…
十一、配置详解?
1、eureka.client.register-with-eureka:
是否向注册中心注册自己,注册为true反之为false。
2、eureka.client.fetch-registry:
是否需要去检索服务,检索为true反之为false。
3、eureka.client.serviceUrl.defaultZone:
指定服务注册中心的地址。
...
十二、Eureka?
1、Eureka可分为三个角色:
服务发现者、服务注册者、注册发现中心。
但是这三个角色,并不和实际部署的模型,是一对一的关系。
2、所有的网络通信,都是基于http(s)协议的。
3、Eureka和AWS是紧密结合的,无论是配置还是源码...
比如Region、zone…...
Region可以通过配置文件进行配置,如果不配置默认使用us-east-1。
同样Zone也可以配置,若不配置默认使用defaultZone。
...
十三、Eureka的高可用配置?
EurekaServer的高可用,实际上就是将自己作为服务向其它服务注册中心注册自己。
这样就可以形成一组互相注册的服务注册中心...
以实现服务清单的互相同步,达到高可用效果。
...
十四、谈谈微服务?
以前所有的代码,都放在同一个工程中,部署在同一个服务器,这就造成了同一项目的不同模块、不同功能互相抢占资源...
微服务,就是将工程根据不同的业务规则,拆分成微服务,部署在不同的服务器上,实现服务之间相互调用。
实现Java微服务的有Dubbo(只能用来做微服务)...
SpringCloud(提供了服务的发现、断路器等)。
微服务的7个特点:
1、按业务划分为一个独立运行的程序,即服务单元;
2、服务之间通过HTTP协议相互通信;
3、自动化部署;
4、可以用不同的编程语言;
5、可以用不同的存储技术;
6、服务集中化管理;
7、微服务是一个分布式系统。
微服务的6点优势:
1、将一个复杂的业务拆分为若干小的业务,将复杂的业务简单化。
新人只需要了解它所接管的服务的代码,这就减少了新人的学习成本。
2、由于微服务是分布式服务,服务于服务之间没有任何耦合。
微服务系统的微服务单元,具有很强的横向拓展能力。
3、服务与服务之间,采用HTTP网络通信协议来通信...
单个服务内部高度耦合,服务与服务之间完全独立,无耦合。
这使得微服务,可以采用任何的开发语言和技术来实现,提高开发效率、降低开发成本。
4、微服务是按照业务进行拆分的,并有坚实的服务边界...
若要重写某一业务代码,不需了解所以业务,重写简单。
5、微服务的每个服务单元是独立部署的...
即独立运行在某个进程中,微服务的修改和部署,对其它服务没有影响。
6、微服务在CAP理论中,采用的AP架构,具有高可用分区容错特点。
高可用主要体现在系统7x24不间断服务...
它要求系统有大量的服务器集群,从而提高系统的负载能力。
分区容错也使得系统更加健壮。
微服务的4点不足:
1、微服务的复杂度
构建一个微服务比较复杂,服务与服务之间,通过HTTP协议或其它消息传递机制通信。
开发者要选出最佳的通信机制,并解决网络服务差时,带来的风险。
2、分布式事物
将事物分成多阶段提交,如果一阶段某一节点失败,仍会导致数据不正确。
如果事物涉及的节点很多,某一节点的网络出现异常...
会导致整个事务处于阻塞状态,大大降低数据库的性能。
3、服务划分
将一个完整的系统,拆分成很多个服务,是一件非常困难的事...
因为这涉及了具体的业务场景。
4、服务部署
最佳部署容器Docker。
...
十五、微服务和SOA的关系?
微服务相对于和ESB联系在一起的SOA,轻便敏捷得多...
微服务,将复杂的业务组件化,也是一种面向服务思想的体现。
对于微服务来说,它是SOA的一种体现,但是它比ESB实现的SOA,更加轻便、敏捷和简单。
...
十六、SpringCoud是如何实现服务注册与发现的?
服务发布时,指定对应的服务名(IP地址和端口号),将服务注册到注册中心(eureka和zookeeper)...
但是这一切是SpringCloud自动实现的;
只需要在SpringBoot的启动类上,加上@EnableDisscoveryClient注解。
同一服务修改端口,就可以启动多个实例调用方法:
传递服务名称,通过注册中心获取所有的可用实例...
通过负载均衡策略(Ribbon和Feign)调用对应的服务。
...
十七、Ribbon和Feign的区别?
两者有3点具体区别,即启动类使用的注解不同,服务的指定位置不同,调用方式不同。
Ribbon添加的maven依赖是spring-starter-ribbon。
使用@RibbonClient(value=“服务名称”),使用RestTemplate调用远程服务对应的方法。
Feign添加的maven依赖是spring-starter-feign...
服务提供方提供对外接口,调用方使用,在接口上使用FeignClient(“指定服务名”)。
3点具体区别:
1、启动类使用的注解不同
Ribbon使用的是@RibbonClient,Feign使用的是@EnableFeignClients。
2、服务的指定位置不同
Ribbon是在@RibbonClient注解上声明。
Feign则是在定义抽象方法的接口中使用@FeignClient声明。
3、调用方式不同
Ribbon需要自己构建http请求,模拟http请求...
然后使用RestTemplate发送给其它服务,步骤比较繁琐。
而Feign,则是在Ribbon的基础上进行了一次改进,采用接口调用的方式...
将需要调用的其它服务的方法,定义成抽象方法即可...
不需要自己构建http请求。
不过要注意的是,抽象方法的注解、方法签名,要和提供方的完全一致。
...
十八、雪崩效应?
分布式系统中的服务通信,依赖于网络...
网络不好,必然会对分布式系统带来很大的影响。
在分布式系统中,服务之间相互依赖,即...
如果一个服务之间出现了故障或者网络延迟,在高并发的情况下...
会导致线程阻塞,在很短的时间内,该服务的线程资源会消耗殆尽,最终使得该服务不可用。
由于服务的相互依赖,可能会导致整个系统的不可用,这就是“雪崩效应”。
为了防止此类事件的发生,分布式系统必然要采取相应的措施,如熔断机制(SpringCloud采用的是Hystrix)。
...
十九、熔断机制?
1、服务故障则开启熔断器
当一个服务出现故障时,请求失败次数超过设定的阀值(默认50)之后...
该服务就会开启熔断器,之后该服务就不进行任何业务逻辑操作,执行快速失败,直接返回请求失败的信息。
其它依赖于该服务的服务,就不会因为得不到响应而造成线程阻塞。
这是除了该服务,以及依赖于该服务的部分功能不可用外,其它功能正常。
2、熔断器的自我修复机制
当一个服务熔断后,经过一段时间(5s)半打开熔断器。
半打开的熔断器,会检查一部分请求(只能有一个请求)是否正常...
其它请求执行快速失败;
检查的请求如果响应成功,则可判断该服务正常了,就可关闭该服务的熔断器,反之则继续打开熔断器。
这种自我熔断机制和自我修复机制...
可以使程序更加健壮,也可以为开发和运维,减少很多不必要的工作。
3、熔断组件提供监控
熔断组件往往会提供一系列的监控...
比如服务可用与否、熔断器是否被打开、目前的吞吐量、网络延迟状态的监控等等。
从而,可以让开发人员和运维人员去了解服务的状况。
...
二十、Eureka的基础架构?
Eureka的基础架构的组成部分是...
1、服务注册中心(失效剔除、自我保护);
2、服务提供者(服务注册、服务同步、服务续约);
3、服务消费者(获取服务、服务调用、服务下线)。
...
下面,就来说下具体内容吧!
1、服务注册中心
Eureka提供的服务端,提供服务注册与发现的功能。
1.1、失效剔除
对于那些非正常下线的服务实例(内存溢出、网络故障导致的)...
服务注册中心,不能收到“服务下线”的请求,为了将这些无法提供服务的实例从服务列表中剔除...
EurekaServer在启动的时候,会创建一个定时任务...
默认每隔一段时间(默认60s),将当前清单中超时(默认90s)没有续约的服务,剔除出去。
1.2、自我保护
EurekaServer在运行期间,会统计心跳失败的比例,在15分钟之内是否低于85%...
如果出现低于的情况(生产环境由于网络不稳定会导致)...
EurekaServer会将当前的实例注册信息保护起来,让这些实例不过期,尽可能保护这些注册信息。
但是在这保护期间内,实例出现问题...
那么客户端,就很容易拿到实际上已经不存在的服务实例,会出现调用失败的情况。
所以客户端必须有容错机制,比如可以使用请求重试、断路器等机制。
在本地进行开发时,可以使用eureka.server.enable-self-preseervation=false参数...
来关闭保护机制,以确保注册中心,可以将不可用的实例剔除。
2、服务提供者
提供服务的应用,可以是SpringBoot应用,也可以是其它的技术平台,且遵循Eureka通信机制的应用。
它将自己提供的服务,注册到Eureka,以供其它应用发现(如service层)。
2.1、服务注册
服务提供者,在启动的时候,会通过发送Rest请求的方式...
将自己注册到EurekaServer(服务注册中心)中,同时带上自身服务的一些元数据;
EurekaServer接收到这个Rest请求后,将元数据存储在一个双层结构Map中;
第一层的key是服务名,第二层key是具体服务的实例名。
2.2、服务同步
若有两个或两个以上的EurekaServer(服务注册中心)时...
它们之间是互相注册的。
当服务提供者,发送注册请求到一个服务注册中心时...
它会将该请求,转发到集群中相连的其它注册中心;
从而实现,注册中心间的服务同步,这样服务提供者的服务信息,可以通过任意一台服务中心获取到。
2.3、服务续约
在注册完服务之后,服务提供者会维护一个心跳,来持续告诉EurekaServer:“我还活着”...
以防止EurekaServer的“剔除任务”将该服务实例,从服务列表中排除出去。
配置:eureka.instance.lease-renewal-in-seconds=30(续约任务的调用间隔时间,默认30秒,也就是每隔30秒向服务端发送一次心跳,证明自己依然存活)。
eureka.instance.lease-expiration-duration-in-seconds=90(服务失效时间,默认90秒,也就是告诉服务端,如果90秒之内没有给你发送心跳就证明我“死”了,将我剔除)。
3、服务消费者
消费者应用,从服务注册中心获取服务列表...
从而使消费者,可以知道去何处调用其所需要的服务。
比如Ribbon实现消费方式,Feign实现消费方式。
3.1、获取服务
当启动服务消费者时,它会发送一个Rest请求给注册中心...
获取上面注册的服务清单;
EurekaServer会维护一份只读的服务清单,来返回给客户端,并且每三十秒更新一次。
3.2、服务调用
在服务消费者获取到服务清单后,通过服务名...
可以获得具体提供服务的实例名和该实例的元信息,采用Ribbon实现负载均衡。
3.3、服务下线
当服务实例,进行正常的关闭操作时...
它会触发一个服务下线的Rest请求,给EurekaServer,告诉服务注册中心“我要下线了”。
服务端接收到请求之后,将该服务状态设置为下线,并把下线时间传播出去。
...
二十一、Eureka和Zookeeper都可以提供服务注册与发现的功能,而两者的区别是?
简单来说,Zookeeper保证了CP(C:一致性,P:分区容错性);
Eureka保证了AP(A:高可用,P:分区容错)。
1、Zookeeper
当向注册中心查询服务列表时...
我们可以容忍,注册中心返回的是几分钟以前的信息;
但不能容忍直接down掉,不可用的。
也就是说,服务注册功能对高可用性要求比较高。
但是Zookeeper会出现这样的一种情况...
当master节点,因为网络故障与其它节点失去联系时...
剩余的节点,会重新选leader。
问题在于,选取leader的时间过长(30~120s),且选取期间Zookeeper集群都不可用...
这样就会导致,选取期间注册服务瘫痪。
在云部署的环境下,因网络问题...
使得Zookeeper集群,失去master节点,是较大概率会发生的事。
虽然服务最终恢复,但是漫长的选择时间,导致的注册长期不可用,是不能容忍的。
2、Eureka
它则看明白这一点,因此在设计上优先保证了高可用性。
Eureka各个节点都是平等的,几个节点挂掉,不会影响到正常节点的工作...
剩余的节点,依然可以提供注册和查询服务。
而Eureka的客户端,再向某个Eureka注册时...
如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在...
就能保证注册服务的可用(保证可用性),只不过查到的信息,可能不是最新的(不保证一致性)。
除此之外,Eureka还有一种自我保护机制...
如果在15分钟内,超过85%的节点都没有正常心跳...
那么Eureka,就认为客户端与注册中心出现了网络故障。
而此时,就会出现以下几种情况:
2.1、Eureka不再从注册列表移除,因为长时间没收到心跳,而应该过期的服务;
2.2、Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(保证当前节点可用);
2.3、当网络稳定时,当前实例新的注册信息,会被同步到其它节点中。
Eureka还有客户端缓存功能(Eureka分为客户端程序和服务器端程序两个部分,客户端程序负责向外提供注册与发现服务接口)。
所以,即便Eureka集群中所有节点都失效,或者发生网络分隔故障,导致客户端不能访问任何一台Eureka服务器。
Eureka服务的消费者,任然可以通过Eureka客户端缓存,来获取所有的服务注册信息。
甚至最极端的环境下,所有正常的Eureka节点,都不对请求产生响应...
也没有更好的服务器解决方案,来解决这种问题。
得益于Eureka的客户端缓存技术,消费者服务...
仍然可以通过Eureka客户端,查询与获取注册服务信息,这点很重要;
因此Eureka,可以很好的应对网络故障,导致部分节点失去联系的情况。
而不像Zookeeper那样,使整个注册服务瘫痪。
...
二十二、CAP理论?
1、Consistency
指数据的强一致性。
如果写入某个数据成功,之后读取,读到的都是新写入的数据;
如果写入失败,读到的都不是写入失败的数据。
2、Availability
指服务的可用性。
3、Partition-tolerance
指分区容错。
...
二十三、Ribbon和Nginx的区别?
1、Nginx性能好,但Ribbon可以剔除不健康节点,Nginx剔除比较麻烦。
2、Ribbon是客户端负载均衡,Nginx是服务端负载均衡。
...
二十四、服务注册与发现?
服务注册,就是向服务注册中心,注册一个服务实例...
服务提供者将自己的服务信息(服务名、IP地址等)告知注册中心。
服务发现,是服务消费另一个服务时,注册中心将服务的实例,返回给服务消费者...
一个服务,既是服务提供者又是服务消费者。
服务注册中心健康检查机制...
当一个服务实例注册成功以后,会定时向注册中心,发送一个心跳证明自己可用;
若停止发送心跳,证明服务不可用将会别剔除;
若过段时间继续向注册中心提供心跳,将会重新加入服务注册中心列表中。
...
二十五、微服务的负载均衡,为何用?怎么用?
1、为什么要用?
微服务是将业务代码拆分为很多小的服务单元...
服务之间的相互调用通过HTTP协议来调用,为了保证服务的高可用,服务单元往往都是集群化部署的。
2、消费者该调用,哪个服务提供者的实例呢?
服务消费者集成负载均衡组件,该组件会向服务消费者...
获取服务注册列表信息,并隔一段时间重新刷新获取列表。
当服务消费者消费服务时,负载均衡组件,获取服务提供者所有实例的注册信息...
并通过一定的负载均衡策略(可以自己配置)选择一个服务提供者实例;
向该实例进行服务消费,这样就实现了负载均衡。
……
以上,就是今天的分享啦!
希望,对你的求职面试,编程工作有那么一点点、一丢丢、一戳戳地帮助哈~
喜欢我分享的,就一键三连于我,可好?!
转码声明:以上内容基于搜索引擎转码技术对网站内容进行转码阅读,自身不保存任何数据,请您支持正版