前言
欢迎来到菜鸟SpringCloud入门实战系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud。
本系列适合有一定Java以及SpringBoot基础的同学阅读。
远程调用服务实战
本章节中需要有三个角色:服务注册中心(对应前文中我们的eureka子模块)、服务提供者(对应前文中我们的eureka-hi子模块)、服务消费者,其中服务注册中心就是我们上一篇的eureka单机版启动既可,流程是首先启动注册中心,服务提供者生产服务并注册到服务中心中,消费者从服务中心中获取服务并执行。
服务提供者:使用原来的eureka-hi子模块
子模块不需要做更改。
值得注意的是,你可以使用@EnableDiscoveryClient代替@EnableEurekaClient
两者的区别:
https://www.jianshu.com/p/f6db3117864f
注解@EnableEurekaClient上有@EnableDiscoveryClient注解,可以说基本就是EnableEurekaClient有@EnableDiscoveryClient的功能,另外上面的注释中提到,其实@EnableEurekaClientz注解就是一种方便使用eureka的注解而已,可以说使用其他的注册中心后,都可以使用@EnableDiscoveryClient注解,但是使用@EnableEurekaClient的情景,就是在服务采用eureka作为注册中心的时候,使用场景较为单一。
服务消费者:新建service-feign子模块
创建子模块service-feign,步骤和之前类似,请参考教程第一章。
修改pom.xml,引入:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> 复制代码
然后在主程序引入:
@EnableFeignClients @EnableEurekaClient 复制代码
这时候,我的springboot2.0.3又出事了,@EnableFeignClients无法引入,需要将pom.xml的引入修改为:
<dependency> <groupId>org.springframework.cloud</groupId> <!--spring boot 2.0.3版本解决方案:spring-cloud-starter-feign--> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> 复制代码
之后,修改application.yml:
server: # 服务端口号 port: 8765 spring: application: # 服务名,即serviceId name: service-feign eureka: client: serviceUrl: # 安全认证的服务注册中心地址 defaultZone: http://localhost:8761/eureka 复制代码
远程调用
首先回顾一下eureka-hi的方法,它提供了一个上述eureka-hi服务提供了一个RESTful风格的接口:
/** 获取端口号 */ @Value("${server.port}") String port; /** * 定义一个简单接口 * @param name * @return */ @GetMapping("/hi/{name}") public String home(@PathVariable String name){ return "hi " + name + ",I am from service-hi, port :" + port; } 复制代码
- 行为:GET
- 资源:/hi/{name}
编写调用eureka-hi提供的接口的本地接口ServiceHi.java,如下:
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; /** * <p>一个Feign服务消费者接口</p> **/ @FeignClient(value = "service-hi") public interface ServiceHi { /** * <p>通过Feign伪Http客户端调用service-hi提供的服务</p> * @author hanchao 2018/5/19 17:59 **/ @GetMapping("/hi/{name}") String sayHiFromServiceHi(@PathVariable(value = "name") String name); } 复制代码
说明:
- 通过@FeignClient标识当前接口是一个Feign客户端,value = "service-hi"表示其针对的是名为service-hi的服务。
- service-hi则是我们eureka-hi子模块的spring.application.name,这个name已经在eureka注册过
- sayHiFromServiceHi方法为伪装成HTTP客户端方法,与eureka-hi的[GET] /hi/{name}服务接口相对应。
之后,新建HelloController.java,如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; /** * <p>服务消费控制层</p> **/ @RestController public class HelloController { /** 注入服务"service-hi"的Feign客户端ServiceHi */ @Autowired private ServiceHi serviceHi; /** * 调用Feign客户端提供的服务,自带负载均衡 * @param name * @return */ @GetMapping("/hello/{name}") public String sayHi(@PathVariable String name){ //调用Feign客户端ScheduleServiceHi的接口 return serviceHi.sayHiFromServiceHi(name); } } 复制代码
重点:
- serviceHi.sayHiFromServiceHi(name)即通过Feign调用伪HTTP客户端的服务接口。
至此我们已经配置完毕,依次启动服务eureka、eureka-hi和service-feign。可以看到两个服务都已经在eureka注册:
访问 http://localhost:8765/hello/rude3knife ,即service-feign提供的服务接口。 这个服务接口会通过Feign去调用服务eureka-hi提供的服务接口,结果显示服务间调用成功。
在该调用中,我们feign并不需要指定端口号,它并不知道这个方法所在的服务提供者现在在哪个端口运行,我们只需要向eureka寻求服务。
三个模块的拓扑图如下:
测试Feign负载均衡
Feign会对服务调用进行负载平衡,我们需要同时打开两个eureka-hi服务,由于在同一台电脑上,就得把端口号从8763改为8764,然后同时开启8763和8764两个服务。
要同时运行两个端口不同的相同服务,需要在run configuration里面把allow parallle打开:
运行结构是这样的:
可以看到有两个Service-Hi进行了注册:
访问http://localhost:8765/hello/rude3knife
连续访问两次,发现两次会分别取调用eureka-hi的两个服务节点:
最后是负载平衡的拓扑图:
本章代码
https://github.com/qqxx6661/springcloud_for_noob/tree/master/04-servier-feign
参考
Spring-Cloud笔记04:服务消费者Feign
https://blog.csdn.net/hanchao5272/article/details/80574441
springcloud(三):服务提供与调用
http://www.ityouknow.com/springcloud/2017/05/12/eureka-provider-constomer.html