一 介绍
在很多次场景下,外部请求需要查询Zuul后端的多个微服务。举个例子,一个电影售票手机APP,在购票订单页上,既需要查询“电影微服务”获得电影相关信息,又需要查询“用户微服务”获得当前用户的信息。如果让手机端直接请求各个微服务(即使使用Zuul进行转发),那么网络开销、流量耗费、耗费时长可能都无法令人满意。那么对于这种场景,可使用Zuul聚合微服务请求——手机APP只需发送一个请求给Zuul,由于Zuul请求用户微服务以及电影微服务,并组织好数据给手机APP。
使用这种方式,手机端只须发送一次请求即可,简化了客户端侧的开发;不仅如此,由于Zuul、用户微服务、电影微服务一般都在同一局域网,因此速度非常快,效率会非常高。
下面围绕以上这个场景,来编写代码。
在本例中,使用了RxJava结合Zuul来实现微服务请求的聚合。
二 新建项目microservice-gateway-zuul-aggregation
三 修改启动类
package com.itmuch.cloud.study;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {public static void main(String[] args) {SpringApplication.run(ZuulApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}
四 创建实体类
package com.itmuch.cloud.study;
import java.math.BigDecimal;
public class User {private Long id;private String username;private String name;private Integer age;private BigDecimal balance;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public BigDecimal getBalance() {return balance;}public void setBalance(BigDecimal balance) {this.balance = balance;}
}
五 创建聚合服务
package com.itmuch.cloud.study;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import rx.Observable;@Service
public class AggregationService {@Autowiredprivate RestTemplate restTemplate;@HystrixCommand(fallbackMethod = "fallback")public Observable<User> getUserById(Long id) {// 创建一个被观察者return Observable.create(observer -> {// 请求用户微服务的/{id}端点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/{id}端点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;}
}
六 创建Controller,在Controller中聚合多个请求
package com.itmuch.cloud.study;import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import rx.Observable;
import rx.Observer;import java.util.HashMap;@RestController
public class AggregationController {public static final Logger LOGGER = LoggerFactory.getLogger(ZuulApplication.class);@Autowiredprivate 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) {// 合并两个或者多个Observables发射出的数据项,根据指定的函数变换它们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>>() {@Overridepublic void onCompleted() {LOGGER.info("完成...");}@Overridepublic void onError(Throwable throwable) {LOGGER.error("发生错误...", throwable);}@Overridepublic void onNext(HashMap<String, User> movieDetails) {result.setResult(movieDetails);}});return result;}
}
七 微服务聚合测试
1 启动eureka
2 启动user微服务
3 启动movie微服务
4 启动聚合微服务
5 访问http://localhost:8040/aggregate/1
{"movieUser":{"id":1,"username":"account1","name":"张三","age":20,"balance":100.00},"user":{"id":1,"username":"account1","name":"张三","age":20,"balance":100.00}}
说明已成功聚合了用户微服务以及电影微服务的RESTful API
八 Hystrix容错测试
1 停止user微服务
2 停止movie微服务
3 访问 http://localhost:8040/aggregate/1
{"movieUser":{"id":-1,"username":null,"name":null,"age":null,"balance":null},"user":{"id":-1,"username":null,"name":null,"age":null,"balance":null}}
说明fallback方法正常被触发,能够正常回退。

使用Zuul聚合微服务相关推荐

  1. Zuul微服务网关、容错与监控、Zuul路由端点、路由配置、Zuul上传文件、Zuul过滤器、Zuul异常处理、Zuul回退、Zuul聚合微服务

    一.为什么要使用微服务网关 二.Zuul 1.编写Zuul微服务网关 2.Zuul的Hystrix容错与监控 3.Zuul的路由端点 4.路由配置 1.自定义指定微服务的访问路径 2.忽略指定微服务 ...

  2. 微服务springcloud—使用Zuul聚合微服务

    使用Zuul聚合微服务 1.复制项目microservice-gateway-zuul.将ArtifactId修改为microservice-gateway-zuul-aggregation. 2.修 ...

  3. SpringCloud 使用Zuul构建微服务网关

    什么是网关? 之前,我一直觉得对这个概念理解的不够清晰,使用了微服务后,大概总结了一下,通俗来讲可以理解如下,某个应用平台一旦需要为外界提供开放接口服务,平台为了对开发的接口做统一管理,权限认证,路由 ...

  4. Spring Cloud版——电影售票系统七使用 Zuul 构建微服务网关

    2019独角兽企业重金招聘Python工程师标准>>> GitHub地址:https://github.com/leebingbin/SpringCloud.MovieTicketi ...

  5. 聚合微服务中的 Swagger API 文档

    没有做 API 文档聚合,访问每个服务的 API 文档都需要访问单独的 swagger-ui.html 页面,既然我们使用了微服务,就应该有统一的 API 文档入口,而 knife4j 有这方面的支持 ...

  6. 使用Zuul构建微服务网关(路由)

    文章目录 一.网关产生的背景 二.Zuul简介 三.Zuul实现API网关 四. 路由配置详解 五.Zuul的容错与回退 六.Zuul的安全与Header 1.敏感头设置 2.忽略Header 七.Z ...

  7. 使用Zuul构建微服务网关(红莲业火)

    1.为什么使用微服务网关 经过前面的学习,微服务架构已经初具雏形,但还有一些问题-不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求. 如果让客户端直接与各 ...

  8. 软件架构-zuul微服务网关(中)

    咱们今天继续说springcloud的zuul.在最早我们是没有网关这个概念的,微服务搭建起来后,客户端就直接访问一个个微服务了,这些方式有很多的弊端,上次都说了,针对这些弊端,我们用一种什么样的方式 ...

  9. 【微服务】Zuul的必要性

    点击上方"后端技术精选",选择"置顶公众号" 技术文章第一时间送达! 作者:种下星星的日子 blog.csdn.net/hongwei15732623364 传 ...

最新文章

  1. node.js写一个json服务
  2. 从源码出发:JAVA中对象的比较
  3. 对抗高并发拯救系统架构,我们并不需要复仇者联盟|深圳活动
  4. OpenCV实现连通域
  5. mysql重启root不能登_Mysql 5.7.28初始化使用root无法登录
  6. [Kali][VMware][2020][窗口大小][分辨率]高分辨率自适应
  7. 估值飙至 280 亿美元,Databricks G 轮融资 10 亿美元,谁说开源不挣钱?
  8. 开源的49款Java 网络爬虫软件
  9. CodeForces 621C 数学概率期望计算
  10. 远程升级单片机程序设计思路
  11. GNU autotools 下载和安装
  12. Bad config encountered during initialization: No such notebook dir:
  13. Unity3D 矩阵运算
  14. Unexpected Exception caught setting '' on 'class com.: Error setting expression '' with value ['', ]
  15. 什么是蜘蛛池的搜索留痕技术
  16. GeneMark-ES:真核生物编码基因预测软件
  17. JZOJ3481. 【NOIP2013模拟10.23】君と彼女の恋(2017.10B组)
  18. 应用程序无法正常启动0x000007b,请单击“确定”关闭应用程序(不要着急,先定位问题)
  19. 深圳将在2015年推广家庭服务机器人
  20. openssl 漏洞

热门文章

  1. macos安装第三方软件提示文件损坏
  2. TMT定量蛋白组学助力PRV-宿主细胞互作的分子机制研究
  3. WASD键控制物体移动
  4. 微信支付后“自动”绑定用户手机号与公众号
  5. 互动玩法任务平台介绍
  6. MTK6236 venus提供那些控件
  7. 唯一让盖茨晕倒的中国人
  8. 【web学习之ideaIU】 IntelliJ IDEA - 学习
  9. latex写带声调上标的字母
  10. 学习Java,会让你变得越来越自信