前言

         微服务架构与治理实战。微服务架构目前已经成为主流的互联网技术架构方案,在项目初始阶段就采用了微服务架构来开发和部署线上服务,经过一年多的实战演变,目前我们几人的开发团队,维护和管理数十个微服务,实现了一套快速开发,部署,以及服务治理和追踪的技术栈。这次我将主要给大家分享我们用到的技术内容以及开源产品的一些使用经验。主要是从系统构建,系统从0到1构建过程、微服务架构怎么样、微服务我们怎么做追踪和治理的,以及我们遇到的开源技术栈和一些总结。

 

一、系统从0->1的构建

       一开始构建我们的系统,做一个互联网项目,部署这些东西的时候,第一个问题就是用什么样的架构创建我们这套系统。我们选了SpringCloud,因为SpringCloud确实在这些方面有些优势。

      Why SpringCloud?

       部署更轻量

       第一,SpringCloud是基于SpringBoot的一整套实现微服务的框架。它提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。最重要的是,基于SpringBoot,会让开发微服务架构非常方便。在编译和部署上面,时间上面的开销也非常少,这就带来了时间上的节省,开发效率更高。

       第二,SpringCloud的源码更可控,主要是SpringCloud生态圈里面我们用到第三方工具包大部分是以开源的形式开放给我们,所以我们用到它的时候,我们很容易知道它的源码。另外如果它缺少一些特性,我们可以手动添加一些特性。当然这里面最主要的一个原因,是因为SpringCloud从一开始设计的时候有一个很重要的思想,就是这个源码写起来要简单,不会同一个东西有很多种写法。这样在阅读别人源码的时候更轻松一些,不会有源代码看起来很费劲的情况。所以这也确实是SpringCloud的一个优势,就算是在团队内部互相去看其他同学代码的时候,也会发现比之前好很多。

       生态圈内部渐渐成熟,很多优秀的工具

   SpringCloud的生态圈里面有非常多优秀的工具,SpringCloud的工具,很多工具都非常优秀,业界鼎鼎大名,包括做Eureka、Zuul等等,在各自行业里都非常好用,给了我们非常大的支持。抛开源本身,我觉得生态作用可能更大一点。

         系统构建与运维

       当时我们构建系统的时候遇到了一些问题,一开始我们没有专门的运维人员,其实到目前为止我们也没有专门的运维人员,开发人员数量也有限。在项目初期,我们对开发效率又看的比较高。当然我们有一个好处,在一开始业务量级不像大公司那么大,所以一开始不太需要考虑大规模的挑战。

       系统部署框架

       结合我们的业务场景,这是我们构建的部署方案,因为我们最终交付给用户的产品是一个web端的东西,所以需要把前端代码部署在OSS上,把所有后端服务部署到k8s里面去,大部分还是k8s请求,做各个微服务之间的转法,微服务之间的通信我们用的是REST和RMQ。

       这是我们整体的部署方案,部署方案完了,我们从一开始定位了运维和开发辅助工具,来帮助我们完成开发。在日志跟踪方面,因为微服务,你的服务数量又多,又都是分布式的。包括线上预警、资源配置、存储管理。

 

二、微服务架构

        微服务架构

      

       接下来,我来介绍一下在我们公司内部微服务架构使用的一些实践。

       首先微服务的架构,现在微服务架构已经成为一个主流,几乎很少有新的业务场景会使用单体应用的架构模式,大部分都会从一开始都定义出微服务。就以典型的小电商网站为例,基本架构,以前我要做一个电商网站,代码是一套,部署也是一套,几台机器。现在我们做了拆分,我们会按照业务率,比如会员注册、会员登陆、修改密码,都在会员系统里,会拆分成很多微服务。

       微服务架构优势

      微服务有什么好处?从领域模型纬度上,把原来很复杂的庞大系统拆分成了各个系统,各个系统之间通过这个接口来进行交互,这样以来各个业务系统变得很清晰。另一个好处是从开发人员的角度,因为这些微服务的拆分,比如我是做交易开发的,我肯定是基于交易的实现。针对会员我只关心接口怎么给我,但不关心具体实现,我编译的代码也不会影响到它的系统。所以这是微服务拆分的好处。

        微服务粒度划分

   微服务的粒度划分,业界都认可的一种方式是按照业务领域模型进行划分,比如会员系统和交易系统,它们俩在业务上有很强的隔离性,会员就管会员注册登陆方面,交易主要完成交易。这时候划分很清晰,大家也不会有什么意见。但如果交易跟退款,这俩业务模型算不算一个独立的业务模型?是分开还是合在一起?人们可能会认为它们两个是独立的业务领域,这是可以的。我一般的做法是按照开发人员纬度来配,比如退款有专门的团队或者专门的同学来管理,这时候就会拆分。如果交易和退款是同一个团队开发的,我觉得拆不拆无所谓,这时候不是很重要的。

       快速构建一个微服务

       再讲一下在我们内部如何快速构建一个微服务。强调快速的原因,也是因为在我们内部构建一个微服务是一个很轻松平常的事,不像之前体量比较大的时候,或者微服务不那么微的时候,这时候不太会去创建一个新的应用,除非你开一条新的应用线。在我们公司内部,平均每周会创建一个微服务,每周可能都要创建一个新的微服务,然后再部署上线。我们内部的微服务相对来说都比较简单,重点是提供接口,第一步定义好微服务的接口,微服务主要分三步走,第一定义接口,第二实现接口定义上线。第一定义接口,在微服务里面一旦把你的接口定义清楚,整个业务域就定义的很清楚了,接口定义清楚之后其他伙伴就可以拿接口做一些定向开发了。

       还有一个要谈的话题是接口可拓展性问题,我们想象一下,在微服务没有拆分的时候我们把所有代码都写在一个工程里,这时候这些微服务除了没有互相隔离开,没有互相部署,这时候没有太大的差别。这时候互相调用,比如交易系统要去获取会员的信息,这时候也会调用会员的接口,只是这是一个纯代码,编译上就直接调用的东西。现在由于微服务的调用,我们强行把它部署到两台机器上。因为现在微服务的存在,会员已经上线了,交易这边有一个接口,做一个改动就会带来问题,所以接口扩展性非常重要。这时候如果想要扩展接口,只要多加一个字段都可以。

       说起接口扩展性,确实很重要,以前也有参与国其他的,比如我们在定义这个接口的时候,我一开始定义输入是一个参数端,这时候如果想再加一个参数,我这个接口就得再写一个XXXV2这样的版本。另外还有一种场景,我们想要统一去分流你的远程调用的时候成本比较高,所以一开始设计好可扩展性很重要。

        至于实现接口部分就是写具体业务逻辑的事项,这部分主要的意见是要给大家提供丰富的工具,能够让大家快速的实现,有一些配置性的东西要提供便捷的方式。比如有一个应用要裂变数据库,最好你能提供获取知识库连接很便捷的方式。因为使用大量的微服务以后,微服务每天配的就会很多,你每天重复配就会很烦,所以尽量用工具化的方式,以及约定大于配置的方式避免这些问题。  

       最后是配置上线,一个新人或者老人,最好能用自动化配置上线的方式,而不是传统的方式,我有一个配置上线,我先找运维申请一台机器资源,再去申请帐号密码等等。这些东西我们在内部用了一些脚本和工具自动化解决掉了,会自动分配这些东西。

      快速构建微服务网关

       网关用了openResty,是一个基于nginx的可伸缩的Web应用服务器,提供了很多高质量的第三方模块,开发人员可以使用lua脚本调动nginx支持的各种C以及lua模块。在性能方面,OpenResty可以快速构造出支持10k以上并发连接响应的高性能Web应用系统。OpenResty在本项目中,用于JWT权限校验、Token超时时间更新、限流保护、无需登录接口的加密串验证

 

      微服务注册与发现

       

      采用Nacos微服务注册中心和配置中心。注册中心,支持权重路由和阈值保护,防止雪崩,本项目中,作为微服务模块的注册中心。配置中心,基于版本管理配置文件,业务配置参数修改后,5即可推送业务模块。

      微服务间通信

       在服务间通信这个方面,Feign设计的目的是实现跨语言远程调用的协议,在我们公司使用的场景是同语言的,因为我们内部服务大部分都是java。我们把client和server统统包在k8s集群内部,也就是后端服务全都是部署在k8s内部的,结合k8s的API来实现REST没有实现的负载均衡和服务发现这个环节,比如这个客户端要调用这个服务,它拿这个服务的名字去k8s的API查询服务对应的IP,然后再通过这个返回值调用匹配目标服务。

       另外是RabbitMQ,消息模式在微服务间通信也是非常重要的模型,在互联网系统和微服务架构比较流行的情况下会非常适用,对于系统的解耦和服务非常有价值。比如当一个订单支付成功的时候,我可能有其他三个微服务都去订阅这个订单支付成功这个消息,这三个系统根据订单支付成功分别做了自己的业务逻辑,比如同时卖家发货等等,这主要是业务通信的环节,也是微服务通信中重要的一环。

 

三、服务追踪与治理

       微服务的追踪跟治理,当微服务数量比较多,而且人员又比较少的时候,服务追踪、治理就显得比较重要了。因为确实太多了,如果凭过去一个一个LOW的方式可能管不过来。这时候从服务标准化和工具上面,一方面是把服务变成非常标准,另外一方面是提供各种各样的工具来管理和运维微服务。

      微服务标准化

       服务标准化,分为4个部分:

      第一是各种命名规范标准化

      第二是工程目录标准化

      第三是标准化以后可以利用工具生来梳理

      第四是标准化以后开发的效率也会提升

      全链路日志追踪

      接下来介绍一下服务治理的工具。第一个是全链路的日志追踪,每个微服务输入主要有三种,http、feign、mq,以及会调用DB、redis、API、FEIGN、MQ。

      这时候我们在每个节点上都打上了插件,各个都打一些插件,投入这些插件采集出这些节点上面的输入输出,还有一些性能相关的数据,把这些数据通过一些格来存储到ES上去。

       我们在这些插件上几乎记录了所有的信息,每个输入、输出以及异常情况。还有每个请求的执行时间、每个请求链路以及每个请求的上下文环境。把这些链路记录下来就很容易实现一些功能,比如我要回放之前的调用情况,我只要拿到我记录下来的数据就可以进行回放。

      还有性能监控和异常率监控,比如每个接口错误率超过30%就会报警,这样基于日志就很容易做出来。还有业务异常监控,比如1万单突然跌到1千单,就可以报警。还有调用链路梳理、依赖关系图、定向问题排查,这些都有相应的定义,也会有相应的支持,包括在问题排查的时候也非常有用,这时候用这种工具回放排查这些问题就非常容易。       这是我们内部全链路日志追踪的系统,可以精准定位到某一个请求,当时我们返回到输入。我们还可以查找它的兄弟节点以及下游节点的信息,这样整个可以在调用链路上进行游走,精准找到问题的请求。

 

四、开源技术栈使用经验

       最后给大家讲一下我们用到的一些开源的技术。在这一年过程中,确实感觉到开源技术给我们带来的用处非常大,很多都是依赖这些东西,尤其是小公司没有精力造轮子,往往是踩着别人的轮子。Nacos都讲过,是微服务注册与发现。Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。适配大部分主流框架,Dubbo,Spring Cloud,gRPC等等。mongodb是一个数据库,性能非常好,以及还有kubernetes。我们公司运维基本上没有人,所以也没有人专门做这个事情,开发的人也不愿意做这些事情,基本上通过开发工具和脚本来解决这些问题。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐