Micro-service applications ribbon 和 hystrix 总是同时出现
, feign 整合了两者
and provides a declarative consumer client
note:
Feign declarative client interface
New sp09-feign project
创建项目
添加依赖
pom.xml (dependency file)
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.tedu</groupId>
<artifactId>sp09-feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sp09-feign</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 公共模块 -->
<dependency>
<groupId>cn.tedu</groupId>
<artifactId>sp01-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>cn.tedu.sp09.Sp09FeignApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
application.yml (configuration file)
spring:
application:
name: feign
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
Adding the main program @EnableDiscoveryClient
and@EnableFeignClients
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Sp09FeignApplication {
public static void main(String[] args) {
SpringApplication.run(Sp09FeignApplication.class, args);
}
}
java source file
Feign declarative client
Feign uses the familiar spring mvc annotations to set the interface method, which reduces our learning cost.
With these settings, Feign can splice back-end services, access paths and submitted parameters
E.g:
@GetMapping("/{userId}/score")
JsonResult addScore(@PathVariable Integer userId, @RequestParam Integer score);
When the method is called like this:
service.addScore(7, 100);
Then feign will send a request to the server:
http://用户微服务/7/score?score=100
注意:如果 score 参数名与变量名不同,需要添加参数名设置:
@GetMapping("/{userId}/score")
JsonResult addScore(@PathVariable Integer userId, @RequestParam("score") Integer s);
service definition interface
定义service接口 相当于我们业务服务器的 service ,用来远程调用
ItemClient (service interface)
@FeignClient(name="item-service")
public interface ItemClient {
@GetMapping("/{orderId}")
JsonResult<List<Item>> getItems(@PathVariable("orderId") String orderId);
@PostMapping("/decreaseNumber")
JsonResult<?> decreaseNumber(@RequestBody List<Item> items);
}
UserClient (service interface)
@FeignClient(name = "user-service")
public interface UserClient {
@GetMapping("/{userId}")
JsonResult<User> getUser(@PathVariable("userId") Integer userId);
@GetMapping("/{UserId}/score")
JsonResult<?> addScore(@PathVariable("userId") Integer userId,@RequestParam("score") Integer score);
}
OrderClient (service interface)
@FeignClient(name = "order-service")
public interface OrderClient {
@GetMapping("/{orderId}")
JsonResult<Order> getOrder(@PathVariable("orderId") String orderId);
@GetMapping("/")
JsonResult<?> saveOrder();
}
@FeignClient(name="业务服务器名")
——Remote call, the item-service business server is called
Controller (control layer)
@RestController
@Slf4j
public class feignController {
@Autowired
private ItemClient itemClient;
@Autowired
private OrderClient orderClient;
@Autowired
private UserClient userClient;
@GetMapping("/item-service/{orderId}")
public JsonResult<List<Item>> getItems(@PathVariable() String orderId){
return itemClient.getItems(orderId);
}
@PostMapping("/item-service/decreaseNumber")
public JsonResult<?> decreaseNumber(@RequestBody List<Item> items){
return itemClient.decreaseNumber(items);
}
@GetMapping("/user-service/{userId}")
public JsonResult<User> getUser(@PathVariable("userId") Integer userId){
return userClient.getUser(userId);
}
@GetMapping("/user-service/{userId}/score")
public JsonResult<?> addSocre(@PathVariable("userId") Integer userId,Integer score){
return userClient.addScore(userId,score);
}
@GetMapping("/order-service/{orderId}")
public JsonResult<Order> getOrder(@PathVariable("orderId") String orderId){
return orderClient.getOrder(orderId);
}
@GetMapping("/order-service")
public JsonResult<?> getOrder(){
return orderClient.saveOrder();
}
}
Call flow
Start the service and access the test
http://localhost:3001/item-service/decreaseNumber
Check whether eureka is registered
http://localhost:3001/item-service/decreaseNumber
测试 item-service