springcloud(十一)-Zuul聚合微服務

前言

咱們接着上一節。在許多場景下,外部請求須要查詢Zuul後端的多個微服務。好比一個電影售票手機APP,在購票訂單頁上,既須要查詢「電影微服務」得到電影相關信息,又須要查詢「用戶微服務」得到當前用戶信息。若是讓手機端直接請求各個微服務(即便使用Zuul進行轉發),那麼網絡開銷,流量耗費,耗費時長可能都沒法使人滿意。那麼對於這種場景,可以使用Zuul聚合微服務請求——手機APP發送一次請求給Zuul,由Zuul請求用戶微服務以及電影微服務,並組織好數據給手機APP。java

使用這種方式,在手機端只需發送一次請求便可,簡化了客戶端側的開發;不只如此,因爲Zuul,用戶微服務,電影微服務通常都在同一個局域網中,所以速度會很是快,效率會很是高。git

編碼

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.建立實體類。app

public class User {
    private Long id;
    private String username;
    private String name;
    private Integer age;
    private BigDecimal balance;

    // getters and setters...
    
}

4.建立java類。ide

@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.this

啓動項目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

相關文章
相關標籤/搜索