Nginx 篇
【1】简述一下什么是Nginx,它有什么优势和功能?
Nginx 是高性能的 HTTP 和反向代理的服务器,处理高并发能力是十分强大的,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。Nginx主要提供功能有
-
http服务器
-
反向代理服务器
-
负载均衡服务器
-
动静分离配置
-
缓存数据
【2】简述一下什么是正向代理,什么是反向代理
正向代理代理的是客户端访问服务端,比如防火墙,反向代理代理的是服务端,等待客户端访问代理服务。具体配置如下:
server {
//监听的端口号
listen 80;
//监听的访问地址
server_name 192.168.8.128
location / {
//转发的地址
proxy_pass http://127.0.0.1:8080
}
}
【3】解释一下什么是Nginx的负载均衡
nginx反向代理tomcat服务集群,当客户端访问nginx服务器时,由nginx负载均衡去访问tomcat集群中的某一个节点。具体配置 。具体配置:
//tomcat集群
upstream myserver1{
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
//监听的端口号
listen 80;
//监听的访问地址
server_name 192.168.8.128
location / {
//根据负载均衡策略访问tomcat集群中的某一个节点
proxy_pass http://myserver1
}
}
负载均衡策略:
【4】说一下什么是动静分离
静态资源配置到nginx服务器中,动态资源通过nginx反向代理到tomcat。
将静态资源挂载到nginx的某个目录,在server模块中的location中配置nginx中挂载静态资源的路径,当访问静态资源时,nginx将配置的路径下的挂载的静态资源响应回去。(有待修改)
Docker 篇
【1】说一下什么是Docker?
Docker是一个开源的应用容器引擎,它让开发者可以将他们的应用以及依赖包打包到一个可移植的镜像中(自带环境) ,然后发布到任何流行的Linux或Windows操作系统的机器上。Docker使用沙箱机制,使得容器之间完全隔离 。Docker的镜像可以包含应用程序的代码、运行环境、依赖库、配置文件等必需的资源,从而实现方便快速并且与平台解耦的自动化部署方式。无论部署环境如何,容器中的应用程序都会运行在同一种环境下(一次封装,到处运行)。
【2】说一下你都用过哪些Docker命令
Docker命令操作主要包含
-
镜像操作
-
容器操作
-
数据卷操作
-
自定义镜像操作
-
网络操作
【3】说一下镜像操作的常用命令
-
docker pull 拉取镜像
-
docker push 推送镜像
-
docker images 查看所有镜像
-
docker inspect 镜像名 查看镜像详细信息
-
docker rmi 镜像名 删除镜像
-
docker build 自定义镜像
-
docker save 保存镜像
-
docker load 加载镜像
【4】说一下Docker容器命令
-
docker run 构建容器,常见参数
-
--name 容器名
-
-d 后台启动
-
-p 端口映射
-
-v 将本地文件或目录挂载到容器的目录中(两种方式,其中一种不需要创建数据卷,直接用目录挂载)
-
-e 设置传递环境变量
-
-i:以交互模式运行容器,通常与 -t 同时使用; -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-
-it 以交互模式运行容器,通常与-d 一起使用
-
--restart 设置容器的重启策略
-
--network 将容器连接到指定网络
-
-
docker start 容器名 启动容器
-
docker stop 容器名 停止容器
-
docker restart 容器名 重启容器
-
docker ps 查看所有正在运行的容器
-
docker ps -a 查看所有容器
-
docker rm 删除容器
【5】说一下数据卷命令
-
docker volume create 创建数据卷
-
docker volume ls 查看所有数据卷
-
docker volume inspect 查看数据卷详细信息
-
docker volume rm 删除数据卷
-
docker volume prune 删除未使用的数据卷
【6】说一下如何自定义镜像
首先编写Dockerfile,Dockerfile内容参照相关文档操作,最后根据docker build -f Dockerfile文件路径 -t 镜像名:[tag] 创建镜像。
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
【7】说一下如何创建网络
-
docker network connect 将容器连接到网络
-
docker network create 创建一个网络
-
docker network ls 列出所有网络
-
docker network inspect 显示一个或多个网络详细信息
-
docker network rm 删除一个获得多个网络
-
docker network prune 删除所有未使用的网络
Zookeeper 篇
【1】说一下什么是Zookeeper ?
ZooKeeper是一个开放源代码的分布式协调服务。ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
Zookeeper主要能作为分布式架构的协调者---注册中心,以及大数据的协调者(了解)
Zookeeper 是一个树形结构的监听机制系统,主要应用场景:
-
数据发布/订阅
-
负载均衡
-
服务命名
-
分布式协调/通知
【2】说一下你都用过哪些zookeeper命令
-
create 创建节点
-
ls 查看节点
-
get /获取节点结构
-
set 设置节点命令
-
delete 删除节点
-
deleteall 删除节点以及节点包含内容
-
stat 查看节点状态
Dubbo 篇
【1】说一下Dubbo执行流程
【2】说一下Dubbo支持哪些协议?
Dubbo 支持如下协议:
-
Dubbo协议
-
Hessian协议
-
HTTP协议
-
RMI协议
-
WebService协议
-
Memcached协议
-
Redis协议
建议使用Dubbo协议。
【3】注册中心挂了,consumer 还能不能调用 provider?
可以。因为刚开始初始化的时候,consumer 会将需要的所有提供者的地址等信息拉取到本地缓存,所以注册中心挂了可以继续通信。但是 provider 挂了,那就没法调用了。
在 Dubbo 中,如果注册中心(如 Zookeeper、Nacos 等)出现故障,消费者(consumer)仍然可以调用提供者(provider)的服务,但需要满足以下条件:
消费者和提供者之间的通信配置正确:消费者需要知道提供者的地址和端口等信息,这些信息通常在配置文件中进行设置。如果这些配置信息正确,消费者可以正常访问提供者的服务。
注册中心故障期间,消费者可以缓存服务信息:在 Dubbo 中,消费者可以通过注册中心缓存服务信息,以减少对注册中心的依赖。
刚开始初始化的时候,consumer 会将需要的所有提供者的地址等信息拉取到本地缓存。即使注册中心出现故障,如果提供者仍然可以正常提供服务,消费者仍然可以调用它们。 然而,如果注册中心故障时间较长,可能会导致消费者无法获取新的服务提供者信息,从而影响服务的发现和调用。
【4】怎么实现动态感知服务下线的呢?
服务订阅通常有 pull 和 push 两种方式:
-
pull 模式需要客户端定时向注册中心拉取配置;
-
push 模式采用注册中心主动推送数据给客户端。
Dubbo ZooKeeper 注册中心采用是事件通知与客户端拉取方式。服务第一次订阅的时候将会拉取对应目录下全量数据,然后在订阅的节点注册一个 watcher。一旦目录节点下发生任何数据变化, ZooKeeper 将会通过 watcher 通知客户端。客户端接到通知,将会重新拉取该目录下全量数据, 并重新注册 watcher。利用这个模式,Dubbo 服务就可以做到服务的动态发现。
注意:ZooKeeper 提供了“心跳检测”功能,它会定时向各个服务提供者发送一个请求(实际上建立 的是一个 socket 长连接),如果长期没有响应,服务中心就认为该服务提供者故障,并将其 剔除。
【5】Dubbo 负载均衡策略?
-
随机(默认):随机来
-
轮训:一个一个来
-
活跃度:机器活跃度来负载
-
一致性 hash:落到同一台机器上
【6】Dubbo 容错策略
-
failover cluster 模式
provider 宕机重试以后,请求会分到其他的 provider 上,默认两次,可以手动设置重试次数,建议把写操作重试次数设置成 0。
-
failback 模式
失败自动恢复会在调用失败后,返回一个空结果给服务消费者。并通过定时任务对失败的调用进行重试,适合执行消息通知等操作。
-
failfast cluster 模式
快速失败只会进行一次调用,失败后立即抛出异常。适用于幂等操作、写操作,类似于 failover cluster 模式中重试次数设置为 0 的情况。
-
failsafe cluster 模式
失败安全是指,当调用过程中出现异常时,仅会打印异常,而不会抛出异常。适用于写入审计日志等操作。
-
forking cluster 模式
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。
-
broadcacst cluster 模式
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
Redis 篇
【1】为什么要使用Redis缓存,你都用过redis做什么?
答:Redis是一个分布式的缓存中间件,使用缓存我从三个方向介绍使用的原因
-
缓存可以提高网站并发读写能力。
-
缓存可以解决跨进程的内存计算问题
-
可以解决跨进程的分布锁问题
1.比如,一个电商的首页需要的并发量非常高,我们如何提供首页的并发能力呢,其根本思路就是减少用户对tomcat服务器的访问压力。用户访问首先从nginx缓存获取数据,如果获取不到通过lua脚本查询Redis,如果Redis有数据就将数据同步到nginx缓存中,然后响应客户端。如果redis没有数据才会查询mysql数据库。使用nginx+redis两层缓存的目的一是提高并发量,二是减少缓存雪崩。
2.再例如缓存可以解决内存计算问题,比如一个网站上传的图片到七牛云,只有保存到数据库的图片才是有用的图片,但操作七牛云和操作数据库的是两个JVM进程时如何计算呢?把两者数据读取到redisset集合,求两个集合的差值就是垃圾图片,然后调用api删除这些图片。在比如商城的购物车数据库是跨JVM进程的,如何存储计算呢?可以通过redis的hash结构存储并计算。
2.再比如跨进程操作共享数据,如何解决多线程安全问题呢,此时JVM线程锁已经失效,可以使用RedissonClient提供的分布式锁实现,商城的超卖问题就可以通过这个解决。
【2】Redis有哪些数据类型?以及各自的使用场景
答:String 类型、List类型、Set类型、Hash类型、Zset类型、Bitmaps类型、Geospatial类型、HyperLogLog类型。
String类型是最基本类型key-value,可以用于数据缓存,做计数器(incrby),求粉丝数,分布式锁的底层原理(setnx)
List类型是一个双向链表结构,可以用于消息队列,最新列表等能。
Set类型是一个无序集合,自动去重复,可以做一些去重复计算,集合计算等。
Hash类型底层是Hash结构,可以用于对象存储并计算,比如用来存购物车数据。
Zset是一个有权重的Set集合,可以利用权重做些排行榜等需求。
Bitmaps是一个直接用二进制表示数据,并存储的类型,因每位只能存两种情况,可以用来实现考勤统计情况
Geospatial是坐标类型,可以实现地图坐标计算等功能。
HyperLogLog是一个基于基数计算的数据类型,可以用来统计基数,如PV、UV统计这些。
【3】为什么 Redis 单线程模型效率也能那么高?
Redis 内部使用文件事件处理器 file event handler ,这个文件事件处理器是单线程的,所以 Redis 才叫做单线程的模型。
-
C语言实现,效率高
-
纯内存操作
-
基于非阻塞的IO复用模型机制
-
单线程的话就能避免多线程的频繁上下文切换问题
-
丰富的数据结构(全称采用hash结构,读取速度非常快,对数据存储进行了一些优化,比如亚索表,跳等)
补充:redis请求处理是多线程地,命令处理是单线程的。
【4】说说什么是Redis的发布订阅?
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息
相关命令
-
subscribe 主题名字 订阅主题
-
publish 主题名字 消息 发送消息
如果发布者发布频道消息时,订阅者还有没有订阅频道是收不到消息的。
【5】如何解决redis的慢查询问题?
慢查询,顾名思义就是比较慢的查询,可以通过慢查询日志获得问题是所在,相关命令:
-
showlog get n 获得前n条慢查询日志
-
showlog len 获得慢查询日志长度
-
config set slowlog-log-slower-than 1000 设置慢查询阀值 单位微妙
-
config set slowlog-max-len 1200 设置慢查询命令长度
-
config rewrire 保存设置
【6】 pipeline 有什么好处,为什么要用 pipeline?
使用 pipeline(管道)的好处在于可以将多次 I/O 往返的时间缩短为一次,但是要求管道中执行的指令间没有因果关系。
用 pipeline 的原因在于可以实现请求/响应服务器的功能,当客户端尚未读取旧响应时,它也可以处理新的请求。如果客户端存在多个命令发送到服务器时,那么客户端无需等待服务端的每次响应才能执行下个命令,只需最后一步从服务端读取回复即可。
【7】说说Redis的持久化技术
Redis是一个支持持久化的内存数据库,通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化。当Redis重启后通过把硬盘文件重新加载到内存,就能达到恢复数据的目的。 实现:单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。
RDB是Redis默认的持久化方式。按照一定的时间周期策略把内存的数据以快照的形式保存到硬盘的二进制文件。即Snapshot快照存储,对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。( 快照可以是其所表示的数据的一个副本,也可以是数据的一个复制品。)
AOF:Redis会将每一个收到的写命令都通过Write函数追加到文件最后,类似于MySQL的binlog。 当Redis重启是会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。 当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。
用AOF来保证数据不丢失,作为数据恢复的第一选择,用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。
【8】Redis 报内存不足怎么处理?
Redis 内存不足可以这样处理:
-
修改配置文件 redis.conf 的 maxmemory 参数,增加 Redis 可用内存;
-
设置缓存淘汰策略,提高内存的使用效率;
-
使用 Redis 集群模式,提高存储量。
【9】说说Redis内存淘汰策略?
当 Redis 内存使用达到最大内存限制时,如果继续进行写入操作会导致 Redis 服务崩溃。因此,为了保证 Redis 服务的稳定性,Redis 在内存使用达到最大限制时采取一系列措施,如内存淘汰、警告等。
Redis 内存淘汰策略主要有 6 种:
noeviction
这是 Redis 的默认策略,这意味着当内存满了时,任何写操作(如 SET,HSET 等)都会返回一个错误,这种情况下,需要管理员手动清除一些键值对或者增加内存才能继续进行写操作。
allkeys-lru
该策略会针对所有的键使用 LRU(最近最少使用)算法来淘汰键值对。对于 Redis 的所有键,按照最近最少使用的原则,优先淘汰那些最近没有使用或很久没有使用的键值对。
# 配置为 allkeys-lru 策略
maxmemory-policy allkeys-lru
volatile-lru
在这种模式下,Redis 会选择过期时间较近的键来淘汰。如果一个键设置了过期时间,并且距离过期时间较远,那么 Redis 不会考虑淘汰该键值对。相反,如果一个键离过期时间只有很短的一段时间,那么 Redis 会优先淘汰该键值对。
# 配置为 volatile-lru 策略
maxmemory-policy volatile-lru
allkeys-random
在这种模式下,Redis 会随机地淘汰一些键值对,重点考虑键值对的访问频率以及键空间。
# 配置为 allkeys-random 策略
maxmemory-policy allkeys-random
volatile-random
同 allkeys-random 模式类似,但它只针对开启过期时间的键空间进行淘汰。
volatile-ttl
在这种模式下,Redis 会选择最接近超时的键来淘汰。它与 volatile-lru 类似,不同之处在于它侧重于超时的键而非最近最少使用的键。
# 配置为 volatile-ttl 策略
maxmemory-policy volatile-ttl
volatile-lfu
该策略中采用的是 LFU(最不常用)算法。Redis 会优先淘汰使用频率最少的键值对。
# 配置为 volatile-lfu 策略
maxmemory-policy volatile-lfu