IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 微服务架构面试01 -> 正文阅读

[大数据]微服务架构面试01


前言

Java架构面试

一、微服务架构


将项目里面的一个模块作为一个微服务,可以更方便的水平扩展

二、缓存和异步消息

缓存:Redis
常用数据结构
在这里插入图片描述
redis线程模型,redis为什么性能好?

  • 单线程,NIO,异步事件处理
    redis内部只有一个线程,给所有请求排队,socket来访问,排队,通过文件事件分派器分给不同的事件处理器
    client socket 和 server socket 建立连接,连接事件、readable事件,分配给事件处理器,处理完之后异步的给客户端返回ok。
    redis里面命令单线程执行,socket连接中的事件异步执行
    场景:分布式锁,分布式Session
    redis架构:哨兵,集群

在这里插入图片描述

消息中间件(activemq (1w并发) ,rabbitmq(1w并发) ,rocketmq(几十万消息) ,kafka(大数据,性能高,几十万、百万消息) ) 区别。

优点:
解耦,异步,削峰

问题:

  • 重复消费
  • 丢消息
  • 消息积压
  • 顺序消费

kafka解决问题:
在这里插入图片描述
如果主节点挂了,选一个从节点当做主节点;
重复消费:消费者消费partition后会提交,kafka会指定从哪个消费起然后提交(自动或手动)commit,记录消费到哪里的偏移量存到zookeeper,下次消费取出,继续消费。正常消费到5提交,结果消费到3,消费者挂了,会产生重复消费。
解决:设置一个主键冲突,把要写数据的表设置一个唯一键,如果插入重复订单(订单重发)会报逐渐冲突;设置一个redis分布式锁,谁拿到谁可以执行,设置判断条件,消息是否存在(redis原子性操作)。

在这里插入图片描述
发送者丢消息:消费者把消息发到kafka集群,做持久化防止丢消息,发到(broker1),同步到(broker2,broker3)的时候节点挂了,kafka选择broker2作为主节点,消费者没来得及消费,消息也没同步过去,消费者下次发送消息会发送到broker2节点,也是连接到消费者,第一条消息就丢掉了。主从切换,同步不及时导致丢消息。
解决方式:kafka有一个参数设置,发送者有一个acks参数设置为all在这里插入图片描述
,就是说,发送者发送一个消息给消息中间件,如果是集群架构,他必须所有节点同步成功,才会返回发送者发送成功。
一旦做了这种设置,性能会变差,每秒接收消息量会减少。发送失败还可以设置重试参数。

消费者丢消息:为了提高性能,消费者接收一条消息后不做任何业务处理,直接commit返回消息中间件,告诉接收成功,你可以删掉消息或者位移消息,再去做业务,业务失败会丢消息。
解决方式:收到消息,先放数据库存起来,返回给中间件接收成功,然后后台有一个线程从本地表里面读消息,消息上有状态码,业务处理完,改成已经处理,设置一个定时任务,如果任务处理失败,再去补偿处理。

消息积压:业务场景碰到秒杀,很多人提交订单,消费者只有两个,瞬间积累几百万消息,消费者只能处理几十或者几百条,或者消费者挂了,如果中间件阻塞消息会影响其他业务。
解决方式:其他中间件可以加消费者,kafka不能开多个消费者,因为一个分区只能被一个消费者消费。
kafka需要先多建立几个分区,原来的消费者业务改成转发,转发给其他分区,将消息迁移到多个分区,再多加几个消费者,用脚本自动化部署,快速消费消息。

顺序消费:kafka课程

三、分布式锁

  • 基于redis
  • 基于zookeeper
    在这里插入图片描述
    多线程互斥操作
    一段业务操作,下单减少库存,查库存是10,减一,更新库存操作。
    三步代码要求三个代码保持顺序,原子性。不同JVM下不能用synchronized控制住,

Redis分布式锁:SETNX,INCR。
INCR KEY会返回1,不存在覆盖,哪个线程返回是1,会认为哪个线程拿到锁了
SETNX,在redis里面设置一个值,哪个设置成功会返回一个1,setnx lock netgrow,哪个设置成功会拿到锁,后面的重复设置不会做任何操作。
setnx == 1执行业务,最后把锁删掉:如果执行业务过程中,业务抛异常了,删除锁的命令就无法执行了,新命令来了不能加锁,就会导致死锁。
可以设置一个超时:
String lockkey = “lockkey”;
Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(“lockkey”,“netgrow”);
业务代码
最后stringRedisTemplate.delete(lockkey);

抛异常用try catch finally解决,但是可能程序挂了,运维可能kill进程或者kill-9,直接kill所有进程,温柔点的用stop,导致整个jvm进程挂了。
可以设置一个超时时间解决,stringRedisTemplate.expire(lockkey,10,TimeUnit.SECONDS);
有可能在上一条代码挂掉,Jedis有set(key,value,nx,expire,…);可以用一条命令让redis来保证代码执行成功。
**超时时间设置多少秒?**设置10s正常够了,但是如果有的不小心超时了,来新的线程可能会被第一个释放掉,第二个会释放第三个,导致后面锁全部失效了。自己的锁被别的线程释放掉
解决:加一个clientId,为UUID,把它放到value里面去,删除锁之前先get一下,判断一下lockkey的值是否为clientId,只有自己加的锁才能删掉,但是还有可能锁超时。
如果要保证一段业务在分布式环境中只有一个线程执行,就是保持原子性,还是有问题,其他解决方案。
用一个redisson框架,生产级别使用的成熟的分布式锁框架,RLock lock = redisson.getLock(lockkey); lock.lock();,try执行业务逻辑 finally lock.unlock();
redission的原理图:
在这里插入图片描述
多个线程,将Redis线程里面写一个锁的值lockkey,redisson也是往里面写值,默认超时时间30s,底层掉setnx很长参数的那个方法,设置太长如果程序挂掉会锁1个小时,超时时间不好估量,redisson设置完这个锁,会开一个锁延时线程,会定期的检查线程还有没有锁,如果持有锁就会延长锁的时间。第一个线程拿到所,其他线程想拿所会自旋锁,一个尝试获取锁,会影响一点性能,CAP问题。
Redis使用主从架构,或者集群,说单机说明你没有分布式经验。集群原理要能讲明白

如果redisson设置一个锁到主节点,主节点没同步锁到从节点,挂掉了,主从切换时,新的节点去操作新的redis主节点没发现锁,线程1还在执行业务逻辑,分布式锁又失效了
可以用zookeeper解决,zookeeper设计理念与分布式锁很符合,zookeeper可以保证数据一致性,zookeeper也是主从架构,使用zookeeper集群架构。
在这里插入图片描述

为什么没有丢失问题,zookeeper集群也有一个leader节点和多个follower节点,如果有一个请求creat一个值,zookeeper不是马上返回ok,会分为两阶段操作之后,再返回ok,
第一阶段先写到日志文件中,同时转发follower,让follower也写到日志文件中,leader如果收到半数以上follower日志文件写入成功回复之后,leader才去做commit操作,其它线程就可以看到这条信息,leader做commit的同时把commit消息同步到其他follower。
如果写的过程中leader挂了,第一阶段挂了主从切换,消息没提交,没问题,第二阶段commit客户端收到ok,进行别的操作,主节点挂了,会选其他节点做主节点,会优先选择日志消息最多的节点,至少有一个节点有日志消息,选择它作为主节点。不会100%解决,但是消息一致性高,paxos算法(少数服从多数)的变种。
zk加锁设置临时节点,会不会有死锁,有异常用finally解决,被kill了临时节点会被删掉。
还可以解决自旋锁问题,调用create命令,谁先创建成功谁拿锁,用监听的方式可以解决自旋问题,watch机制,很多线程过来加锁,创建临时有序节点,第一个线程加锁成功,拿到节点,在root根节点下面,谁创建临时节点,序号最小谁就拿到那把锁,线程1执行完删掉锁,挂掉了锁也会消失,对根节点进行监听,有监听回调机制,释放锁,删掉001节点后,所有线程都会收到删除事件,还是谁的序号最小,谁拿到这把锁,就去主动在回调的事件里执行自己的业务逻辑,就不会使用while循环持续尝试加锁。
在这里插入图片描述

四、分布式事务

在这里插入图片描述

在这里插入图片描述

五、分布式Session

在这里插入图片描述
tomcat弊端需要依赖tomcat容器,可以用spring-session 不依赖容器。

总结

普及微服务架构,缓存和异步消息,如何用分布式锁解决问题。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-07-15 23:47:47  更:2021-07-15 23:49:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 3:39:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码