人人都是架构师总结


//---------- 需求 ----------//
互联网各个领域
教育
医疗
农业
娱乐
社交
购物
旅游
政府
金融
交通

//---------- 架构演变 ----------//
一旦业务开始加速发展,用户逐渐增多,系统瓶颈开始暴露,可以做以下四点调整
独立部署
web服务器集群,实现可伸缩性
部署分布式缓存系统,使查询尽可能在缓存命中
数据库实施读/写分离,实现HA(高可用)架构

发展到一定阶段
利用cdn加速系统响应
业务垂直化,降低耦合,从而实现分而治之的管理

soa
微服务

//---------- 系统服务化需求 ----------//
超时和重试(failover 读操作)
<!--- 服务调用失败时, 重试其他服务节点,通常用于读操作 --->
<dubbo:registry cluster="failover" />
<!--- 只发起一次调用, 失败立即报错,通常用于非幂等性的写操作 --->
<dubbo:registry cluster="failfast" />
<!--- 失败安全,出现异常时直接忽略,通常用于写入审计日志等操作 --->
<dubbo:registry cluster="failsafe" />
<!--- 失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作 --->
<dubbo:registry cluster="failback" />
<!--- 并行调用多个服务节点,成功1个即返回,通常用于实时性要求较高的读操作 --->
<dubbo:registry cluster="forking" />

上面的配置也适用于服务提供方,如果服务调用方和服务提供方配置有相同的参数, 默认以调用方为主

服务治理
服务的动态注册与发现
服务的扩容评估
服务的升/降级处理
黑白名单
权限控制
服务负责人
资源调度
服务跟踪

分布式事务
分布式事务一般情况下保持最终一致性即可
jvm调优,吞吐量和低延迟是相互矛盾

//---------- 分布式调用跟踪系统 ----------//
(定期清理数据)
服务性能低损耗
业务代码低侵入
监控界面可视化
数据分析准实时

dubbo RpcContext

采样率方案(可配置)

//---------- 大流量限流/消峰 ----------//
问题:
连接资源耗尽
分布式缓存的容量被撑爆
数据库吞吐量降低

方案:
扩容
动静分离(静态放cdn)
缓存
服务降级
限流

令牌桶算法限制的是流量的平均流入速率
漏桶算法限制的是流量的流出速率

guava ratelimiter

nginx 接入层限流
http {
    
    # 定义每个IP的session空间大小
    limit_zone one $binary_remote_addr 20m;

    # 与limit_zone类似,定义每个IP每秒允许发起的请求数
    limit_req_zone $binary_remote_addr zone=req_one:20m rate=10r/s;

    # 定义每个IP能够发起的并发连接数
    limit_conn one 10;

    # 缓存还没来得及处理的请求,缓存不下新的请求将会被拒绝和抛弃
    limit_req zone=req_one burst=100;

    server {
        listen 80;
        server_name localhost;
        location / {
            stub_status on;
            access_log off;
        }
    } 

}

消峰
分时段
排队

异步
多线程/fork join

mq(activeMq)

rocketMQ
支持顺序消息
支持事物消息
支持集群与广播模式
亿级消息堆积能力
完善的分布式特性
支持push和pull两种消息订阅模式

单master模式
多master模式(建议,宕机不能消费)
多master/slave异步复制模式(性能低)
多master/slave同步双写模式(性能高)


//---------- 分布式配置管理服务案例 ----------//
集中式资源配置需求
配置信息统一管理
动态获取/更新配置信息
降低运维人员的维护成本
降低配置出错率

zookeeper
配置管理
分布式协调/通知
分布式锁
统一命名

节点维护着一个版本号(dataVersion),随着数据的变更递增
实现Wathcer接口用于监听事件变更
Znode不适合存储大数据

// bean动态注册
//实现接口ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    //如果Bean定义中配置了数据源信息,一定要将属性"destroy-method"设置为"close"
    ConfigurableApplicationContext cfgContext = (ConfigurableApplicationContext)applicationContext;
    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)cfgContext.getBeanFactory();
    new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(new FileSystemResource(""));
    String[] beanNames = beanFactory.getBeanDefinitionNames();
    for (String beanName: beanNames) {
        beanFactory.getBean(beanName);
    }
}

客户端容灾
Diamond
配置信息固化到服务端数据库,服务端本地缓存,客户端本地缓存中

//---------- 大促场景下热点数据的读/写优化案例 ----------//

缓存
缓解应用系统或关系型数据库的负载压力
提升系统吞吐量

Ehcache
Ehcache的本质是同一个进程内的缓存技术
特殊的应用场景下,本地缓存 + 分布式缓存

oof-heap
存放生命周期长的对象

redis
jedis

集群
水平化处理

分布式缓存可能存在的单点瓶颈

同一热卖商品高并发读需求
基于redis集群多写多读方案
使用zookeeper来配置同一热卖商品的key

localcacahe结合redis集群的多级cache方案
本地缓存只需缓存两类数据+定时轮询查询更新+不设置TTL过期策略
商品详情
商品库存
实时热点自动发现机制

同一热卖商品高并发写需求
乐观锁
利用"实际库存数>=扣减库存数"

查询InnoDB行锁时所引起的一系列问题
select * from information_schema.INNODB_TRX where trx_state='LOCK WAIT';

分布式锁来避免超卖
分布式锁不能沦为系统瓶颈
不能产生死锁
支持重入锁

redssion
clusterServersConfig.setMasterConectionPoolSize(100);
clusterServersConfig.setSlaveConnectionPoolSize(100);
clusterServersConfig.setTimeout(1000);

redisson = Redisson.create(config);
RLock lock = redisson.getLock("xxx");
lock.lock(20,TimeUnit.MILL);
lock.unlock();
boolean lockResult = lock.tryLock(10,20,TimeUnit.MILLISECONDS);
if(lockResult) {
    lock.forceUnlock();
}

批量提交扣减库存
库存扣减结果如何响应给指定的用户
如何避免商品库存售不罄

redis watch命令实现乐观锁

控制单机并发写流量方案
单机排队串行写方案(不建议)
抢购限流方案
AliSQL5.6.32


//---------- 数据库分库分表案例 ----------//

数据库读写分类

数据库垂直分库

数据库水平分库分表

sharding
sharkey(路由条件)
定义一套特定的路由算法和规则

Cobar 代理
Mycat 代理 √
Shark 应用集成 √

Shark
支持两类分库分表模式
单库多表模式
多库多表模式

读写分离
wr_index=r32w0 //不配置读写分离 r0w0

分库分表模式
shardMode=true
consistent=true
分库路由算法
dbRuleArray=#key1|key2# % 1024 / 32
分表路由算法
tbRuleArray=#key1|key2# % 1024 / 32
表后缀拼接规则
tbSuffix=_0000

com.sharksharding.core.shard.SharkDatasourceGroup
targetDataSources
key=0
value-ref="dataSource1"
...

扩容
片的数量=2*库的数量

使用jdbcTemplate

如果sql语句中的第一个参数并不是定义在配置信息中的路由条件时,那么shark将抛出异常

分库分表后的影响
acid如何保证
多表之间的关联查询如何进行
无法继续使用外键约束
无法继续使用oracle提供的sequence或mysql提供的AUTO_INCREMENT生成全局唯一和连续性ID

避免多表联合查询

多级sequenceId

shark获取唯一性和连续性的sequenceID
建表
配置数据源
SequenceIDManger.init(dataSource);
调用SequenceIDManger.getSequenceId(100,10,5000); //IDC机房,业务类别,数字长度(向数据库申请的ID缓存数)

Solr
满足多维度的复杂条件查询(解决like模糊查询慢)

分布式事务
两阶段提交协议
三阶段提交协议
paxos协议

尽量避免分布式事务

数据库高可用方案
主从
基于配置中心实现主从切换(手动切换)
shark
GetJdbcTemplate.getJdbcTemplate();
<bean /> 标签中属性destroy-methos一定要设置为close

基于Keepalived实现主从切换(自动切换)

基于MHA实现主从切换

mysql半同步复制
峰值流量较大的场景TPS有影响

(分库分表后)订单冗余表需求
同一份(买家卖家)订单数据进行冗余存储

数据同步写入
数据异步写入

优先保证买家的数据落盘

保障冗余表的数据一致性
最终一致性

线上检测补偿

基于增量日志扫描的线下检测(定时任务扫描)

1,单机

 2,集群

3,使用cdn加速系统响应

4,垂直拆分

5,企业soa

6,微服务架构

 服务化与RPC

序列化与反序列化在重性能场景可以使用二进制协议

为dubbo设置超时时间应该是有针对性的,业务时间短,设置短,业务时间长,设置长一些

写服务不建议开启failover,读服务开启才会显得有意义

限流

令牌桶算法流程

 

漏桶算法流程

 rocketMQ

消峰案例

缓存优化-cdn

缓存

多级缓存

实时自动发现机制

库存扣减

库存扣减优化

redis watch

并发写抢购

读写分离

垂直分库

水平分库分表

数据库高可用

主从

keepalived

 mysql半同步复制机制

写冗余表(起线程或者队列)

线上检测补偿机制

线下检测补偿

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

星月IWJ

曾梦想杖键走天涯,如今加班又挨

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

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

打赏作者

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

抵扣说明:

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

余额充值