一. 面向对象和设计模式
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。设计模式是在面向对象技术出现以后,由工程师们总结出来的宝贵经验。其中,最主要的23种设计模式,收录在【Design Patterns: Elements of Reusable Object-Oriented Software】一书中
设计模式的细节可能不同,但是总体的设计思想和原则都遵循如下:
单一职责原则 (Single Responsiblity Principle SRP)
开闭原则(Open Closed Principle,OCP)
里氏代换原则(Liskov Substitution Principle,LSP)
依赖倒转原则(Dependency Inversion Principle,DIP)
接口隔离原则(Interface Segregation Principle,ISP)
合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)
二. 引入docker技术带来的新变化
随着docker技术和微服务的日趋成熟。怎样合理的设计container的边界职责和协作带来了新的挑战。这个问题和面向对象及其之上的设计模式要解决的问题十分类似。container 相当于object,image相当于Class定义
三. 3种抽象设计模式
1. single-container patterns for container management
- container本身提供了类似Object一样的封闭性
container暴露的interface相当于类暴露的public方法
例如,container的资源使用情况,健康情况,等等
container生命周期的hooks,比如:created,started,before termination等等
container的可复制性-replica:类似拷贝构造函数
2. single-node patterns of closely cooperating containers
-
sidecar pattern
在主要工作的container之外,挂载一个"保姆container"。二者一起提供某种服务。kubernetes中的pod实现了类似的思想。其中"保姆container"可以被复用。
上图中的"保姆container"提供了日志收集的功能,职责分离,可以分别单独测试,可以被复用
这样设计的另一个好处是:可以分开升级,不相互影响。"保姆container"可以关闭,降级服务 ambassador pattern
代理模式。一个额外的代理container负责与外部的分布式服务通讯,简化、屏蔽了外部系统的复杂性。主container只需要假设和localhost的进程通讯即可
如上图,代理container可以负责与外部的分布式存储连接提供容错,负载均衡等功能。该container可以被复用
-
Adapter pattern
如上图,adapter container 适配了不同的主container和统一的监控框架之间的信息差异。同样,adapter container 也可以方便的复用
3. multi-node patterns for distributed algorithms
leader election pattern
原来的选主操作需要application集成lib来实现,如:集成raft协议的lib来实现。另一个更好的选择是使用一组带leader election 功能的“保姆container”来实现。application需要区分主从的时候,依赖本pod的“保姆container”状态来区分。带leader election的container可以复用work queue pattern
使用docker 灵活的启动消费Worker container来处理Queue中的Job
一个真实Use Case:视频处理, 1pod分析处理1个mp4视频文件,并且使用gpu硬件加速
灰色的worker container中基础框架部分,可以重用
kubernetes 原生支持此workload类型:Job
- scatter/gather pattern
这种模式在搜索引擎中十分常见。整体后端服务,是一个树形的结构。根节点接收/分发query给不同的库,之后,整合,rank不同库的返回结果,返回给用户
如上图,灰色的container完成了并发的分发,和整合数据的复杂操作,可以复用。用户自定义的逻辑container可以方便的在之上做进一步操作处理
综合上述的3种设计模式。个人觉得,基于docker的设计模式有如下的优点
1)更好地拆分服务(模块,containers)给不同的team,支持各种语言,提高研发效率。微服务架构也是类似
2)更高级别的复用模块,如:一个container整体通过配置,可以很方便地添加到一套新的分布式系统中去,想拼积木一样,灵活插拔