Spring Cloud Eureka 服务治理--服务发现与消费

这篇文章主要介绍如何使用Spring Cloud Eureka来实现服务治理--服务消费 ,是一个总结 记录 方便自己记忆。

文章知识 均来自以下系列文章,请参考原文

 Spring Cloud构建微服务架构:服务消费(基础)【Dalston版】

Spring Cloud构建微服务架构:服务消费(Ribbon)【Dalston版】

Spring Cloud构建微服务架构:服务消费(Feign)【Dalston版】

使用Spring Cloud Eureka来实现服务治理

 

2.服务注册与发现 : 创建 服务提供者 ---创建提供服务的客户端,并向服务注册中心注册自己

Step1:创建一个Spring Boot项目eureka-client,添加起步依赖 spring-cloud-starter-netflix-eureka-client ,spring-boot-starter-web

Step2:在项目入口添加 @EnableDiscoveryClient 注解,该注解能激活Eureka中的DiscoveryClient实现,这样才能实现Controller中对服务信息的输出。

Step3:在application.properties文件中配置一下

#微服务的名称:后续在调用的时候只需要使用该名称就可以进行服务的访问
spring.application.name=eureka-client
#微服务端口
server.port=2001

#指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
View Code

Step4:添加一个 该微服务可以提供的功能,例如 通过 DiscoveryClient对象,在日志中打印出服务实例的相关内容

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DiscoveryClientController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/discoveryClient")
    public String discoveryClient() {
        // 服务实例相关内容
        String service = "Services: " + discoveryClient.getServices();

        // 打印出服务实例相关内容
        System.out.println(service);

        // 返回服务实例相关内容
        return service;
    }
}
View Code

Step5:启动 eureka-client项目,再访问http://localhost:1001/就会在Instances currently registered with Eureka列表看到刚刚注册的eureka-client服务

Step6:如果要访问eureka-client微服务提供的discoveryClient 服务,可以访问http://localhost:2001/discoveryClient

待解决:那么我们其实需要的是 如何在其它微服务 访问 eureka-client eureka-client微服务提供的discoveryClient 服务。也就是 如何去消费服务提供者的接口 ,接着看 

 

3.1 服务消费 :创建服务消费者 并消费 eureka-client提供的服务--基础版

使用Spring Cloud提供的负载均衡器客户端接口 LoadBalancerClient接口 实现服务的消费。通LoadBalancerClient接口来获取某个服务的具体实例,并根据实例信息来发起服务接口消费请求。

Step1:创建一个Spring Boot项目 eureka-consumer(服务消费者工程),添加起步依赖 spring-cloud-starter-netflix-eureka-client ,spring-boot-starter-web

Step2:在项目入口类添加@EnableDiscoveryClient 注解,激活Eureka中的DiscoveryClient实现,将当前应用加入到服务治理体系中。

Step3:在application.properties文件添加配置

#微服务的名称:后续在调用的时候只需要使用该名称就可以进行服务的访问
spring.application.name=eureka-consumer
#微服务端口
server.port=2101
 
#指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
View Code

Step4:在配置类中初始化RestTemplate,用来真正发起REST请求。

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}
View Code

Step5: 创建一个接口用来消费eureka-client提供的接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class DiscoveryClientController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer")
    public String discoveryClient() {

        // LoadBalancerClient负载均衡的选出一个eureka-client的服务实例,把这个服务实例的基本信息存储在ServiceInstance中
        ServiceInstance serviceInstance = loadBalancerClient.choose("eureka-client");

        // 拼接出访问eureka-client微服务 /discoveryClient接口的详细地址
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "discoveryClient";
        System.out.println("url==" + url);

        // 利用RestTemplate对象实现对服务提供者接口的调用。
        String services = restTemplate.getForObject(url, String.class);
        return services;
    }
}
View Code

Step6:启动eureka-server,eureka-client,eureka-consumer。并访问http://localhost:2101/consumer 。就会看到eureka-consumer服务是如何消费eureka-client服务的/discoveryClient接口的

 

3.2 服务消费 :创建服务消费者 并消费 eureka-client提供的服务--Ribbon

基础版 通过LoadBalancerClient接口实现服务的消费,需要我们手工编写服务的选择,链接拼接等操作,对于开发人员不友好。所以Spring Cloud针对客户端负载均衡提供了工具包Spring Cloud Ribbon。

Spring Cloud Ribbon

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。它是一个基于HTTP和TCP的客户端负载均衡器。它可以通过在客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到均衡负载的作用。

当Ribbon与Eureka联合使用时,ribbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中心中获取服务实例列表。同时它也会用NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动。

我们在使用Spring Cloud Ribbon的时候,不论是与Eureka还是Consul结合,都会在引入Spring Cloud Eureka或Spring Cloud Consul依赖的时候通过自动化配置来加载上述所说的配置内容,所以我们可以快速在Spring Cloud中实现服务间调用的负载均衡。

使用Spring Cloud Ribbon来实现服务的调用以及客户端均衡负载。

Step1:创建Spring Boot项目eureka-consumer-ribbon,添加起步依赖 spring-cloud-starter-netflix-eureka-client ,spring-boot-starter-web,spring-cloud-starter-netflix-ribbon。

Step2:在项目入口类添加@EnableDiscoveryClient注解,将当前应用 添加到 服务治理体系中。

Step3:在application.properties文件中配置微服务

#微服务的名称:后续在调用的时候只需要使用该名称就可以进行服务的访问
spring.application.name=eureka-consumer-ribbon
#微服务端口
server.port=2201

#指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
View Code

Step4:在配置类中初始化RestTemplate,用来真正发起REST请求。并增加@LoadBalanced注解


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
View Code

Step5: 创建一个接口用来消费eureka-client提供的接口 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class DiscoveryClientController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer")
    public String discoveryClient() {
        String services = restTemplate.getForObject("http://eureka-client/discoveryClient", String.class);
        return services;
    }
}
View Code

 Step6:启动eureka-server,eureka-client,eureka-consumer-ribbon。并访问http://localhost:2201/consumer 。就会看到eureka-consumer-ribbon服务是如何消费eureka-client服务的/discoveryClient接口的

总结:使用 Spring Cloud Ribbon 的@LoadBalanced 注解 ,就可以使用 服务名和接口url 去调用服务。 因为Spring Cloud Ribbon有一个拦截器,它能够在这里进行实际调用的时候,自动的去选取服务实例,并将实际要请求的IP地址和端口替换这里的服务名,从而完成服务接口的调用。

 

3.3 服务消费 :创建服务消费者 并消费 eureka-client提供的服务--Feign

Spring Cloud Feign
Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端。它使得编写Web服务客户端变得更加简单。
我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。
Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

使用Feign方便的声明对eureka-client服务的定义和调用

Step1:创建Spring Boot项目eureka-consumer-feign,添加起步依赖 spring-cloud-starter-netflix-eureka-client ,spring-boot-starter-web,spring-cloud-starter-openfeign

Step2:在项目入口类添加@EnableDiscoveryClient注解,将当前应用 添加到 服务治理体系中。

Step3:在application.properties文件中配置微服务

#微服务的名称:后续在调用的时候只需要使用该名称就可以进行服务的访问
spring.application.name=eureka-consumer-feign
#微服务端口
server.port=2301

#指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
View Code

Step4:在配置类 添加  @EnableFeignClients注解,开启扫名Spring Cloud Feign客户端功能。

Step5:创建一个Feign的客户端接口定义。使用@FeignClient注解来指定这个接口所要调用的服务名称,接口中定义的各个函数使用Spring MVC的注解就可以来绑定服务提供方的REST接口,比如下面就是绑定eureka-client服务的/discoveryClient接口的例子:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

@Service
@FeignClient("eureka-client")
public interface DiscoveryClientService {

    @GetMapping("/discoveryClient")
    public String consumer();
}
View Code

Step6:创建controller ,通过定义的feign客户端来调用服务提供方的接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DiscoveryClientController {

    @Autowired
    private DiscoveryClientService discoveryClientService;

    @GetMapping("/consumer")
    public String comsumer() {
        String services = discoveryClientService.consumer();

        return services;
    }
}
View Code

Step7:启动eureka-server,eureka-client,eureka-consumer-feign。并访问http://localhost:2301/consumer 。就会看到eureka-consumer-feign服务是如何消费eureka-client服务的/discoveryClient接口的

总结:通过Spring Cloud Feign来实现服务调用的方式更加简单了。通过@FeignClient定义的接口来统一的声明我们需要依赖的微服务接口,而在具体使用的时候就跟调用本地方法一点的进行调用即可
由于Feign是基于Ribbon实现的,所以它自带了客户端负载均衡功能,也可以通过Ribbon的IRule进行策略扩展。
另外,Feign还整合的Hystrix来实现服务的容错保护,在Dalston版本中,Feign的Hystrix默认是关闭的。待后文介绍Hystrix带领大家入门之后,我们再结合介绍Feign中的Hystrix以及配置方式。

 

3种方式总结对比:

基础版:用Spring Cloud的LoadBalancerClient接口 获取获取某个服务的具体实例,链接拼接。并通过RestTemplate发起REST请求。

Ribbon版:用Spring Cloud的@LoadBalanced注解 通过服务提供者的服务名 ,并通过RestTemplate发起REST请求。和基础版相比 不再需要拼接服务url

Feign版:把服务提供者 通过@FeignClient注解 定义成 服务消费者的一个接口。服务提供者的方法 可以定义成接口中的方法。在服务消费者方 通过调用接口的方式 调用其它微服务的方法。

3种方式可以互为替代。

 

4.几台服务提供相同服务来做均衡负载

我们可以准备多个微服务,来提供相同的服务。这样当消费者调用服务时,Eureka Server 会随机调用某个微服务。

创建微服务eureka-client-1,提供和eureka-client微服务一样的服务,共消费方调用。

Step1:创建一个Spring Boot项目eureka-client-1,添加起步依赖 spring-cloud-starter-netflix-eureka-client ,spring-boot-starter-web

Step2:在项目入口添加 @EnableDiscoveryClient 注解,该注解能激活Eureka中的DiscoveryClient实现,这样才能实现Controller中对服务信息的输出。

Step3:在application.properties文件中配置一下

#微服务的名称:后续在调用的时候只需要使用该名称就可以进行服务的访问
spring.application.name=eureka-client
#微服务端口
server.port=2002

#指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
View Code
  • spring.application.name 和 微服务eureka-client  保持一致

Step4:添加一个 该微服务可以提供的功能,例如 通过 DiscoveryClient对象,在日志中打印出服务实例的相关内容

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class DiscoveryClientController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/discoveryClient")
    public String discoveryClient() {
        // 服务实例相关内容
        String service = "this is client 2 Services: " + discoveryClient.getServices();

        // 打印出服务实例相关内容
        System.out.println(service);

        // 返回服务实例相关内容
        return service;
    }
}
View Code
  • eureka-client 提供的服务的url 和 微服务eureka-client  保持一致。但输出内容不同

Step5:启动 eureka-client-1项目,再访问http://localhost:1001/就会在Instances currently registered with Eureka列表看到刚刚注册的eureka-client-1服务

Step6:如果要访问eureka-client-1微服务提供的discoveryClient 服务,可以访问http://localhost:2002/discoveryClient

Step7:启动eureka-consumer,并多次访问http://localhost:2101/consumer 。就会看到eureka-client 和 eureka-client-1 返回的两种结果交替出现,说明两个服务中心自动提供了服务均衡负载的功能。

posted on 2020-07-03 16:11  dreamstar  阅读(191)  评论(0编辑  收藏  举报