这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战
承接上一篇文章《上手实践Spring Cloud Eureka 和 Feign(二)》,上篇文章成功启动了注册中心,服务提供方,这篇文章基于Feign发现并消费服务。
三、Feign
这一章节我们从三个方面递进的讲Feign,第一如果没有Feign,我们将如何调用注册中心的服务;第二Feign是什么,能为我们带来哪些便利?第三,如何上手使用Feign。
3.1 如果没有Feign
为什么是Feign呢,如果不使用Feign我们该如何调用注册到Eureka上的服务呢?
如果不使用Feign,为了保证正常的服务发现和调用,我们必须要做到以下核心几步:
- 第一步,使用
Ribbon
进行负载均衡 - 第二步,获取服务的实例,并且获取根URL,再拼凑方法的URL
- 第三步,最后使用 REST 模板或者其它方式来使用指定的服务
对于第一步,使用Ribbon
获取服务实例,大致的代码如下。
@Autowired
private LoadBalancerClient loadBalancer;
pulic void method(){
ServiceInstance serviceInstance=loadBalancer.choose("producer");
}
对于第二步,大致的代码如下:
pulic void method(){
String baseUrl=serviceInstance.getUri().toString();
baseUrl=baseUrl+"/targetURL";
}
最后对于第三步,执行访问,并获取结果,大致的代码如下。
pulic void method(){
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response=null;
try{
response=restTemplate.exchange(baseUrl,
HttpMethod.GET, getHeaders(),String.class);
}catch (Exception ex)
{
System.out.println(ex);
}
System.out.println(response.getBody());
}
在整个调用过程中,是很复杂的,我们还需要处理一些空异常等等,我们使用Feign可以做到简化以上的步骤。
3.2 Feign介绍
Feign
旨在简化HTTP API客户端,它是一个声明式Web Service客户端。Fegin是一个java调用HTTP的客户端binder,其灵感来自于Retrofit、JAXRS-2.0和WebSocket。
使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS
标准的注解,并且Feign也支持可拔插式的编码器和解码器。
那么Feign是如何工作的呢?简单地说,Feign基于将注解转换成请求模板的方式工作,参数会简单直接的应用到模板上。具体原理不做过深的阐述。
像上面提供的未使用Feign的例子,使用Feign后其调用链图如下。
正如Eureka,Spring Cloud也提供了方便使用的OpenFeign Starter
,我们将看到如何使用 Netflix Feign 使服务发现和调用变得更加容易和整洁。
3.3 上手实践
在这里,我们就使用上篇文章介绍提供的服务注册中心,和服务提供方。
首先新建一个模块,引入相关依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
注意,我们因为要去发现Eureka的提供的服务,所以还是要引入Eureka Client的依赖。
接下来提供与服务方调用一模一样的接口GreetingClient
。
@FeignClient("spring-cloud-eureka-client")
public interface GreetingClient {
@GetMapping("/greeting")
String greeting();
}
所以这里就有一个问题,服务提供方和消费要声明同样一套接口,按照最佳工程实践,建议把这部分接口抽象出来作为单独Modeling
,然后对应的服务提供方和消费方引入这个包。
接下来是,写启动类和Web服务,为了方便,把两者都写到启动类Launcher
吧。
@SpringBootApplication
@EnableFeignClients
@RestController
public class Launcher {
@Autowired
private GreetingClient greetingClient;
public static void main(String[] args) {
SpringApplication.run(Launcher.class,args);
}
@GetMapping("/get-greeting")
public String greeting(){
return greetingClient.greeting();
}
}
application.yml
配置信息如下。
spring:
application:
name: spring-cloud-eureka-feign-client
server:
port: 8080
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
然后启动这个消费服务,观察Eureka的管理页面,可以看到这个消费方也注册到Eureka注册中心了。
然后访问http://{yourhost}:8080/get-greeting
,即得到hello...
的回复,代表调用链通畅。
在这个例子中,并没有引入负载均衡,如果想要做到,引入Ribbon
的依赖后,在代码调用服务的地方,正常去调用远程服务即可。
@Autowired
private RemoteCallService loadBalancer;
#服务方法中这样使用去调用远程方法去获取数据
data tmp = loadBalancer.getData();
四、总结
相较而言,这一整篇文章还是比较简单,上手实践一点都不难,因为整个系列都是以入门教程为主,让读者认识到这些分布式组件为什么要提供,我们能用它们分别做什么。服务注册中心还有很多,比如Zuul、ZK等等,接下来的教程会一一讲到,敬请期待!
少年,没看够?点击石头的主页,随便点点看看,说不定有惊喜呢?欢迎支持点赞/关注/评论,有你们的支持是我更文最大的动力,多谢啦!