四. SpringCloud负载均衡与调用 (5)

由于80为服务消费方,只是调用服务提供方的服务,所以可以不讲自己注册到服务注册中心。

server: port: 80 eureka: client: register-with-eureka: false # 客户端就不注册入服务注册中心了 service-url: defaultZone: :7001/eureka/,:7002/eureka/ 6.4 主启动类

注意主启动类上需要添加 @EnableFeignClients 注解,这个注解声明80服务可以使用Feign来实现服务接口的调用。

@SpringBootApplication @EnableFeignClients //激活Feign功能 public class OrderFeignMain80 { public static void main(String[] args) { SpringApplication.run(OrderFeignMain80.class); } } 6.5 业务类

前面就提到过,在Feign的实现下,只需要创建一个接口并使用注解的方式来配置,这是什么意思呢,就是我们在服务消费方中的service中编写接口,并在该接口上使用 @FeignClient 注解,这样的话就能够实现对服务提供方的服务调用,首先我们看服务提供方8001中有如下的一个服务:

@RestController @Slf4j @RequestMapping("/payment") public class PaymentController { //... @GetMapping("/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) { Payment paymentById = paymentService.getPaymentById(id); log.info("===> payment: " + paymentById); if(paymentById != null) { return new CommonResult(200, "查询成功,端口号:" + serverPort,paymentById); } return new CommonResult(400,"查询失败",null); } //... }

在服务消费方80中编写如下的接口即可对服务提供方的服务进行调用:

@Component @FeignClient("CLOUD-PAYMENT-SERVICE") public interface PaymentFeignService { @GetMapping("/payment/get/{id}") public CommonResult getPaymentById(@PathVariable("id") Long id); }

@FeignClient 注解中的value值为要调用的服务名称,也就是8001/8002服务提供方注册到Eureka注册中心的服务名,这个注解就是告诉该接口调用哪个服务,而默认OpenFeign会使用轮训的负载均衡算法来调用具体的服务实例,在这个接口中我们需要使用服务提供方服务的哪个具体方法,将该方法作为接口方法写入接口中即可。

然后编写80服务消费方的Controller:

@RestController @Slf4j @RequestMapping("/consumer") public class OrderFeignController { @Autowired private PaymentFeignService paymentFeignService; @GetMapping("/payment/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) { return paymentFeignService.getPaymentById(id); } } 6.6 测试

我们先启动Eureka的集群注册中心,然后启动服务提供方8001/8002,再启动服务消费方80,访问,我们可以发现OpenFeign使用轮询的负载均衡算法实现了服务提供方服务接口的调用。

6.7 总结

简言之就是客户端的服务接口使用用 @FeignClient 注解根据服务名称去调用服务提供方的具体服务。

7. OpenFeign超时控制 7.1 超时设置

咱们这里故意设置超时演示出错情况

服务提供方8001故意写暂停程序

@GetMapping("/feign/timeout") public String paymentFeignTimeout() { //暂停几秒线程 try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return serverPort; }

服务消费方80service添加超时方法paymentFeignTimeout,controller添加超时接口paymentFeignTimeout

@Component @FeignClient("CLOUD-PAYMENT-SERVICE") public interface PaymentFeignService { @GetMapping("/payment/feign/timeout") String paymentFeignTimeout(); } @RestController @Slf4j @RequestMapping("/consumer") public class OrderFeignController { @Resource private PaymentFeignService paymentFeignService; @GetMapping("/payment/feign/timeout") public String paymentFeignTimeout() { //openfeign底层为ribbon,客户端一般默认等待1秒钟 return paymentFeignService.paymentFeignTimeout(); } }

测试:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsxgd.html