Feign是一個聲明式的HttpClient?更簡潔的實現Http請求發送
安裝Feign組件:
配置Feign的依賴坐標:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud-demo</artifactId> <groupId>cn.itcast.demo</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!--eureka客戶端依賴--> <!--<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>--> <!-- nacos客戶端依賴包 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--feign客戶端依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--引入HttpClient依賴--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> <!--引入feign的統一api--> <dependency> <groupId>cn.itcast.demo</groupId> <artifactId>feign-api</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <finalName>app</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
啟動類注冊Feign
package cn.itcast.order; import cn.itcast.feign.clients.UserClient; import cn.itcast.feign.config.DefaultFeignConfiguration; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @MapperScan("cn.itcast.order.mapper") @SpringBootApplication @EnableFeignClients(clients = UserClient.class,defaultConfiguration = DefaultFeignConfiguration.class) public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } /** * 創建RestTemplate並注入Spring容器 */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } /* @Bean public IRule randomRule() { return new RandomRule(); }*/ }
編寫Feign客戶端接口?
package cn.itcast.feign.clients; import cn.itcast.feign.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "userservice") public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id); }
Feign的內部已經集成了Ribbon,使用方法不變
全局配置方式
server: port: 8088 spring: datasource: url: jdbc:mysql://mysql:3308/cloud_order?useSSL=false username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver application: name: orderservice cloud: nacos: server-addr: nacos:8848 # nacos服務地址 # discovery: # namespace: 4d6ce343-9e1b-44df-a90f-2cf2b6b3d177 # dev環境 # ephemeral: false # 是否是臨時實例 mybatis: type-aliases-package: cn.itcast.user.pojo configuration: map-underscore-to-camel-case: true logging: level: cn.itcast: debug pattern: dateformat: MM-dd HH:mm:ss:SSS #eureka: # client: # service-url: # eureka的地址信息 # defaultZone: http://127.0.0.1:10086/eureka userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 負載均衡規則 ribbon: eager-load: enabled: true # 開啟飢餓加載 clients: # 指定飢餓加載的服務名稱 - userservice feign: httpclient: enabled: true # 支持HttpClient的開關 max-connections: 200 # 最大連接數 max-connections-per-route: 50 # 單個路徑的最大連接數 client: config: default: # default 表示全局生效 | 局部生效 指定服務名稱 userservice 針對某一個服務進行配置 loggerLevel: FULL
局部配置方式
client:
config: 服務名: # default 表示全局生效 | 局部生效 指定服務名稱 userservice 針對某一個服務進行配置 loggerLevel: FULL
Java代碼配置方式:
package cn.itcast.feign.config; import feign.Logger; import org.springframework.context.annotation.Bean; public class DefaultFeignConfiguration { @Bean public Logger.Level logLevel(){ return Logger.Level.BASIC; } }
全局配置位置在啟動類上注解:
package cn.itcast.order; import cn.itcast.feign.clients.UserClient; import cn.itcast.feign.config.DefaultFeignConfiguration; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @MapperScan("cn.itcast.order.mapper") @SpringBootApplication @EnableFeignClients(clients = UserClient.class,defaultConfiguration = DefaultFeignConfiguration.class) public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } /** * 創建RestTemplate並注入Spring容器 */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } /* @Bean public IRule randomRule() { return new RandomRule(); }*/ }
局部單個服務在Feign定義的服務接口上配置:
package cn.itcast.feign.clients; import cn.itcast.feign.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClientProperties; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "userservice", configuration = FeignClientProperties.FeignClientConfiguration.class) public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id); }
Feign性能調整:
引入Feign的HttpClient依賴:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud-demo</artifactId> <groupId>cn.itcast.demo</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!--eureka客戶端依賴--> <!--<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>--> <!-- nacos客戶端依賴包 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--feign客戶端依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--引入HttpClient依賴--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> <!--引入feign的統一api--> <dependency> <groupId>cn.itcast.demo</groupId> <artifactId>feign-api</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <finalName>app</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Feign的連接池配置:
server: port: 8088 spring: datasource: url: jdbc:mysql://mysql:3308/cloud_order?useSSL=false username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver application: name: orderservice cloud: nacos: server-addr: nacos:8848 # nacos服務地址 # discovery: # namespace: 4d6ce343-9e1b-44df-a90f-2cf2b6b3d177 # dev環境 # ephemeral: false # 是否是臨時實例 mybatis: type-aliases-package: cn.itcast.user.pojo configuration: map-underscore-to-camel-case: true logging: level: cn.itcast: debug pattern: dateformat: MM-dd HH:mm:ss:SSS #eureka: # client: # service-url: # eureka的地址信息 # defaultZone: http://127.0.0.1:10086/eureka userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 負載均衡規則 ribbon: eager-load: enabled: true # 開啟飢餓加載 clients: # 指定飢餓加載的服務名稱 - userservice feign: httpclient: enabled: true # 支持HttpClient的開關 max-connections: 200 # 最大連接數 max-connections-per-route: 50 # 單個路徑的最大連接數 # client: # config: # default: # default 表示全局生效 | 局部生效 指定服務名稱 userservice 針對某一個服務進行配置 # loggerLevel: FULL
Feign的最佳使用方式
使用接口來共同約束編寫規范
官方不推薦這種方式,緊耦合,約束過強,SpringMVC支持其他Http對象入參,被約束后將不適用
好處就是沒有規范爭議,閉着眼睛只管實現就完了
方式二:直接放在Common模塊中,統一聲明一系列配置,實體類,API接口
不管是哪個服務都統一從這里面進行資源調取
這個Feign-API POM信息:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud-demo</artifactId> <groupId>cn.itcast.demo</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>feign-api</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> </project>
User實體類:
package cn.itcast.feign.pojo; import lombok.Data; @Data public class User { private Long id; private String username; private String address; }
Feign的日志配置:
package cn.itcast.feign.config; import feign.Logger; import org.springframework.context.annotation.Bean; public class DefaultFeignConfiguration { @Bean public Logger.Level logLevel(){ return Logger.Level.BASIC; } }
Feign接口:
package cn.itcast.feign.clients; import cn.itcast.feign.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClientProperties; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "userservice", configuration = FeignClientProperties.FeignClientConfiguration.class) public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id); }
其他服務安裝Feign-API,從Feign-API里面獲取即可:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud-demo</artifactId> <groupId>cn.itcast.demo</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!--eureka客戶端依賴--> <!--<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>--> <!-- nacos客戶端依賴包 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--feign客戶端依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--引入HttpClient依賴--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> <!--引入feign的統一api--> <dependency> <groupId>cn.itcast.demo</groupId> <artifactId>feign-api</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <finalName>app</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>