<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Feign on 小蜜蜂</title>
        <link>https://xumf.net/tags/feign/</link>
        <description>Recent content in Feign on 小蜜蜂</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Fri, 15 Jun 2018 15:43:54 +0800</lastBuildDate><atom:link href="https://xumf.net/tags/feign/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Feign</title>
            <link>https://xumf.net/blog/feign/</link>
            <pubDate>Fri, 15 Jun 2018 15:43:54 +0800</pubDate>
            <guid>https://xumf.net/blog/feign/</guid>
            <description>&lt;h2 id=&#34;什么是feign&#34;&gt;什么是Feign&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 是 Netflix 开源的声明式 HTTP 客户端，用于简化 RESTful 服务的调用&lt;/li&gt;&#xA;&lt;li&gt;通过定义接口和注解，Feign 可以自动生成HTTP请求的实现&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;特点&#34;&gt;特点&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;声明式 API ：通过接口注解定义 HTTP 请求，无需手动编写 HTTP 客户端代码&lt;/li&gt;&#xA;&lt;li&gt;集成 Ribbon ：默认集成 Ribbon ，支持客户端负载均衡&lt;/li&gt;&#xA;&lt;li&gt;集成 Hystrix ：支持熔断和降级机制&lt;/li&gt;&#xA;&lt;li&gt;可扩展性：支持自定义编码器、解码器和拦截器&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;工作原理&#34;&gt;工作原理&#xA;&lt;/h2&gt;&lt;h2 id=&#34;1接口定义&#34;&gt;（1）接口定义&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;使用 @FeignClient 注解定义 Feign 客户端接口&lt;/li&gt;&#xA;&lt;li&gt;通过方法注解（如 &lt;strong&gt;@GetMapping&lt;/strong&gt;、&lt;strong&gt;@PostMapping&lt;/strong&gt;）定义 HTTP 请求&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;2动态代理&#34;&gt;（2）动态代理&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 通过动态代理技术生成接口的实现类&lt;/li&gt;&#xA;&lt;li&gt;在运行时，Feign 会将方法调用转换为 Http 请求&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;3请求处理&#34;&gt;（3）请求处理&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 根据接口定义生成 HTTP 请求，并通过 Ribbon 进行负载均衡&lt;/li&gt;&#xA;&lt;li&gt;请求结果通过解码器为 Java 对象&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;4集成-ribbon-和-hystrix&#34;&gt;（4）集成 Ribbon 和 Hystrix&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 默认集成了 Ribbon，支持客户端负载均衡&lt;/li&gt;&#xA;&lt;li&gt;通过配置可以启用 Hystrix，实现熔断和降级&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;feign-的配置&#34;&gt;Feign 的配置&#xA;&lt;/h2&gt;&lt;h3 id=&#34;1基本配置&#34;&gt;（1）基本配置&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;使用 @FeignClient 注解定义 Feign 客户端：&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@FeignClient&lt;/span&gt;(name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service-name&amp;#34;&lt;/span&gt;, url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://localhost:8080&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MyFeignClient&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@GetMapping&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/endpoint&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    String &lt;span style=&#34;color:#a6e22e&#34;&gt;getResponse&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2负载均衡&#34;&gt;（2）负载均衡&#xA;&lt;/h3&gt;&lt;h3 id=&#34;-feign-默认集成了-ribbon无需额外配置&#34;&gt;* Feign 默认集成了 Ribbon，无需额外配置&#xA;&lt;/h3&gt;&lt;h3 id=&#34;-可以通过配置文件自定义-ribbon-的负载均衡策略&#34;&gt;* 可以通过配置文件自定义 Ribbon 的负载均衡策略：&#xA;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;service-name&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;ribbon&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;NFLoadBalancerRuleClassName&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;com.netflix.loadbalancer.RoundRobinRule&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;3熔断和降级&#34;&gt;（3）熔断和降级&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;通过 &lt;strong&gt;@FeignClient&lt;/strong&gt; 的** Fallback** 属性指定降级类：&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@FeignClient&lt;/span&gt;(name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service-name&amp;#34;&lt;/span&gt;, fallback &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MyFeignClientFallback.&lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MyFeignClient&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@GetMapping&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/endpoint&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    String &lt;span style=&#34;color:#a6e22e&#34;&gt;getResponse&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@Component&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MyFeignClientFallback&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;implements&lt;/span&gt; MyFeignClient {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; String &lt;span style=&#34;color:#a6e22e&#34;&gt;getResponse&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Fallback response&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;4自定义配置&#34;&gt;（4）自定义配置&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;通过 **@Configuration **类自定义 Feign 的编码器、解码器和拦截器：&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@Configuration&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FeignConfig&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Bean&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; Encoder &lt;span style=&#34;color:#a6e22e&#34;&gt;feignEncoder&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; JacksonEncoder();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Bean&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; Decoder &lt;span style=&#34;color:#a6e22e&#34;&gt;feignDecoder&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; JacksonDecoder();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Bean&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; RequestInterceptor &lt;span style=&#34;color:#a6e22e&#34;&gt;feignRequestInterceptor&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; template &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; template.&lt;span style=&#34;color:#a6e22e&#34;&gt;header&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Bearer token&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;feign-的使用场景&#34;&gt;Feign 的使用场景&#xA;&lt;/h2&gt;&lt;h3 id=&#34;1微服务调用&#34;&gt;（1）微服务调用&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;在微服务架构中，Feign 常用于服务之间的调用&lt;/li&gt;&#xA;&lt;li&gt;自定义接口和注解，简化 HTTP 请求的编写&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;2负载均衡-1&#34;&gt;（2）负载均衡&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 默认集成了 Ribbon，支持客户端负载均衡&lt;/li&gt;&#xA;&lt;li&gt;可以根据配置选择不同的负载均衡策略&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;3熔断和降级-1&#34;&gt;（3）熔断和降级&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;通过集成 Hystrix，Feign 支持熔断和降级机制&lt;/li&gt;&#xA;&lt;li&gt;当服务不可用时，可以返回降级结果，避免系统崩溃&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;4自定义-http-客户端&#34;&gt;（4）自定义 HTTP 客户端&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 支持自定义编码器、解码器和拦截器，满足复杂的业务需求&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;feign-的底层原理&#34;&gt;Feign 的底层原理&#xA;&lt;/h2&gt;&lt;h3 id=&#34;1动态代理&#34;&gt;（1）动态代理&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 通过 JDK 动态代理或者 CGLIB 生成接口的实现类&lt;/li&gt;&#xA;&lt;li&gt;在运行时，Feign 会将方法调用转换为 HTTP 请求&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;2请求模版&#34;&gt;（2）请求模版&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 使用 RequestTemplate 类表示 HTTP 请求模版&lt;/li&gt;&#xA;&lt;li&gt;通过解析接口注解和方法参数，生成具体的 HTTP 请求&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;3编码器和解码器&#34;&gt;（3）编码器和解码器&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 使用编码器将 Java 对象转换为 HTTP 请求体&lt;/li&gt;&#xA;&lt;li&gt;使用编码器将 HTTP 响应体转为 Java 对象&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;4拦截器&#34;&gt;（4）拦截器&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Feign 支持请求拦截器，可以在发送请求前修改请求头或者请求体&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre class=&#34;mermaid&#34; style=&#34;visibility:hidden&#34;&gt;graph TD&#xA;    A[客户端调用 Feign 接口方法] --&gt; B[ReflectiveFeign.newInstance 创建动态代理]&#xA;    B --&gt; C[InvocationHandler.invoke 拦截方法调用]&#xA;    C --&gt; D[SynchronousMethodHandler.invoke 处理请求]&#xA;    D --&gt; E[RequestTemplate.Factory.create 生成请求模板]&#xA;    E --&gt; F[RequestInterceptor.apply 应用拦截器]&#xA;    F --&gt; G[Encoder.encode 编码请求体]&#xA;    G --&gt; H[LoadBalancerFeignClient.execute 选择服务实例]&#xA;    H --&gt; I[Client.execute 发送 HTTP 请求]&#xA;    I --&gt; J[Decoder.decode 解析响应]&#xA;    J --&gt; K[返回结果给客户端]&lt;/pre&gt;</description>
        </item></channel>
</rss>
