最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何基于springcloud模擬RPC調(diào)用(Feign)

 更新時(shí)間:2020年04月13日 11:44:01   作者:pengjunlee  
這篇文章主要介紹了如何基于springcloud模擬RPC調(diào)用(Feign),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

Feign簡(jiǎn)介

Feign是一個(gè)聲明式的Web Service客戶端,它能夠讓W(xué)eb Service客戶端的編寫變得更加容易(你只需創(chuàng)建一個(gè)接口,并在接口上添加相應(yīng)注解即可)。除了Feign自帶的注解外它還支持JAX-RS注解,SpringCloud又為Feign增加了對(duì)SpringMVC注解的支持,同時(shí)為了能夠使用和Spring Web中默認(rèn)使用的相同的httpMessageConverter,SpringCloud集成了Ribbon和Eureka,用來(lái)在使用Feign時(shí)能夠?yàn)槠涮峁┮粋€(gè)負(fù)載均衡的HTTP客戶端。

總起來(lái)說,F(xiàn)eign具有如下特性:

1.可插拔的注解支持,包括Feign注解和JAX-RS注解;

2.支持可插拔的HTTP編碼器和解碼器;

3.支持Hystrix和它的Fallback;

4.支持Ribbon的負(fù)載均衡;

5.支持HTTP請(qǐng)求和響應(yīng)的壓縮。

接下來(lái)我們將通過對(duì)上一章《客戶端負(fù)載均衡(Ribbon)》中的 message-center 項(xiàng)目進(jìn)行改造,演示如何使用Feign。

message-center改造

引入Feign依賴

由于Feign依賴中默認(rèn)包含了Ribbon,所以只需要在 pom.xml 文件中引入Feign依賴即可,Ribbon依賴無(wú)需重復(fù)引入:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.6.RELEASE</version>
  </parent>
 
  <properties>
    <spring-cloud.version>Finchley.SR2</spring-cloud.version>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Eureka-Client 依賴 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!-- Feign 依賴 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
  </dependencies>
 
  <dependencyManagement>
    <dependencies>
      <!-- SpringCloud 版本控制依賴 -->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

修改啟動(dòng)類

在MessageCenterApplication啟動(dòng)類上增加@EnableFeignClients注解:

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class MessageCenterApplication {
  public static void main(String[] args) {
    new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args);
  }
}

這里我們?cè)趩?dòng)類中增加了@EnableFeignClients注解,用來(lái)開啟Feign客戶端發(fā)現(xiàn)功能。

如果你的Feign客戶端類文件不在Spring的包掃描路徑之中,可以在@EnableFeignClients注解中對(duì)Feign客戶端的包路徑進(jìn)行指定。

@SpringBootApplication
@EnableFeignClients(basePackages = "com.pengjunlee.client.**")
public class MessageCenterApplication {
  public static void main(String[] args) {
    new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args);
  }
}

創(chuàng)建Feign客戶端

對(duì)外提供服務(wù)的HTTP接口定義在MessageController

@RestController
@RequestMapping("/api/v1/msg")
public class MessageController {
 
  @Value("${server.port}")
  private String port;
 
  /**
   * 返回一條消息
   */
  @GetMapping("/get")
  public String getMsg() {
    return "This message is sent from port: " + port;
  }
}

接下來(lái),我們?cè)谙M(fèi)端message-center中為它創(chuàng)建一個(gè)Feign客戶端。新建一個(gè)接口取名MessageServiceClient,并在上面添加@FeignClient注解,完整代碼如下:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
 
@FeignClient(name = "message-service")
public interface MessageServiceClient {
 
  @GetMapping("/api/v1/msg/get")
  public String getMsg();
}

說明:此處@FeignClient注解的name屬性應(yīng)與message-service應(yīng)用的spring.application.name屬性相同,表示為message-service服務(wù)創(chuàng)建一個(gè)Feign客戶端。接口的映射地址路徑以及接口入?yún)⒍急仨毰cMessageController中的方法完全相同。

調(diào)用Feign客戶端

接下來(lái),我們來(lái)看一看如何在消費(fèi)端使用創(chuàng)建好的Feign客戶端對(duì)message-service服務(wù)進(jìn)行調(diào)用,示例代碼如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.pengjunlee.service.MessageServiceClient;
@RestController
@RequestMapping("/api/v1/center")
public class MessageCenterController {
  @Autowired
  private MessageServiceClient messageService;
  @GetMapping("/msg/get")
  public Object getMsg() {
    String msg = messageService.getMsg();
    return msg;
  }
}

啟動(dòng)應(yīng)用,再次請(qǐng)求 http://localhost:8781/api/v1/center/msg/get ,返回如下結(jié)果表明服務(wù)調(diào)用成功:

關(guān)于傳參

Feign除了支持自帶的注解和JAX-RS注解外,還支持 SpringMVC注解,常用的有:@RequestParam 、@PathVariable、@RequestBody 等。

例如,服務(wù)端提供如下兩個(gè)服務(wù)接口:

/**
 * 獲取消息詳情
 */
@GetMapping("/api/v1/msg/detail/{id}")
public MessageEntity getDetail(@PathVariable(name = "id") Long id) {
  return messageService.getById(id);
}
 
/**
 * 新建一條消息
 */
@PostMapping("/api/v1/msg/save")
public MessageEntity save(@RequestBody MessageEntity message) {
  return messageService.save(message);
}

相應(yīng)的,在Feign客戶端中可以進(jìn)行如下定義:

/**
 * 獲取消息詳情
 */
@GetMapping("/api/v1/msg/detail/{id}")
public MessageEntity getDetail(@PathVariable(name = "id") Long id) ;
 
/**
 * 新建一條消息
 */
@PostMapping("/api/v1/msg/save")
public MessageEntity save(@RequestBody MessageEntity message) ;

重寫Feign的默認(rèn)配置

在Spring Cloud對(duì)Feign的支持實(shí)現(xiàn)中,一個(gè)核心的概念就是客戶端命名,每一個(gè)Feign客戶端都是整個(gè)組件系統(tǒng)的一部分,它們相互協(xié)同一起工作來(lái)按照需求與遠(yuǎn)程服務(wù)器取得聯(lián)系。并且它們每一個(gè)都有自己的名字,應(yīng)用程序開發(fā)人員可以使用@feignclient來(lái)給它取名。Spring Cloud按照自己的需要又使用FeignClientsConfiguration為每一個(gè)已命名的客戶端創(chuàng)建了一個(gè)ApplicationContext,額外包含了一個(gè)feign.Decoder、一個(gè) feign.Encoder 和一個(gè) feign.Contract。你可以通過指定@FeignClient注解的contextId 屬性來(lái)設(shè)置ApplicationContext的名字。

SpringCloud還允許你在FeignClientsConfiguration的基礎(chǔ)之上使用@FeignClient聲明一些額外的配置,從而實(shí)現(xiàn)對(duì)Feign客戶端的完全控制,如下例所示:

@FeignClient(name = "message-service", configuration = MessageConfiguration.class)
public interface MessageServiceClient {
  //..
}

在這個(gè)例子中,這個(gè)Feign客戶端將由FeignClientsConfiguration 和MessageConfiguration中的組件一起組成(后者會(huì)覆蓋前者的配置)。

注意:本例中,MessageConfiguration不必用@Configuration注解進(jìn)行標(biāo)注,如果確實(shí)要加上@Configuration注解,你需要注意把MessageConfiguration排除在@ComponentScan和@SpringBootApplication掃描的包路徑之外,否則它將成為feign.Decoder、feign.Encoder 和 feign.Contract 等的默認(rèn)值。

下表列出了 Spring Cloud Netflix 缺省為Feign提供的所有 Bean(Bean類型 Bean名稱:Bean實(shí)現(xiàn)):

Decoder feignDecoder: ResponseEntityDecoder (包裝了一個(gè) SpringDecoder)
Encoder feignEncoder: SpringEncoder
Logger feignLogger: Slf4jLogger
Contract feignContract: SpringMvcContract
Feign.Builder feignBuilder: HystrixFeign.Builder
Client feignClient: 啟用 Ribbon 時(shí)是 LoadBalancerFeignClient,否則使用 feign.Client.Default。

你可以使用 OkHttpClient 或者 ApacheHttpClient 的Feign客戶端,只需要將 feign.okhttp.enabled 或者 feign.httpclient.enabled 設(shè)置為 true ,并將相應(yīng)類添加到項(xiàng)目的CLASSPATH即可。你也可以使用自定義的HTTP 客戶端,使用 Apache 時(shí)提供一個(gè)ClosableHttpClient 類型Bean或者使用OK HTTP時(shí)提供一個(gè)OkHttpClient 類型Bean。

默認(rèn)情況下,Spring Cloud Netflix 并沒有為Feign提供下列的Bean,但依然會(huì)從Spring容器中查找這些類型的Bean用來(lái)創(chuàng)建Feign客戶端。

Logger.Level
Retryer
ErrorDecoder
Request.Options
Collection<RequestInterceptor>
SetterFactory

創(chuàng)建這些類型的一個(gè)Bean 并將它寫到 @FeignClient 聲明的配置中,這樣你就能夠?qū)@些Bean中的每一個(gè)進(jìn)行重寫。例如下面的 MessageConfiguration 利用feign.Contract.Default替代了SpringMvcContract 并向RequestInterceptor 集合中添加了一個(gè)RequestInterceptor 。

@Configuration
public class MessageConfiguration {
  @Bean
  public Contract feignContract() {
    return new feign.Contract.Default();
  }
 
  @Bean
  public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
    return new BasicAuthRequestInterceptor("user", "password");
  }
}

當(dāng)然,@FeignClient 也支持通過配置文件進(jìn)行配置。

feign:
client:
config:
message-service:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: full
errorDecoder: com.pengjunlee.SimpleErrorDecoder
retryer: com.pengjunlee.SimpleRetryer
requestInterceptors:
- com.pengjunlee.FooRequestInterceptor
- com.pengjunlee.BarRequestInterceptor
decode404: false
encoder: com.pengjunlee.SimpleEncoder
decoder: com.pengjunlee.SimpleDecoder
contract: com.pengjunlee.SimpleContract

默認(rèn)配置可以通過@EnableFeignClients的defaultConfiguration屬性進(jìn)行指定,然后會(huì)被應(yīng)用到所有的Feign客戶端。如果你希望使用配置文件對(duì)所有的@FeignClient進(jìn)行配置,可以使用 default 作為Feign客戶端的名稱。

feign:
 client:
  config:
   default:
    connectTimeout: 5000
    readTimeout: 5000
    loggerLevel: basic

如果我們同時(shí)使用了@Configuration Bean和文件配置,文件配置會(huì)優(yōu)先生效。如果你希望優(yōu)先使用 @Configuration Bean中的配置,可以將 feign.client.default-to-properties 設(shè)置為 false 。

如果你需要在RequestInterceptor中使用ThreadLocal 變量,你需要將Hystrix 的線程隔離策略設(shè)置為 SEMAPHORE 或者直接禁用Hystrix 。

# To disable Hystrix in Feign
feign:
 hystrix:
  enabled: false
 
# To set thread isolation to SEMAPHORE
hystrix:
 command:
  default:
   execution:
    isolation:
     strategy: SEMAPHORE 

關(guān)于超時(shí)

在啟用Ribbon的情況下,F(xiàn)eign客戶端是一個(gè)LoadBalancerFeignClient Bean,其內(nèi)部有一個(gè) execute() 方法用來(lái)發(fā)送一個(gè)HTTP請(qǐng)求并獲取響應(yīng), 本質(zhì)上其實(shí)還是使用的Ribbon做負(fù)載均衡,并使用RestTemplate發(fā)送的請(qǐng)求。execute() 接口聲明如下:

public Response execute(Request request, Request.Options options) throws IOException;

其中,Request 用來(lái)封裝HTTP請(qǐng)求的詳細(xì)信息。

/**
 *
 * An immutable request to an http server.
 *
 */
public final class Request {
  private final String method;
  private final String url;
  private final Map<String, Collection<String>> headers;
  private final byte[] body;
  private final Charset charset;
  // ...
}

Options 則封裝了一些請(qǐng)求控制參數(shù):

public static class Options {
 
  private final int connectTimeoutMillis;
  private final int readTimeoutMillis;
  private final boolean followRedirects;
  public Options(int connectTimeoutMillis, int readTimeoutMillis) {
    this(connectTimeoutMillis, readTimeoutMillis, true);
  }
  public Options() {
    this(10 * 1000, 60 * 1000);
  } 
  // ...
}

從Options 源碼來(lái)看,F(xiàn)eign客戶端默認(rèn)的讀取超時(shí)時(shí)間為60秒。若同時(shí)使用了Hystrix,由于Hystrix 默認(rèn)的讀取超時(shí)時(shí)間為1秒,會(huì)導(dǎo)致Feign客戶端默認(rèn)的讀取超時(shí)時(shí)間設(shè)置無(wú)效,即超過1秒即為讀取超時(shí)??墒褂萌缦屡渲猛瑫r(shí)對(duì)Feign客戶端和Hystrix 的超時(shí)配置進(jìn)行重寫。

feign:
 client:
  config:
   default:
    connectTimeout: 5000
    readTimeout: 5000

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java解析多層嵌套json字符串問題

    java解析多層嵌套json字符串問題

    這篇文章主要介紹了java解析多層嵌套json字符串問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器

    使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器

    這篇文章主要介紹了使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • maven 打包項(xiàng)目的幾種方式

    maven 打包項(xiàng)目的幾種方式

    maven目前在web上面的使用方式很普遍,而打包的方式也存在很多方式,本文就詳細(xì)的介紹了三種方式,具有一定的參考價(jià)值,感興趣的可以了解下
    2021-06-06
  • SpringBoot中的server.context-path的實(shí)現(xiàn)

    SpringBoot中的server.context-path的實(shí)現(xiàn)

    本文主要介紹了SpringBoot中的server.context-path的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • Java中的synchronized鎖膨脹詳解

    Java中的synchronized鎖膨脹詳解

    這篇文章主要介紹了Java中的synchronized鎖膨脹詳解,正常創(chuàng)建的對(duì)象,狀態(tài)為無(wú)鎖,對(duì)象頭的Mark?Word?中主要記錄了?對(duì)象的年齡,也就是經(jīng)歷了多少次GC還存活下來(lái),需要的朋友可以參考下
    2024-01-01
  • 解決@Scope(“prototype“)不生效的問題

    解決@Scope(“prototype“)不生效的問題

    這篇文章主要介紹了解決@Scope(“prototype“)不生效的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 詳解Spring中Bean的生命周期和作用域及實(shí)現(xiàn)方式

    詳解Spring中Bean的生命周期和作用域及實(shí)現(xiàn)方式

    這篇文章主要給大家介紹了Spring中Bean的生命周期和作用域及實(shí)現(xiàn)方式的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-03-03
  • 項(xiàng)目為什么引入log4j而不是logback代碼

    項(xiàng)目為什么引入log4j而不是logback代碼

    這篇文章主要介紹了項(xiàng)目為什么引入log4j而不是logback代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 基于Java編寫一個(gè)粽子大作戰(zhàn)小游戲

    基于Java編寫一個(gè)粽子大作戰(zhàn)小游戲

    端午節(jié),又稱龍舟節(jié)、重午節(jié),是中國(guó)的傳統(tǒng)節(jié)日之一,每年農(nóng)歷五月初五慶祝,雖然端午假期已經(jīng)過去了,小編還是用Java編寫了一個(gè)粽子大作戰(zhàn)小游戲,感興趣的可以了解一下
    2023-06-06
  • JavaEE開發(fā)基于Eclipse的環(huán)境搭建以及Maven Web App的創(chuàng)建

    JavaEE開發(fā)基于Eclipse的環(huán)境搭建以及Maven Web App的創(chuàng)建

    本文主要介紹了如何在Eclipse中創(chuàng)建的Maven Project,本文是JavaEE開發(fā)的開篇,也是基礎(chǔ)。下面內(nèi)容主要包括了JDK1.8的安裝、JavaEE版本的Eclipse的安裝、Maven的安裝、Tomcat 9.0的配置、Eclipse上的M2Eclipse插件以及STS插件的安裝。
    2017-03-03

最新評(píng)論

柳江县| 高唐县| 石台县| 四会市| 孙吴县| 金川县| 策勒县| 成安县| 林周县| 崇义县| 文成县| 湘阴县| 淅川县| 大宁县| 定襄县| 洛浦县| 乐东| 江口县| 平和县| 尼勒克县| 恭城| 绥中县| 兴隆县| 平定县| 中西区| 岑溪市| 呼图壁县| 莒南县| 民和| 宿松县| 安乡县| 宿州市| 水城县| 久治县| 高清| 司法| 临泽县| 安塞县| 星子县| 抚州市| 黄石市|