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/feign2. 可以發現輪流輸出 '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版權聲明:本文為部落客原創文章,轉載請附上博文連結!