SpringCloud笔记(一)服务注册与服务发现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhoujian_Liu/article/details/85170605

目录

1、Spring Cloud概述

2、环境搭建

2.1 搭建注册中心eureka-server

 pom.xml

application.yml

启动类:

2.2 注册服务提供者springcloud-producer

pom.xml

application.yml

Controller:

启动类:

2.3 服务消费者 SpringCloud-Consumer

pom.xml

application.yml

Controller:

启动类:

3、负载均衡测试

4、服务注册与发现原理


1、Spring Cloud概述

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

Spring Cloud包含了多个子项目:

Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,可以使用它搭建分布式配置中心。

Spring Cloud Netflix:核心组件,对多个Netflix OSS开源套件进行整合。

      Eureka:服务治理组件,包含服务注册中心、服务注册与发现机制的实现。

      Hystrix:容错管理组件,实现断路器模式,帮助服务依赖出现的延迟和未故障提供强大的容错能力。

      Ribbon:客户端负载均衡的服务调用组件。

      Feign:基于Ribbon和Hystrix的声明式服务调用组件

      Zuul:网关组件,提供智能路由、访问过滤等功能。

Spring Cloud Bus:时间、消息总线,用于传播集群中的状态变化或事件,以触发后续的处理,比如用来动态刷新配置等。

Spring Cloud Consul:服务发现与配置管理工具。

Spring Cloud Stream:通过Redis、Rabbit或者Kafka实现的消息微服务,通过简单点的声明式模型来发送和接收消息。

Spring Cloud Sleuth: Spring Cloud应用的分布式跟踪实现,可以完美整合Zipkin。

Spring Cloud Starters:Spring Cloud的基础组件,它是基于Spring Boot风格项目的基础依赖模块。

……

2、环境搭建

在此博客中使用Eureka作为注册中心,实现服务的注册与发现,项目结构如下:

2.1 搭建注册中心eureka-server

 pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lzj</groupId>
<artifactId>euraker-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>euraker-server</name>
<description>this is a register server</description>

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.M3</spring-cloud.version>
</properties>

<dependencies>
    <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-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.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>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

application.yml

#端口号
server:
  port: 8100

eureka:
  instance:
    #注册到本地地址
    hostname: 127.0.0.1

  client:
    serviceUrl:
      #客户端访问的路径
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    #自己就是注册中心,不需要注册自己
    register-with-eureka: false
    #自己就是注册中心,不需要检索自己
    fetch-registry: false


启动类:

  @SpringBootApplication
  @EnableEurekaServer //开启eurekaServer
  public class EurakerServerApplication {
    public static void main(String[] args) {                
        SpringApplication.run(EurakerServerApplication.class, args);
    }
}

此时将注册中心运行起来,测试搭建是否成功。

通过访问:http://localhost:8100 看到如下界面,则表示搭建成功,不过此时并没有注册任何服务。

 

2.2 注册服务提供者springcloud-producer

pom.xml

    <!--pom文件中主要部分:netflix-eureka-client-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
=        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

application.yml

spring:
  application:
    name: app-producer

server:
  port: 8000

eureka:
  client:
    service-url:
         defaultZone: http://localhost:8100/eureka/
    register-with-eureka: true
    fetch-registry: true

Controller:


  @RestController
  public class ProducerController {
 
    @Value("${server.port}")
    private String port;
 
    @RequestMapping("/getMember")
    public String getMember() {
        return "this is a member service" + port;
    }
}

启动类:


 @SpringBootApplication 
 @EnableEurekaClient //启动会员服务
  public class SpringcloudProducerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringcloudProducerApplication.class, args);
    }
}

当SpringCloud Producer启动后,会在注册中心看到有该服务名称。

此时可以通过浏览器直接访问该服务:http://localhost:8000/getMember

2.3 服务消费者 SpringCloud-Consumer

现在有了注册中心,有了服务的提供者,现在再启动一个服务消费者,在Spring Cloud-Consumer中通过RPC远程调用技术调用SpringCloud-Producer中的服务(一个服务既可以当做提供者又可以当做消费者)。

pom.xml

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  </dependency>

application.yml

spring:
  application:
    name: app-consumer

server:
  port: 8001

eureka:
  client:
    service-url:
         defaultZone: http://localhost:8100/eureka/ #注册中心地址
    register-with-eureka: true
    fetch-registry: true


Controller:

 @RestController
  public class OrderController {

   @Autowired

   private RestTemplate restTemplate;
 

   @RequestMapping("/getorder")

   public String getOrder() {
      // order 使用rpc 远程调用技术 调用 会员服务restTemplate
      String memberUrl = "http://app-producer/getMember";
      String result = restTemplate.getForObject(memberUrl, String.class);
      System.out.println("会员服务调用订单服务,result:" + result);
      return result;
   }
}

启动类:

 @SpringBootApplication
 @EnableEurekaClient
  public class SpringcloudConsumerApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringcloudConsumerApplication.class, args);
    }

    @Bean
    @LoadBalanced  //让RestTemplate在请求时拥有客户端负载均衡的能力
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    //不加@LoadBalanced 将出现无法解析app-producer地址的错误:java.net.UnknownHostException
  }

在进行远程调用时,采用了RestTemplate方式,这种方式底层采用的是Ribbon本地负载均衡,(还有一个Feign远程调用技术更常用,在以后的博客中会介绍到Feign客户端调用方式)。当使用RestTemplate时,需要自己注入一个bean对象,并且在该对象上面加上@LoadBalance开启本地负载均衡,否则会造成服务名称无法解析的错误:java.net.UnknownHostException

当两个服务都启动时,此时注册中心信息如下:

现在访问springcloud-consumet的getOrder接口,以此进行远程调用。

浏览器访问:http://localhost:8001/getorder

说明底层通过RestTemplate完成了远程调用。

3、负载均衡测试

修改springcloud-producer的端口号为8002,重新再启动一个,模拟一个服务的集群。

可以看到APP-PRODUCER有两个服务实例,分别运行在8000端口和8002端口。

当访问http://localhost:8001/getorder时,Ribbon底层会自动实现负载均衡。

 

4、服务注册与发现原理

a、首先启动eureka注册中心

b、启动springcloud-producer或springcloud-consumer后,会将服务别名、服务所在的地址和端口号以键值对的形式注册到eureka注册中心,如:

key:APP-PRODUCER  value:127.0.0.1:8000, 127.0.0.1:8002

并且每隔一段时间发送心跳包维持连接

c、当通过springcloud-consumer进行远程调用时,首先通过服务别名(APP-PRODUCER)去注册中心查找对应的键,获取对应的值(value:127.0.0.1:8000, 127.0.0.1:8002),当获取到值的时候,首先缓存在本地JVM中,并且缓存的值默认每隔30s刷新一次。之后通过本地负载均衡选取一个服务,底层通过HttpClient技术进行远程调用。

项目源码:https://github.com/liuzhoujian/springcloud-eureka

 

猜你喜欢

转载自blog.csdn.net/zhoujian_Liu/article/details/85170605