SpringCloud服务组合
SpringCloud生态强调微服务,微服务也就意味着将各个功能独立的业务抽象出来,做成一个单独的服务供外部调用。但每个人对服务究竟要有多“微”的理解差异很大,导致微服务的粒度很难掌控,划分规则也不统一。这导致的一个问题就是在实现一个业务场景的过程中,无法避免的需要对微服务进行整合。本文提出了一种对微服务进行组合的方案,来解决上述的问题。
其实我觉得微服务的理想化调用方式应该是如图一所示的。在完成某一个具体的功能时,外部应用只需要单独调用对应的service就好了。但现实的情况往往是图二所示的调用方式。外部应用在完成某一项具体功能时,需要并发的调用Service1和Service2然后把二者数据进行汇总,之后再把汇总数据发送给Service3,Service3成功调用意味着此次业务功能完成。简单来说就是需要对微服务进行组装。

图一 图二
微服务的组合其实就是一个DAG图,例如图三,这是一个服务组合,其基本功能是并发调用Service1和Service2,二者结果作为参数调用Service3,调用Service3的同时并发调用Service4,Service3和Service4的结果合并作为参数调用Service5,Service5的最终结果作为此次服务组合的最终结果。可以看出这个服务组合的功能还是非常复杂的。要实现这样一个服务组合,难点有两个:1、服务的DAG工作流控制;2、服务结果的合并,以及合并后如何映射给下一个服务的参数。

图三 图四
我们来逐步分析上面的两个难点,以及如何巧妙的解决他们。其实我们可以把图三的DAG图,优化成图四这样的DAG。也就是增加一个虚拟服务VirtualService3,VirtualService3用来汇总Service1/Service2的结果数据,并调起下一次的组合服务。其实就是把图三的DAG划分成了两个Step。图四由不同的Step组成,每个Step内的调用逻辑是非常一致的:并发的调用1个或多个服务,然后合并服务的结果,调用nextStep,并用nextStep的结果作为整个DAG的结果。如果nextStep为空,则直接将合并的结果作为整个DAG的结果。
优化后的DAG就是用Step递归实现整个DAG的运行和结果汇总!
下一个问题就是服务结果的合并。整个问题稍显复杂,我们要把它放到SpringCloud的情景中来看。在SpringCloud中,微服务是以restfulApi的形式暴露的,也就是http协议的调用。那么http调用的参数可以简单分为URL、URL参数、HEADER、BODY、METHOD这5中类型。其中BODY最为复杂,因为其形式是不固定的,可能是JSON、XML或者PLAIN TEXT;URL参数、HEADER基本都是K/V的形式,映射起来比较简单。
映射的第一步就是对各种参数进行解析。下面是一个实际的HTTP请求,从结果来看,URL参数和HEADER解析起来比较简单,在SpringBoot中会自动应射成对应的Map。而BODY就比较复杂了,可能是有格式的PLAIN TEXT,如下图是冒号分隔的KV字符串,或者是有格式的JSON。不过幸运的是在使用SpringBoot构建的微服务,即使是无格式的PLAIN TEXT,也都不是直接给人看的,而是给程序用来解析、使用的。那就意味着也是可以解析的,只不过解析比较麻烦而已。
但无论怎么解析,最终都可以被解析成有个K/V形式的MAP。一旦被解析成MAP对象,映射起来就比较方便了。



首先我们需要对映射的定义进行限制,映射只是参数的重新组合、替换、舍弃,而不能含有业务含义或者复杂的组装逻辑(例如字段的加减乘除等操作)。一旦对映射的功能进行限定,我们会发现实现参数的组合将变得简单起来。freemarker完全就可以胜任这个工作!
FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。其实简单来说就是它可以把输入的数据,按照指定的模板生成对应的输出文本。
下面是一个FreeMarker的例子,非常简单但足够说明它的功能,代码把map对象中的数据,去替换模板中对应的变量,然后打印替换后的结果。怎么样,这是不是可以满足我们对restful调用参数的映射呢?
public class Test {
public static void main(String[] args) throws Exception{
//创建一个模版对象
Template t = new Template(null, new StringReader("用户名:${user};URL: ${url};姓名: ${name}"), null);
//创建插值的Map
Map map = new HashMap();
map.put("user", "lavasoft");
map.put("url", "http://www.baidu.com/");
map.put("name", "百度");
//执行插值,并输出到指定的输出流中
t.process(map, new OutputStreamWriter(System.out));
}
}
输出:
用户名:lavasoft;URL: http://www.baidu.com/;姓名: 百度
到这里我们就把服务结果的组合也将清楚了。那我们就看一下我设计的相关表结构和demo吧。



上面是表结构,下面是调用结果,其中result其实是两次hello调用结果的合并。

SpringCloud服务组合的实现方案基本就讲解清楚了,不过限于篇幅没有放代码,如果有需要的可以联系我微信: HelloGrape。
SpringCloud服务组合的更多相关文章
- 基于WS-BPEL2.0的服务组合研究
http://tech.it168.com/soadocument/2008-01-03/200801031332376.shtml WS-BPEL是为组合Web服务而制定的一项规范.它的前身是由IB ...
- 使用BPEL创建Web服务组合
http://www.cnblogs.com/ahhuiyang/archive/2012/12/18/2824131.html 为简单起见,本例的Web服务组合只调用一个Web Service AP ...
- SpringCloud服务间调用
SpringCloud服务间的调用有两种方式:RestTemplate和FeignClient.不管是什么方式,他都是通过REST接口调用服务的http接口,参数和结果默认都是通过jackson序列化 ...
- Compoxure 微服务组合proxy 中间件
Compoxure 是一个不错的微服务组合中间件,使用此工具我们可以快速的进行micro frontends 应用的开发 使用此工具我们可以替换esi+ ssi 的开发模型(尽管都挺不错). 同时支持 ...
- SpringCloud服务发现(Eureka)简介
Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能. 为什么要使用Eure ...
- SpringCloud服务注册中心
SpringCloud服务注册中心 Spring Cloud 是一系列框架的有序集合,如服务注册发现.配置中心.消息总线.负载均衡.断路器等,都可以用 Spring Boot 的开发风格做到一键启动和 ...
- SpringCloud --服务调用Feign
介绍 服务间通信简介 一个系统可以由不同的微服务构成,比如一个电商系统可以由订单服务.商品服务.用户服务等共同组成. 这些服务相互独立,但又相互依赖.由于它们相互依赖,所以需要通过通信的方式来进行相互 ...
- Kubernetes(K8s)部署 SpringCloud 服务实战
1. 概述 老话说的好:有可能性就不要放弃,要敢于尝试. 言归正传,之前我们聊了一下如何在 Kubernetes(K8s)中部署容器,今天我们来聊一下如何将 SpringCloud 的服务部署到 Ku ...
- SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign
1.Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的-套客户端―负载均衡的工具. 简单的说,Ribbon是Netlix发布的开源项目,主要功能是提供客户端的 ...
随机推荐
- 51nod 1118 机器人走方格【dp】
M * N的方格,一个机器人从左上走到右下,只能向右或向下走.有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果. 收起 输入 第1行,2个数M,N,中间用空格隔开.( ...
- Python学习-while循环练习
1.计算1-100的和 i = 1; total = 0; while i <= 100: total = total + i; i = i + 1; print(total); 2.打印出1- ...
- 03 Python的那些事
目录: 1) 创始人以及重要发展历程 2) Python语言的特点 3) TIOBE排名 4) 解释器 5) Python后缀名 6) 变量规则和约定 7) 常量 8) 注释 9) 缩进 10) Py ...
- 在vue项目中快速使用element UI
推荐使用npm安装 1.安装:npm install element-ui -S 2.整体引入: 在你项目的main.js中写入: import ElementUI from 'element-ui' ...
- ansible plugins简介
ansible插件是增强ansible的核心功能的代码片段,ansible使用插件架构来实现丰富,灵活和可扩展的功能集. Ansible提供了许多方便的插件,您可以轻松编写自己的插件. 下边简单介绍A ...
- 这可能是vue-cli最全的解析了……
题言: 相信很多vue新手,都像我一样,只是知道可以用vue-cli直接生成一个vue项目的架构,并不明白,他究竟是怎么运行的,现在我们一起来研究一下... 一.安装vue-cli,相信你既然会用到v ...
- 20180710使用gh
转自:http://www.ywnds.com/?p=14265 一.背景 GitHub正式宣布以开源的方式发布gh-ost:GitHub的MySQL无触发器在线更改表定义工具!下面是官方给出gh-o ...
- - > 听学姐讲那过去的故事——打代码的小女孩
童话故事 不知道大家有没有看过 天冷极了,下着雪,又快黑了.这是一年的最后一天——大年夜.在这又冷又黑的晚上,一个乖巧的小女孩在机房里调试程序.她从家里出来的时候还穿着一件外套,但是有什么用呢?那是 ...
- Sublime Text 3显示文本编码
在Settings上加入"show_encoding":true 进入这个选项:[Preferences]->[Settings] 搞定之后,在右下角可以看见文本编码
- SiteMesh2-示例工程
了解SiteMesh的最佳方法是使用它.假设SiteMesh设置在您的Web应用程序中,本教程将展示如何掌握SiteMesh最强大的方面,如下所示装饰页面: 效果发生在第2步,其中Menu.jsp页面 ...