網頁

2019/7/15

Spring Cloud Eureka 使用RestTemplate實作服務間溝通範例二

本篇示範如何在一個Spring Cloud Eureka的一個服務透過RestTemplate呼叫另一外一個服務的REST API。

建議先看過Spring Cloud Netflix Eureka簡介來了解什麼是Eureka Server,什麼是Eureka Client。

本篇建立方式同Spring Cloud Eureka 使用RestTemplate實作服務間溝通(Service to Service Communication)範例一,只是做了以下修改。

不同於上一篇,本範例是在Member服務的MemberController中以RestTemplate呼叫Message服務的API,而非直接在MemberApplication直接呼叫。


MemberApplication內容改成以下。設定一個產生RestTemplate的Bean。

Member serivce - MemberApplication

package com.abc.member;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class MemberApplication {

    public static void main(String[] args) {
        SpringApplication.run(MemberApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
    
}

你可能會發現為什麼這邊沒有加上@EnableDiscoveryClient,因為現在只要classpath有引入Discovery Client的實作,例如Spring Cloud Netflix Eureka的依賴jar,Spring Boot會自動向Eureka Discovery Server註冊為Eureka Client,所以可以省略。


在Member應用程式中新增一個MemberController,負責接收瀏覽器送來的請求並透過RestTemplate轉去呼叫Message服務的API,然後把結果返回瀏覽器。

MemberController注入EurekaClient並根據服務名稱從Eureka Server取得其他服務實例的URL位址。

Member serivce - MemberController

package com.abc.member.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;

@RestController
@RequestMapping("members")
public class MemberController {
    
    @Autowired
    private EurekaClient eurekaClient;
    
    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping(value = "/{memberId}", produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMemberMessages(@PathVariable int memberId) throws JsonProcessingException {
        String serviceName = "message-service";
        String url = getServiceUrl(serviceName);
        url = new StringBuilder(url).append("/messages/").append(memberId).toString();
        final String response = restTemplate.getForObject(url, String.class);
        return response;
    }
    
    /**
     * 取得服務位址
     * @param serviceName 服務名稱
     * @return
     */
    public String getServiceUrl(String serviceName) {
        InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka(serviceName, false);
        return instanceInfo.getHomePageUrl();
    }
}

完成以上修改後,依順序啟動Eureka Server專案 -> Message服務專案 -> Member服務專案。

在瀏覽器輸入http://localhost:8761/開啟Eureka Server UI確認兩個Eureka Client都已註冊。



在瀏覽器位址輸入http://localhost:2223/members/1來呼叫Member服務的API,也就是MemberController.getMemberMessages(),然後會轉去呼叫Message服務的MessageController.getAllMessagesByMemberId

若成功會在畫面顯示如下結果。



下一篇請見Spring Cloud Netflix Eureka + Ribbon 使用Load-balanced RestTemplate實作客戶端負載平衡服務溝通


參考:

沒有留言:

張貼留言