石墨文档基于K8S的Go微服务实践(上篇)

1 架构演进

互联网的WEB架构演进可以分为三个阶段:单体应用时期、垂直应用时期、微服务时期。

单体应用时期一般处于一个公司的创业初期,他的好处就是运维简单、开发快速、能够快速适应业务需求变化。但是当业务发展到一定程度后,会发现许多业务会存在一些莫名奇妙的耦合,例如你修改了一个支付模块的函数,结果登录功能挂了。为了避免这种耦合,会将一些功能模块做一个垂直拆分,进行业务隔离,彼此之间功能相互不影响。但是在业务发展过程中,会发现垂直应用架构有许多相同的功能,需要重复开发或者复制粘贴代码。所以要解决以上复用功能的问题,我们可以将同一个业务领域内功能抽出来作为一个单独的服务,服务之间使用RPC进行远程调用,这就是我们常所说的微服务架构。

总的来说,我们可以将这三个阶段总结为以下几点。单体应用架构快速、简单,但耦合性强;垂直应用架构隔离性、稳定性好,但复制粘贴代码会比较多;微服务架构可以说是兼顾了垂直应用架构的隔离性、稳定性,并且有很强的复用性能力。可以说微服务架构是公司发展壮大后,演进到某种阶段的必然趋势。

6ecc671122c1326d1faa9acc563d71bc.png

但微服务真的那么美好吗?我们可以看到一个单体架构和微服务架构的对比图。在左图我们可以看到一个业务可以通过Nginx+服务器+数据库就能实现业务需求。但是在右图微服务架构中,我们完成一个业务需要引入大量的组件,比如在中间这一块我们会引入DNS、HPA、ConfigMap等、下面部分引入了存储组件Redis、MySQL、Mongo等。以前单体应用时期我们可能直接上机器看日志或上机器上查看资源负载监控,但是到了微服务阶段,应用太多了,肯定不能这么去操作,这个时候我们就需要引入ELK、Prometheus、Grafana、Jaeger等各种基础设施,来更方便地对我们的服务进行观测。

d57f7f05d35843a9c251ea41fa53b842.png

微服务的组件增多、架构复杂,使得我们运维变得更加复杂。对于大厂而言,人多维护起来肯定没什么太大问题,可以自建完整的基础设施,但对于小厂而言,研发资源有限,想自建会相当困难。

不过微服务的基础设施维护困难的问题在 Kubernetes 出现后逐渐出现了转机。在2014年6月Google开源了Kubernetes后,经过这几年的发展,已逐渐成为容器编排领域的事实标准。同时 Kubernetes 已俨然成为云原生时代的超级操作系统,它使得基础设施维护变得异常简单。

在传统模式下,我们不仅需要关注应用开发阶段存在的问题,同时还需要关心应用的测试、编译、部署、观测等问题,例如程序是使用systemd、supervisor启动、还是写bash脚本启动?日志是如何记录、如何采集、如何滚动?我们如何对服务进行观测?Metrics 指标如何采集?采集后的指标如何展示?服务如何实现健康检查、存活检查?服务如何滚动更新?如何对流量进行治理,比如实现金丝雀发布、流量镜像?诸如此类的问题。我们业务代码没写几行,全在考虑和权衡基础设施问题。然而使用Kubernetes后,可以发现大部分问题都已经被Kubernetes或周边的生态工具解决了,我们仅仅只需要关心上层的应用开发和维护Kubernetes集群即可。

90d3e52f13fe2e2857d7edf20d81a7b8.png

Kubernetes在微服务中的作用就如同建高楼的地基,做了很多基础工作,统一了大量的基础设施标准,以前我们要实现服务的启动、配置、日志采集、探活等功能需要写很多中间件,现在我们只需要写写yaml文件,就可以享受这些基础设施的能力。运维更加简单这个也显而易见,例如在以前出现流量高峰时研发提工单后增加副本数,运维处理工单,人肉扩缩容,现在我们可以根据实际应用的负载能力,合理的配置好副本 CPU、Mem 等资源及 HPA 规则,在流量高峰时由 Kubernetes 自动扩容、流量低谷时自动缩容,省去了大量人工操作。

同时在框架层面,传统模式下基础设施组件很多都是自研的,基本上没有太多标准可言,框架需要做各种switch case对这种基础设施组件的适配,并且框架经常会为因为基础设施的改变,做一些不兼容的升级。现在只需要适配Kubernetes即可,大大简化微服务的框架难度和开发成本。

2 微服务的生命周期

刚才我们讲到Kubernetes的优势非常明显,在这里会描述下我们自己研发的微服务框架Ego怎么和Kubernetes结合起来的一些有趣实践。

我们将微服务的生命周期分为以下6个阶段:开发、测试、部署、启动、调用、治理。

7c59fcbec153a1718da58e8e6b58e696.png

2.1 开发阶段

在开发阶段我们最关注三个问题。如何配置、如何对接,如何调试。

2.1.1 配置驱动

大家在使用开源组件的时候,其实会发现每个开源组件的配置、调用方式、debug方式、记录日志方式都不一样,导致我们需要不停去查看组件的示例、文档、源码,才能使用好这个组件。我们只想开发一个功能,却需要关心这么多底层实现细节,这对我们而言是一个很大的心智负担。

所以我们将配置、调用方式做了统一。可以看到上图我们所有组件的地址都叫addr,然后在下图中我们调用redis、gRPC、MySQL的时候,只需要基于组件的配置Key path去 Load 对应的组件配置,通过build方法就可以构造一个组件实例。可以看到调用方式完全相同,就算你不懂这个组件,你只要初始化好了,就可以根据编辑器代码提示,调用这个组件里的API,大大简化我们的开发流程。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值