云原生
2023-06-05 15:33:23 0 举报
AI智能生成
云原生 云计算
作者其他创作
大纲/内容
云计算(基于云的业务产品及盈利模式)
产品形态(封装和抽象的层级及力度不一样)
IAAS
PAAS
SAAS
FAAS
部署模式
公有云
私有云
混合云
云原生(基于云的应用的实现方式)
现代化设计12要素(描述了云端应用服务应当遵循的一些最佳实践,可衡量一个后端服务是否适合搬到云上)
Codebase:基线代码
基线代码可以理解为多层意思:一个项目一个仓库;Git分支也不要分岔之后合不回来了;不要在多个仓库出现重复的代码,把通用的代码抽成独立维护的仓库。
Dependencies:显式和隔离的依赖
完善的依赖管理机制、显式的依赖声明文件和版本锁机制,能够减少因为错误的依赖版本导致的Bug。
Configuration:配置分离存储到环境中
配置数据和构建产物完全分离,配置数据单独管理,只在运行环境中出现。
《Beyond the Twelve-Factor App》[2]中有一个比喻:代码制品、生产环境配置 是两个危险的化学物质,混合到一起就可能随时爆炸。因此,我们需要把配置(尤其是密钥类、功能开关、策略类配置)的重要性提升到很高的级别,小心翼翼地管理。
若是配置不完全和代码分离,相当于两个危险的化合物一开始就被混合在一起,环境相关的配置,混在容器镜像、甚至代码包中,每个环境需要单独构建打包一个版本
《Beyond the Twelve-Factor App》[2]中有一个比喻:代码制品、生产环境配置 是两个危险的化学物质,混合到一起就可能随时爆炸。因此,我们需要把配置(尤其是密钥类、功能开关、策略类配置)的重要性提升到很高的级别,小心翼翼地管理。
若是配置不完全和代码分离,相当于两个危险的化合物一开始就被混合在一起,环境相关的配置,混在容器镜像、甚至代码包中,每个环境需要单独构建打包一个版本
Backing services:分离基础的后端组件
所有依赖的基础组件或者其他应用服务,比如数据库、缓存服务、消息队列、二方/三方服务,都视为外部资源,独立部署,通过网络访问。
用面向对象的术语类比,就是视别的服务为“关联”的而非“组合的”。“关联”意味着更弱的耦合,仅通过网络端口与这些依赖的服务交互,而不是进程间通信。
反模式的例子:把缓存服务和应用服务打包到同一个容器镜像,通过/var/redis.sock这样的Domain Socket形式访问;或者把第二方应用服务的源码直接复制到自己的代码中,在一个进程中互相调用。
用面向对象的术语类比,就是视别的服务为“关联”的而非“组合的”。“关联”意味着更弱的耦合,仅通过网络端口与这些依赖的服务交互,而不是进程间通信。
反模式的例子:把缓存服务和应用服务打包到同一个容器镜像,通过/var/redis.sock这样的Domain Socket形式访问;或者把第二方应用服务的源码直接复制到自己的代码中,在一个进程中互相调用。
Build, release, run:严格分离构建、发布、运行
“构建、发布、运行”三个阶段分离有两个好处:
1.职责和关注点的分离。构建是开发测试人员更关注的、发布是产品经理更关注的、运行是运维更关注的;
2.流水线模式带来的效率提升,以及各阶段之间的缓冲空间,每个阶段有专门的工具和方法论。
反模式的例子:开发改完代码,本地打个Patch发给运维,也不告知产品经理改了什么,直接口头告诉运维批量更换某些文件。
1.职责和关注点的分离。构建是开发测试人员更关注的、发布是产品经理更关注的、运行是运维更关注的;
2.流水线模式带来的效率提升,以及各阶段之间的缓冲空间,每个阶段有专门的工具和方法论。
反模式的例子:开发改完代码,本地打个Patch发给运维,也不告知产品经理改了什么,直接口头告诉运维批量更换某些文件。
Processes:无状态的服务进程
按照上一节说的,把依赖的服务分离出去,一些应用服务已经可以实现“无状态”了。但有时候,还需要对应用内部做一些改造才能实现无状态。无状态是水平扩展的前提,对于Serverless应用更是必要条件。
反模式的例子:应用服务的多个实例之间互相通信,共享一些内存数据;或者开发自治的集群选主、任务分发等功能。
反模式的例子:应用服务的多个实例之间互相通信,共享一些内存数据;或者开发自治的集群选主、任务分发等功能。
Port binding:自带端口绑定
不要依赖运行平台提供端口绑定的功能,提供出去的可运行程序,直接运行就会绑定到某个端口。比如Springboot应用通常内嵌tomcat/undertow/jetty等Java Web容器,构建出的包直接运行就绑定了端口。
反模式的例子:提供出去部署的包的是 放到Tomcat的war、放到IIS的dll,自己本身没有描述通信协议,也没有指定绑定的端口,完全依赖Tomcat/IIS的配置。
反模式的例子:提供出去部署的包的是 放到Tomcat的war、放到IIS的dll,自己本身没有描述通信协议,也没有指定绑定的端口,完全依赖Tomcat/IIS的配置。
Concurrency:通过进程的水平扩展增大并发能力
无状态的应用服务,很容易实现水平扩展,自身不会制约到并发能力。传统应用服务通常是性能靠提升单机配置,可用性靠双机热备;而云原生应用,注重的是伸缩能力(Elastic, Scalable)。
反模式的例子:把Session放到内存中。
反模式的例子:把Session放到内存中。
Disposability:易处置 - 快速启动和优雅退出
因为云原生应用需要保持更优秀的可伸缩性,服务的部署实例随时可能被创建出来、或者被销毁掉,这就要求服务自身提供快速启动和优雅退出能力。
不具有快速启动能力,水平扩容的速度受限;不具备优雅退出能力,缩容时未处理完的业务中断,会导致用户请求错误、数据不一致性等问题。
反模式的例子:很重的Java服务启动耗时十几分钟;缩容靠kill -9强杀进程;服务也没有实现收到SIGTERM信号进入“跛脚鸭状态”,也没有等待请求处理完再关闭进程。
不具有快速启动能力,水平扩容的速度受限;不具备优雅退出能力,缩容时未处理完的业务中断,会导致用户请求错误、数据不一致性等问题。
反模式的例子:很重的Java服务启动耗时十几分钟;缩容靠kill -9强杀进程;服务也没有实现收到SIGTERM信号进入“跛脚鸭状态”,也没有等待请求处理完再关闭进程。
Dev/prod parity:环境对等
开发、测试、预上线、生产环境等等,甚至本地环境,都保持环境一致,这样能最大限度减少“我本地是正常的啊”、“开发环境是正常的啊”、“是不是环境/机器问题”这类甩锅式的抱怨。
Log:日志作为事件流
应用服务不应该管日志怎么处理,日志如何处理是平台的职责,而非应用自身的业务。因此,应用服务只要把日志作为事件流抛出去就好了,容器环境中,最好的办法就是直接打印到标准输出和标准错误(stdout, stderr)。
反模式的例子:项目中写了一堆log4xx的复杂配置,日志文件存哪个路径、多长时间轮滚、保留多久删除。传统的软件这是必备的,但云原生应用,请仅保留打印到标准输出/标准错误。还有一个反模式的例子,在应用内就通过代码把日志抛到Kafka这类Broker中,无形中也让应用服务和Kafka耦合到了一起。
很多人不相信日志打印到stdout/stderr就完事了,是因为不够了解云原生世界中,各类日志收集和处理组件的强大。我们对传统的做法习以为常,却忘记了“单一职责原则”。
反模式的例子:项目中写了一堆log4xx的复杂配置,日志文件存哪个路径、多长时间轮滚、保留多久删除。传统的软件这是必备的,但云原生应用,请仅保留打印到标准输出/标准错误。还有一个反模式的例子,在应用内就通过代码把日志抛到Kafka这类Broker中,无形中也让应用服务和Kafka耦合到了一起。
很多人不相信日志打印到stdout/stderr就完事了,是因为不够了解云原生世界中,各类日志收集和处理组件的强大。我们对传统的做法习以为常,却忘记了“单一职责原则”。
Admin processes:分离管理类任务
什么是管理类任务(Admin Processes)?直译成“管理进程”感觉不太好,这里是Admin Processes指的是执行数据库DDL、周期执行的运维任务、一次性的数据迁移和修复等等这类事情,更贴切的说法是“后台管理类任务”。
反模式的例子:在应用服务运行环境中安装一个数据库客户端,运维人员手动跑一堆修改数据库的SQL;或者安装一些运维脚本,放到机器的cron table定期执行一些脚本。
反模式的例子:在应用服务运行环境中安装一个数据库客户端,运维人员手动跑一堆修改数据库的SQL;或者安装一些运维脚本,放到机器的cron table定期执行一些脚本。
微服务架构
实现方式一:SDK Spring Cloud
实现方式二:平台化 Service Mesh(未来发展主流)
容器化(微服务架构会产生成百上千个应用实例,需要对运维方式提供全新的设计和考量)
容器化引擎(实现容器化的基本职能):Docker/Podman/Containerd
容器化编排工具(大规模分布式应用编排) Kubernetes
建立在容器化基础上的 后端支持
数据库
消息列队
分布式缓存
任务调度
注册中心
配置中心
系统监控
规则引擎
自动化设施(测试,打包,部署)
DevOps
CI 持续集成
CD 持续交付&部署
0 条评论
下一页