欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

跟我学SpringCloud | 第三篇:服务的提供与Feign调用

程序员文章站 2022-05-26 14:42:44
跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简单的客户端去调用服务端提供的服务。 本篇文章中需要三个角色,分别是服务的提供者,服务的消费者,还有一 ......

跟我学springcloud | 第三篇:服务的提供与feign调用

上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简单的客户端去调用服务端提供的服务。

本篇文章中需要三个角色,分别是服务的提供者,服务的消费者,还有一个是上一篇文章的主角——注册中心eureka(使用单机版本即可,本篇的示例也会使用单机版本的eureka)。

整体流程为:

  1. 先启动注册中心eureka
  2. 启动服务的提供者将提供服务,并将服务注册到注册中心eureka上
  3. 启动服务的消费者,在注册中心中找到服务并完成消费

1. 服务提供者

1. pom.xml

<?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>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.1.6.release</version>
        <relativepath/> <!-- lookup parent from repository -->
    </parent>
    <groupid>com.springcloud</groupid>
    <artifactid>producer</artifactid>
    <version>0.0.1-snapshot</version>
    <name>producer</name>
    <description>demo project for spring boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>greenwich.sr1</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-netflix-eureka-client</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>

2. 配置文件application.yml

server:
  port: 8080
spring:
  application:
    name: spring-cloud-producer
eureka:
  client:
    service-url:
      defaultzone: http://localhost:8761/eureka/

3. 启动类producerapplication.java

增加@enableeurekaclient,如果是其他注册中心可以使用注解@enablediscoveryclient来进行服务的注册

package com.springcloud.producer;

import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.cloud.netflix.eureka.enableeurekaclient;

@springbootapplication
@enableeurekaclient
public class producerapplication {

    public static void main(string[] args) {
        springapplication.run(producerapplication.class, args);
    }

}

4. controller

package com.springcloud.producer.controller;

import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;

/**
 * created with intellij idea.
 *
 * @date: 2019/7/2
 * @time: 0:02
 * @email: inwsy@hotmail.com
 * description:
 */
@restcontroller
public class hellocontroller {
    @requestmapping("/hello")
    public string hello(@requestparam string name) {
        return "hello "+name+",producer is ready";
    }
}

先在可以先启动上一篇当中单机版的eureka,再启动我们刚写好的producer服务提供者,启动成功后,访问链接http://localhost:8761/,可以看到我们的的服务提供者producer已经成功注册在注册中心上了。

跟我学SpringCloud | 第三篇:服务的提供与Feign调用

至此,服务的提供者已经配置完成。

2. 服务消费者

1. pom.xml

<?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>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.1.6.release</version>
        <relativepath/> <!-- lookup parent from repository -->
    </parent>
    <groupid>com.springcloud</groupid>
    <artifactid>consumers</artifactid>
    <version>0.0.1-snapshot</version>
    <name>consumers</name>
    <description>demo project for spring boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>greenwich.sr1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupid>org.springframework.cloud</groupid>
            <artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>
        <dependency>
            <groupid>org.springframework.cloud</groupid>
            <artifactid>spring-cloud-starter-openfeign</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>

spring-boot-starter-web: 这个包是通用的web开发包,里面包含了spring-web、spring-webmvc等包

spring-cloud-starter-openfeign: 这个包是springcloud对于feign的封装,feign是一个声明式的web服务客户端。它支持feign本身的注解、jax-rs注解以及springmvc的注解。spring cloud集成ribbon和eureka以在使用feign时提供负载均衡的http客户端。

2. 配置文件application.yml

server:
  port: 8081
spring:
  application:
    name: spring-cloud-consumers
eureka:
  client:
    service-url:
      defaultzone: http://localhost:8761/eureka/

3. 启动类consumersapplication.java

同上,增加@enableeurekaclient,如果是其他注册中心可以使用注解@enablediscoveryclient来进行服务的注册

package com.springcloud.consumers;

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 consumersapplication {

    public static void main(string[] args) {
        springapplication.run(consumersapplication.class, args);
    }

}

@enablefeignclients: 这个注解是通知springboot在启动的时候,扫描被 @feignclient 修饰的类,@feignclient这个注解在进行远程调用的时候会用到。

4. feign远程调用

feign是一个声明式web service客户端。使用feign能让编写web service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持jax-rs标准的注解。feign也支持可拔插式的编码器和解码器。spring cloud对feign进行了封装,使其支持了spring mvc标准注解和httpmessageconverters。feign可以与eureka和ribbon组合使用以支持负载均衡。

创建一个remote接口

package com.springcloud.consumers.remote;

import org.springframework.cloud.openfeign.feignclient;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;

/**
 * @author: shiyao.wei
 * @date: 2019/7/2 11:14
 * @version: 1.0
 * @desc:
 */
@feignclient(name= "spring-cloud-producer")
public interface helloremote {
    @requestmapping(value = "/hello")
    string hello(@requestparam(value = "name") string name);
}
  • name:远程服务名,及spring.application.name配置的名称
  • 此类中的方法和远程服务中contoller中的方法名和参数需保持一致

5. web层调用远程接口 controller

package com.springcloud.consumers.controller;

import com.springcloud.consumers.remote.helloremote;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.pathvariable;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

/**
 * @author: shiyao.wei
 * @date: 2019/7/2 11:25
 * @version: 1.0
 * @desc:
 */
@restcontroller
public class hellocontroller {
    @autowired
    helloremote helloremote;

    @requestmapping("/hello/{name}")
    public string index(@pathvariable("name") string name) {
        return helloremote.hello(name);
    }
}

现在,一个最简单的服务注册和调用的例子就完成了。

3. 测试

简单调用

顺次启动eureka、producer、consumer三个项目

启动成功后,先在浏览器输入http://localhost:8080/hello?name=springcloud

可以看到页面显示:hello springcloud,producer is ready

证明我们的producer已经正常启动,提供的服务也正常

接下来,我们测试服务消费者,在浏览器中输入:http://localhost:8081/hello/spring

可以看到页面显示:hello spring,producer is ready

说明客户端已经成功的通过feign调用了远程服务hello,并且将结果返回到了浏览器。

负载均衡

将上面的producer复制一份,修改名称为producer2,修改pom.xml中的<name></name>为producer2,修改其中的controller:

package com.springcloud.producer.controller;

import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;

/**
 * created with intellij idea.
 *
 * @date: 2019/7/2
 * @time: 0:02
 * @email: inwsy@hotmail.com
 * description:
 */
@restcontroller
public class hellocontroller {
    @requestmapping("/hello")
    public string hello(@requestparam string name) {
        return "hello "+name+",producer2 is ready";
    }
}

修改application.yml配置文件启动端口为8082

启动我们刚复制好的producer2,这时可以看一下注册中心eureka,我们现在已经有两个producer服务了。

跟我学SpringCloud | 第三篇:服务的提供与Feign调用

这时我们再去访问:http://localhost:8081/hello/spring

第一次返回结果:hello spring,producer is ready

第二次返回结果:hello spring,producer2 is ready

连续刷新页面,两个结果会交替出现,说明注册中心提供了服务负载均衡功能。将服务数提高到n个,会发现测试结果一样,请求会自动轮询到每个服务端来处理。

好了,现在可以将代码打包扔到github上去了,欢迎大家前往github骚扰:)

示例代码-github