本文共 5315 字,大约阅读时间需要 17 分钟。
大家好,我是来自贝壳金控的赵文乐,目前主要从事架构方面的工作。今天我想跟大家分享《基于 Spring Cloud 的服务治理实践》。我先简单向大家介绍一下服务治理的概念,然后介绍实际案例中的实践。
\\
\\上图是我简单制作的「服务治理实践过程中遇到的问题和解决方法」,不是非常完全,但也可以代表服务治理的大致范围。
\\在服务治理方面,我们需要解决四个方面的问题:
\\
\\
\\当我们在说微服务时,我们是在说:到底微服务的颗粒度要做到多细或多粗。这就需要我们先定义服务的不同分类,可以按照不同的维度来做。如服务业务、服务流程或不同的业务域,这是第一种流程服务,即满足最高层服务的流程。在流程服务下还会出现组合服务,会调用多个其他服务进行封装组合。再下面还会有平台服务 —— 在某业务域下的核心服务。最后是基础服务,它通常没有特别的业务含义,是比较通用的服务。
\\同时,我们也可以根据服务的属性来分类:
\\
\\所以,我们可以按照以上原则做系统分解:
\\
\\服务设计原因包括:
\\服务治理原则包括:
\\
\\上图中比较核心的组建包括:
\\其他还包括:
\\
\\更换配置中心。携程的Apollo是一个更好的选择。它里面的很多功能都是原生Spring Cloud配置中心不支持的。所以建议大家尝试一下比较成熟的配置中心。
\\
\\因为 API Gateway在Spring Cloud中没有操作界面,所以我们就为之定制了专属界面,让它能够管理不同的路由规则。我们还开发了一系列Filter,可以在API Gateway里做签名检查和解密。同时,我们还集成了自己的账户系统和单点登录,支持不同的登录方式。
\\除此之外,我们集成了用户中心( Accountservice )。因为当 API Gateway开放给渠道用户或合作伙伴用户时,通常没有交互,所以我们就需要通过参数的自动抓取匹配用户,据此判断这个用户是否已经注册。如果还未注册,我们就会自动注册。同时,当一个潜在用户使用我们系统、调用API时,我们就可以通过这种方式把硬件指纹记录下来,后台会给这些用户打标签,我们就可以针对这些用户做push等营销手段。
\\最后,还有一些前置Filter用于抽取数据。当API请求时,会异步通过日志抽取报文做数据清洗,通过ETL写到数据仓库里。
\\
\\举个例子,比如我们把年龄小于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查询消息轨迹以及一些项目管理相关的离线服务治理等功能集成在一起。
\\问:下层服务和上层服务指的是什么?
\\\\\答:所谓的下层服务,就是底下平台级的服务。比如你有一个发短信的服务,如果这个服务跟你的账户体系耦合在一起,它就是反向调用,如果在短信服务里需要到会员中心获取手机号,这就是不合理的设计,就是下层服务调上层服务的例子。
\
问:服务调用是每个服务各自写一个FeignClient,还是由服务方提供统一的jar包?
\\\\\答:我们现在做法是:在定义服务接口时,这个服务接口就是FeignClient,然后把服务接口和它领域的对象封装成统一的jar包,作为服务方提供。之后,客户端用它来调用就可以了。在调用过程中,框架里的拦截器会做埋点、注入及监控的工作。
\
问:老的服务如何调用FeignClient?
\\\\\答:用延伸注解来实现。FeignClient在Spring Cloud用的是比较新的OpenFeign注解,支持一些特殊功能。比如插入自己的http client和做很多拦截器,老的FeignClient不是很友好,而且它跟Spring mvc的注解也不一致,但是作为一个很老的服务,如果要调用FeignClient的话,我们通常会把所有FeignClient用到的class打成一个大的jar包,为这些老的服务实现调用。
\
问:如果有机会是不是直接选择自研好一点?
\\\答:作为开发人员或架构师,每个人都想自研,确实也有很多团队自己做自研框架。但自研的问题是从入门到融会贯通的时间。虽然Spring Cloud现在十分简陋,但上手就可以用。如果在整个团队里都用Spring Cloud,可以很快地做一些简单的服务治理,然后再慢慢的优化这个过程。还有一个原因,Spring Cloud在行业里的接受度比较高,大家的学习曲线比较短,通常自研的框架很多工程师可能不太接受或不太信任。
\
转载地址:http://vouyx.baihongyu.com/