一.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监控