2018-05-10贝壳金控赵文乐:基于 Spring Cloud 的服务治理实践

文章原创首发于微信公众号「 TGO 鲲鹏会」,原文地址:贝壳金控赵文乐:基于 Spring Cloud 的服务治理实践

4 月 23 日,TGO 鲲鹏会上海分会会员,贝壳金控高级架构总监赵文乐作为 TGO 鲲鹏会线上分享第六季的嘉宾,以直播的形式分享了服务治理的范围及原因、服务拆分和治理的原则以及 Spring Cloud 的服务治理等内容。本文根据当天直播内容整理。

大家好,我是来自贝壳金控的赵文乐,目前主要从事架构方面的工作。今天我想跟大家分享《基于 Spring Cloud 的服务治理实践》。我会先简单向大家介绍一下服务治理的概念,然后介绍实际案例中的实践。

服务治理的范围及原因

上图是我制作的「服务治理实践过程中遇到的问题和解决方法」,虽然不是非常完全,但也可以代表服务治理的大概范围。

服务治理的范围

在服务治理方面,我们需要解决四个方面的问题:

服务质量。包括:服务列表、服务性能 KPI 、链路监控、依赖监控、故障管理与报警系统等;

线上治理。包括服务发现(让客户端能够发现这个服务)、服务调度(包括客户端和服务端的负载均衡、服务路由、升降级熔断和监控)和配置管理;

线下治理。包括开发工具、上线审批、下线通知、服务文档;

运维生态。如容器云、用户角色权限管理、服务的流程审批。

为什么要进行服务治理?

当服务越来越多时,过去简单记录服务的 end point 会越来越复杂。所以“注册中心”是我们做的第一步,之后是“服务发现”和“客户端定制” ;

当服务开始越来越复杂时,我们就要依赖于管理服务。如果架构师不了解系统里所有服务之间的依赖关系,则需要借助框架自动画出依赖关系并予以管理;

当调用越来越多时,我们需要增加监控、容量规划以及度量;

当依赖变得复杂时,除了了解服务的依赖关系,还要动态的察觉依赖;

一般情况下,下层服务如果反调上层服务,会造成循环依赖,需要 SOA 做到服务之间互相沟通,使管理更加容易;

如果想要防止文档变得混乱,就需要更集中化的文档管理,让大家能够搜到、看到所有的服务文档;

如果大家都可以公开调用内部服务,那么就会出现安全问题;

质量问题也会难以保障,需要有非常好的服务监控;

当调用多个服务时,需要做服务聚合。特别是当我们依赖于服务编排时,如果用框架来做会更方便。

服务拆分和治理的原则

服务拆分的原则

当我们在说微服务时,我们是在说:到底微服务的颗粒度要做到多细或多粗。这就需要我们先定义服务的不同分类,可以按照不同的维度来做。如服务业务、服务流程或不同的业务域,这是第一种流程服务,即满足最高层服务的流程。

在流程服务下还会出现组合服务,会调用多个其他服务进行封装组合。再下面还会有平台服务 —— 在某业务域下的核心服务。最后是基础服务,它通常没有特别的业务含义,是比较通用的服务。

同时,我们也可以根据服务的属性来分类:

稳定服务和不稳定 / 易变服务需要隔离;

核心服务和非核心服务需要隔离;

非功能服务和功能服务。非功能服务通常更容易复用,会把它放在最底层,由不同的服务来调用;

高可用服务和容错服务。有些服务能容忍一定错误率,这样的服务不能和高可用服务部署在一起。

所以,我们可以按照以上原则做系统分解:

不同的业务域划分大的业务系统,每个业务调用数据量最大的需要拆分;

风险高、频率高、经常更新的需要拆分的;

经常会被复用的底层服务需要拆分;

服务需要专业技能、专业团队,特别是技术栈不统一时进行拆分。

服务设计原则

服务设计原因包括:

服务无状态,幂等性。在设计微服务时,一般都会从领域模型。基于这些领域来驱动微服务 REST API 的设计;

服务业务隔离,领域驱动( Domain Driven Design );

服务契约驱动( Design by Contract )。先定义接口,再去做服务的实现;

服务资源隔离(数据库、线程池等)。如果不隔离服务的数据库,就很难知道有没有其他服务在调用我们的数据库,至少数据库的用户是需要隔离,不同用户要有不同的权限;

故障可隔离(熔断机制)。Spring Cloud 里有 Hystrix 框架就可以很好的解决这个问题。

服务治理原则包括:

服务 SLA ;

服务需自治;

服务可开关、降级、限流、动态调整负载路由;

服务可监控、可统计,提供 Metrics 和 Health Check( Metrics Driven Design );

服务文档和版本管理;

服务权限控制;

服务调用链可监控。

Spring Cloud 的服务治理

Spring Cloud 组件

上图中比较核心的组建包括:

服务注册提供很多选型。默认是 Eureka ,还支持 Consul 和 Zookeeper 服务注册;

服务调用,REST API 通常用 Feign Client 做服务调用,集成客户端的负载均衡,所以 Feign Client 在服务治理中非常重要;

服务路由和服务过滤,在 Spring Cloud 提供的 route API 、gateway 之类的工具;

其他还包括:

服务监控,在 Spring Cloud 环境下用的较多的是 Hystrix —— 监控控制台,集成的 Turbine 可以做跨集群的监控;

配置中心,Spring Cloud 默认提供的配置管理是通过地址文件进行管理,也支持诸如 Zookeeper 之类配置中心;

安全控制集成 SpringSecurity ,它本身不是属于 Spring Cloud 的范畴,但会提供 SpringSecurity Starter ,帮助我们快速的建立权限管理;

用 Spring Cloud Sleuth 做分布式的链路监控,集成 Zipkin 之类的框架。

Spring Cloud 存在的问题和痛点

配置管理。Spring Cloud 的配置管理比较简陋,没有特别好的配置管理中心,也没有共享配置。另外,Spring Cloud 配置不支持灰度;

网关( API Gateway )。网关需要做很多二次开发,没有动态路由;同时,Zuul 做不了服务编排,而在市场上也没有一个很好的服务编排的框架;

服务跟踪。Sleuth 框架不成熟。如果跟一些比较成熟的 APM 框架相比,它是非常欠缺的;

UI 。spring cloud 的 UI 界面非常分散,像 Hystrix 、eureka 、tubine 、zipkin 都有自己的界面。但这些缺乏集中的管理,用户体也普遍比较差、感觉比较简单,跟商业级的服务治理平台无法相比。

如何改善

更换配置中心。携程的 Apollo 是一个更好的选择。它里面的很多功能都是原生 Spring Cloud 配置中心不支持的。所以建议大家尝试一下比较成熟的配置中心。

因为 API Gateway 在 Spring Cloud 中没有操作界面,所以我们就为之定制了专属界面,让它能够管理不同的路由规则。我们还开发了一系列 Filter ,可以在 API Gateway 里做签名检查和解密。同时,我们还集成了自己的账户系统和单点登录,支持不同的登录方式。

除此之外,我们集成了用户中心( Accountservice )。因为当 API Gateway 开放给渠道用户或合作伙伴用户时,通常没有交互,所以我们就需要通过参数的自动抓取匹配用户,据此判断这个用户是否已经注册。如果还未注册,我们就会自动注册。同时,当一个潜在用户使用我们系统、调用 API 时,我们就可以通过这种方式把硬件指纹记录下来,后台会给这些用户打标签,我们就可以针对这些用户做 push 等营销手段。

最后,还有一些前置 Filter 用于抽取数据。当 API 请求时,会异步通过日志抽取报文做数据清洗,通过 ETL 写到数据仓库里。

API gateway 的动态路由

举个例子,比如我们把年龄小于 30 岁的男性路由到一个不同的 endpoint ,我们在这过程中会在请求头、请求参数或请求头中通过 Json Parse抽取参数和数据转换。我们可以从 body 里第一个 customer 对象的 ID 得到 uid ,之后保存到上下文中,输出到 output ,当我们指定 endpoint 为另外一个 URL 时把 UID 这个参数传过去。

还有一种是报文的转换,即 Payload Transformation 。这个技术其实在很久以前就已经存在了,在 ESB 、SOAP 时代,我们通常会利用 XML 来做报文的转换。所以现在通常用来做报文转换的工具是 Json 、Json Paser 、Velocity Template 、FreeMarker 等。还有一些协议的转换,我们内部有很多 API 都是基于 dubbo 或者是其他的一些 RPC 协议。所以当收到外部 REST API 请求时,我们会做一个协议、格式的转换。

在上图中,入参是比较复杂的 Json ,我们通过 Input Mapping 模板上逻辑输出变量,嵌入到另外的 Json 对象中。如果我们在内部有一套比较标准的 API ,可以通过这种方式适配到外部不同的 API 。这样便集成了规则引擎,可以做一些比较基本的服务编排。

一体化的服务监控和跟踪

在 Spring Cloud 里提供了很多不同的服务监控工具,利用这些工具可以做服务的业务监控和埋点,来收集各种 Metrics 。当我们发送消息时,我们会在适当的地方做埋点,收集数据,最后再把这些集成起来,做报表展示和告警。所以整个这套服务监控和跟踪都是一体化的。

我们在做中间件埋点时,可以有许多的选择,比如 JDK proxy 、http client 、Servlet filters 、Spring MVC handler 都可以添加埋点,但我们更多会在 Feign Client 提供一些拦截器,当服务调用时,会有一些不同的 event 。

在 DB 里,我们用的比较多的是 Druid datasource filter ,它提供了很多扩展,我们可以在这里边做 SQL 查询的埋点,记录每条 SQL 的响应时间和调用频次。同时,Mybatis 也可以做埋点,定制一些插件。

服务监控的整体架构

过去我们使用日志做服务监控的数据收集,大家都知道也有不少的服务监控都是基于上报的 API 。但我们通过日志的方式收集数据对应用的性能比较友好,不会因为我们埋点影响到业务。同时,耦合度也比较低,只是分析度量数据。通过不同的 Instruments 写到日志里。最后通过 Logstash 到 Kafka 进入 ElasticSearch ,基于这些查询可以快速生成简单的报表。

以上所说的内容,如果都只是停留在框架级别,用户和程序员根本看不到服务治理的概念。所以我们做了一套服务治理平台,可以看到所有服务治理内容。同时,我们还把配置中心嵌到了服务治理平台中,将服务网关管理、Rabbit MQ 消息队列管理、通过消息队列业务 ID 查询消息轨迹以及一些项目管理相关的离线服务治理等功能集成在一起。

Q & A

下层服务和上层服务指的是什么?

所谓的下层服务,就是底下平台级的服务。比如你有一个发短信的服务,如果这个服务跟你的账户体系耦合在一起,它就是反向调用,如果在短信服务里需要到会员中心获取手机号,这就是不合理的设计,就是下层服务调上层服务的例子。

服务调用是每个服务各自写一个 FeignClient ,还是由服务方提供统一的 jar 包?

我们现在做法是:在定义服务接口时,这个服务接口就是 FeignClient ,然后把服务接口和它领域的对象封装成统一的 jar 包,作为服务方提供。之后,客户端用它来调用就可以了。在调用过程中,框架里的拦截器会做埋点、注入及监控的工作。

老的服务如何调用 FeignClient ?

用延伸注解来实现。FeignClient 在 Spring Cloud 用的是比较新的 OpenFeign 注解,支持一些特殊功能。比如插入自己的 http client 和做很多拦截器,老的 FeignClient 不是很友好,而且它跟 Spring mvc 的注解也不一致,但是作为一个很老的服务,如果要调用 FeignClient 的话,我们通常会把所有 FeignClient 用到的 class 打成一个大的 jar 包,为这些老的服务实现调用。

如果有机会是不是直接选择自研好一点?

作为开发人员或架构师,每个人都想自研,确实也有很多团队自己做自研框架。但自研的问题是从入门到融会贯通的时间。虽然 Spring Cloud 现在十分简陋,但上手就可以用。如果在整个团队里都用 Spring Cloud ,可以很快地做一些简单的服务治理,然后再慢慢的优化这个过程。还有一个原因,Spring Cloud 在行业里的接受度比较高,大家的学习曲线比较短,通常自研的框架很多工程师可能不太接受或不太信任。

- End -

声明:文章为 TGO 鲲鹏会原创,并首发于微信公众号 TGO 鲲鹏会( ID:tgo-kunpenghui ),未经授权,不得转载!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,717评论 6 342
  • 微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务。但如果要将微服务架构运用到生产项目上,并且能够发挥...
    程序员技术圈阅读 2,770评论 10 27
  • Spring Cloud是一系列框架的集合,其基于Spring Boot的开发便利性巧妙地简化了分布式系统基础设施...
    CD826阅读 95,572评论 24 120
  • 查了查词典,管理是动词,意思是负责某项工作使其顺利进行;保管料理,比如说:管理财务,管理生产,管理国家大事…… 我...
    花妖呀阅读 486评论 0 5