丰巢面试真题讲解系列-NO5

119 篇文章 0 订阅
本文介绍了CDN的工作原理、异地多活架构、进程间通信的不同方式(包括匿名管道、高级管道、有名管道等),展示了如何使用Redis实现分布式锁,并详细讲解了Spring框架中的七种事务传播行为。还讨论了分布式系统中服务器宕机处理的方案,如Dubbo和SpringCloud的心跳检测机制。
摘要由CSDN通过智能技术生成

一.cdn(异地多活)

CDN,全称Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。

CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。

1、异地多活:异地多活指分布在异地的多个站点同时对外提供服务的业务场景。异地多活是⾼可⽤架构设计的⼀种,与传统的灾备设

计的最主要区别在于“多活”,即所有站点都是同时在对外提供服务的。

2、两地容灾切换⽅案:

在两个城市(城市1位于华南1地域、城市2位于华东1地域)均部署⼀套完整的业务系统。

二.进程之间的通信⽅式

1、匿名管道通信:

a. ⽗进程创建管道,得到两个⽂件描述符指向管道的两端

b. ⽗进程fork出⼦进程,⼦进程也有两个⽂件描述符指向同⼀管道。

c. ⽗进程关闭fd[0],⼦进程关闭fd[1],即⽗进程关闭管道读端,⼦进程关闭管道写端(因为管道只⽀持单向通信)。⽗进程可以往

管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。

2、⾼级管道通信:将另⼀个程序当做⼀个新的进程在当前程序进程中启动,则它算是当前程序的⼦进程,这种⽅式我们成为⾼级管

道⽅式。

3、有名管道通信:有名管道也是半双⼯的通信⽅式,但是它允许⽆亲缘关系进程间的通信。

4、消息队列通信:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能

承载⽆格式字节流以及缓冲区⼤⼩受限等缺点。

5、信号量通信

6、信号通信

7、共享内存通信

8、套接字通信

三.写⼀个redis分布式锁

private static final String LOCK_SUCCESS = "OK";

2 private static final String SET_IF_NOT_EXIST = "NX";

3 private static final String SET_WITH_EXPIRE_TIME = "PX";

4 private static final Long RELEASE_SUCCESS = 1L;

5

6 // Redis客户端

7 private Jedis jedis;

8

9 /**

10 * 尝试获取分布式锁

11 * @param lockKey 锁

12 * @param expireTime 超期时间

13 * @return 是否获取成功

14 */

15 public boolean lock(String lockKey, int expireTime) {

16 //获取客户唯⼀识别码,例如:mac+线程信息

17 String custId = getCustId();

18 String result = jedis.set(lockKey, custId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);

19

20 if (LOCK_SUCCESS.equals(result)) {

21 return true;

22 }

23 

24 return false;

25 }

26

27 /**

28 * 释放分布式锁

29 * @param lockKey 锁

30 * @param requestId 请求标识

31 * @return 是否释放成功

32 */

33 public boolean unlock(String lockKey,) {

34 //获取客户唯⼀识别码,例如:mac+线程信息

35 String custId = getCustId();

36 String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"

37 Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList

38

39 if (RELEASE_SUCCESS.equals(result)) {

40 return true;

41 }

42 return false;

43 }

44/**

46 * 获取锁信息

47 * @param lockKey 锁

48 * @return 是否重⼊锁

49 */

50 public boolean checkReentrantLock(String lockKey){

51 //获取客户唯⼀识别码,例如:mac+线程信息

52 String custId = getCustId();

53 

54 //获取当前锁的客户唯⼀表示码

55 String currentCustId = redis.get(lockKey);

56 if (custId.equals(currentCustId)) {

57 return true;

58 }

59 return false;

60 }

61

// 调用

1 public void test() {

2 String lockKey = "lockKey";

3 //判断是否重⼊锁

4 if (!checkReentrantLock(lockKey)) {

5 //⾮重⼊锁

6 while (!lock(lockKey)) {

7 //获取锁失败, 则阻塞⾄获取锁

8 try{

9 Thread.sleep(100)

10 } catch(Exception e) {

11 }

12 }

13 }

14 //TODO 业务处理

15 

16 //释放锁

17 unlock(lockKey);

18 }

四.spring 7种事务的传播⾏为

PROPAGATION_REQUIRED如果当前没有事务,就新建⼀个事务,如果已经存在⼀个事务中,加⼊到这个事务中。这是最常⻅的选

择。

PROPAGATION_SUPPORTS⽀持当前事务,如果当前没有事务,就以⾮事务⽅式执⾏。

PROPAGATION_MANDATORY使⽤当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED以⾮事务⽅式执⾏操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER以⾮事务⽅式执⾏,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执⾏。如果当前没有事务,则执⾏与PROPAGATION_REQUIRED类似的

操作。

五.分布式下down机的处理⽅案(⼼跳检测)

1、dubbo:服务器宕机,zk临时被删除;

2、springcloud:每30s发送⼼跳检测重新进⾏租约,如果客户端不能多次更新租约,它将在90s内从服务器注册中⼼移除。

3、apm监控

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵然间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值