Skip to content

OpenFeign 负载均衡

TIP

OpenFeign 是一个声明式 HTTP 客户端,让服务间调用就像调用本地方法一样简单。它集成了 Spring Cloud LoadBalancer 实现负载均衡。

引入依赖

xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

启用 Feign

java
@SpringBootApplication
@EnableFeignClients(basePackages = "com.example.client")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

声明 Feign 客户端

java
@FeignClient(name = "user-service", path = "/user")
public interface UserFeignClient {

    @GetMapping("/{id}")
    Result<User> getUser(@PathVariable("id") Long id);

    @PostMapping("/list")
    Result<List<User>> getUserList(@RequestBody List<Long> ids);

    @PutMapping
    Result<Void> updateUser(@RequestBody User user);
}

使用 Feign 客户端

java
@Service
public class OrderService {

    @Autowired
    private UserFeignClient userClient;

    public Order createOrder(Long userId, Long productId) {
        // 像调用本地方法一样调用远程服务
        User user = userClient.getUser(userId).getData();
        Order order = new Order();
        order.setUserId(user.getId());
        order.setUserName(user.getName());
        return orderDao.save(order);
    }
}

统一异常处理

java
@Component
public class FeignErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        int status = response.status();
        String body = "";

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(response.body().asInputStream()))) {
            body = br.lines().collect(Collectors.joining("\n"));
        } catch (IOException e) {
            // ignore
        }

        if (status == 400) {
            return new BadRequestException(body);
        }
        return new BusinessException(status, body);
    }
}

配置超时和重试

yaml
spring:
  cloud:
    openfeign:
      client:
        config:
          default:
            connect-timeout: 5000
            read-timeout: 10000
            logger-level: FULL
          user-service:         # 针对特定服务
            connect-timeout: 3000
            read-timeout: 5000

      compression:
        request:
          enabled: true
        response:
          enabled: true

TIP

Feign 默认集成了负载均衡,请求会根据服务名自动分发到不同实例。推荐配置合理的超时和重试策略,避免因网络问题导致雪崩。