您的位置:首页 > 编程语言 > Java开发

SpringCloud之服务注册与发现Eureka+客户端Feign

2019-07-10 11:22 375 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_39447211/article/details/95311130

一、Spring Cloud简介

  1. Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。

  2. Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud CloudFoundry、Spring Cloud AWS、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI等项目。

二、前言介绍

  1. SpringCloud 是微服务中的翘楚,最佳的落地方案。

  2. Eureka 作为注册中心,是 SpringCloud 体系中最重要最核心的组件之一。

  3. Feign 使用接口加注解的方式调用服务,配合 Eureka 还能实现负载均衡。

三、源码

@: 1. GitHub地址:https://github.com/intomylife/SpringCloud
@: 2. 把工程项目使用 IntelliJ IDEA 打开
@: 3. 把项目从 GitHub 中下载到你的本地
@: 4. 打开 IntelliJ IDEA
@: 5. 点击 File -> Open
@: 6. 打开你下载到本地的项目目录
@: 7. springcloud-eureka -> springcloud-eureka-service(选择打开此工程)
@: 8. 打开 service 工程后
@: 9. 再次点击 File -> Project Structrue
@: 10. 选择 Modules,点击 ‘+’ 符号
@: 11. 点击 Import Module
@: 12. 还是打开你下载到本地的项目目录
@: 13. springcloud-eureka -> springcloud-eureka-commons -> pom.xml
@: 14. 点击 OK
@: 15. 点击 Next,Finish
@: 16. 点击 Apply,OK

四、环境

  1. JDK 1.8.0 +
  2. Maven 3.0 +
  3. SpringBoot 2.0.3
  4. SpringCloud Finchley.RELEASE

五、正文-开始

[一]、commons 工程

  1. commons 工程 -pom 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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>
    
    </project>

    @:配置一些共用依赖

  2. commons 工程 - 项目结构

[二]、service 工程

@:此工程下有四个模块:一个注册中心,两个提供者以及一个消费者

  1. registry-service(注册中心)

  2. registry-service-pom 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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>
    
    </project>

    @:主要是加入 spring-cloud-starter-netflix-eureka-server 依赖

  3. 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 端口,当然也可以更改,不过在发现调用服务端的注册中心地址端口要与它一致

  4. 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 注解表示此工程是注册中心

  5. registry-service - 启动项目

    @:项目启动成功后访问 http://localhost:8761/ 即可看到 eureka-server 主页面

[三]、Provider(提供者)

  1. Provider - POM 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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>
    
    </project>

    @:主要是加入 spring-cloud-starter-netflix-eureka-client 依赖

  2. Provider - application.yml 配置文件

    # 端口
    server:
    port: 8090
    
    # 应用名称
    spring:
    application:
    name: say-hello
    
    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:
    serviceUrl:
    # 注册中心地址
    defaultZone: http://${eureka.instance.hostname}:8761/eureka/

    @:注意此处配置注册中心地址的端口为 8761 也就是上面注册中心工程配置的端口
    @:有两个消费者工程,只有此处的端口不一致,此处端口为 8090,另一个端口为 8091。就不再赘述
    @:两个消费者工程作用是为了达到负载均衡的效果
    @:spring.application.name:应用名称,被消费者调用时需要用到

  3. 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 和端口

  4. Provider - 启动类

    package com.zwc;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class SpringcloudEurekaProviderfirstServiceCoreApplication {
    
    public static void main(String[] args) {
    SpringApplication.run(SpringcloudEurekaProviderfirstServiceCoreApplication.class, args);
    }
    
    }

    @:添加 @EnableEurekaClient 注解表示此工程可以向注册中心提供服务

  5. Provider - 启动项目

    @:项目启动成功后访问 http://localhost:8090/hello 看到输出内容 ‘Hello Spring Cloud!!!port:8090’

    @:刷新 http://localhost:8761/ (注册中心)可以看到服务已经被注册进来了

    @:同理,还有一个提供者工程只是端口不一致,也启动起来

    @:项目启动成功后访问 http://localhost:8091/hello 看到输出内容 ‘Hello Spring Cloud!!!port:8091’

    @:再次刷新 http://localhost:8761/(注册中心)可以看到相同的服务有两个提供者

[四]、Consumer(消费者)

  1. Consumer - POM 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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>
    
    </project>

    @:与提供者一致,需要加入 spring-cloud-starter-netflix-eureka-client 依赖
    @:还需要加入 Feign 的起步依赖 spring-cloud-starter-openfeign

  2. Consumer - application.yml 配置文件

    # 端口
    server:
    port: 8080
    
    # 应用名称
    spring:
    application:
    name: service-feign
    
    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:
    serviceUrl:
    # 注册中心地址
    defaultZone: http://${eureka.instance.hostname}:8761/eureka/

    @:注意此处配置注册中心地址的端口为 8761 也就是上面注册中心工程配置的端口
    @:spring.application.name:应用名称,被消费者调用时需要用到,它在消费的同时也可以被消费

  3. Consumer - 服务调用

    package com.zwc.consumer.api.feign;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
    * @ClassName FeignApi
    * @Desc TODO   使用 Feign 调用 Api - 接口
    * @Date 2019/5/15 16:11
    * @Version 1.0
    */
    @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 中的方法,只不过这里要定义成接口
    @:注意要与提供者具有相同返回值,相同方法名以及相同参数

  4. Consumer - controller 前端控制器

    package com.zwc.consumer.controller;
    
    import com.zwc.consumer.api.feign.FeignApi;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    /**
    * @ClassName FeignController
    * @Desc TODO   使用 Feign 调用 Api - 前端控制器
    * @Date 2019/5/15 16:18
    * @Version 1.0
    */
    @RestController
    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 中的方法调用服务
    @:此类对外暴露接口,调用的实则是提供者的服务

  5. Consumer - 启动类

    package com.zwc;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    public class SpringcloudEurekaConsumerServiceCoreApplication {
    
    public static void main(String[] args) {
    SpringApplication.run(SpringcloudEurekaConsumerServiceCoreApplication.class, args);
    }
    
    }

    @:添加 @EnableEurekaClient 注解表示此工程可以向注册中心提供服务
    @:添加 @EnableFeignClients 注解表示开启 Feign 功能进行远程调用

  6. Consumer - 启动项目

    @: 1. 项目启动成功后多次访问 http://localhost:8080/feign

    @: 2. 可以发现轮流输出 ‘Hello Spring Cloud!!!port:8090’ 和 ‘Hello Spring Cloud!!!port:8091’

    @: 3. 此时已经达到了负载均衡的效果

    @:4. 再次刷新 http://localhost:8761/(注册中心)可以看到此时多了一个消费者

  7. service 工程 - 项目结构

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐