SpringCloud-OpenFeign組件的使用

  • 思考: 使用RestTemplate+ribbon已經能夠完成服務間的調用,爲何還要使用feign?
String restTemplateForObject = restTemplate.getForObject("http://服務名/url?參數" + name, String.class);

存在問題:html

  • 1.每次調用服務都須要寫這些代碼,存在大量的代碼冗餘
  • 2.服務地址若是修改,維護成本增高
  • 3.使用時不夠靈活

說明java

  • https://cloud.spring.io/spring-cloud-openfeign/reference/html/
  • Feign是一個聲明式的僞Http客戶端,它使得寫Http客戶端變得更簡單。使用Feign,只須要建立一個接口並註解。它具備可插拔的註解特性(能夠使用springmvc的註解),可以使用Feign 註解和JAX-RS註解。Feign支持可插拔的編碼器和解碼器。Feign默認集成了Ribbon,默認實現了負載均衡的效果而且springcloud爲feign添加了springmvc註解的支持。

1.openFeign 服務調用

仍是在上一個項目的基礎之上,在users項目中web

1.服務調用方法引入依賴OpenFeign依賴

<!--Open Feign依賴-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.入口類加入註解開啓OpenFeign支持

@SpringBootApplication
@EnableFeignClients   //開啓openfeign支持
public class Users9999Application {
    public static void main(String[] args) {
        SpringApplication.run(Users9999Application.class, args);
    }
}

3.建立一個客戶端調用接口

// 此時的product項目中的方法
@RestController
@Slf4j
public class ProductController {

    @Value("${server.port}")
    private int port;

    @GetMapping("/product/findAll")
    public Map<String, Object> findAll(){
        log.info("商品服務調用成功,當前的服務端口:[{}]",port);
        HashMap<String, Object> map = new HashMap<>();
        map.put("msg","服務調用成功,服務提供的端口爲:"+port);
        map.put("status",true);
        return map;
    }
}


//--------------------------------------------------------------------
package com.md.clients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author md
 * @Desc 調用商品服務的組件
 * @date 2020/12/9 15:30
 */

// 指定當前的接口是openfeign組件,value是調用的服務名
@FeignClient("products")
public interface ProductClient {

    @GetMapping("/product/findAll")
    String findAll();
}

4.使用feignClient客戶端對象調用服務

@RestController
@Slf4j
public class UserController {

	//注入客戶端對象
	@Autowired
	private ProductClient productClient;

	@GetMapping("/user/findAllFeignClient")
	public String findAllFeignClient(){
  		log.info("經過使用OpenFeign組件調用商品服務...");
  		String msg = productClient.findAll();
  		return msg;
	}
}

5.訪問並測試服務

2.調用服務並傳參

  • 服務和服務之間通訊,不單單是調用,每每在調用過程當中還伴隨着參數傳遞,接下來重點來看看OpenFeign在調用服務時如何傳遞參數

3.GET方式調用服務傳遞參數

  • 在商品服務中加入須要傳遞參數的服務方法來進行測試
  • 在用戶服務中進行調用商品服務中須要傳遞參數的服務方法進行測試

1.商品服務中添加以下方法

@GetMapping("/product/findOne")
public Map<String,Object> findOne(String productId){
  log.info("商品服務查詢商品信息調用成功,當前服務端口:[{}]",port);
  log.info("當前接收商品信息的id:[{}]",productId);
  Map<String, Object> map = new HashMap<String,Object>();
  map.put("msg","商品服務查詢商品信息調用成功,當前服務端口: "+port);
  map.put("status",true);
  map.put("productId",productId);
  return map;
}

2.用戶服務中在product客戶端中聲明方法

//
@FeignClient("products")
public interface ProductClient { 
	@GetMapping("/product/findOne")
 	 Map<String, Object> findOne(@RequestParam("productId") String productId);
}

注意:使用openfeign的get方式傳遞參數,參數變量必須經過@RequestParam註解進行修飾spring

3.用戶服務中調用並傳遞參數

//
//注入客戶端對象
@RestController
@Slf4j
public class UserController {	

    @Autowired
    private ProductClient productClient;

      @GetMapping("/user/findOne")
      public Map<String, Object> findOne(String productId){
          log.info("用來測試Openfiegn的GET方式參數傳遞");
          Map<String, Object> msg = productClient.findOne(productId);
          log.info("調用返回信息:[{}]",msg);
          return msg;
      }       
}

4.測試訪問

4.post方式調用服務傳遞參數

  • 在商品服務中加入須要傳遞參數的服務方法來進行測試
  • 在用戶服務中進行調用商品服務中須要傳遞參數的服務方法進行測試

1.商品服務加入post方式請求並接受name

@PostMapping("/product/save")
public Map<String,Object> save(String name){
  log.info("商品服務保存商品調用成功,當前服務端口:[{}]",port);
  log.info("當前接收商品名稱:[{}]",name);
  Map<String, Object> map = new HashMap<String,Object>();
  map.put("msg","商品查詢服務完成當前服務端口: "+port);
  map.put("status",true);
  map.put("name",name);
  return map;
}

2.用戶服務中在product客戶端中聲明方法

//value屬性用來指定:調用服務名稱
@FeignClient("products")
public interface ProductClient {
    @PostMapping("/product/save")
    String save(@RequestParam("name") String name);
}

3.用戶服務中調用並傳遞參數

@Autowired
private ProductClient productClient;

@PostMapping("/user/save")
public Map<String, Object> save(String productName){
  log.info("接收到的商品信息名稱:[{}]",productName);
  Map<String, Object> map = productClient.save(productName);
  log.info("調用成功返回結果: "+map);
  return map;
}

4.測試訪問

5.傳遞對象類型參數

  • 商品服務定義對象
  • 商品服務定義對象接收方法
  • 用戶服務調用商品服務定義對象參數方法進行參數傳遞
//1.商品服務定義對象
@Data
public class Product {
    private Integer id;
    private String name;
    private Date bir;
}
//2.商品服務定義接收對象的方法
@PostMapping("/product/saveProduct")
public Map<String,Object> saveProduct(@RequestBody Product product){
  log.info("商品服務保存商品信息調用成功,當前服務端口:[{}]",port);
  log.info("當前接收商品名稱:[{}]",product);
  Map<String, Object> map = new HashMap<String,Object>();
  map.put("msg","商品服務查詢商品信息調用成功,當前服務端口: "+port);
  map.put("status",true);
  map.put("product",product);
  return map;
}
//3.將商品對象複製到用戶服務中
// 先階段先這樣用着

//4.用戶服務中在product客戶端中聲明方法
@FeignClient("products")
public interface ProductClient {
  @PostMapping("/product/saveProduct")
  String saveProduct(@RequestBody Product product);
}
//注意:服務提供方和調用方必定要加入@RequestBody註解

注意:服務提供方和調用方必定要加入@RequestBody註解 mvc

// 5.在用戶服務中調用保存商品信息服務
//注入客戶端對象
@Autowired
private ProductClient productClient;

	@PostMapping("/user/saveProduct")
    public Map<String, Object> saveProduct(Product product){
        log.info("接收到的商品信息:[{}]",product);
        Map<String, Object> map = productClient.saveProduct(product);
        log.info("調用成功返回結果: "+map);
        return map;
    }

測試app

5.OpenFeign超時設置

1.超時說明

  • 默認狀況下,openFiegn在進行服務調用時,要求服務提供方處理業務邏輯時間必須在1S內返回,若是超過1S沒有返回則OpenFeign會直接報錯,不會等待服務執行,可是每每在處理複雜業務邏輯是可能會超過1S,所以須要修改OpenFeign的默認服務調用超時時間。

2.模擬超時

  • 服務提供方加入線程等待阻塞

3.進行客戶端調用

4.修改OpenFeign默認超時時間

# 這裏的PRODUCTS使用的是大寫的方法
feign.client.config.PRODUCTS.connectTimeout=5000  #配置指定服務鏈接超時
feign.client.config.PRODUCTS.readTimeout=5000		  #配置指定服務等待超時
#feign.client.config.default.connectTimeout=5000  #配置全部服務鏈接超時
#feign.client.config.default.readTimeout=5000			#配置全部服務等待超時

6.OpenFeign調用詳細日誌展現

0.說明

  • 每每在服務調用時咱們須要詳細展現feign的日誌,默認feign在調用是並非最詳細日誌輸出,所以在調試程序時應該開啓feign的詳細日誌展現。feign對日誌的處理很是靈活可爲每一個feign客戶端指定日誌記錄策略,每一個客戶端都會建立一個logger默認狀況下logger的名稱是feign的全限定名須要注意的是,feign日誌的打印只會DEBUG級別作出響應。
  • 咱們能夠爲feign客戶端配置各自的logger.level對象,告訴feign記錄那些日誌logger.lever有如下的幾種值
    NONE 不記錄任何日誌 BASIC 僅僅記錄請求方法,url,響應狀態代碼及執行時間
    HEADERS 記錄Basic級別的基礎上,記錄請求和響應的header FULL 記錄請求和響應的header,body和元數據

1.開啓日誌展現

# 這裏的PRODUCTS使用的是大寫的方法
feign.client.config.PRODUCTS.loggerLevel=full  #開啓指定服務日誌展現
#feign.client.config.default.loggerLevel=full  #全局開啓服務日誌展現
logging.level.com.baizhi.feignclients=debug    #指定feign調用客戶端對象所在包,必須是debug級別

2.測試服務調用查看日誌

相關文章
相關標籤/搜索