目录
应用的服务化改造
应用分层设计
- 通常从垂直方向划分应用,分成服务层、业务逻辑层和数据层,每一层尽量做到解耦,上层依赖下层,而下层不要反向依赖上层
- 分层涉及最怕超级数据结构,如传递一个对象,然后把这个对象一直传递下去,而且每个层都可能修改这个对象,这种做法会导致两个问题:
- 一旦该对象修改,所有层都要进行修改
- 无法知道该对象在哪一层被修改过,排查问题比较复杂
因此,在设计接口时尽量使用原生数据类型,如int, string等
大中台、小前台
系统规模的发展
第一阶段:单系统
早期业务简单,几台机器撑起一个业务系统。所有的业务逻辑都部署在一台几台(甚至1台)机器上
第二阶段:分布式业务系统
单系统所有业务逻辑杂糅,问题百出,功能开发和问题排查困难
分布式业务系统:将原来的单一系统拆分成多个高内聚、低耦合的中心化系统。比如用户中心、商品中心、交易中心等等。。。
“高内聚、低耦合”:个人理解,功能高度内聚,中心与中心之间低耦合
第三阶段:平台化阶段
对于每个独立的高内聚业务系统,为了快速应对业务需求,很多时候都是通过代码来写业务逻辑;但是不同的业务,对应的业务逻辑必然会有所不同,就会导致代码层面逻辑复杂,业务之间逻辑耦合严重;最终影响研发效率,平台化应运而生
什么是平台? 就是要把基础能力和每个业务方的特性拆分,隔离业务和业务之间的逻辑。比如说两个相似的业务方有可能是冲突的,但他们需要在同一个平台上执行,这时我们必须把业务的逻辑分开。
平台化最核心的要点,是业务抽象建模和系统架构的开放性;业务抽象解决80%的共性问题,系统架构的开放解决20%的个性化问题
平台化通过合理的业务抽象建模,可以解决80%的共性问题;往往新业务的接入,可以复用这80%的共性,大大提高研发效率
个人理解:
- 平台化最核心就是业务抽象建模;“高内聚”必然可以抽象出很多通用的逻辑
- 平台只是解决了领域内部的问题
第四阶段:业务中台阶段
平台化的问题在于,每个业务都是跨几个甚至十几个领域的,而且相互关联,时间久了之后没人能够说清全局,单纯通过开发人员翻查代码了解细节,成本极高;最终往往形成需求评估效率低,业务响应速度差等问题;根源在于没人了解整个链路,非技术问题,而是复杂生态的协作问题
业务中台化在平台的基础上需要解决协作问题,主要通过三样东西
- 协议标准,运行机制
- 满足标准的分布式执行单元
- 中心化的控制单元
业务中台是一套由业务能力标准、运行机制、业务分析方法论、配置管理、执行系统以及运营服务团队构成的体系,能够给各业务方提供快速、低成本的接入和创新能力
个人理解:
- 中台必须要构建自己的一套协议标准,业务方接入是要按照中台的协议来的
- 中台是一套完整的“运产研测”体系,运营、产品在宏观上把控中台的发展方向,研发测试从技术角度规范化中台能力
中台
中台的定位
所谓定位就是要告诉别人我能做什么、我需要什么和我不要什么。
- 我能做什么,这是中台的基本盘。中台一定是提供了明确的、高内聚的功能,业务方有这方面的功能第一时间想到的就是这个中台
- 我需要什么,这是中台必须有的协议和规范;不论是新业务的接入,还是老业务的功能迭代,一定是基于这套规范进行;接入中台需要哪些数据、提供什么样的交互方式等等,要按照中台的规范来做
- 我不要什么,这是中台需要明确的界限;中台可以提供什么样的服务是有界限的。
中台的效率提升
- 沟通效率问题
- 统一术语;尤其是在运营产品和开发人员的沟通中,术语不统一会造成非常大的沟通障碍(需要关注一些形成数据的技巧,比如起一个好名字)
- 结构化表达需求:把产品需求通过一系列的术语、图表、页面等可以更好理解和呈现的方式在同一个语境中表达出来,让对方可以更好的理解
- 统一业务身份
- 开发效率
- 测试效率
- 运维效率
应用程序优化: 代码级优化
了解系统瓶颈
一个请求到服务端后会消耗各种系统资源,服务器本身会消耗CPU、内存、网络、磁盘等资源,第三方会消耗数据库连接数、redis连接数等,同时数据库、缓存本身也有性能问题需要考虑;正是这些方方面面的资源存在上限,并发请求量到达一定数量之后,某个资源可能被消耗完,从而导致系统崩盘;
作为一个系统架构师,必须了解自己系统的承载能力,以及系统短板(出现问题后可以迅速定位短板并解决问题)
一些重要的系统指标
- CPU
- 内存
- 网络(网卡流量)
- IO
- QPS
- 接口响应时间(平均、P90、P95、P99等)
- 数据库
- 客户端连接池连接数
- 服务端连接数
- QPS
- CPU
- 锁冲突
- 锁等待
- 慢查询
- redis连接数
- 客户端连接池连接数
- 服务端连接数
- QPS
- 内存使用率
- 慢查询
- 大key
大部分指标都可以从监控系统中查到;作为系统架构师(开发工程师),日常应该多关注这些指标,了解系统能力,发现系统问题
语言层面的编码建议
- 尽量使用局部变量
- 局部变量在栈内创建,速度快,且函数执行完后即销毁;不占内存,不用额外的垃圾回收
- 减少方法调用
- 每一次方法调用都会产生函数栈,开销相对较大;尽量让其成为局部变量,可减少函数调用次数
- 减少并发冲突
- 减少序列化
- 序列化与反序列化消耗较大
- 使用长连接
- 不用新建连接,减少连接使用成本