zoukankan      html  css  js  c++  java
  • 微服务实战SpringCloud之Spring Cloud Feign

    简介

    在项目中我们有时候需要调用第三方的API,微服务架构中这种情况则更是无法避免——各个微服务之间通信。比如一般的项目中,有时候我们会使用 HTTP Client 发送 HTTP 请求来进行调用,而在微服务架构,Spring Cloud 全家桶中,Spring Cloud Feign 则是更常见的选择。那么,我如何只使用 Spring Cloud Feign 而不引入整个 Spring Cloud 呢?

    什么是Feign?

    Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。

    而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix,可以让我们不再需要显式地使用这两个组件。

    总起来说,Feign具有如下特性:

    • 可插拔的注解支持,包括Feign注解和JAX-RS注解;
    • 支持可插拔的HTTP编码器和解码器;
    • 支持Hystrix和它的Fallback;
    • 支持Ribbon的负载均衡;
    • 支持HTTP请求和响应的压缩。

    这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。

    首先找一个AIP

    免费的API特别多,github上也有免费API地址汇总的repo,但这些都太正式了。有趣的事物总是会相互吸引的,无意间我发现了这么一个网站,“渣男:说话的艺术”(lovelive.tools) ,每次请求都可以获取一句甜言蜜语(渣男语录),特别良心的是,作者提供了API列表,给作者点赞!

    如何调用第三方服务?

    首先,我们先快速构建一个 Spring Boot 的 web 项目,这里我就省略了。然后在pom中添加feign的相关依赖

    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-openfeign</artifactId>
         <version>2.1.3.RELEASE</version>
    </dependency>

    然后,在启动类添加响应的注解 @EnableFeignClients:

    @SpringBootApplication
    @EnableFeignClients
    public class SpringbootMiddlewareFeignApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringbootMiddlewareFeignApplication.class, args);
        }
    }

    接着,我们便可以配置我们的 Client 了,我们先创建一个接口类,比如叫BadGuyFeignClient ,并声明为 FeignClient:

    @FeignClient
    public interface BadGuyFeignClient {
    
    }

    @FeignClient有以下几个较常用属性:

    属性名默认值作用备注
    value 空字符串 调用服务名称,和name属性相同,如果项目使用了 Ribbon,name属性会作为微服务的名称,用于服务发现;  
    serviceId 空字符串 服务id,作用和name属性相同 已过期
    name 空字符串 调用服务名称,和value属性相同,如果项目使用了 Ribbon,name属性会作为微服务的名称,用于服务发现;  
    url 空字符串 url一般用于调试,可以手动指定@FeignClient调用的地址  
    decode404 false 配置响应状态码为404时是否应该抛出FeignExceptions  
    configuration {} Feign配置类,可以自定义 Feign的 Encoder、Decoder、LogLevel、Contract; 参考FeignClientsConfiguration
    fallback void.class 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口 底层依赖hystrix,启动类要加上@EnableHystrix
    fallbackFactory void.class 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码  
    path 空字符串 自动给所有方法的requestMapping前加上前缀,类似与controller类上的requestMapping  

    然后,我们便可以配置对应的属性,这里我们只是用来实现类似于 HTTP Client 的功能,所以只是简单配置了url和path这些属性:

    @FeignClient(name = "badGuy", url = "${bab.guy.url}", path = "api")
    public interface BadGuyFeignClient {
    
        /**
         * 随机获取一句甜言蜜语
         *
         * @return
         */
        @GetMapping("SweetNothings")
        String getSweetNothings();
    
        /**
         * 获取 count 条甜言蜜语
         *
         * @param count 获取甜言蜜语条数
         * @return Json 格式的结果
         */
        @GetMapping("SweetNothings/{count}/Serialization/Json")
        ReturnResult<List<String>> getSweetNothingsJsonByCount(@PathVariable("count") Integer count);
    
    }

    声明为FeignClient之后,我们便可以在代码中使用@Resource或者@Autowire进行注入使用了:

    提示 org.apache.http.impl.client.HttpClientBuilder 这个类找不到 问题的解决

    java.lang.IllegalStateException: Error processing condition on org.springframework.cloud.commons.httpclient.HttpClientConfiguration$ApacheHttpClientConfiguration.apacheHttpClientBuilder
    	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    	......
    	
    Caused by: java.lang.IllegalStateException: @ConditionalOnMissingBean did not specify a bean using type, name or annotation and the attempt to deduce the bean's type failed
    	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.validate(OnBeanCondition.java:487) ~[spring-boot-autoconfigure-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    	......
    	... 18 common frames omitted
    Caused by: org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanTypeDeductionException: Failed to deduce bean type for org.springframework.cloud.commons.httpclient.HttpClientConfiguration$ApacheHttpClientConfiguration.apacheHttpClientBuilder
    	......
    	... 20 common frames omitted
    Caused by: java.lang.ClassNotFoundException: org.apache.http.impl.client.HttpClientBuilder
    	......
    	... 22 common frames omitted
    
    2021-03-15 07:34:52.548  WARN 11915 --- [           main] o.s.boot.SpringApplication               : Unable to close ApplicationContext
    
    java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.commons.httpclient.HttpClientConfiguration$ApacheHttpClientConfiguration] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
    	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    	......
    Caused by: java.lang.NoClassDefFoundError: org/apache/http/impl/client/HttpClientBuilder
    	at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_241]
    	......
    	... 21 common frames omitted
    Caused by: java.lang.ClassNotFoundException: org.apache.http.impl.client.HttpClientBuilder
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_241]
    	......
    	... 25 common frames omitted
    
    
    Process finished with exit code 1
    

     这是springcloud 中的依赖,我们发现在这里有两个不同版本的httpclient, 盲猜是低版本的依赖中没有那个类所以与springboot 项目不兼容。打开目录结构果然没有发现 httpClientBuilder 这个类。

     引入httpclient 的版本即可

    <properties>
       <httpclient.version>4.5</httpclient.version>
    </properties>
    <dependencyManagement>
       <dependencies>
           <dependency>
               <groupId>org.apache.httpcomponents</groupId>
               <artifactId>httpclient</artifactId>
               <version>${httpclient.version}</version>
           </dependency>
       </dependencies>
    </dependencyManagement>
  • 相关阅读:
    Class constructor FileManager cannot be invoked without 'new' in undefined (line undefined, column undefined)
    vscode插件
    面试题
    使用NPOI读取word表格里面的图片
    Postgresql安装过程记录
    .net Core 新增Area的步骤
    kendo grid上的模版示例
    unicode与string之间的转换
    使用yarn安装puppeteer失败的解决方案
    abp第一篇《框架的下载与mysql数据库的切换》
  • 原文地址:https://www.cnblogs.com/yuarvin/p/15601272.html
Copyright © 2011-2022 走看看