微服务化的利弊及其解决方案

写在前面

原打算分析一下K8s日志收集性能相关的内容(包含文件系统、Ext4格式、磁盘寻址等内容),顺便对比一下 SSD 和 HDD 的指标从而方便决策 我的日志方案该怎么设计,②如何发挥各个组件的最大效能从而给公司省钱。不过在写背景的时候发现要表达的东西有点多,索性干脆先写一篇综述来给后面的文章做个铺垫。

本文简单谈一谈我对微服务化的一些认识,包括它们解决的实际问题,以及由它们引出的一些实际问题,并引出微服务化的解决方案——Kubernetes 技术栈。

适用人群

入门——初级√——中级——高级;本文适应初、中级及以上。

微服务化及其解决方案

应用进化趋势——粒度越来越小

(应用进化示意图——粒度越来越小)

如果了解 IT 技术的发展,同时对架构设计及其意义有一定的认识,可以这样总结过去几十年里应用的进化趋势:“单体应用” -> “初步拆分的中小应用” -> “进一步拆分的微应用(微服务)” ;也就是说应用被拆分得越来越细,粒度越来越小。

如果进一步推敲能得出这个趋势里隐含着的两个特点一、单个应用的代码越来越少,所需要的开发团队的规模越来越小(优点)。①在“单体应用”时代,单个应用的代码规模随随便便就可能到十万量级甚至百万量级,复杂度非常高,因此往往需要庞大的开发团队遵照需求梳理、架构设计、模块划分、开发、测试等一系列步骤,持续研发几个月甚至几年的时间才能实现应用的发布或交付。②到了“小应用”时代,按照业务分类把应用拆分为不同的小应用(或子模块),通过定义接口和协议淡化模块之间的耦合,一定程度降低应用的迭代成本,比如 SOA(面向服务的架构)。因为单个应用的代码规模变小了,于是可以把原来庞大的开发团队拆分为许多独立的小团队,让他们分别负责各个模块的开发,降低开发人员之间的沟通成本从而提升开发效率(参考《 人月神话 》)。③接下来到了当前的“微应用”时代,应用按照业务拆分后再按照功能进一步拆分,于是衍生出粒度更小的微服务,服务的迭代成本进一步降低;以电商购物为例,可以按照账号系统、货品详情系统、评价系统、通知系统等拆分,通知系统可进一步拆分为电话通知系统、短信通知系统、邮件通知系统等。此时,每个微应用所包含的代码规模进一步减小,开发团队也进一步缩小规模(可能一个人负责一个甚至多个应用的开发),开发成本进一步降低,单应用的开发效率进一步提升。

二、被拆的细碎以后,应用的边界越来越多,导致应用编排、运维管理变得越来越困难(缺点)a)首先,单体应用被拆分成小、微服务以后,这些服务均需要单独部署,导致部署成本变高了。程序员把应用开发完成并测试通过后,一般由运维人员负责把应用部署到生产机器;然而,开发过程与部署过程的割裂大概率造成开发环境与部署环境不一致,从而导致部署时出现各种问题,无形中增加了开发角色与运维角色之间的协作成本。b)拆分后的应用分布在不同的地方运行,让运维工作变得棘手。应用的粒度越小,资源的划分粒度也要越小,资源分配变复杂了(考虑把一台性能强劲的服务器分给一个小应用的情况,非常浪费!);应用日志分布在各种地方,日志查看变复杂了;各个应用之间通过网络互连,调用链路的跟踪变困难了,等等。c)拆分后的应用会强依赖一些公共服务,对架构和运维的要求比较高,比如被拆分的应用没有必要各自开发一套鉴权系统,可以依赖某个公共的鉴权服务对其他服务的调用进行鉴权。这类应用需要在做方案时考虑各种场景,满足所有微服务的各种需求;同时需要保证服务的高可靠性(或做好降级方案),否则很可能一个核心功能出问题整个业务出问题。d)应用拆分后,每个应用的开发团队变得非常小,团队知识积累变慢,个人成长变慢,代码质量下降。这个简单意会一下吧。

服务拆分的粒度越小越好吗

很多讲微服务化的文章大多都在①讲概念、②跑 Demo、③谈未来趋势,很少见到有文章讲服务拆分的方法论,比如:拆分粒度多大是合适的?服务拆分粒度越细越好吗?

谈架构必须要考虑实际的应用领域,所以需要根据实际情况进行分析,推荐领域驱动开发(DDD)的方法论(参考上一篇博文《从 Clean-Architecture 谈架构原理及其应用》)。

微服务化是一种趋势,应用被拆分得越来越小,这带来了一些好处,也带来了一些问题。微服务化能够给企业带来一些好处,比如对人才的要求低了,功能迭代可以更迅捷,需求响应可以更及时;但是微服务化也带来了不少问题,比如增加了 DevOps 的难度,增加了抽象公共服务的难度及公共服务的运维成本,一定程度上还增加了人才培养的难度。所以微服务实际落地时,应根据具体情况对服务拆分的粒度进行权衡,应避免贪图时髦而把团队和业务开发带入坑

微服务化的解决方案

目前业界对微服务管理的解决方案,一个是偏运维开发视角的 Kubernetes 技术栈(包括容器技术、CI/CD、Kubernetes 等),目标定位是解决微应用部署相关的问题(打包、发版、扩缩容、服务注册发现、负载均衡、服务暴露等);另一个是偏架构师视角的微服务架构(比如以 IstioLinkerdEnvoy为代表的 ServiceMesh ,Java技术栈里的 Spring Cloud,腾讯开源的TARS,等等),目标定位是解决微应用之间的流量管控(调用协议、鉴权、分限流、遥测监控等)。

这里提到的名词比较多,如果读者朋友感兴趣可以自行搜索 Docker、CICD、Kubernetes、Istio 这几个关键词(目前我是这个技术栈,以后可以一起讨论问题😆)。受到篇幅的限制,更细的就不在这里展开了。

小结

微服务化降低了应用的开发难度,加快了应用的迭代速度,但同时增加了应用之间的边界,增加了运维的挑战。Kubernetes 技术栈的出现一定程度上解决了微服务的管理问题,是一个非常值得投入时间了解的技术栈。

那么,微服务化以后应用分布在各处,如何把这些分散在各处的应用的日志收集起来从而便于查看分析呢?敬请期待下一篇博客。

参考