简单介绍下项目情况,包括业务量,项目整体结构
介绍下对spring cloud的理解
redis使用场景,分布式锁使用场景
zookeeper项目使用场景,选举机制
工作过程中参与过哪些项目优化工作
socket使用场景
hashmap底层实现原理
线程安全的hashmap有吗,底层实现原理
线程池使用场景,使用注意事项
表索引设计原则及注意事项
介绍下java内存模型
性能调优做过哪些
1.spring cloud的理解
SpringCloud不是一种技术!是一种生态
Spring Cloud,
微服务
架构。包括 服务发现(Eureka)、断路器(Hystrix)、服务网关(Zuul)、客户端负载均衡(Ribbon)、服务跟踪(Sleuth)、消息总线(Bus)、消息驱动(Stream)、批量任务(Task)等。
诸多的解决方案其实解决的还是四个问题:
1.API
2.HTTP,RPC(通信问题)
3.注册和发现
4.熔断机制
Zuul网关
可以做
统一的降级、限流、认证授权、安全
=====================================
Eureka
。
Consul
。 zookeeper
同样作为注册中心,
Eureka
和Zookeeper的区别是什么?
分布式事务的CAP的理论,C是一致性,A是可用性,P是分区容错性(必备)。
Eureka是AP,注重可用性。
而Zookeeper是cp,注重一致性。
Consul
遵循 CAP 原理中的 CP 原则,保证了强一致性和分区容错性,且使用的是 Raft 算法,比
ZooKeeper
使用的 Paxos 算法更加简单。
虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 Raft 协议要求必须过半数的节点都写入成功才认为注册成功。
Consul 强一致性(C)带来的是:
服务注册相比 Eureka 会稍慢一些。因为 Consul 的 Raft 协议要求必须过半数的节点都写入成功才认为注册成功Leader 挂掉时,重新
选举期间整个 Consul 不可用
。保证了强一致性但牺牲了可用性。
Eureka 保证高可用(A)和最终一致性:
服务注册相对要快,因为不需要等注册信息 Replicate 到其他节点,也不保证注册信息是否 Replicate 成功。当数据出现不一致时,虽然 A,B 上的注册信息不完全相同,但每个 Eureka 节点依然能够正常对外提供服务,这会出现查询服务信息时
如果请求 A 查不到,但请求 B 就能查到
。如此保证了可用性但牺牲了一致性。
其他方面,Eureka 就是个 servlet 程序,跑在 servlet 容器中;Consul 则是 Go 编写而成。
=================================================================
Feign
Ribbon
Feign怎么知道该请求哪台机器呢?
-
这时Spring Cloud Ribbon就派上用场了。Ribbon就是专门解决这个问题的。它的作用是
负载均衡
,会帮你在每次请求时选择一台机器,均匀的把请求分发到各个机器上 -
Ribbon的负载均衡默认使用的最经典的
Round Robin轮询算法
。这是啥?简单来说,就是如果订单服务对库存服务发起10次请求,那就先让你请求第1台机器、然后是第2台机器、第3台机器、第4台机器、第5台机器,接着再来—个循环,第1台机器、第2台机器。。。以此类推。
=============================================
Hystrix
Hystrix
可以进行服务降级、服务隔离、服务熔断。
7.服务隔离:
Hystrix使用”舱壁模式”实现线程池的隔离
,它会为每一个Hystrix命令创建一个独立的线程池,这样就算某个在Hystrix命令包装下的依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响,而不会拖慢其他的服务。
通过对依赖服务实现线程池隔离,应用更加健壮,不会因为个别依赖服务出现问题而引起非相关服务的异常。
8.服务降级:当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
10.Hystix隔离机制:
线程池隔离
、信号量隔离。
2.redis的 redlock redission
Redission 为 Redis 官网
分布式
解决方案
lua脚本
可重入加锁机制 计数器 +1。-1
是redis cluster,或者是redis master-slave架构的主从异步复制导致的redis分布式锁的最大缺陷:在redis master实例宕机的时候,可能导致多个客户端同时完成加锁。
补充:
Redission 还支持了RedLock 算法实现,但是目前存在争议,可自行查询及谨慎使用
Socket
了解HTTP和
Socket
之前先对网络7层协议有个了解:
7
应用层
http
6 表示层
5 会话层
4 传输层 socket tcp/udp
3 网络层
2
数据链路层
1
物理层
其中高层,既7、6、5、4层定义了应用程序的功能,下面3层,既3、2、1层主要面向通过网络的
端到端
的数据流。
HTTP是基于应用层,socket是基于传输层(tcp/udp)
比如:视频,图片,断点续传的情况下要用socket
Socket
实现服务器与客户端之间的物理连接,并进行数据传输。主要有TCP/UDP两个协议。Socket处于网络协议的传输层。
Http请求主要有http协议,基于http协议的soap协议,常见的http数据请求方式有get和post,web服务。
Socket
适用场景:网络游戏,银行交互,支付。
http适用场景:公司OA服务,互联网服务。
Http连接:http连接就是所谓的短连接
,及客户端向服务器发送一次请求,服务器端相应后连接即会断掉。
socket连接:socket连接及时所谓的长连接
,理论上客户端和服务端一旦建立连接,则不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该链接已释放网络资源。所以当一个socket连接中没有数据的传输,那么为了位置连续的连接需要发送心跳消息,具体心跳消息格式是开发者自己定义的。
介绍下java内存模型
Java内存模型:Java内存模型(即Java Memory
Model
,简称JMM)
原子性、可见性和有序性
原子性:由Java内存模型来直接保证的原子性变量操作包括read、load、assign、use、store、和write这留个,我们大致可以认为基本数据类型的访问读写时具备原子性的(long和double的非原子性协定例外)。
如果应用场景需要一个更大范围的原子性保证,Java内存模型还提供了lock和unlock操作来满足这种需求,尽管虚拟机没有把lock和unlock操作直接开放给用户使用,但却提供了更高层次的字节码指令monitorenter和monitorexit来隐式的使用这两个操作,这两个字节码指令反映到Java代码中就是同步块-synchronized关键字,因此synchronized块之间的操作也具备原子性。
可见性:当一个线程修改了共享变量的值,其他线程能够立即得知这个修改
**有序性:**Java程序中天然的有序性可以总结为一句话:如果在本线程内观察,所有的操作都是有序的;如果在一个线程中观察另一个线程,所有的操作都是无序的。前半句是指线程内表现为串行的语义,后半句是指“指令重排序”现象和“工作内存与主内存同步延迟”现象
Volatile不能保证的原子性
除了volatile外,Synchronized和final也提供了可见性,
happens-before
从jdk5开始,java使用新的JSR-133内存模型,基于happens-before的概念来阐述操作之间的内存可见性。
在JMM中,
如果一个操作的执行结果需要对另一个操作可见
,那么这两个操作之间必须要存在happens-before关系,这个的两个操作既可以在同一个线程,也可以在不同的两个线程中。
注意:两个操作之间具有happens-before关系,并不意味前一个操作必须要在后一个操作之前执行!
仅仅要求前一个操作的执行结果,对于后一个操作是可见
的,且前一个操作按顺序排在后一个操作之前。