{"id":1964,"date":"2023-04-01T10:28:46","date_gmt":"2023-04-01T02:28:46","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1964"},"modified":"2023-04-22T08:35:15","modified_gmt":"2023-04-22T00:35:15","slug":"spring-cloud-feign-advanced-application","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/04\/01\/spring-cloud-feign-advanced-application\/","title":{"rendered":"Spring Cloud Feign \u9ad8\u7ea7\u5e94\u7528"},"content":{"rendered":"<h2>\u4f7f\u7528feign\u8fdb\u884c\u670d\u52a1\u95f4\u7684\u8c03\u7528<\/h2>\n<h3>\u670d\u52a1\u63d0\u4f9b\u8005<\/h3>\n<p>\uff081\uff09\u521b\u5efaprovider-service\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u6dfb\u52a0\u5982\u4e0b\u4f9d\u8d56\uff1a<\/p>\n<p><!-- more --><\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-netflix-eureka-client&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>\uff082\uff09application.properties\u914d\u7f6e\u6587\u4ef6\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code>server.port=9600\nspring.application.name=provider-service\neureka.instance.prefer-ip-address=true\n#\u914d\u7f6e\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740\neureka.client.serviceUrl.defaultZone=http:\/\/zy:zy123@localhost:10025\/eureka\/<\/code><\/pre>\n<p>\uff083\uff09\u542f\u52a8\u4e3b\u7c7b\u6dfb\u52a0<code>@EnableDiscoveryClient<\/code><\/p>\n<pre><code class=\"language-java\">@EnableDiscoveryClient\n@SpringBootApplication\npublic class ProviderServiceApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(ProviderServiceApplication.class, args);\n    }\n}<\/code><\/pre>\n<p>\uff084\uff09\u521b\u5efaHelloController\uff0c\u6dfb\u52a0\u4e00\u4e2ahello\u65b9\u6cd5<\/p>\n<pre><code class=\"language-java\">@RestController\npublic class HelloController {\n\n    @RequestMapping(&quot;\/hello&quot;)\n    public String hello(String name){\n        return  &quot;hello &quot; + name;\n    }\n}<\/code><\/pre>\n<h3>\u670d\u52a1\u6d88\u8d39\u8005<\/h3>\n<p>\uff081\uff09\u521b\u5efaconsumer-service\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u6dfb\u52a0\u5982\u4e0b\u4f9d\u8d56\uff1a<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-netflix-eureka-client&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n&lt;!-- \u56e0\u4e3a\u8981\u4f7f\u7528feign\u8c03\u7528\u5176\u4ed6\u670d\u52a1\uff0c\u6240\u4ee5\u9700\u8981\u6dfb\u52a0\u6b64\u4f9d\u8d56 --&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>\uff082\uff09application.properties\u914d\u7f6e\u6587\u4ef6\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code>server.port=9700\nspring.application.name=consumer-service\neureka.instance.prefer-ip-address=true\n# \u914d\u7f6e\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740\neureka.client.serviceUrl.defaultZone=http:\/\/zy:zy123@localhost:10025\/eureka\/<\/code><\/pre>\n<p>\uff083\uff09\u542f\u52a8\u4e3b\u7c7b\u6dfb\u52a0<code>@EnableDiscoveryClient<\/code>\u3001<code>@EnableFeignClients<\/code>2\u4e2a\u6ce8\u89e3<\/p>\n<pre><code class=\"language-java\">@EnableFeignClients\n@EnableDiscoveryClient\n@SpringBootApplication\npublic class ConsumerServiceApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(ConsumerServiceApplication.class, args);\n    }\n}<\/code><\/pre>\n<p>\uff084\uff09\u521b\u5efa\u4e00\u4e2a\u63a5\u53e3HelloFeignService\uff0c\u8c03\u7528\u670d\u52a1\u63d0\u4f9b\u8005<\/p>\n<pre><code class=\"language-java\">\/\/name\u4e3a\u670d\u52a1\u63d0\u4f9b\u8005\u5411\u6ce8\u518c\u4e2d\u5fc3\u6ce8\u518c\u7684\u5b9e\u4f8b\u540d\n@FeignClient(name = &quot;provider-service&quot; )\npublic interface HelloFeignService {\n    \/\/\u5730\u5740\u4e3a\u670d\u52a1\u63d0\u4f9b\u8005\u5bf9\u5916\u66b4\u9732\u7684\u5730\u5740\n    @RequestMapping(value = &quot;\/hello&quot;, method = RequestMethod.GET)\n    String hello(@RequestParam(&quot;name&quot;) String name);\n}<\/code><\/pre>\n<p>\uff085\uff09\u521b\u5efaIndexController\u63a7\u5236\u5668\uff0c\u6ce8\u5165feign\uff0c\u50cf\u672c\u5730\u65b9\u6cd5\u4e00\u6837\u8c03\u7528\u670d\u52a1\u63d0\u4f9b\u8005\u7684\u670d\u52a1<\/p>\n<pre><code class=\"language-java\">@RestController\npublic class IndexController {\n\n    @Autowired\n    private HelloFeignService feignService;\n\n    @RequestMapping(value = &quot;\/hello&quot; , method = RequestMethod.GET)\n    public String hello(String name){\n        return feignService.hello(name);\n    }\n}<\/code><\/pre>\n<p>\uff086\uff09\u542f\u52a82\u4e2a\u9879\u76ee\uff0c\u8bbf\u95ee\u670d\u52a1\u6d88\u8d39\u8005 <a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/localhost:9700\/hello?name=joe\">http:\/\/localhost:9700\/hello?name=joe<\/a><\/p>\n<h2>feign\u5f00\u542fGzip\u538b\u7f29<\/h2>\n<p>Spring Cloud Feign\u652f\u6301\u5bf9\u8bf7\u6c42\u4e0e\u54cd\u5e94\u7684\u538b\u7f29\uff0c\u4ee5\u63d0\u9ad8\u901a\u4fe1\u6548\u7387\uff0c\u5728\u670d\u52a1\u6d88\u8d39\u8005\u914d\u7f6e\u6587\u4ef6\u5f00\u542f\u538b\u7f29\u652f\u6301\u548c\u538b\u7f29\u6587\u4ef6\u7684\u7c7b\u578b\u5373\u53ef<\/p>\n<pre><code>#feign \u8bf7\u6c42\u4e0e\u54cd\u5e94\u7684\u538b\u7f29\nfeign.compression.request.enabled=true\nfeign.compression.response.enabled=true\nfeign.compression.request.mime-types=text\/xml,application\/xml,application\/json\nfeign.compression.request.min-request-size=2048<\/code><\/pre>\n<h2>feign\u5f00\u542f\u65e5\u5fd7<\/h2>\n<p>feign\u5f00\u542f\u65e5\u5fd7\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u4e00\u79cd\u662f\u4f7f\u7528\u914d\u7f6e\u6587\u4ef6\uff0c\u4e00\u79cd\u662f\u4f7f\u7528java\u4ee3\u7801\uff0c\u4e0b\u9762\u5c06\u4ecb\u7ecd\u4ee3\u7801\u65b9\u5f0f<\/p>\n<p>\u521b\u5efa<code>FeignLogConfig<\/code>\u7c7b\uff0c\u6dfb\u52a0\u4e00\u4e2a<code>LoggerBean<\/code><\/p>\n<pre><code class=\"language-java\">@Configuration\npublic class FeignLogConfig {\n\n    \/**\n     * \u65e5\u5fd7level\u67094\u4e2a\u7ea7\u522b\n     * 1.NONE\uff0c\u4e0d\u8bb0\u5f55\u4efb\u4f55\u65e5\u5fd7\n     * 2.BASIC\uff0c\u4ec5\u8bb0\u5f55\u8bf7\u6c42\u65b9\u6cd5\u3001URL\u4ee5\u53ca\u54cd\u5e94\u72b6\u6001\u7801\u548c\u6267\u884c\u65f6\u95f4\n     * 3.HEADRES\uff0c\u9664\u4e86BASIC\u4ee5\u5916\u7684\u8fd8\u4f1a\u8bb0\u5f55\u8bf7\u6c42\u548c\u54cd\u5e94\u7684\u5934\u4fe1\u606f\n     * 4.FULL\uff0c\u6240\u6709\n     * @return\n     *\/\n    @Bean\n    Logger.Level feignLogger(){\n        return Logger.Level.FULL;\n    }\n}<\/code><\/pre>\n<h2>feign\u66ff\u6362JDK\u9ed8\u8ba4\u7684URLConnection\u4e3aokhttp<\/h2>\n<p>\u4f7f\u7528okhttp\uff0c\u80fd\u63d0\u9ad8qps\uff0c\u56e0\u4e3aokhttp\u6709\u8fde\u63a5\u6c60\u548c\u8d85\u65f6\u65f6\u95f4\u8fdb\u884c\u8c03\u4f18<\/p>\n<p>\uff081\uff09\u5728\u670d\u52a1\u6d88\u8d39\u8005\u4e2d\uff0c\u6dfb\u52a0feign-okhttp\u4f9d\u8d56<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;io.github.openfeign&lt;\/groupId&gt;\n    &lt;artifactId&gt;feign-okhttp&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>\uff082\uff09\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\uff0c\u7981\u7528\u9ed8\u8ba4\u7684http\uff0c\u542f\u7528okhttp<\/p>\n<pre><code>feign.httpclient.enabled=false\nfeign.okhttp.enabled=true<\/code><\/pre>\n<p>\uff083\uff09\u521b\u5efaOkHttpConfig\u7c7b\uff0c\u6dfb\u52a0okhttp\u7684bean<\/p>\n<pre><code class=\"language-java\">\/**\n * \u914d\u7f6eokhttp\u4e0e\u8fde\u63a5\u6c60\n * ConnectionPool\u9ed8\u8ba4\u521b\u5efa5\u4e2a\u7ebf\u7a0b\uff0c\u4fdd\u63015\u5206\u949f\u957f\u8fde\u63a5\n *\/\n@Configuration\n@ConditionalOnClass(Feign.class)\n@AutoConfigureBefore(FeignAutoConfiguration.class)\npublic class OkHttpConfig {\n\n    @Bean\n    public okhttp3.OkHttpClient okHttpClient(){\n        return new okhttp3.OkHttpClient.Builder()\n                \/\/\u8bbe\u7f6e\u8fde\u63a5\u8d85\u65f6\n                .connectTimeout(10, TimeUnit.SECONDS)\n                \/\/\u8bbe\u7f6e\u8bfb\u8d85\u65f6\n                .readTimeout(10, TimeUnit.SECONDS)\n                \/\/\u8bbe\u7f6e\u5199\u8d85\u65f6\n                .writeTimeout(10, TimeUnit.SECONDS)\n                \/\/\u662f\u5426\u81ea\u52a8\u91cd\u8fde\n                .retryOnConnectionFailure(true)\n                .connectionPool(new ConnectionPool(10, 5L, TimeUnit.MINUTES))\n                .build();\n    }\n}<\/code><\/pre>\n<h2>feign\u8d85\u65f6\u8bbe\u7f6e<\/h2>\n<pre><code># feign\u542f\u7528hystrix\uff0c\u624d\u80fd\u7194\u65ad\u3001\u964d\u7ea7\nfeign.hystrix.enabled=true\n\n# hystrix\u7684\u8d85\u65f6\u65f6\u95f4\nhystrix.command.default.execution.timeout.enabled=true\nhystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000\n\n# ribbon\u7684\u8d85\u65f6\u65f6\u95f4\nribbon.ReadTimeout=10000\nribbon.ConnectTimeout=10000<\/code><\/pre>\n<h2>feign\u4f7f\u7528hystrix\u8fdb\u884c\u7194\u65ad\u3001\u964d\u7ea7\u5904\u7406<\/h2>\n<p>\u4e0a\u9762\u7684\u8d85\u65f6\u65f6\u95f4\u8bbe\u7f6e\u4e3a10\u79d2\uff0c\u628a\u670d\u52a1\u63d0\u4f9b\u8005sleep\u7761\u7720\u65f6\u95f4\u5927\u4e8e10\u79d2\uff0c\u670d\u52a1\u6d88\u8d39\u8005\u5c31\u4f1a\u89e6\u53d1hystrix\uff0c\u8fdb\u884c\u7194\u65ad\u4fdd\u62a4<\/p>\n<p>\uff081\uff09\u6539\u9020\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u8ba9\u670d\u52a1\u7761\u772060\u79d2<\/p>\n<pre><code class=\"language-java\">@RequestMapping(&quot;\/hello&quot;)\npublic String hello(String name){\n    try {\n        \/\/\u7761\u772060\u79d2\uff0c\u6d4b\u8bd5feign\u7684\u7194\u65ad\u3001\u964d\u7ea7\n        Thread.sleep(60 * 1000);\n    }catch (Exception e){\n        e.printStackTrace();\n    }\n    return  &quot;hello &quot; + name;\n}<\/code><\/pre>\n<p>\uff082\uff09\u6539\u9020\u670d\u52a1\u6d88\u8d39\u8005\uff0c\u6dfb\u52a0feign\u7684\u7194\u65ad\u3001\u964d\u7ea7\u65b9\u6cd5\uff0cfeign\u7684hystrix\u7194\u65ad\u964d\u7ea7\u5f88\u597d\u5b9e\u73b0\uff0c\u53ea\u8981\u5728FeignClient\u7684fallback\u56de\u6eda\u65b9\u6cd5\u4e2d\u6307\u5b9a\u90a3\u4e2a\u5b9e\u73b0\u7c7b\u5373\u53ef<\/p>\n<pre><code class=\"language-java\">@FeignClient(name = &quot;provider-service&quot;, fallback = HelloFeignFallbackService.class)\npublic interface HelloFeignService {\n\n    @RequestMapping(value = &quot;\/hello&quot;, method = RequestMethod.GET)\n    String hello(@RequestParam(&quot;name&quot;) String name);\n}<\/code><\/pre>\n<p>HelloFeignFallbackService\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-java\">\/**\n * hystrix\u670d\u52a1\u964d\u7ea7\u5904\u7406\uff0c\u9632\u6b62\u56e0\u8d85\u65f6\u3001\u5f02\u5e38\u7b49\u5bfc\u81f4\u7684\u670d\u52a1\u8c03\u7528\u96ea\u5d29\n *\/\n@Service\npublic class HelloFeignFallbackService implements HelloFeignService {\n    @Override\n    public String hello(String name) {\n        return &quot;\u672a\u627e\u5230&quot; + name;\n    }\n}<\/code><\/pre>\n<p>\uff083\uff09\u7136\u540e\u542f\u52a8\u670d\u52a1\u63d0\u4f9b\u8005\u4e0e\u6d88\u8d39\u8005\uff0c\u518d\u8bbf\u95ee <a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/localhost:9700\/hello?name=joe\">http:\/\/localhost:9700\/hello?name=joe<\/a> \uff0c\u53d1\u73b0\u9875\u9762\u7f13\u4e8610\u6765\u79d2\uff0c\u5c31\u76f4\u63a5\u8fd4\u56de\u4e86\u7194\u65ad\u65b9\u6cd5\u4e2d\u7684\u5185\u5bb9\uff0c\u8bf4\u660ehystrix\u7194\u65ad\u964d\u7ea7\u6210\u529f<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4f7f\u7528feign\u8fdb\u884c\u670d\u52a1\u95f4\u7684\u8c03\u7528 \u670d\u52a1\u63d0\u4f9b\u8005 \uff081\uff09\u521b\u5efaprovider-service\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u6dfb\u52a0\u5982\u4e0b\u4f9d\u8d56 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[42],"tags":[251],"class_list":["post-1964","post","type-post","status-publish","format-standard","hentry","category-spring-cloud","tag-feign"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1964","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1964"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1964\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1964"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1964"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1964"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}