组件设计原则
- 软件组件是早于编程语言出现的。
- 组件和模块的区别
- 组件更多指的是物理上的,模块更多指的是逻辑上的
- 软件复杂正度和它的规模成指数关系
- 一个复杂度是100的软件系统,如果拆分成2个互补相关同等规模的子系统,那每个系统的复杂度应该是25,而不是50.
- 架构师注重的应该是每个模块之间的关系,以及整体的关系,而不是某个模块内部的逻辑
- 架构师的职责是不能让整个系统烂掉
组件内聚原则
- 复用发布等同原则
- 如果你希望别人以怎样的粒度复用你的软件,你就应该以怎样的粒度发布你的软件
- 组件是软件复用和发布的最小粒度软件单元。
- 版本号约定建议
- 主版本号+次版本号+修订号
- 主版本号升级,表示组件发生了不会向前兼容的重大修订
- 次版本号升级,表示进行了重要功能的修改,但是是向前兼容的
- 修订号升级,表示组件进行了不重要的功能修改
- 共同封闭原则
- 应该将那些会同时修改,并且为了相同目的而修改的类放到同一组件中,而将不会同时修改,并且不会为了相同目的而修改的类放到不同的组件中。
- 目的是为了在发生变更时,只需要重新发布这个组件即可,而不是一大堆组件收到牵连。
- 类似于单一职责原则
- 共同复用原则
- 不要强迫一个组件的用户依赖他们不需要的东西。
- 如果不是被共同依赖的类,就不应该放到一个组件中。
组件耦合原则
- 无循环依赖原则
- 组件依赖中不应该出现环。如A依赖B,B依赖C,C依赖A
- 稳定依赖原则
- 组件依赖关系必须指向更稳定的方向。
- 较少变更的组件是稳定的,变更较多的组件是不稳定的。
- 如果一个组件被更多组件依赖,那么就需要它是相对稳定的,不经常变更的
- 如果一个组件依赖了太多组件,那么它自己相对就是不稳定的,因为他依赖的任何组件变更都可能导致自己的不稳定
- 组件不应该依赖一个比自己还不稳定的组件
- 稳定抽象原则
- 一个组件的抽象化程度应该与其稳定程度一致,一个稳定的组件应该是抽象的,而不稳定的组件应该是具体的。
- 如果你设计的组件是具体的,不稳定的,那么可以为这个组件对外提供服务的类设计一组接口,并把这组接口封装在一个专门的组件中,那么这个组件相对就比较稳定,抽象。
- 组件的边界与依赖关系,不仅仅是技术问题
- 易变与稳定,依赖与被依赖,都需要放到业务场景中去考察
- 还需要考虑人的问题,有时组件的功能划分还会涉及到部门的职责边界,甚至和公司内的政治关联
- 技术、团队、业务是架构师需要考虑的三个方面
安全架构
- 应该有一个专门的架构师负责安全,性能方面的架
常见攻击
- XSS 攻击
- 通过服务器攻击其他用户
- 防御手段
- 消毒:对某些危险的html字符进行转义
- SQL注入
- 攻击服务器
- 防御手段
- 消毒:对sql关键字转义
- SQL预编译参数绑定
CSRF攻击
Error Code:通过服务器端返回给浏览器的异常堆栈信息来获取一些关键信息
- HTML 注释
- 文件上传:设置白名单
- 路径遍历:
- 防御方法是将js,css等资源文件独立服务器,独立域名,其他文件不使用静态url访问,动态参数不包含文件路径信息。
- 阿里的做法,在apache收到前台的请求url后再进行转换,得到真正的请求url
WEB应用防火墙
- 一个单独的类似网关的模块
- 通过管道和各种正则,识别和处理请求中的异常请求
- 开源的web应用防火墙:modSecurity,能够通过正则识别到大部分的攻击。
- 采用处理逻辑和规则集合分离的架构模式
- 处理逻辑负责请求和响应的拦截过滤,规则加载执行等功能
- 规则结合则负责对具体的攻击的规则定义,识别,防御策略等功能
- 处理逻辑比较稳定,规则集合需要不断针对漏洞进行升级,这是一种可扩展的架构设计
三种加密方式
- 单向散列加密
- 不需要知道具体的明文是什么, 只需要验证是否一致
- 比如Md5
- 对称加密
- 非对称加密
密钥安全管理与加解密服务系统架构
垃圾邮件
- 贝叶斯分类算法
- 给定条件计算概率
- A: 红色球; B: 在一号箱
- 布隆过滤器
风险控制
- 规则引擎
- 机器学习
高可用
高可用系统如何度量
- 可用性指标
- 故障分管理
- 优先故障处理
- 事后评估故障分
- 故障处理流程及考核
引起故障的原因
- 硬件故障
- 软件bug
- 系统发布
- 并发压力
- 网络攻击
- 外部灾害
高可用的架构策略
- 解耦
- 代码层的高可用是首位的
- 在逻辑层对业务进行隔离
- 隔离, 在物理层对业务进行隔离
- 业务与子系统隔离
- 微服务与中台隔离
- 生产者和消费者隔离
- 虚拟机和容器隔离
- 异步
- 多线程编程
- 反应式编程
- 异步通信网络编程
- 事件驱动异步架构, 不再由业务驱动
- 备份
- 集群设计
- 数据库复制
- CAP原理
- failover失效转移
- 数据库主主失效转移
- 负载均衡失效转移
- 如何确认失效, 需要转移
- zookeeper
- 设计无状态的服务
- 幂等
- 在失效转移时, 要求动作时要幂等的
- 事务补偿
- 传统的ACID
- 分布式事务的BASE
- 通过执行业务逆操作,使得事务回滚到之前的状态
- 重试
- 多级调用时,上游调用者超时时间要大于下游调用者超时时间只和
- 熔断
- 当某个服务故障时,为了避免出现服务级联失效, 阻止对故障服务的调用
- 断路器的三种状态:关闭/打开/半开
- 限流: 是要在客户端做的, 尽量靠前
- 当系统访问量超过了系统的承受能力, 为了保护系统, 拒绝外包的访问
- 算法
- 计数器(固定窗口)算法
- 临界点问题, 在上一个节点结束的时间点和下一个时间点开始的时间点, 可能会控制不住
- 计数器(滑动窗口)算法
- 令牌通算法
- 以固定的速度想令牌桶中增加令牌, 直到令牌通满, 请求到达时现向令牌桶申请令牌, 申请不到则触发限流
- 漏桶算法
- 令牌桶可能会出现同一时间涌入大量请求的情况
- 漏桶算法时以固定的速率释放访问请求, 如果已达到限流值, 则直接丢弃, 不会进入系统
- 自适应限流
- 实时监控和自动评估QPS
- 计数器(固定窗口)算法
- 降级
- 降级是对系统功能的限制, 在保证流量的前提下, 为了保证系统主要功能, 对系统低价值功能的限制
- 比如双十一时销售是高价值功能, 评价,收货等功能是低价值功能
- 异地多活
- 是为了解决外部异常的问题
高可用系统的运维
- 发布
- 负载均衡
- 自动化测试
- 在产品相对比较稳定后才能引入自动化测试
- 自动化部署
- 持续部署
- 持续集成
- 持续交付
- 持续部署
- 持续部署要经过自动化测试
- 预发布验证
- 预发布服务器是一种特殊用途的服务器
- 和线上服务器的唯一区别就是没有配置在负载均衡上, 外部用户无法访问
- 代码版本控制
- 主干开发/分支发布
- 分支开发/主干发布
- 分支开发/分支发布
- 团队大的适合分支多, 团队小的适合分支少
- 自动化发布
- 灰度发布
- 大规模服务器场景下, 分多次完成发布工作
- 网站运营监控
- 用户行为日志采集
- 服务器性能监控
- 业务运行数据报告
- 监控指标
监控管理
保持简单, 使得问题易于发现, 快速解决
- 目标明确, 解决特定环境下的具体问题
- 价值回归, 成本收益要合理