当前位置:   article > 正文

Spring Cloud - 项目练习 - 2.服务注册与发现 - Eureka

Spring Cloud - 项目练习 - 2.服务注册与发现 - Eureka

Spring Cloud - 项目练习 - 2.服务注册与发现 - Eureka

回到总概
上一篇:Spring Cloud - 项目练习 - 1.项目准备
下一篇

服务提供者构建

  1. 建Module:创建eureka-provider-payment8001子Module
  2. 改pom:引入依赖
<dependencies>
    <!--引入自己定义的api通用包-->
    <dependency>
        <groupId>cloud.learn</groupId>
        <artifactId>example-common-api</artifactId>
        <version>${project.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
    </dependency>
    <!--mysql-connector-java-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--jdbc-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <!-- 热部署 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  1. 写yml
server:
  port: 8001

spring:
  application:
    name: eureka-provider-payment
  datasource:
    # 当前数据源操作类型
    type: com.alibaba.druid.pool.DruidDataSource
    # mysql驱动包
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/cloud_learn?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: #数据库用户名
    password: #数据库密码

mybatis:
  # xml文件夹位置
  mapper-locations: classpath:mapper/*.xml
  # 所有Entity别名类所在包
  type-aliases-package: cloud.learn.entities
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  1. 主启动类:创建cloud/learn/Payment8001.Java类
  2. 数据库搭建:直接复用cloud_learn数据库
  3. 业务构建:数据层创建PaymentDao类和对应的xml,业务层创建PaymentService接口、实现类以及对应的Controller类
  4. 测试:复用示例Module的测试

服务消费者构建

  1. 建Module:创建eureka-consumer-order80子Module
  2. 改pom
<dependencies>
    <!--引入自己定义的api通用包-->
    <dependency>
        <groupId>cloud.learn</groupId>
        <artifactId>example-common-api</artifactId>
        <version>${project.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- 热部署 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  1. 写yml
server:
  port: 80

spring:
  application:
    name: eureka-consumer-order
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 主启动类:创建cloud/learn/Order.java类
  2. 数据库搭建:无需数据库
  3. 业务构建:创建ApplicationContextConfig配置类、OrderController类
package cloud.learn.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
package cloud.learn.controller;

import cloud.learn.entities.CommonResult;
import cloud.learn.entities.Payment;
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 javax.annotation.Resource;

@RestController
@RequestMapping("eureka/order/")
public class OrderController {
    private String URL_PAYMENT_PRE = "http://localhost:8001/eureka/payment/";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("get/{id}")
    public CommonResult queryById(@PathVariable("id") Long id) {
        System.out.println("eureka-consumer-order80");
        CommonResult result = restTemplate.getForObject(URL_PAYMENT_PRE + "get/" + id, CommonResult.class);
        result.setMessage(result.getMessage()+"eureka-consumer-order80");
        return result;
    }

    @GetMapping("create")
    public CommonResult create(Payment payment) {
        System.out.println("eureka-consumer-order80");
        CommonResult result = restTemplate.postForObject(URL_PAYMENT_PRE + "insert", payment, CommonResult.class);
        result.setMessage(result.getMessage()+"eureka-consumer-order80");
        return result;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  1. 测试:请求localhost/eureka/order/get/1localhost/eureka/order/create?serial=aa并对比数据库

服务注册中心构建

  1. 建Module:创建eureka-server7001工程
  2. 改pom:导入以下依赖
<dependencies>
    <!-- eureka-server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  1. 写yml
server:
  port: 7001

eureka:
  instance:
    # eureka server名称
    hostname: localhost
  client:
    # 不向服务注册中心注册自身
    register-with-eureka: false
    # 不会拉取服务列表
    fetch-registry: false
    service-url:
      # eureka server的地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 主启动类:创建cloud/learn/EurekaServer.java类
package cloud.learn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {

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

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 测试:启动项目后访问localhost:7001成功显示eureka网页

服务注册

  1. 改pom:给order和payment两个微服务添加以下依赖
<!-- 服务注册中心的客户端端 eureka-client -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 改yml:给order和payment两个微服务添加以下配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka
  • 1
  • 2
  • 3
  • 4
  1. 改主启动类:分别给两个微服务的主启动类的类头上添加@EnableEurekaClient 注释
  2. 测试:先启动服务注册中心微服务,再启动order和payment微服务,然后访问localhost:7001 查看表(Instances currently registered with Eureka)中两个微服务成功注册

服务注册中心集群构建

服务注册中心集群

  1. 建Module:创建eureka-server7002工程
  2. 改Pom:引入与 eureka-server7001子Module相同的依赖
  3. 写yml:新建工程的yml如下(注意defaultZone属性值端口后的路径不能修改),同时修改eureka-server7002子Module的yml
# eureka-server7002子Module
server:
  port: 7002

eureka:
  instance:
    # eureka server名称
    hostname: eurekaServer7002
  client:
    # 不向服务注册中心注册自身
    register-with-eureka: false
    # 不会拉取服务列表
    fetch-registry: false
    service-url:
      # eureka server的地址
      defaultZone: http://eurekaServer7001:7001/eureka
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
# eureka-server7001子Module
server:
  port: 7001

eureka:
  instance:
    # eureka server名称
    hostname: eurekaServer7001
  client:
    # 不向服务注册中心注册自身
    register-with-eureka: false
    # 不会拉取服务列表
    fetch-registry: false
    service-url:
      # eureka server的地址
      defaultZone: http://eurekaServer7002:7002/eureka
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  1. 主启动类:创建EurekaServer7002主启动类
package cloud.learn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer7002 {

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

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 测试:启动两个子Module,访问localhost:7001 localhost:7002 地址查看两个服务注册中心,能正常显示且可以查看到另一个服务注册中心

服务提供者注册

  1. 写yml:修改eureka-consumer-order80和eureka-provider-payment8001两个服务提供者的yml文件,将其中defaultZone的值修改为http://eurekaServer7001:7001/eureka/,http://eurekaServer7002:7002/eureka/
  2. 修改host映射:修改C:\Windows\System32\drivers\etc文件夹下的hosts文件,加入127.0.0.1 eurekaServer7001 127.0.0.1 eurekaServer7002 两行
  3. 测试:先启动两个服务注册中心,在启动两个服务提供者,访问服务注册中心的网页查看两个服务提供者成功注册,并且能正常访问服务提供者的接口

服务提供者集群构建

服务提供者集群

  1. 建Module:创建eureka-provider-payment8002子Module
  2. 改xml:引入与eureka-provider-payment8001微服务相同的依赖
  3. 写yml:为新建的Module写入以下yml
server:
  port: 8002

spring:
  application:
    name: eureka-provider-payment
  datasource:
    # 当前数据源操作类型
    type: com.alibaba.druid.pool.DruidDataSource
    # mysql驱动包
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/cloud_learn?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

mybatis:
  # xml文件夹位置
  mapper-locations: classpath:mapper/*.xml
  # 所有Entity别名类所在包
  type-aliases-package: cloud.learn.entities

eureka:
  client:
    service-url:
      defaultZone: http://eurekaServer7001:7001/eureka/,http://eurekaServer7002:7002/eureka/
  instance:
    # 注入服务注册中心时使用的别名,不写时默认使用spring.application.name
    instance-id: payment8002
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  1. 主启动类:依照payment8001微服务创建Payment8002主启动类
  2. 业务构架:复制payment8001微服务的数据层和业务层
  3. 测试:先启动服务注册中心集群,再启动服务提供者集群,查看服务注册中心网页能看到两个服务提供者成功注册,并能够正常访问每个服务提供者的接口

服务消费者访问

  1. 访问地址修改:order微服务的controller类中URL_PAYMENT_PRE访问地址从固定的ip地址和端口号localhost:8001 改为别名eureka-provider-payment
  2. RestTemplate类平衡策略:为order微服务ApplicationContextConfig配置类的getRestTemplate()方法添加@LoadBalanced 注释
  3. 测试:启动服务注册中心和服务提供者集群后,访问order微服务的接口发现(在控制台和响应报文中输出接口号来区分)轮询使用payment8001和payment8002微服务的接口

服务发现

  1. 主启动类:在Payment8001微服务的主启动类的类头上添加@EnableDiscoveryClient注释
  2. 业务构建:在controller类中添加以下接口
@GetMapping("discovery")
public CommonResult discovery() {
    Map<String, List<String>> servicesResult = new HashMap<>();
    List<String> services = discoveryClient.getServices();
    for (String service : services) {
        List<ServiceInstance> instances = discoveryClient.getInstances(service);
        List<String> tmp = new ArrayList<>();
        for (ServiceInstance instance : instances) {
            tmp.add(instance.getServiceId()+"\t"+instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());
        }
        servicesResult.put(service, tmp);
    }

    return new CommonResult(200, "success", servicesResult);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 测试:访问该接口查看响应中的服务列表信息

自我保护禁用

  1. 服务注册中心改yml:为yml文件添加以下配置
eureka:
  server:
    # 关闭自我保护机制
    enable-self-preservation: false
    # 扫描失效服务的间隔时间(单位毫秒,默认是60秒)
    eviction-interval-timer-in-ms: 2000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 服务提供者改yml:为yml文件添加以下配置
eureka:
  instance:
    # 客户端向注册中心发送心跳的时间间隔
    lease-renewal-interval-in-seconds: 1
    # 注册中心等待下一次心跳的超时时间
    lease-expiration-duration-in-seconds: 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

sult);
}

3. 测试:访问该接口查看响应中的服务列表信息

## 自我保护禁用

1. 服务注册中心改yml:为yml文件添加以下配置
```yml
eureka:
  server:
    # 关闭自我保护机制
    enable-self-preservation: false
    # 扫描失效服务的间隔时间(单位毫秒,默认是60秒)
    eviction-interval-timer-in-ms: 2000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  1. 服务提供者改yml:为yml文件添加以下配置
eureka:
  instance:
    # 客户端向注册中心发送心跳的时间间隔
    lease-renewal-interval-in-seconds: 1
    # 注册中心等待下一次心跳的超时时间
    lease-expiration-duration-in-seconds: 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/92256
推荐阅读
相关标签
  

闽ICP备14008679号