zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    1.4.2.3. SETUP(Core Data 应用程序实践指南)
    1.4.2.2. PATHS(Core Data 应用程序实践指南)
    1.4.2.1. FILES(Core Data 应用程序实践指南)
    1.4.2. 实现 Core Data Helper 类(Core Data 应用程序实践指南)
    1.4.1. Core Data Helper 简介(Core Data 应用程序实践指南)
    1.4. 为现有的应用程序添加 Core Data 支持(Core Data 应用程序实践指南)
    1.3.2. App Icon 和 Launch Image(Core Data 应用程序实践指南)
    1.3.1. 新建Xcode项目并设置故事板(Core Data 应用程序实践指南)
    php验证邮箱是否合法
    如何使js函数异步执行
  • 原文地址:https://www.cnblogs.com/fengyuduke/p/10998225.html
Copyright © 2011-2022 走看看