SpringCloud組件:Eureka的服務發現與消費

在以前的章節咱們已經把服務註冊到Eureka Server,那麼咱們該怎麼調用已經註冊後的服務呢? 咱們本章來簡單的介紹咱們具體該怎麼調用服務節點請求內容。html

本章目標

消費Eureka註冊的服務節點的請求信息。java

構建項目

咱們只須要建立一個服務節點項目便可,由於服務提供者也是消費者,而後將本項目註冊到以前編寫的服務註冊中心,下載文章SpringCloud組件:搭建Eureka服務註冊中心源碼運行便可。 咱們使用idea開發工具建立一個SpringBoot項目,對應的選擇spring-boot-starter-webspring-cloud-starter-netflix-ribbonspring-cloud-starter-netflix-eureka-client三個依賴,pom.xml配置文件以下所示:git

......
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>

<dependencies>
    <!--Web依賴-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
    <!--client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
......
複製代碼

添加完依賴後咱們須要對本項目進行配置,讓本項目註冊到服務中心,在以前的章節SpringCloud組件:將微服務提供者註冊到Eureka服務中心有講過,這裏就不作過多的贅述。github

配置Eureka客戶端

打開XxxApplication入口類,添加@EnableDiscoveryClient註解,以下所示:web

@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudEurekaConsumerApplication {
 //...
}
複製代碼

修改application.yml配置文件

下面咱們修改application.yml配置文件,添加Eureka Client對應的配置信息,以下所示:spring

# 服務名稱
spring:
  application:
    name: hengboy-spring-cloud-eureka-consumer
# 啓動端口號
server:
  port: 20002
# Eureka 服務註冊中心配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10000/eureka/
  # 配置優先使用IP地址註冊服務
  instance:
    prefer-ip-address: true
複製代碼

獲取服務實例信息

若是你只是將服務註冊到服務註冊中心也就是Eureka Server上,到如今已經徹底沒有問題了,可是咱們想要經過服務名(spring.application.name)來獲取服務實例列表該怎麼操做呢?數據庫

本章內容涉及一點有關Ribbon的知識點,咱們經過添加依賴spring-cloud-starter-netflix-ribbon就能夠直接使用RestTemplate類進行發送http請求,並且RestTemnplate能夠直接使用服務名進行發送請求!!!瀏覽器

實例化RestTemplate

spring-cloud-starter-netflix-ribbon依賴並無爲咱們實例化RestTemplate,咱們須要手動進行實例化,我採用@Bean方式進行實例化,在XxxApplication類內添加以下代碼:bash

/**
 * 實例化RestTemplate對象實例
 *
 * @return
 */
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}
複製代碼

在這裏有個@LoadBalanced註解,咱們後續章節會對它詳細的講解,博客搜索關鍵字LoadBalanced查詢文章信息,不過若是你不添加並使用這個註解,你是沒有辦法經過服務名直接發送請求的,會出現錯誤信息。微信

瞭解DiscoveryClient

咱們須要建立一個發送請求以及請求消費Controller,以下所示:

/**
 * 消費者控制器
 *
 * @author:於起宇 <p>
 * ================================
 * Created with IDEA.
 * Date:2018/9/29
 * Time:5:55 PM
 * 簡書:http://www.jianshu.com/u/092df3f77bca
 * 碼雲:https://gitee.com/hengboy
 * GitHub:https://github.com/hengyuboy
 * ================================
 * </p>
 */
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {
    /**
     * logger instance
     */
    static Logger logger = LoggerFactory.getLogger(ConsumerController.class);
    /**
     * 注入服務客戶端實例
     */
    @Autowired
    private DiscoveryClient discoveryClient;
    /**
     * 注入restTemplate模板
     */
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 服務消費者業務邏輯方法
     * 該方法使用restTemplate訪問獲取返回數據
     *
     * @return
     */
    @RequestMapping(value = "/logic")
    public String home() {
        return "this is home page";
    }

    /**
     * 請求地址
     * 輸出服務的基本信息
     */
    @RequestMapping(value = "/index")
    public void index() {
        discoveryClient.getInstances("hengboy-spring-cloud-eureka-consumer")
                .stream()
                .forEach(
                        instance -> {
                            logger.info("服務地址:{},服務端口號:{},服務實例編號:{},服務地址:{}", instance.getHost(), instance.getPort(), instance.getServiceId(), instance.getUri());
                            String response = restTemplate.getForEntity("http://" + instance.getServiceId() + "/consumer/logic", String.class).getBody();
                            logger.info("響應內容:{}", response);
                        }

                );
    }
}

複製代碼

在上面代碼中咱們注入了DiscoveryClient,這是一個接口類,具體該接口的實現類是什麼要取決你使用的是什麼服務註冊中心,咱們本章採用的Eureka理所固然使用的是Eureka實現類,源碼能夠查看org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient,在EurekaDiscoveryClient內能夠看到具體是怎麼經過服務名獲取實例的列表,部分源碼以下所示:

@Override
public List<ServiceInstance> getInstances(String serviceId) {
    List<InstanceInfo> infos = this.eurekaClient.getInstancesByVipAddress(serviceId,
            false);
    List<ServiceInstance> instances = new ArrayList<>();
    for (InstanceInfo info : infos) {
        instances.add(new EurekaServiceInstance(info));
    }
    return instances;
}
複製代碼

你若是對具體的源碼執行流程感興趣,可使用斷點來一步一步的觀察。 在獲取ServiceInstance服務實例後,能夠獲得實例的一些基本信息如:

  • serviceId:服務名稱、服務的實例編號,也就是spring.application.name配置信息
  • host:註冊該實例的hostName
  • port:註冊該實例的端口號,對應server.port配置信息
  • uri:服務地址
  • metadata:服務自定義的元數據map集合

請求轉發流程

執行流程:咱們在訪問/consumer/index請求地址時,會經過RestTemplate轉發請求訪問http://hengboy-spring-cloud-eureka-consumer/consumer/logic地址並返回信息this is home page

運行測試

咱們的測試流程以下:

  1. 啓動服務註冊中心
  2. 啓動本章項目
  3. 訪問http://localhost:20002/consumer/index
  4. 查看控制檯輸出內容是否有this is home page

訪問有多種形式,你能夠瀏覽器直接訪問地址,我經過curl命令來訪問地址,打開terminal輸入如下命令:

curl http://localhost:20002/consumer/index
複製代碼

請求正常,查看控制檯輸出內容以下所示:

2018-10-04 15:23:36.333  INFO 29075 --- [io-20002-exec-5] c.y.c.h.s.e.consumer.ConsumerController  : 服務地址:192.168.1.75,服務端口號:20002,服務實例編號:HENGBOY-SPRING-CLOUD-EUREKA-CONSUMER,服務地址:http://192.168.1.75:20002
......
2018-10-04 15:23:36.748  INFO 29075 --- [io-20002-exec-5] c.y.c.h.s.e.consumer.ConsumerController  : 響應內容:this is home page
複製代碼

總結

本章經過Ribbon簡單的實現了服務節點的消費,經過RestTemplate發送請求來獲取響應內容,須要注意的是咱們並非經過IP:Port的形式,而是經過服務名的形式發送請求,這都歸功於@LoadBalanced這個註解,這個註解在講解Ribbon時會詳細的說明。

源碼位置

有問題要問?

若是你有技術相關的問題想要諮詢恆宇少年,請去博客首頁左側導航欄,點擊知識星球微信掃碼加入個人星球。

與恆宇少年面對面

若是你喜歡恆宇少年的相關文章,那麼就去微信公衆號(恆宇少年)關注我吧!!! 固然你也能夠去 SpringCloud碼雲源碼 項目底部掃描微信公衆號二維碼關注我,感謝閱讀!!!

學習目錄推薦

開源信息

這段時間一直在編寫開源的相關框架,致力於公司使用的框架升級以及開源計劃,將公司使用到的工具以及插件進行升級重構而且開源。

  • 代碼生成器(Code-Builder) code-builder代碼生成器根據你提供的模板文件(目前支持freemarker)自動生成實體類,能夠很大頗有效的提升開發效率。 Gitee地址gitee.com/hengboy/cod… Github地址github.com/hengyuboy/c…
  • 持久化框架(MyBatis-Enhance) mybatis-enhance是一個對mybatis框架的加強封裝,提供一系列的內部方法來完成單表數據的操做,多表數據提供DSL方式進行操做。 Gitee地址gitee.com/hengboy/myb… Github地址github.com/hengyuboy/m…
  • 自動分頁插件 MyBatis-Pageable是一款自動化分頁的插件,基於MyBatis內部的插件Interceptor攔截器編寫完成,攔截Executor.query的兩個重載方法計算出分頁的信息以及根據配置的數據庫Dialect自動執行不一樣的查詢語句完成總數量的統計。 Gitee地址gitee.com/hengboy/myb…
相關文章
相關標籤/搜索