天天看點

SpringCloud之服務注冊與發現Eureka+用戶端Feign端口應用名稱端口應用名稱端口應用名稱

SpringCloud之服務注冊與發現Eureka+用戶端Feign

前言

  SpringCloud 是微服務中的翹楚,最佳的落地方案。

  Eureka 作為注冊中心,是 SpringCloud 體系中最重要最核心的元件之一。

  Feign 使用接口加注解的方式調用服務,配合 Eureka 還能實作負載均衡。

源碼

  GitHub位址:

https://github.com/intomylife/SpringCloud

環境

JDK 1.8.0 +

Maven 3.0 +

SpringBoot 2.0.3

SpringCloud Finchley.RELEASE

開發工具

IntelliJ IDEA 

正文

commons 工程

commons 工程 - POM 檔案

<?xml version="1.0" encoding="UTF-8"?>

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- 三坐标 -->
<groupId>com.zwc</groupId>
<artifactId>springcloud-eureka-commons</artifactId>
<version>1.0</version>

<!-- 工程名稱和描述 -->
<name>springcloud-eureka-commons</name>
<description>公用工程</description>

<!-- 打包方式 -->
<packaging>jar</packaging>

<!-- 在 properties下聲明相應的版本資訊,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
<properties>
    <!-- 編碼 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- jdk -->
    <java.version>1.8</java.version>

    <!-- SpringBoot -->
    <platform-bom.version>Cairo-SR3</platform-bom.version>

    <!-- SpringCloud -->
    <spring-cloud-dependencies.version>Finchley.RELEASE</spring-cloud-dependencies.version>
</properties>

<!-- 加入依賴 -->
<dependencies>

</dependencies>

<!-- 依賴 jar 包版本管理的管理器 -->
<!-- 如果 dependencies 裡的 dependency 自己沒有聲明 version 元素,那麼 maven 就此處來找版本聲明。 -->
<!-- 如果有,就會繼承它;如果沒有就會報錯,告訴你沒有版本資訊 -->
<!-- 優先級:如果 dependencies 裡的 dependency 已經聲明了版本資訊,就不會生效此處的版本資訊了 -->
<dependencyManagement>
    <dependencies>
        <!-- SpringBoot -->
        <dependency>
            <groupId>io.spring.platform</groupId>
            <artifactId>platform-bom</artifactId>
            <version>${platform-bom.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- SpringCloud -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud-dependencies.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- 插件依賴 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
           

配置一些共用依賴

commons 工程 - 項目結構

service 工程

  此工程下有四個子產品:一個注冊中心,兩個提供者以及一個消費者

registry-service(注冊中心)

registry-service - POM 檔案

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- 繼承父 -->
<parent>
    <groupId>com.zwc</groupId>
    <artifactId>springcloud-eureka-service</artifactId>
    <version>1.0</version>
</parent>

<!-- 三坐标 -->
<groupId>com.zwc</groupId>
<artifactId>springcloud-eureka-registry-service</artifactId>
<version>0.0.1-SNAPSHOT</version>

<!-- 工程名稱描述 -->
<name>springcloud-eureka-registry-service</name>
<description>注冊中心</description>

<!-- 打包方式 -->
<packaging>jar</packaging>

<!-- 在 properties下聲明相應的版本資訊,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
<properties>

</properties>

<!-- 加入依賴 -->
<dependencies>
    <!-- commons工程 依賴 -->
    <dependency>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-eureka-commons</artifactId>
        <version>1.0</version>
    </dependency>

    <!-- 服務注冊中心 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

<!-- 插件依賴 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
           

主要是加入 spring-cloud-starter-netflix-eureka-server 依賴

registry-service - application.yml 配置檔案

端口

server:

port: 8761

應用名稱

spring:

application:

name: eurka-server
           

eureka:

instance:

# 使用 ip 代替執行個體名
prefer-ip-address: true
# 執行個體的主機名
hostname: ${spring.cloud.client.ip-address}
# 執行個體的 ID 規則
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}           

client:

# 是否向注冊中心注冊自己
registerWithEureka: false
# 是否向注冊中心擷取注冊資訊
fetchRegistry: false
serviceUrl:
  # 注冊中心位址
  defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/           

這裡使用了預設的 8761 端口,當然也可以更改,不過在發現調用服務端的注冊中心位址端口要與它一緻

registry-service - 啟動類

package com.zwc;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication

@EnableEurekaServer

public class SpringcloudEurekaRegistryServiceApplication {

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

}

在啟動類中添加 @EnableEurekaServer 注解表示此工程是注冊中心

registry-service - 啟動項目

  1. 項目啟動成功後通路 

http://localhost:8761/

 即可看到 eureka-server 首頁面

Provider(提供者)

Provider - POM 檔案

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- 繼承父 -->
<parent>
    <groupId>com.zwc</groupId>
    <artifactId>springcloud-eureka-providerfirst-service</artifactId>
    <version>1.0</version>
</parent>

<!-- 三坐标 -->
<groupId>com.zwc</groupId>
<artifactId>springcloud-eureka-providerfirst-service-core</artifactId>
<version>1.0</version>

<!-- 工程名稱描述 -->
<name>springcloud-eureka-providerfirst-service-core</name>
<description>提供者一号服務工程 - 核心</description>

<!-- 打包方式 -->
<packaging>jar</packaging>

<!-- 在 properties下聲明相應的版本資訊,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
<properties>

</properties>

<!-- 加入依賴 -->
<dependencies>
    <!-- commons工程 依賴 -->
    <dependency>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-eureka-commons</artifactId>
        <version>1.0</version>
    </dependency>

    <!-- api工程 依賴 -->
    <dependency>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-eureka-providerfirst-service-api</artifactId>
        <version>1.0</version>
    </dependency>

    <!-- 提供者消費者 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

<!-- 插件依賴 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
           

主要是加入 spring-cloud-starter-netflix-eureka-client 依賴

Provider - application.yml 配置檔案

port: 8090

name: say-hello
           
# 使用 ip 代替執行個體名
prefer-ip-address: true
# 執行個體的主機名
hostname: ${spring.cloud.client.ip-address}
# 執行個體的 ID 規則
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}           
serviceUrl:
  # 注冊中心位址
  defaultZone: http://${eureka.instance.hostname}:8761/eureka/           

注意此處配置注冊中心位址的端口為 8761 也就是上面注冊中心工程配置的端口

有兩個消費者工程,隻有此處的端口不一緻,此處端口為 8090,另一個端口為 8091。就不再贅述

兩個消費者工程作用是為了達到負載均衡的效果

spring.application.name:應用名稱,被消費者調用時需要用到

Provider - controller 前端控制器

package com.zwc.providerfirst.controller;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

  • @ClassName SayHelloController
  • @Desc TODO Say Hello
  • @Date 2019/5/15 15:28
  • @Version 1.0

    */

@RestController

public class SayHelloController {

/*
 * @ClassName SayHelloController
 * @Desc TODO   讀取配置檔案中的端口
 * @Date 2019/5/15 15:49
 * @Version 1.0
 */
@Value("${server.port}")
private String port;

/*
 * @ClassName SayHelloController
 * @Desc TODO   Say Hello
 * @Date 2019/5/15 15:30
 * @Version 1.0
 */
@RequestMapping("/hello")
public String hello(){
    return "Hello Spring Cloud!!!port:" + port;
}
           

提供一個服務:輸出 Hello 和端口

Provider - 啟動類

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient

public class SpringcloudEurekaProviderfirstServiceCoreApplication {

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

添加 @EnableEurekaClient 注解表示此工程可以向注冊中心提供服務

Provider - 啟動項目

  1. 項目啟動成功後通路 

http://localhost:8090/hello

 看到輸出内容 'Hello Spring Cloud!!!port:8090'

  2. 重新整理 

(注冊中心)可以看到服務已經被注冊進來了

  3. 同理,還有一個提供者工程隻是端口不一緻,也啟動起來

  4. 項目啟動成功後通路 

http://localhost:8091/hello

 看到輸出内容 'Hello Spring Cloud!!!port:8091'

  5. 再次重新整理 

(注冊中心)可以看到相同的服務有兩個提供者

Consumer(消費者)

Consumer - POM 檔案

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- 繼承父 -->
<parent>
    <groupId>com.zwc</groupId>
    <artifactId>springcloud-eureka-consumer-service</artifactId>
    <version>1.0</version>
</parent>

<!-- 三坐标 -->
<groupId>com.zwc</groupId>
<artifactId>springcloud-eureka-consumer-service-core</artifactId>
<version>1.0</version>

<!-- 工程名稱描述 -->
<name>springcloud-eureka-consumer-service-core</name>
<description>消費者服務工程 - 核心</description>

<!-- 打包方式 -->
<packaging>jar</packaging>

<!-- 在 properties下聲明相應的版本資訊,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
<properties>

</properties>

<!-- 加入依賴 -->
<dependencies>
    <!-- commons工程 依賴 -->
    <dependency>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-eureka-commons</artifactId>
        <version>1.0</version>
    </dependency>

    <!-- api工程 依賴 -->
    <dependency>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-eureka-consumer-service-api</artifactId>
        <version>1.0</version>
    </dependency>

    <!-- 提供者消費者 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!-- feign -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>

<!-- 插件依賴 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
           

與提供者一緻,需要加入 spring-cloud-starter-netflix-eureka-client 依賴

還需要加入 Feign 的起步依賴 spring-cloud-starter-openfeign

Consumer - application.yml 配置檔案

port: 8080

name: service-feign
           
# 使用 ip 代替執行個體名
prefer-ip-address: true
# 執行個體的主機名
hostname: ${spring.cloud.client.ip-address}
# 執行個體的 ID 規則
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}           
serviceUrl:
  # 注冊中心位址
  defaultZone: http://${eureka.instance.hostname}:8761/eureka/           

spring.application.name:應用名稱,被消費者調用時需要用到,它在消費的同時也可以被消費

Consumer - 服務調用

package com.zwc.consumer.api.feign;

import org.springframework.cloud.openfeign.FeignClient;

  • @ClassName FeignApi
  • @Desc TODO 使用 Feign 調用 Api - 接口
  • @Date 2019/5/15 16:11

@FeignClient("say-hello")

public interface FeignApi {

/*
 * @ClassName FeignApi
 * @Desc TODO   通過 say-hello 服務名調用 /hello 方法
 * @Date 2019/5/15 16:17
 * @Version 1.0
 */
@RequestMapping("/hello")
String hello();
           

通過 @FeignClient("say-hello") 注解來指定調用哪個服務

say-hello 就是提供者的 spring.application.name:應用名稱

String hello();:可以發現,此方法就是提供者 SayHelloController 中的方法,隻不過這裡要定義成接口

注意要與提供者具有相同傳回值,相同方法名以及相同參數

Consumer - controller 前端控制器

package com.zwc.consumer.controller;

import com.zwc.consumer.api.feign.FeignApi;

import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;

  • @ClassName FeignController
  • @Desc TODO 使用 Feign 調用 Api - 前端控制器
  • @Date 2019/5/15 16:18

public class FeignController {

@Autowired(required = false)
private FeignApi feignApi;

/*
 * @ClassName FeignController
 * @Desc TODO   調用 Say Hello 方法
 * @Date 2019/5/15 16:20
 * @Version 1.0
 */
@RequestMapping("/feign")
public String feign(){
    return feignApi.hello();
}
           

使用 @Autowired 注解裝配 Bean,通過此 Bean 中的方法調用服務

此類對外暴露接口,調用的實則是提供者的服務

Consumer - 啟動類

import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients

public class SpringcloudEurekaConsumerServiceCoreApplication {

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

添加 @EnableFeignClients 注解表示開啟 Feign 功能進行遠端調用

Consumer - 啟動項目

  1. 項目啟動成功後多次通路 

http://localhost:8080/feign

  2. 可以發現輪流輸出 'Hello Spring Cloud!!!port:8090' 和 'Hello Spring Cloud!!!port:8091'

  3. 此時已經達到了負載均衡的效果

  4. 再次重新整理 

(注冊中心)可以看到此時多了一個消費者

service 工程 - 項目結構

把多工程項目使用 IntelliJ IDEA  打開

把項目從 GitHub 中下載下傳到你的本地

打開 IntelliJ IDEA 

點選 File -> Open

打開你下載下傳到本地的項目目錄

springcloud-eureka -> springcloud-eureka-service(選擇打開此工程)

打開 service 工程後

再次點選 File -> Project Structrue

選擇 Modules,點選 '+' 符号

點選 Import  Module

還是打開你下載下傳到本地的項目目錄

springcloud-eureka -> springcloud-eureka-commons -> pom.xml

點選 OK

點選 Next,Finish

點選 Apply,OK

作者:鬥苦故事

來源:CSDN

原文:

https://blog.csdn.net/qq_41402200/article/details/90264207

版權聲明:本文為部落客原創文章,轉載請附上博文連結!