Spring Cloud微服务系列文,服务调用框架Feign

3 @SpringBootApplication

4 public class ServiceCallerApp

5 {

6 public static void main( String[] args )

7 { SpringApplication.run(ServiceCallerApp.class, args); }

8 }

第四步,通过Feign封装客户端调用的细节,外部模块是通过Feign来调用客户端的,这部分的代码是在Controller.java里。

1 省略必要的package和import的代码

2 //通过注解指定待调用的服务名

3 @FeignClient(“sayHelloServiceProvider”)

4 //在这个接口里,通过Feign封装客户端的调用细节

5 interface FeignClientTool

6 {

7 @RequestMapping(method = RequestMethod.GET, value = “/hello/{name}”)

8 String sayHelloInClient(@PathVariable(“name”) String name);

9 }

10 //Controller是控制器类

11 @RestController

12 public class Controller {

13 @Autowired

14 private FeignClientTool tool;

15 //在callHello方法是,是通过Feign来调用服务

16 @RequestMapping(value = “/callHello”, method = RequestMethod.GET)

17 public String callHello(){

18 return tool.sayHelloInClient(“Peter”);

19 }

20 }

在Controller.java这个文件,其实定义了一个接口和一个类。在第5行的FeignClientTool接口里,我们封装了Feign的调用业务,具体来说,是通过第3行的FeignClient注解,指定了该接口会调用“sayHelloServiceProvider“服务提供者的服务,而通过第8行的,则指定了调用该服务提供者中sayHelloInClient的方法。

而在第12行的Controller类里,先是在第14行里,通过Autowired注解,引入了FeignClientTool类型的tool类,随后在第17行的callHello方法里,是通过tool类的sayHelloInClient方法,调用了服务提供者的相关方法。

也就是说,在callHello方法里,我们并没有再通过RestTemplate,以输入地址和服务名的方式调用服务,而是通过封装在FeignClientTool(Feign接口)里的方法调用服务。

完成上述代码后,我们可以通过如下的步骤查看运行效果。

第一步,启动FeignDemo-Server项目,随后输入http://localhost:8888/,能看到注册到Eureka服务器里的诸多服务。

第二步,启动FeignDemo-ServiceProvider项目,随后输入http://localhost:1111/hello/Peter,能调用其中的服务,此时,能在浏览里看到“hello Peter”的输出。

第三步,启动FeignDemo-ServiceCaller项目,随后输入http://localhost:8080/callHello,同样能在浏览里看到“hello Peter”的输出。请注意,这里的调用是通过Feign完成的。

2 通过比较其它调用方式,了解Feign的封装性

在之前的代码里,我们是通过如下形式,通过RestTemplate对象来调用服务。

1      RestTemplate template = getRestTemplate();

2             String retVal = template.getForEntity(“http://sayHello/hello/Eureka”, String.class).getBody();

在第2行的调用中,我们需要指定url以及返回类型等信息。

之前我们还见过基于RestClient对象的调用方式,关键代码如下。

1      RestClient client = (RestClient)ClientFactory.getNamedClient(“RibbonDemo”);

2       HttpRequest request = HttpRequest.newBuilder().uri(new URI(“/hello”)).build();

3      HttpResponse response = client.executeWithLoadBalancer(request);

其中是在第1行指定发起调用的RestClient类型的对象,在第2行里指定待调用的目标地址,随后在第3行发起调用。

这两种调用方式有着如下的共同点:调用时,需要详细地知道各种调用参数,比如服务提供者的url,如果有需要通过Ribbon实现负载均衡等机制,也需要在调用时一并指定。

但事实上,这些调用方式的底层细节,应该向服务使用者屏蔽,比如在调用时,无需关注目标url等信息。这就好比某位老板要秘书去订飞机票,作为服务使用者的老板只应当关心调用的结果,比如买到的飞机票是几点开的,该去哪个航站楼登机,至于调用服务的底层细节,比如该到哪个订票网站去买,服务使用者无需知道。

说得更专业些,这叫“解耦合”,即降低服务调动者和服务提供者之间的耦合度,这样的好处是,一旦服务提供者改变了实现细节(没改变服务调用接口),那么服务调用者部分的代码无需改动。

我们再来回顾下通过Feign调用服务的方式。

1      private FeignClientTool tool; //定义Feign类

2      tool.sayHelloInClient(“Peter”); //直接调用

第2行是调用服务,但其中,我们看不到任何服务提供者的细节,因为这些都在第1行引用的FeignClientTool类里封装掉了。也就是说,通过基于Feign的调用方式,开发者能真正地做到“面向业务”,而无需过多地关注发起调用的细节。

3 通过注解输出调用日志

在开发和调试阶段,我们希望能看到日志,从而能定位和排查问题。这里,我们将讲述在Feign里输出日志的方法,以便让大家能在通过Feign调用服务时,看到具体的服务信息。

这里我们将改写FeignDemo-ServiceCaller项目。

改动点1:在application.yml文件里,增加如下的代码,以开启Feign客户端的DEBUG日志模式,请注意,这里需要指定完成的路径,就像第3行那样。

1      logging:

2        level:

3          com.controller.FeignClientTool: DEBUG

改动点2:在这个项目的启动类ServiceCallerApp.java里,增加定义日志级别的代码,在第7行的feignLoggerLevel方法里,我们通过第8行的代码,指定了Feign日志级别是FULL。

1 //省略必要的pacakge和import代码

2 @EnableFeignClients

3 @EnableDiscoveryClient

4 @SpringBootApplication

5 public class ServiceCallerApp{

6 @Bean //定义日志级别是FULL

7 Level feignLoggerLevel() {

8 return Level.FULL;

9 }

10 //启动类

11 public static void main( String[] args ) {

12 SpringApplication.run(ServiceCallerApp.class, args);

13 }

14 }

完成后,依次运行Eureka服务器、服务提供者和服务调用者的启动类,随后在浏览器里输入http://localhost:8080/callHello,即能在控制台里看到DEBUG级别的日志,下面给出了部分输出。

1      2018-06-17 12:18:27.296 DEBUG 208 — [rviceProvider-2] com.controller.FeignClientTool           : [FeignClientTool#sayHelloInClient] —> GET http://sayHelloServiceProvider/hello/Peter?name=Peter HTTP/1.1

2      2018-06-17 12:18:27.296 DEBUG 208 — [rviceProvider-2] com.controller.FeignClientTool           : [FeignClientTool#sayHelloInClient] —> END HTTP (0-byte body)

从第1行的输出里,我们能看到以GET的方式向FeignClientTool类的sayHelloInClient方法发起调用,从第2行的输出里,能看到调用结束。

在上文里,我们用的是FULL级别的日志,此外,还有NONE、BASIC和HEADERS这三种,在下表里,我们将详细讲述各级别日志的输出情况。

日志输出级别

描述

NONE

不输出任何日志

BASIC

只输出请求的方法,请求的URL和相应的状态码,以及执行的时间

HEADERS

除了会输出BASIC级别的日志外,还会记录请求和响应的头信息

FULL

输出所有的和请求和响应相关的日志信息

一般情况下,在调试阶段,可以把日志级别设置成FULL,等上线后,可以把级别调整为BASIC,因为在生产环境上,过多的日志反而会降低排查和定位问题的效率。

4 压缩请求和返回,以提升访问效率

在网络传输过程中,如果我们能降低传输流量,那么即可提升处理请求的效率。尤其地,在一些日常访问量比较高的网络应用中,如果能降低处理请求(Request)和发送返回信息(Response)的时间,那么就能提升本站的吞吐量。

在Feign里,我们一般能通过如下的配置,来压缩请求和响应。

第一,可以通过在application.yml里增加如下的配置,从而压缩请求和返回信息。

1      feign:

2        compression:

3          request:

4            enabled: true

5      feign:

6         compression:

7           response:

8            enabled: true

其中,前4行是压缩请求,而后4行是压缩返回。

第二,可以通过如下的代码,设置哪类请求(或返回)将被压缩,这里我们在第4行里,指定了两类格式的请求将被压缩。

1      feign:

2        compression:

3          request:

4            mime-types: text/xml,application/xml

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
h2-1715061739823)]

[外链图片转存中…(img-4H107UBr-1715061739824)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值