作者:杨磊
青团社是国内当先的一站式灵便用工招聘服务企业,灵便用工行业的 Top1。青团社于 2013 年在杭州成立,业务曾经覆盖全国,在行业深耕 10 年。我的分享将分为以下三局部:
- 青团社架构演进的历程
- 青团社如何实现云原生
- 总结与瞻望
云原生架构的演进历程
2020 年,咱们的技术架构比拟单薄,存在较多问题。面对这些问题,团队开始了架构演进,存在的问题次要是以下多个方面。
第一,运维能力和可观测性比拟差,因为公司大部分都是业务研发人员,业余的 DBA 和运维都没有。
第二,在业务刚刚开始起步时,业务迭代速度十分快,每天都会有很频繁的公布,线上常常因为公布导致一些稳定性的问题,作为平台型公司连贯 B 端和 C 端两端,对线上可用性要求十分高,但晚期的架构设计也不太正当,所以很多时候利用是无奈反对高可用的。
第三,因为线上的资源部署不太正当,比拟浪费资源,资源老本较高。
第四,部署模式比拟粗放,日志、告警都没有,所以出了问题之后排查十分艰难,研发人员通常须要很长时间能力把这些问题弄清楚,响应工夫比拟长,置信大部分初创型公司在业务晚期倒退的阶段都存在这种问题。
那咱们如何去应答这些挑战呢?答案就是 应用云原生架构来重塑架构体系, 一直地对架构进行演进,抉择适合的技术栈,配合应用云的基础设施,来构建业务平台,让零碎达到好的水准。
从下图中能够看到,青团社的业务架构演变遵循从单体架构到 SOA 架构再到微服务。基础架构物理机是没有的,团队从 2014 年开始就间接应用阿里云 ECS,在 2021 年开始容器化,最终达到冀望的云原生架构状态。
云原生基金会官网对云原生的定义是 5 局部,第一是容器化,第二是不可变基础设施,第三个是申明式 API,而后是服务网格和微服务,其中微服务作为承载业务利用的外围,围绕这个,会有像调度编排、流量治理、可观测、DevOps 这些畛域的一些能力,这是技术架构要做的事件。
从技术角度看,云原生架构是基于云原生技术的一组架构准则和一些设计模式的组合,将利用中的非核心的业务逻辑剥离进来,而后下沉到云原生基础设施这一层来对立解决,这样业务开发人员只须要关怀本人的业务开发,让咱们的业务利用变得更加轻量,高效。
因为公司是 2013 年成立的,晚期的业务非常简单,运维能力也比拟差,所以单体架构是优选。通过四五年的倒退,业务有了长足的提高,平台的性能和模块都曾经比拟多了,因而,就降级到 Spring Cloud 微服务架构。过后用的是一套规范的用法,比方服务注册核心、配置核心用的是 Eureka,网关用的是 Spring Cloud Gateway。
此时,尽管实现了微服务架构,但也存在诸多问题,例如服务不稳固、排查效率低下、资源利用率低等。基于这些问题,开始做业务容器化革新。
首先,选用成熟的 K8s 平台去做业务容器平台,先解决部署与排查问题。一开始咱们选型的是阿里云容器服务 ACK Serverless 版,次要是看中了它开箱即用,不须要额定去保护,比较简单的长处。在应用的过程中,次要是先在开发侧去验证它,用了一段时间到 2021 年的时候,就实现了线上的迁徙。
之后选用阿里云 ACK 的技术底座去实现线上容器化革新的起因是,过后在用 Serverless 过程中呈现一些问题,比方调度比较慢等,在过后咱们是没有这些能力去解决的。革新之后,大略是 300 多个微服务。此外,还波及到一些基础架构的革新,比方服务注册核心,咱们原先用的是 Eureka,起初迁徙到 MSE 的 Nacos 里,配置核心应用了 MSE Nacos,来晋升性能和稳定性。
在可观测性和应用性的架构上,开始用阿里云利用实时监控服务 ARMS 的利用监控能力和 MSE 产品来对应用服务进行性能观测与流量治理,这些都是在 2021 年这一年去实现的。
2021 年 8 月,咱们将 Spring Cloud Gateway 进行了迁徙,因为过后 Spring Cloud Gateway 的问题比拟多,性能也比拟差,所以就基于开源做了本人的 API 网关,再联合 MSE 的微服务套件,实现了流量治理。2022 年之后,开始做业务指标监控和稳定性建设这方面的工作。
青团社云原生架构实际
接下来是实际的局部,这张图是线上的部署图。
后面这 4 个局部都是技术接入层,如 BGP 高防、WAF、BFF 等,次要提供根底的平安防护和路由转发性能。到了虚线这一部分是 K8s 集群,是基于 ACK 构建的容器运行平台,咱们所有的业务容器都运行在 ACK 外面。
大家能够看到,咱们使用了很多阿里云的中间件服务,比方 Kafka、RocketMQ。这些都是在应用 MSE 微服务引擎之后最新的一版架构,因为咱们人手无限,所以 为了线上的服务稳定性和升高运维老本,会间接用阿里云的这些云产品。 网关方面,微服务外部的东西向流量次要由微服务引擎 MSE 来做流量治理,它给咱们提供了一些能力,比方服务优雅上线下线,流量灰度,还有同可用区域这些部署能力。
接下来,咱们将从 调度编排、流量治理、可观测 3 个维度开展咱们的实际。
1. 云原生架构实际调度编排
第一局部是调度编排方面,咱们有三个伎俩。首先是应用阿里云 ACK 作为技术底座来构建容器平台,再配合资源隔离的部署模式,保障多条业务线互不影响,因为咱们有两条不同的业务线,所以无论是在成本核算还是服务稳定性,都会做到资源隔离。弹性伸缩方面是通过一些弹性伸缩策略获得老本和稳定性之间的均衡,降老本的同时不能损失稳定性。
接下来,通过两个案例论述一下,第一是咱们怎么样用 ACK 来实现高效弹性部署。
首先,在部署的时候是多可用区的,有杭州 H 区和 K 区,这是两个主可用区,所有的服务在部署的时候,在 K8s 的节点分隔上和调度策略上加一些标记,让它可能把业务负载给打散,这样一个服务有两个实例的话就是 K 区和 H 区各一个,一个挂了另一个还是好的。
在公布阶段,因为滚动更新是 K8s 内置的机制,能够通过简略的配一些健康检查的机制来失去好的公布体验,保障服务在公布的过程中不会呈现业务受损。通过资源监控和业务容器监控,能够灵便伸缩业务容器的规模。节点池设计是 ACK 独有的,它相当于能为不同的业务线配专属节点,这样就能够达到物理隔离,有了节点池,要去做集群的弹性伸缩容的时候就十分不便,集群资源不够时能够通过简略的通过节点池的扩容操作,霎时把节点池资源能力晋升下来。
CSI 插件次要是用在开发测试环境。咱们为了节省成本,很多开发测试环境,像中间件都是用容器自建的,容器自建属于有状态利用,有状态利用须要存储来反对它。CSI 插件,阿里云提供了很多对应的对接,比方阿里云的云盘 OSS、NAS 等。咱们次要是用云盘插件来对接,把云盘挂到容器里,这样像数据库、Redis 等就能够失去稳固高效的存储。
VPC 方面,因为 ACK 里 VPC 网络是直通的,咱们用的是阿里云的 Terway 插件,这个插件能够把容器外部的网络和咱们的 VPC 相互买通,这个能力咱们感觉比拟重要,是因为没有上容器平台之前,咱们的服务都是部署在 ECS 机器上的,当初如果要迁进去,咱们的服务发现组件它在集群之外,就必然要让网络可能互通,否则它发现不了也就无奈迁徙了,所以 VPC 直通性能对咱们是十分有用的。
另外还有集群监控,次要是体现在 ACK 提供了开箱即用的集群,借助与 ACK 深度集成的可观测监控 Prometheus 版,对 K8s 集群和业务容器轻松构建资源监控体系。一方面,能够及时理解容器运行状况和集群运行状况,另一方面,这些集群监控的技术指标能够作为咱们判断零碎是否须要扩容缩容的数据根据。通过部署基于指标或者是事件的弹性深度机制,可能疾速对容器进行扩容。
以上这些应用场景,大部分公司应该都是相似的,能够总结一点:通过容器化来部署,充分运用云的能力,升高利用老本,保障利用高可用。 这是第一个案例。
第二个案例是如何利用云来实现业务弹性。
这里有三个小的业务场景,第一是埋点,第二个是广告投放,第三个是热点流动。
埋点大家应该都不生疏,每个互联网公司都会须要埋点,通过埋点数据来理解用户,剖析用户。埋点数据作为剖析用户行为的数据资源,在整个产品的生命周期外面都十分重要。然而埋点数据的量通常都是十分微小的,用户每一次点击,页面的曝光,还有用户的交互都会产生很多埋点数据。这些数据能够上传到后盾去剖析产品的应用状况,剖析用户的行为和应用习惯,还能够延长出做用户画像,用户偏好及用户转化门路这一系列数据产品。
咱们的埋点有很显著的潮汐特色,流量通常是早上七八点钟开始逐步回升,到了中午十一点、下午两点达到一天的高峰,而后再开始逐步降落,到夜晚四五点钟的时候就达到一天中最低,埋点数据量的规模也遵循这样的法则。
埋点数据,咱们通常是先把数据发到后盾,后盾有埋点接收数据的处理程序,先简略的把它解决一下,而后给它丢到 Kafka 里,再由大数据的一个平台的组件去生产,生产完之后存储进去。
咱们的大数据团队会通过埋点数据来构建不同的数据层,供不同的业务场景应用,在部署埋点接管程序的时候,就会充分考虑埋点流量的潮汐特色,去把它做一些定时扩容缩容的机制,比方能够加一些定时工作,早上九点、十点开始扩容扩一倍,就能够应答一天的流量顶峰,到早晨再把它缩回去。
广告投放方面也很重要。咱们平台也和很多互联网平台有广告投放的单干。在他们平台外面去投放广告吸引新用户。作为一项日常的经营工作,投放的工夫点可能不太固定,它的成果也不肯定能依照预期来,有时候呈现爆点,流量就可能会被打爆。同时,随同流量而来的一些点击数据或埋点数据都会剧增。
为了做好日常广告投放的工作,咱们做了基于指标和事件的动静扩缩容机制。如果是因为利用容器资源,比方 CPU 内存爆了或者是达到了警戒线,又或者是解决数据的程序,有 MQ 音讯积压的事件呈现了之后,就去对事件进行监控,而后动静的去扩容。
咱们用开源的 KEDA 工具配置业务指标进行监听,KEDA 工具通过监听 Prometheus 外面的指标 (咱们所有的指标都存在 Prometheus 外面),如果触发条件了之后会向 K8s 的 API server 发动一个 Pod 的扩容申请,这样就实现了扩容操作,整个过程都是自动化的。
最初的热点流动,相似于电商外面的促销流动,这个场景的特点是它的开始工夫和完结工夫都是曾经提前晓得的,这样只须要装备提前扩容的程序就能够了,比方到体验流动开始前的半小时先把容器给扩下来,完结之后就缩回去,咱们次要是基于指标和事件这两点来做弹性扩容。
2. 流量治理
这部分次要分享一下怎么去对流量进行治理。咱们次要分三个局部:网关、流量服务治理引擎 MSE、音讯队列。
这里有两个案例,因为作为头部的灵便用工企业,咱们有很多端,比方有 C 端,B 端,有安卓平台,有 iOS 平台。各大互联网平台,像支付宝、抖音、快手、百度、QQ 等都有对应的投放、产品和小程序在下面。
行业上也次要聚焦于 8 大行业,像餐饮、物流、商超这些。在这种在多端口,多行业的场景下,咱们的报名岗位在类目上,或者是端口上都有很多差别,无论展现逻辑还是流量散发的规定都是有差别的。咱们通过 API 网关和 BFF 来实现流量编排和不同端口的差异化解决。
网关这块次要是把流量引进来,BFF 次要是适配各端,它本人可能须要独有的一些数据格式,而后再调用后端的数据返回去。在网关里,BFF 自身是作为后端服务存在的,流量先通过网关,再通过 BFF 后通过后端把数据返回去。BFF 具体的实际架构不再赘述,但在青团社是用这个模式来做多端口的适配。
第二个案例是基于事件驱动构建灵便响应零碎,案例是咱们灵工管家这个产品,该产品次要是提供一系列的治理服务,比方考勤、发薪,还有排班等服务,这些服务是企业用到的一些企业级服务。平台用户能够做到薪资日结,像很多兼职岗位,商家都是提供兼职日,你早上去下班打卡,而后上班打完卡,还没到你回家,工资就到账了,这个就任体验是十分好的。
这就是基于事件来驱动,上班打卡之后会触发上班打卡的事件,触发算工时、算薪资的逻辑,再到提前到账,整个流程是全副事件驱动的,快的话可能几秒钟你的薪资就能到账,这也是灵工管家的比拟好的一个产品卖点。
当然音讯 MQ 的场景是很常见的音讯解耦,但咱们还有别的场景,咱们把 MQ 用在数据同步和音讯散发上。数据同步用了一些插件和组件做一些数据同步的工作,MQ 能够给它做一个缓冲,防止数据很多,一下子把对端给打爆了。
音讯散发的话,咱们音讯平台会有一些定时须要触发的定时音讯,比方给用户发推送短信,咱们会利用 MQ 的提早音讯能力去做,相当于到点之后,你就去触发这一音讯,而后给用户发短信,发 push,这是一个具体的案例。
上面的案例介绍一下怎么实现灰度。晚期咱们没有灰度,所有的服务只有一上线,就相当于是全量状态,没法去验证服务到底对用户有多大影响。在 2021 年实现业务容器化革新之后,咱们就引入了 MSE 微服务引擎来帮忙咱们实现全链路的灰度。
所谓全链路,指的是在流量链路这一层,网关进来之后到服务再到数据库,或者到通过消息中间件的这个链路。还有一个就是音讯方面,要对流量的特色进行打标,而后链路的下一跳可能也须要打标,标识一下它要去到哪里。网关要负责南北流量的散发,在内部,咱们通过开源的 APISIX 网关,它是有流量分拆插件的,能够在公布的时候,通过部署多个版本,在公布的时候,部署两个版本或者或多个版本,叫 deployment。部署完了之后,再给它打标,而后网关下面会有个流量分拆插件,你能够配一些特色,而后让流量进到指定的版本。
进来之后,这外面东西向的流量就属于 MSE 微服务引擎来做的事件。它通过 agent 插装的形式,把整个链路给串起来,实现了整个链路的灰度。
比如说像 HTTP 申请,它能够在申请头上加 gray 标识,而后顺次透传到底层去。到消息中间件这一块,它对 MQ 这块做一些加强,相当于是埋点一样,把这些流量的灰度标记埋进去。而后在生产端做一下管制,这样就能够保障你的流量能依照你预约的规定顺利的进来。
重要的线上服务要公布的时候,先走一下灰度,能够显著的加强咱们的信念。原先没有灰度的状况下,公布的时候都是很忐忑的,个别白天不敢发,都是夜晚才发,就是为了避免故障,因为你如果有问题的话,可能会影响很多用户。当初咱们曾经有 7300 万用户了,尽管说日活不是很高,但月活也有 1000 多万,所以说白天的流量还是十分大的。通过灰度公布,有问题的话在灰度阶段就能发现把它解决掉。
上面的案例是应用微服务引擎实现优雅高低线,这个能力也比拟重要。因为晚期很多线上故障都是因为公布导致的,常常在公布中发现很多服务调不通了,是因为它在下线过程中,但调用方这边不晓得还去申请,就会报错。因而,在 2021 年,咱们用微服务引擎 MSE 把服务期间不平滑的问题解决了。
优雅下线的原理其实非常简单,比如说服务提供者,咱们称为 provider,他如果发了新的实例,当然流程还跟以前 K8s 滚动更新机制是一样的。他先滚动更新一个新版本的过程中,会触发老版本的下线动作,老版本下线动作就会执行 pre stop 钩子函数,这个函数是 K8s 提供了内置的机制,这个函数里 MSE 会提供一个接口,通过调用这个接口,让 MSE 的 agent 感知到服务要下线了,连忙触发下线的事件。
事件触发之后,它的调用方能够感触到事件,而后在本人本地的 ribbon 服务列表缓存外面把 IP 给摘掉,摘掉之后,前面的申请就不再调用了,相当于我晓得你要下线就把你提前摘掉,不调用就不会报错了。
服务上线的原理也差不多,上线之前先提早一会儿,先不那么快到注册核心,而是放一点点流量进来,这个节奏是通过 K8s 健康检查机制来实现的。MSE 提供健康检查的接口,它会通过接口去向 K8s 裸露服务到底有没有准备就绪。当初没有准备就绪,流量就不能全副放进,能够放一点点,比方百分之零点几的流量进来,我先把服务预热一下,该建设的链接先建设起来,等到服务齐全就绪之后,再把流量放进来,这样无论是下线还是上线,服务都是处于绝对安稳的状态,下线调用端提前晓得的话就不会再调用了。上线是先给你一段时间,让你先筹备好,筹备好之后,我再把流量放进来,这是优雅上线的原理。
3. 可观测和监控
接下来我讲一下可观测的实际,可观测次要用到 阿里云 ARMS 利用监控 + Prometheus + Grafana 以及云监控 这个组合。
这个图就是用阿里云的云监控进行根底资源监控,如 ECS、云数据库 PolarDB、云音讯队列,这些根底监控都有些对应的指标。
那如果要进行更精密、全面的指标监控,阿里云也提供 Prometheus 指标监控能力,它会把你的指标放到 Prometheus 外面,利用预置模板疾速构建告警体系的同时,也能够通过本人的业务需要去配置相应的自定义告警规定。
第二个是利用实时监控服务 ARMS,作为一个具备诸多监控模块的云原生可观测平台,咱们用其中的利用监控来解决 Java 利用性能的监控问题,咱们的利用在线上跑的时候可能会忽然发现有几个申请报错,或者是响应极慢,那研发人员要要怎么去排查呢?
通过 ARMS 利用监控去观测整个调用链路,及时发现整个链路到底哪一环节执行的比较慢。通过耗时数看失去,看失去之后定位一下的问题,比如说像这个实例外面,这是高德的三方接口比较慢,因为三方接口耗时的确是不可控的,这种问题咱们能够提前晓得,还有一些超时、异样问题,这些都能够通过 ARMS 利用监控发现,当然也能够配相应的一些告警规定。
除了云基础设施以及利用性能,咱们心愿进一步对业务指标进行监控,实现全栈可观测。针对业务指标监控,咱们次要是用 Prometheus 和 Grafana 来进行加工与出现。这里有两个案例,一个案例是基于业务指标,也就是音讯核心的监控大盘,这外面的所有的数据都是通过 Java 端用 Prometheus 的客户端把指标数据裸露进去,而后 Prometheus 服务端把这些数据采集上来,再给它配成这种图表。
配成图表之后就能够可视化了,能看到当初的业务运行状况,这个曲线和两个图例应该都是理论的业务经营情况,有了这些数据,就有了监控告警的条件,没有这些货色就不晓得业务到底运行怎么样。
而后日志告警核心这部分,像一些重大的日志报错,Error 日志这些比拟重要的日志报错,咱们会配对应的一些告警规定,在呈现问题的时候进行及时告警。
通过这么多年业务倒退,咱们的业务始终是在云上一直的倒退和壮大,充沛用了云的各项能力来构建平台。咱们次要思考的是 老本,稳定性和研发效率 这三块,心愿能达到均衡。因为咱们团队自身也比拟小,所以用云的劣势是非常明显的,能够利用云的弹性有效应对日益剧增的业务增长规模。云原生之路咱们还将持续,在此先汇报咱们的成绩。
通过容器化部署,进步部署密度的形式,把原先的 ECS 老本升高了 50%, 因为原先 ECS 部署的比拟粗放,可能一台机器上只部署一两个或者两三个服务。通过容器化的部署,能够进步部署密度。
第二个是利用实现了高可用和弹性调度,使咱们能够从容的应答将来的业务增长。
第三个是通过全面实施根底资源、应用服务及业务监控,疾速理解零碎运行状态。过来,零碎运行状况对咱们来说是一个黑盒。即便有一部分数据,也无奈无效的对不同类型数据进行加工与利用,一切都是未知。通过这些能力,从无到有的建设,咱们当初能够十分疾速的去理解、观测零碎的状态。
第四个成绩是运维老本大幅升高,把机器给省上来了,像一些人工须要做的事件,当初通过高度的自动化能够实现大规模的集群治理。
总结与瞻望
展望未来,可能会更多的思考这以下三个方向,这些也是咱们将来要做的事件。
- 咱们当初比较关心的服务网格,因为当前也会有更多语言,像一些利用比如说 Java、Python、Go 这些,MSE 目前可能对 Java 的反对十分好,前面咱们也会摸索基于服务网格的通用的流量治理能力。
- 因为 Java 占咱们整个利用的体量大略是 80%,后续会思考用一些新的技术,比方用 GraaLVM native 来实现原生镜像部署,这样能够进一步升高利用的资源占用状况,进步利用的响应峰值性能。
- 通过混沌工程的施行,进一步提高线上的稳定性。目前咱们的稳定性可能还没有达到现实的指标,这是前面的致力方向。