Spring Cloud(Dalston.SR5)--Eureka 服务消费

时间:2023-03-08 16:17:23

服务被注册、发布到 Eureka 服务器后,需要有程序去发现他,并且进行调用,称为服务消费,一个服务可能会部署多个实例,调用过程可能涉及负载均衡、服务器查找等问题,这些问题 Netflix 项目已经帮助我们解决了,并且 Spring Cloud 已经封装了一次,我们可以仅需编辑少量代码就可以实现服务调用。

  • 创建项目

    创建名称为 service-invoker 的 Spring Cloud 项目,修改 POM.xml 中增加以下依赖项:

    <?xmlversion="1.0"encoding="UTF-8"?>

    <projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>org.lixue.webservice</groupId>

    <artifactId>service-invoker</artifactId>

    <version>1.0-SNAPSHOT</version>

    <parent>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-parent</artifactId>

    <version>1.5.4.RELEASE</version>

    <relativePath/><!--lookupparentfromrepository-->

    </parent>

    <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <java.version>1.8</java.version>

    <spring-cloud.version>Dalston.SR5</spring-cloud.version>

    </properties>

    <dependencies>

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

    <dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-eureka</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>

    </project>

  • 创建 REST 调用

    创建 InvokerHelloWorldController 类,用于调用之前创建的 helloworld-provider 的 REST 服务,在调用服务时输入的 url 为 http://服务名称:端口/uri 的方式调用,没有指定具体的服务地址,那为什么能够访问到我们的服务呢。

    因为 Spring Cloud 对 RestTemplate 进行了扩展,在启动类中使用了 @LoadBalanced 注解进行标注,使得 RestTemplate 实例具有了访问分布式服务的能力,代码如下:

    package org.lixue.serviceinvoker;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestMethod;

    import org.springframework.web.bind.annotation.RequestParam;

    import org.springframework.web.bind.annotation.RestController;

    import org.springframework.web.client.RestTemplate;

    import java.io.UnsupportedEncodingException;

    import java.net.URLEncoder;

    @RestController

    public class InvokerHelloWorldController{

    @Autowired

    private RestTemplate restTemplate;

    @RequestMapping(method=RequestMethod.GET,name="speak")

    public String invokerSpeak(@RequestParam(value="body",required=false)String body)

    throws UnsupportedEncodingException{

    StringencodeBody="";

    if(body!=null){

    encodeBody="?body="+URLEncoder.encode(body,"utf-8");

    }

    returnrestTemplate.getForObject("http://helloworld-provider/speak"+encodeBody,String.class);

    }

    }

  • 启动类启用 Eureka 客户端

    在启动类中,使用 @EnableDiscoveryClient 注解来修改启动类,该注解使得服务调用有能力去 Eureka 中发现服务,RestTemplate 对象实例使用 @LoadBalanced 注解来标注,表示该对象实例具有了访问分布式服务的能力。

    package org.lixue.serviceinvoker;

    import org.springframework.boot.SpringApplication;

    import org.springframework.boot.autoconfigure.SpringBootApplication;

    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

    import org.springframework.cloud.client.loadbalancer.LoadBalanced;

    import org.springframework.context.annotation.Bean;

    import org.springframework.web.client.RestTemplate;

    @SpringBootApplication

    @EnableDiscoveryClient

    public class ServiceInvokerApplication{

    publicstaticvoidmain(String[]args){

    SpringApplication.run(ServiceInvokerApplication.class,args);

    }

    @Bean

    @LoadBalanced

    public RestTemplate restTemplate(){

    return new RestTemplate();

    }

    }

  • 基本配置

    #配置应用名称

    spring:

    application:

    name:service-invoker

    #配置服务端口

    server:

    #eureka基本配置

    eureka:

    instance:

    #配置应用名称,优先级低于spring.applicaton.name

    appname:service-invoker

    client:

    #配置服务注册中心地址

    service-url:

    defaultZone:http://localhost:9000/eureka/

  • 启动项目

    按照顺序启动 Eureka 注册中心、服务提供者和项目,访问地址 http://localhost:8088/speak ,可以看到响应报文

    hello world 的返回,表示服务调用正常