Loading... 本节示例代码在: [https://github.com/laolunsi/spring-boot-stack](https://github.com/laolunsi/spring-boot-stack) --- ## 一、概述 在上一节中,我们利用eureka成功注册了一个client服务,那么疑问来了,我们创建微服务的最终作用还是要去调用它。在SpringCloud下,我们怎么去调用创建的微服务呢? 先看没有微服务的情况,程序A调用程序B: ![file](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1577284730199.png) 而在微服务架构中,服务调用是这样的: ![file](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1577284737050.png) 在本篇文章中,我们就来建立这样一个SpringCloud下的服务调用系统。 **SpringCloud中常用的服务调用方式有两种:Ribbon和Feign,而Feign是基于Ribbon封装的。这一篇,我们先基于更简单易用的Feign来实现。** > 官网地址:[https://spring.io/projects/spring-cloud-openfeign](https://spring.io/projects/spring-cloud-openfeign) > > Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations **思路:需要以下三种角色:服务注册中心、服务提供者、服务消费者。** 服务注册中心基于之前的eureka构建,服务提供者添加测试接口,而服务调用者需要引入feign的依赖和配置,然后以声明式的方式来调用服务提供者的接口。 注1:这里的服务可以简单理解为Web接口的集合。 注2:本例中的服务注册中心参考上一节建立一个即可,端口号设为8100。SpringBoot使用2.0.x,SpringCloud使用`Finchley.RELEASE`版本。 --- ## 二、创建服务提供者 注册一个service-producer服务,端口号8101 添加如下依赖(主要就是eureka-client): ```xml <properties> <java.version>1.8</java.version> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 引入netlfix-eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </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> ``` 配置文件: ```yml server: port: 8101 spring: application: name: service-provider eureka: client: service-url: defaultZone: 'http://peer1:8100/eureka' ``` 在Application类上加上`@EnableDiscoveryClient`注解,也可以使用`@EnableEurekaClient` 编写一个接口: ```java package com.example.serviceprovider; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping(value = "hello") public class HelloAction { @GetMapping(value = "{name}") public String hello(@PathVariable("name") String name) { return "hello, " + name + ", this is service provider's response."; } } ``` --- ## 三、创建服务消费者 注册一个service-consumer服务,端口号8102 引入eureka-client和feign依赖: ```xml <properties> <java.version>1.8</java.version> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 引入eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- 引入openfeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </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> ``` 配置文件: ```yaml server: port: 8102 spring: application: name: service-consumer eureka: client: service-url: defaultZone: 'http://peer1:8100/eureka' # eureka服务地址 ``` Application类添加两个注解: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableDiscoveryClient @EnableFeignClients @SpringBootApplication public class ServiceConsumerApplication { public static void main(String[] args) { SpringApplication.run(ServiceConsumerApplication.class, args); } } ``` `@EnableFeignClients`注解使得服务消费者开启了Feign。 下面编写一个`@FeignClient`对应的接口,如下: ```java import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; // 这里的name对应的就是要调用的服务的名称 @FeignClient(name = "service-provider") public interface HelloRemote { @GetMapping(value = "hello/{name}") public String hello(@PathVariable("name") String name); } ``` 如上,使用了`@FeignClient(name = "service-provider")`标明对应要调用的服务,name就是服务的名称。 下面的方法与服务提供者(service provider)中编写的接口名称、参数等均相同。 然后在服务消费者里编写一个新的接口,通过调用它来进一步调用服务提供者: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "consumer") public class TestAction { @Autowired private HelloRemote helloRemote; @GetMapping(value = "test") public String consume(String name) { String res = helloRemote.hello(name); String str = "服务消费者调用服务提供者,提供参数name=" + name + ",获取返回值:" + res; System.out.println(str); return str; } } ``` ------ ## 四、启动与测试 分别启动`eureka-server`, `service-provider`, `service-consumer`,打开浏览器,输入`http://localhost:8100`,看到如下页面: ![file](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1577284766041.png) 两个服务都注册成功了。 下面我们测试一下,首先测试一下service-producer提供的接口是否正常: ![file](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1577284783524.png) 最后我们利用service-consumer的接口来测试服务互相调用是否正常: ![file](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1577284797117.png) 至此,我们利用Eureka做服务注册与发现,Feign进行服务调用的示例项目已完成。 ------ 参考资料 > 1. 纯洁的微笑-SpringCloud专栏3-服务提供与调用:http://www.ityouknow.com/springcloud/2017/05/12/eureka-provider-constomer.html > 2. 方志朋-SpringCloud系列3-服务消费者(Feign):https://blog.csdn.net/forezp/article/details/69808079 Last modification:December 25, 2019 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 请作者喝杯肥宅快乐水吧!