后端场景设计第一弹
如何设计RPC框架
远程过程调用(Remote Procedure Call)的目的是让我们调用远程方法一样像本地方法一样没区别。
核心组件
RPC框架主要包含四个核心部分:
-
顶层代理设计
- 提供统一的调用类,屏蔽底层细节
- 通过动态代理实现接口的远程调用
-
序列化/反序列化
- 将对象转换为二进制数据流
- 常用序列化协议:Protobuf、JSON、Hessian等
-
拼接协议/解析协议
- 定义请求和响应的数据格式
- 包含服务名、方法名、参数类型、参数值等信息
-
底层网络传输
- 基于TCP/UDP的网络通信
- 支持长连接、连接池等优化手段
如何设计一个秒杀功能
问题点
- 瞬时流量的承接
- 防止超卖
- 防止黑产
- 避免正常服务受到影响
前端解决方案
- 用CDN缓存资源,减少压力
- 在前端随机限流,降低请求量
- 按钮防抖,防止用户多次点击
后端解决方案
- 用nginx做统一接入,实现负载均衡和限流
- 服务拆分,将秒杀功能拆分成独立的服务,避免其他功能受到影响
- 将秒杀数据拆分或缓存,可以使用分布式缓存或本地缓存
- 精准的库存扣减,防止超卖,此时需要加锁,数据库常用的是乐观锁
- 使用验证码答题等手段防止系统刷单
- 幂等操作防止重复加载
- 风控识别黑产,进行流量防控且需要动态黑名单
如何设计一个消息队列
重要角色
- 生产者:发送消息的一方
- 消费者:接收消息的一方
- broker:消息中转站,负责存储和转发消息
- 注册中心:用于broker/生产者/消费者的发现,即让生产者找到当前有什么可用的broker的ip和端口这些
流程
- 生产者生产消息发送到broker
- 消费者从broker中获取消息来消费
如何设计一个线程池
什么是线程池
线程池说白了就是一个存储线程的容器,用于统一管理线程的创建和销毁。
设计考虑点
- 初始线程数:线程池初始化时创建的线程数量
- 最大线程数:线程池能够容纳的最大线程数量
- 核心线程数:线程池运行起来后长期稳定的线程数,即使有空闲线程也不会被销毁
- 任务的设计和执行:是否设计任务优先级
- 超负荷如何解决
- 设置超时然后丢弃,也可以根据优先级处理
- 日志告警或者抛出异常
如何设计一个哈希表
哈希表是什么
一个key-value的集合,通过将key进行哈希散列后对散列值取模,找到对应的value。
设计要点
- 设计哈希函数:运算要快,还不能经常哈希碰撞
- 解决哈希冲突:链表法、开放寻址法等
- 若数组太大了则考虑转成红黑树:提高查询效率
评论