springcloud(十一)-Zuul聚合微服务
前言
我们接着上一节。在许多场景下,外部请求需要查询Zuul后端的多个微服务。比如一个电影售票手机APP,在购票订单页上,既需要查询“电影微服务”获得电影相关信息,又需要查询“用户微服务”获得当前用户信息。如果让手机端直接请求各个微服务(即使使用Zuul进行转发),那么网络开销,流量耗费,耗费时长可能都无法令人满意。那么对于这种场景,可使用Zuul聚合微服务请求——手机APP发送一次请求给Zuul,由Zuul请求用户微服务以及电影微服务,并组织好数据给手机APP。
使用这种方式,在手机端只需发送一次请求即可,简化了客户端侧的开发;不仅如此,由于Zuul,用户微服务,电影微服务一般都在同一个局域网中,因此速度会非常快,效率会非常高。
编码
1.复制项目microservice-gateway-zuul,将ArtifactId修改为microservice-gateway-zuul-aggregation.
2.修改启动类。
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication { public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
} }
3.创建实体类。
public class User {
private Long id;
private String username;
private String name;
private Integer age;
private BigDecimal balance;
// getters and setters...
}
4.创建java类。
@Service
public class AggregationService {
@Autowired
private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "fallback")
public Observable<User> getUserById(Long id){ // 创建一个被发现者
return Observable.create(observer -> {
User user = restTemplate.getForObject(
"http://microservice-provider-user/{id}",User.class,id);
observer.onNext(user);
observer.onCompleted();
});
}
@HystrixCommand(fallbackMethod = "fallback")
public Observable<User> getMovieUserByUserId(Long id){
return Observable.create(observer -> {
User movieUser = restTemplate.getForObject(
"http://microservice-consumer-movie/user/{id}",User.class,id);
observer.onNext(movieUser);
observer.onCompleted();
});
} public User fallback(Long id) {
User user = new User();
user.setId(-1L);
return user;
} }
5.创建Controller,在Controller中聚合多个微服务请求。
@RestController
public class AggregationController {
public static final Logger LOGGER = LoggerFactory.getLogger(ZuulApplication.class); @Autowired
private AggregationService aggregationService;
@GetMapping("/aggregate/{id}")
public DeferredResult<HashMap<String,User>> aggregate(@PathVariable Long id){ Observable<HashMap<String,User>> result = this.aggregateObservable(id);
return this.toDeferredResult(result); } public Observable<HashMap<String,User>> aggregateObservable(Long id){ // 合并两个或者多个Observeables发射出的数据项,根据指定的函数变换它们
return Observable.zip(
this.aggregationService.getUserById(id),
this.aggregationService.getMovieUserByUserId(id),
(user,movieUser) -> {
HashMap<String,User> map = Maps.newHashMap(); map.put("user",user);
map.put("movieUser",movieUser);
return map;
}
);
}
public DeferredResult<HashMap<String,User>> toDeferredResult(Observable<HashMap<String,User>> details){ DeferredResult<HashMap<String,User>> result = new DeferredResult<>();
// 订阅
details.subscribe(new Observer<HashMap<String,User>>(){
@Override
public void onCompleted() {
LOGGER.info("完成...");
} @Override
public void onError(Throwable throwable) {
LOGGER.error("发生错误...",throwable);
}
@Override
public void onNext(HashMap<String,User> movieDetails) {
result.setResult(movieDetails);
} });
return result;
} }
这样,代码就编写完了。当然,这里是用RxJava写的。也可以不用这种方式。只要实现调用多个微服务请求,然后将结果数据组织好返回出去就行。
测试1
启动项目microservice-discovery-eureka.
启动项目microservice-provider-user.
启动项目microservice-consumer-movie.
启动项目microservice-gateway-zuul-aggregation.
访问http://localhost:8040/aggregate/1,获得结果。
<HashMap>
<movieUser>
<id>1</id>
<username>account1</username>
<name>张三</name>
<age>20</age>
<balance>98.23</balance>
</movieUser>
<user>
<id>1</id>
<username>account1</username>
<name>张三</name>
<age>20</age>
<balance>98.23</balance>
</user>
</HashMap>
说明已成功用Zuul聚合了用户微服务以及电影微服务的RESTful API.
测试2
1.在测试1基础上停止项目microservice-provider-user以及microservice-consumer-movie.
2.访问http://localhost:8040/aggregate/1
<HashMap>
<movieUser>
<id>-1</id>
<username/>
<name/>
<age/>
<balance/>
</movieUser>
<user>
<id>-1</id>
<username/>
<name/>
<age/>
<balance/>
</user>
</HashMap>
我们看到,Zuul聚合微服务也实现了容错机制。
代码下载地址:https://gitee.com/fengyuduke/my_open_resources/blob/master/microservice-gateway-zuul-aggregation.zip
springcloud(十一)-Zuul聚合微服务的更多相关文章
- springcloud使用Zuul构建微服务网关入门
为什么要使用微服务网关 不同的微服务一般会经过不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求. 如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会多次请求不同的微 ...
- Spring Cloud(Dalston.SR5)--Zuul 网关-微服务集群
通过 url 映射的方式来实现 zuul 的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了.实际上在实现微服务架构时,服务名与服务实例地 ...
- 8. 使用Zuul构建微服务网关
使用Zuul构建微服务网关 8.1. 为什么要使用微服务网关 8.2. Zuul简介 8.3. 编写Zuul微服务网关 8.4. Zuul的路由端点 8.5. Zuul ...
- SpringCloud实战 | 第五篇:SpringCloud整合OpenFeign实现微服务之间的调用
一. 前言 微服务实战系列是基于开源微服务项目 有来商城youlai-mall 版本升级为背景来开展的,本篇则是讲述SpringCloud整合OpenFeign实现微服务之间的相互调用,有兴趣的朋友可 ...
- SpringCloud微服务实战——搭建企业级开发框架(十九):Gateway使用knife4j聚合微服务文档
本章介绍Spring Cloud Gateway网关如何集成knife4j,通过网关聚合所有的Swagger微服务文档 1.gitegg-gateway中引入knife4j依赖,如果没有后端代码编 ...
- springcloud系列11 整合微服务网关zuul
这个模块是一个独立的模块所以需要建立一个模块, 首先引入: 依赖pom.xml <?xml version="1.0" encoding="UTF-8"? ...
- dubbo初认知(dubbo和springCloud关系,在微服务架构中的作用等)(持续更新中)
一:dubbo是什么? dobbuo是阿里开源的一个高性能优秀的服务框架, 可通过高性能的 RPC 实现服务的输出和输入功能,使得应用可以和 高性能的rpc实现输入和输出的功能,可以了 Spring ...
- springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
1.代码生成器: [正反双向](单表.主表.明细表.树形表,快速开发利器)freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本.处理类.service等完整模块2. ...
- SpringCloud(1)---基于RestTemplate微服务项目案例
基于RestTemplate微服务项目 在写SpringCloud搭建微服务之前,我想先搭建一个不通过springcloud只通过SpringBoot和Mybatis进行模块之间额通讯.然后在此基础上 ...
随机推荐
- 为什么有些应用非VxWorks不可
实时操作系统(RTOS)是专用于对时间精确度敏感的操作系统.典型的情况是,这种应用需要从传感器收集数据.做出分析并对关键性设备进行控制,例如飞机.列车.手术刀.这类控制必须精准,不容许出现 ...
- vue-cli 3x 的使用
当我们使用 npm 下载过文件之后,里面就会有缓存 我们要使用 npm cache clean --force 来清除缓存 创建项目:vue create 文件名 然后:cd 文件名 启动程序:npm ...
- java 包引入时*会全部加载吗
有一个虚拟机参数: -XX:+TraceClassLoading 这两种写法,最终加载的类是一样的. 对比了一下输出的都是618行
- Java异常超详细总结
1.1,什么是异常: 异常就是Java程序在运行过程中出现的错误. 骚话: 世界上最真情的相依就是你在try我在catch,无论你发什么脾气,我都静静接受,默默处理(这个可以不记) 1.2,异常继 ...
- linux/windows/Mac平台生成随机数的不同方法
linux平台,使用rand.Seed() //rand_linux.go package main import ( "math/rand" "time" ) ...
- JMeter自带工具录制配置方法
打开Jmeter,看到左边显示一个空的测试计划,把该测试计划改名为TestPlan1.右键单击该测试计划,选择“添加”-“线程组”,添加一个线程组,改名为TestGroup1.为了录制浏览器的操作,需 ...
- Delphi组件编辑器
看到Dev中的cxGrid组件的编辑器很强大,于是很想探究一下,跟踪cxGrid的代码比较麻烦,但原理大概知道一二.首先来研究一下设计器双击cxGrid弹出一个编辑窗体,选择窗体中的一个内容后,属性编 ...
- charles安装&破解
走在测试的道路上,我们总归要学习抓包,仅仅是为了更好的定位bug出现的位置.抓包工具何其之多,但是我个人推荐的是charles,主要是因为windows和ios可以同时使用,这样就可以方便不少.不废话 ...
- js多元运算
for(var i=1;i<=100;i++){ var f = i%3 == 0, b = i%5 == 0; if(f){ if(b){ console.log("FizzBuzz ...
- LeetCode.1071-字符串最大公约数(Greatest Common Divisor of Strings)
这是小川的第391次更新,第421篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第253题(顺位题号是1071).对于字符串S和T,当且仅当S = T + ... + T ...