经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
SpringCloud OpenFeign基本介绍与实现示例
来源:jb51  时间:2023/2/22 15:20:31  对本文有异议

介绍

  在上面一篇介绍Nacos的文章最后,两个服务的相互调用是用的RestTemplate类完成的。但这种方式不是很推荐,更佳的方式是用OpenFeign组件去调用。OpenFeign是官方推出的服务调用和负载均衡组件,基于Ribbon和Hystrix,前身是第一代Spring Cloud的Feign,对Feign进行了扩展,支持了SpringMvc的相关注解。

常用注解

  OpenFeign是使用接口+注解实现的,因此了解它的常用注解是必要的,有以下几个:

@EnableFeignClients:在启动类上添加,用于开启OpenFeign功能。当项目启动时,会扫描带有@FeignClient的接口,生成代理类并注册到Spring容器中

@FeignClient:通知OpenFeign组件对该注解下的接口进行解析,通过动态代理的方式产生实现类,完成服务调用

@RequestMapping:SpringMvc中的注解,不过此时该注解表示发起Request请求(默认Get方式)

@GetMapping:SpringMvc中的注解,不过此时该注解表示发起Get请求

@PostMapping:SpringMvc中的注解,不过此时该注解表示发起Post请求

代码实现

  首先得把Nacos启动

  服务提供方,

  bootstrap.yml:

server:
  port: 8083
  servlet:
    context-path: /nacosProvider

spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

  引入依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-starter-alibaba-nacos-discovery
  5. </artifactId>
  6. <version>2.2.0.RELEASE</version>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.projectlombok</groupId>
  10. <artifactId>lombok</artifactId>
  11. </dependency>
  12. </dependencies>

  服务方法:

  1. @Controller
  2. @RequestMapping("/provide")
  3. public class ProviderController {
  4. @RequestMapping("/distribute")
  5. @ResponseBody
  6. public String distribute() {
  7. return "吃鸡胸肉";
  8. }
  9. @RequestMapping("/distribute1")
  10. @ResponseBody
  11. public String distribute1(String name, Integer age) {
  12. return "姓名:" + name + ",年龄:" + age;
  13. }
  14. @PostMapping("/distribute2")
  15. @ResponseBody
  16. public String distribute2(@RequestBody Person p) {
  17. return "身高:" + p.getHeight() + ",肤色:" + p.getSkin();
  18. }
  19. }
  1. import lombok.Data;
  2. @Data
  3. public class Person {
  4. private Integer height;
  5. private String skin;
  6. }

  服务调用方,

  bootstrap.yml

server:
  port: 8082
  servlet:
    context-path: /nacosInvoke

spring:
  application:
    name: nacos-invoke
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

  引入依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-starter-alibaba-nacos-discovery
  5. </artifactId>
  6. <version>2.2.0.RELEASE</version>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.springframework.cloud</groupId>
  10. <artifactId>spring-cloud-starter-openfeign</artifactId>
  11. <version>2.2.0.RELEASE</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.projectlombok</groupId>
  15. <artifactId>lombok</artifactId>
  16. </dependency>
  17. </dependencies>

  启动类上添加注解:

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.openfeign.EnableFeignClients;
  4. //开启OpenFeign
  5. @EnableFeignClients
  6. @SpringBootApplication
  7. public class NacosInvokeApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(NacosConfigApplication.class, args);
  10. }
  11. }

  创建@FeignClient修饰的接口:

  1. import com.gs.nacos_invoke.dto.Person;
  2. import org.springframework.cloud.openfeign.FeignClient;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.bind.annotation.PostMapping;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestParam;
  7. /**
  8. * value值是服务提供方的服务名称
  9. */
  10. @FeignClient(value = "nacos-provider")
  11. public interface InvokeClient {
  12. @GetMapping("/nacosProvider/provide/distribute")
  13. String distribute();
  14. @GetMapping("/nacosProvider/provide/distribute1")
  15. String distribute1(@RequestParam("name") String name,
  16. @RequestParam("age") Integer age);
  17. @PostMapping("/nacosProvider/provide/distribute2")
  18. String distribute2(@RequestBody Person p);
  19. }

  Person类(服务调用方再创建一个,不是同一个):

  1. import lombok.Data;
  2. @Data
  3. public class Person {
  4. private Integer height;
  5. private String skin;
  6. }

  编写控制器,使用接口请求提供方的服务:

  1. import com.gs.nacos_invoke.dto.Person;
  2. import com.gs.nacos_config.feign.InvokeClient;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. @Controller
  8. @RequestMapping("/user")
  9. public class UserController {
  10. @Autowired
  11. private InvokeClient invokeClient;
  12. @GetMapping("/invoke")
  13. public void invoke(String name, Integer age) {
  14. String str = invokeClient.distribute();
  15. System.out.println(str);
  16. }
  17. @GetMapping("/invoke1")
  18. public void invoke1() {
  19. String str = invokeClient.distribute1("coder", 20);
  20. System.out.println(str);
  21. }
  22. @GetMapping("/invoke2")
  23. public void invoke2() {
  24. Person p = new Person();
  25. p.setHeight(183);
  26. p.setSkin("黄皮肤");
  27. String s = invokeClient.distribute2(p);
  28. System.out.println(s);
  29. }
  30. }

注意事项

  OpenFeign是基于Ribbon的,所以它默认是负载均衡的。其次,它也是基于Hystrix的,有超时降级的处理:默认服务提供方的接口超时时间是1s,超过1s服务调用方会报错。1s是可以配置的,按照业务需要调整。@FeignClient注解有个fallback属性,当该属性有值时,服务提供方超时,会返回程序所指定的降级值。

  服务调用方,bootstrap.yml添加(更规范的做法是引入spring-cloud-starter-alibaba-nacos-config依赖,nacos中新建配置,然后在这个配置中添加):

feign:
  hystrix:
    enabled: true
ribbon:
    # 请求连接的超时时间
    ConnectionTimeout: 3000
    # 请求处理的超时时间
    ReadTimeout: 3000

hystrix:
    command:
        default:
            execution:
                isolation:
                    thread:
                        timeoutInMilliseconds: 3000

  接口修改为:

  1. import com.gs.nacos_invoke.dto.Person;
  2. import org.springframework.cloud.openfeign.FeignClient;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.bind.annotation.PostMapping;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestParam;
  7. @FeignClient(value = "nacos-provider",
  8. fallback = InvokeClientFallback.class)
  9. public interface InvokeClient {
  10. @GetMapping("/nacosProvider/provide/distribute")
  11. String distribute();
  12. @GetMapping("/nacosProvider/provide/distribute1")
  13. String distribute1(@RequestParam("name") String name,
  14. @RequestParam("age") Integer age);
  15. @PostMapping("/nacosProvider/provide/distribute2")
  16. String distribute2(@RequestBody Person p);
  17. }

  fallback指定的类:

  1. import com.gs.nacos_invoke.dto.Person;
  2. import org.springframework.stereotype.Component;
  3. @Component
  4. public class InvokeClientFallback implements InvokeClient {
  5. @Override
  6. public String distribute() {
  7. return "超时3s";
  8. }
  9. @Override
  10. public String distribute1(String name, Integer age) {
  11. return "超时3s";
  12. }
  13. @Override
  14. public String distribute2(Person p) {
  15. return "超时3s";
  16. }
  17. }

  服务提供方ProviderController类的方法中,加入Thread.sleep(4000);或者throw new RuntimeException("抛异常");来触发降级(抛出未捕获的异常也能触发)。

到此这篇关于SpringCloud OpenFeign基本介绍与实现示例的文章就介绍到这了,更多相关SpringCloud OpenFeign内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号