传统架构 vs 云原生架构,谈谈为什么我们需要云原生架构?
云原生架构是什么
为什么需要云原生架构
餐饮 SaaS 厂商帮助线下餐饮门店开发小程序点餐系统,实现无接触点餐。 电商零售领域的 ERP 厂商帮助企业建立会员管理系统。 营销 SaaS 厂商通过流量平台帮助企业在线营销,远程触达客户。
大多 SaaS 产品只做所谓的通用能力,或者只是一味模仿国外产品,一旦深入到行业属性比较重的场景时便无法满足需求,所以被贴上了“半成品”的标签,导致市场接受程度不如预期。
产品模块单一、功能相似的 SaaS 产品很容易陷入价格竞争,最后只能以亏损获得网络效应,但会终食恶果。
市场对 SaaS 产品的定制化需求过多,使得 SaaS 企业缺乏对产品打磨的精力,把一个 SaaS 型公司做成了项目型公司。
云原生将三方软件和非功能性能力的完全兜底,可以极大程度解放企业研发、运维人员的精力,并使其可以专注在业务上。
系统的横向扩展性、高可用性、健壮性、SLA 由云原生架构兜底,解决了 SaaS 产品最忌讳的稳定性问题。
将一些自建的组件迁移至云原生架构中,对传统的部署方式和资源进行云原生化,GitOps 的落地,在资源成本和人力成本方面都有进一步的优化。
如何落地云原生架构
传统架构
无服务化(Serverless)
运维成本高:ECS 的各项状态、高可用都需要运维同学维护。
弹性能力不足:每次有大促活动时,都需要提前购买 ECS,扩展服务的节点数,然后再释放,并且这种情况只适用于定时定点的活动,如果是不定时的流量脉冲则无法应对。
1、命名空间
2、创建应用
应用名称:服务名称,用户自行输入。
专有网络配置:
自动配置:自动帮用户配置 VPC、Vswitch、安全组。这些组件都会新创建。
自定义配置:用户选择命名空间,VPC,VSwitch 以及安全组。一般选择自定义配置,因为咱们的服务所属的VPC肯定要和其他云资源的 VPC 是相同的,这样才能保证网络畅通。这里需要注意的一点是,当在新的命名空间下第一次创建好应用后,该命名空间就会和所选的 VPC 进行绑定,之后再创建应用时,该命名空间对应的 VPC 不可更改。如果需要更改,可以进入命名空间详情进行更改。
应用实例数:应用(服务)节点数量,这里的节点数量按需设置,而且不是最终设定,因为后续可以手动或者自动的扩缩节点数。
VCPU/ 内存:该应用在运行过程中需要的CPU和内存的规格。这里的规格是单个实例数的规格。既如果选择了 2C4G,那么有 2 个实例的话,就是 4C8G。
技术栈语言:Java 语言支持镜像、War 包、Jar 包三种部署方式,其他语言支持镜像部署方式。以 Java Jar 包方式为例:
应用运行环境:默认标准 Java 应用运行环境即可。
Java 环境:目前支持 JDK7 和 JDK8。
文件上传方式:支持手动上传 Jar 包或者配置可以下载 Jar 包的地址。
版本:支持时间戳和手动输入。
启动命令设置:配置 JVM 参数。
环境变量设置:设置容器环境中的一些变量,便于应用部署后灵活的变更容器配置。
Host 绑定设置:设置 Host 绑定,便于通过域名访问应用。
应用健康检查设置:用于判断容器和用户业务是否正常运行。
应用生命周期管理设置:容器侧的生命周期脚本定义,管理应用在容器在运行前和关闭前的一些动作,比如环境准备、优雅下线等。
日志收集服务:和 SLS 日志服务集成,统一管理日志。
持久化存储:绑定 NAS。
配置管理:通过挂载配置文件的方式向容器中注入配置信息。
3、绑定 SLB
4、服务/配置中心
需要快速转型,对服务/配置中心高可用要求不是特别极致的情况下,建议直接使用 SAE 自带的 Nacos 即可,代码不需要做改动,直接在 SAE 中创建应用即可。SAE 控制台提供的配置管理在界面操作和功能上和开源 Nacos 的控制台基本一致。
对服务/配置中心高可用要求比较高的情况下,建议使用 MSE Nacos,它的优势是独享集群,并且节点规格和节点数量可以根据实际情况动态的进行调整。唯一不足的一点就是需要修改 Nacos 的接入点,算是有一点代码侵入。
支持三大主流服务中心,节点规格和数量灵活搭配,可在运行时动态调整节点规格/数量。
通过命名空间逻辑隔离不同环境。
配置变更实时推送并且可追踪。
弹性能力(Elasticity)
1、手动扩缩
2、自动扩缩
3、成本优化
可观测性(Observability)
应用的整体健康状况。
应用每个实例的健康状况。
应用每个接口的健康状况。
1、应用整体健康状况
总请求量:可以一目了然的看到请求量是否明显的异常,比如骤降或者陡升。
平均响应时间:应用整体接口的平均响应时间,这个指标直接反映最真实的应用健康状况。
Full GC:JVM 里比较重要的指标,也是会直接影响系统性能的因素。
慢 SQL:智能抓取执行时间大于 500ms 的 SQL。
一些曲线视图:帮助我们掌握不同时段的应用情况。
2、应用实例节点健康状况
3、应用接口健康状况
4、纵向 Metrics 指标
5、横向调用链路
该接口在服务级别的完整请求链路,比如 ikf(前端)-> ikf-web(java 服务)-> ikf-blog(java 服务)-> ikf-blog(java 服务)。
每个服务的状态情况,比如状态一列是红点,说明在这个环节是有异常出现的。
在每个服务中请求的接口名称。
每个服务的请求耗时。
上游服务 ikf-web 的总耗时是 2008ms,但下游服务 ikf-blog 的总耗时是 5052ms,而且耗时起点是一样的,说明 ikf-web 到 ikf-blog 是一个异步调用。
既然 ikf-web 到 ikf-blog 是异步调用,然而 ikf-web 的耗时有 2s 之多,说明 ikf-web 服务中的接口也有问题。
在 ikf-blog 服务中,又有内部接口被调用,因为从调用链上出现了两个 ikf-blog,并且这个内部调用是同步调用,而且问题出现在最后一个接口调用上。
具体的方法。
每个方法的耗时。
方法产生的具体异常信息。
数据库操作的具体 SQL 语句,甚至 SQL 上的 Binding Value。
BlogController.findBlogByIsSelection(int isSelection)
这个方法的耗时是 5s,但是该方法内部的数据库操作的耗时很少,只有 1ms,说明耗时是属于业务代码的,毕竟业务代码我们是抓不到也不会去抓取信息的。这时我们可以有两种方式去定位具体问题:从方法栈信息中已经知道了具体的服务和具体的方法,那么直接打开 IDE 查看、分析代码。
查看方法栈页签旁边的线程剖析,也基本可以确定问题所在。比如上图这个情况,我们查看线程剖析后会发现他的耗时是因为
java.lang.Thread.sleep( ):-2 [3000ms]
。
韧性能力(Resilience)
1、优雅上下线
注册中心不可靠、通知不及时。
客户端轮训不实时、客户端缓存。
自定义镜像非1号进程,Sigterm 信号无法传递。
无默认优雅下线方案,需要添加 actuator 组建。
2、多 AZ 部署
3、限流降级
自动化能力(Automation)
1、基于 Gitlab 和 Jenkins
toolkit_profile.yaml:配置 RegionID、AccessKey ID、AccessKey Secret。 toolkit_package.yaml:配置比如应用部署包类型、部署包地址、镜像地址。 toolkit_deploy.yaml:配置比如 SAE 应用的 ID、应用所属命名空间 ID、应用名称、发布方式等。
clean package toolkit:deploy -Dtoolkit_profile=toolkit_profile.yaml -Dtoolkit_package=toolkit_package.yaml -Dtoolkit_deploy=toolkit_deploy.yaml
2、基于 Open API
总结
无服务化:3分 弹性能力:3分 可观测性:2分 韧性能力:2分 自动化能力:2分
﹀
﹀
﹀