OpenFeign入门以及超时控制

OpenFeign入门

​ 跟着yang哥的视频学,来简单做一下入门笔记,新手使用Markdown,如果有写的不对的地方请多多指教_

  • 什么是openFeign

    • openFeign是一个微服务调用框架,主要作用在消费者端,即调用服务。

    • 是个声明式的web服务客户端,让编写web服务客户端变得更加容易,只需创建一个接口并在接口上添加注解即可–>@FeignClient,即只需要提供一个与provider服务一模一样的接口,并加上@GetMapping/@PostMapping,Feign就会帮我们调用这个ProVider的方法

    • SpringCloud对Feign进行了封装,指出Spring mvc标准注解以及HttpMessageConverters。

  • OpenFeign的入门案例

    • 入门案例所需环境IDEA+eureka(做服务注册与发现,现已停更可以改用zookeeper/consul)+OpenFeign+SpringCloud H+mybatis

    • 一、provider服务

      • maven的依赖
      <dependencies>
              
              <dependency>
                  <groupId>org.springframework.cloudgroupId>
                  <artifactId>spring-cloud-starter-zipkinartifactId>
              dependency>
      
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-webartifactId>
              dependency>
              
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-actuatorartifactId>
              dependency>
              <dependency>
                  <groupId>org.mybatis.spring.bootgroupId>
                  <artifactId>mybatis-spring-boot-starterartifactId>
              dependency>
              
              <dependency>
                  <groupId>org.springframework.cloudgroupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
              dependency>
              <dependency>
                  <groupId>com.alibabagroupId>
                  <artifactId>druid-spring-boot-starterartifactId>
                  
              dependency>
              
              <dependency>
                  <groupId>mysqlgroupId>
                  <artifactId>mysql-connector-javaartifactId>
              dependency>
              
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-jdbcartifactId>
              dependency>
              
      
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-devtoolsartifactId>
                  <scope>runtimescope>
                  <optional>trueoptional>
              dependency>
              <dependency>
                  <groupId>org.projectlombokgroupId>
                  <artifactId>lombokartifactId>
                  <optional>trueoptional>
              dependency>
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-testartifactId>
                  <scope>testscope>
              dependency>
              <dependency>
                  <groupId>com.psfgroupId>
                  <artifactId>cloud-api-commonsartifactId>
                  <version>${project.version}version>
              dependency>
      
              <dependency>
                  <groupId>org.springframework.cloudgroupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
              dependency>
      
          dependencies>
      
      • 配置yml

        server:
          port: 8001
        #配置名字
        spring:
          application:
            name: cloud-payment-service
          datasource:
            # 当前数据源操作类型
            type: com.alibaba.druid.pool.DruidDataSource
            # mysql驱动类
            driver-class-name: com.mysql.jdbc.Driver
            username: root
            password: 123
            url: jdbc:mysql://localhost:3306/db2019?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
        
        mybatis:
        	//在resources下创建一个Mapper目录管理mybatis的xml
          mapper-locations: classpath*:mapper/*.xml
          type-aliases-package: com.psf.springcloud.entities
        
        eureka:
          client:
            register-with-eureka: true
            fetch-registry: true
            service-url:
        #       单击版
        #      defaultZone: http://localhost:7001/eureka
        #      集群版
              defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #集群版
          #配置访问7001端口的时候显示的信息
          instance:
            instance-id: payment8001
            #显示ip地址
            prefer-ip-address: true
            lease-renewal-interval-in-seconds:  1
            lease-expiration-duration-in-seconds:  2
        
      • 编写主启动类

        @SpringBootApplication
        //使注解生效
        @EnableEurekaClient
        @EnableDiscoveryClient
        public class PaymentMain8001 {
                   
            public static void main(String[] args) {
                   
                SpringApplication.run(PaymentMain8001.class,args);
            }
        }
        
      • 编写dao

        @Mapper
        public interface PaymentDao {
                   
        
            public int create(Payment payment);
        
            public Payment getPaymentById(@Param("id") Long id);
        
        }
        
      • 编写service(这里还要编写一个实现类,就不写出)

        public interface PaymentService {
                   
            public int create(Payment payment);
        
            public Payment getPaymentById(@Param("id") Long id);
        }
        
      • 编写controller

        @RestController
        @Slf4j
        public class PaymentController {
                   
             @Autowired
            private PaymentService paymentService;
        
            @Value("${server.port}")
            private String serverPort;
            
            /**CommonResult是个实体类,如果没看过yang哥的视频的同学可以参考下面属性去创建,主要属性有
            private Integer code;
            private String message;
            private T       data;
            */
            @GetMapping("/payment/get/{id}")
            public CommonResult getPaymentById(@PathVariable("id") Long id){
                   
                Payment payment = paymentService.getPaymentById(id);
                log.info("*****查询结果"+payment);
        
                if (payment !=null){
                   
                    return new CommonResult(200,"查询成功,端口号:"+serverPort,payment);
                }else {
                   
                    return new CommonResult(444,"没有对应记录,查询id"+id,null);
                }
            }
        }
        
      • controller写完

    • 二、customer服务

      • 由于customer是调用provider端的,所以可以不用dao层,service层也有一点变化

      • pom其实就是多了个OpenFeign的starter

        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>
        
      • 配置yml

        server:
          port: 80
        eureka:
          client:
            register-with-eureka: false
            service-url:
            #这里配置的是集群
              defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
        
      • 主启动类

        @SpringBootApplication
        @EnableFeignClients
        public class OrderFeignMain80 {
                   
            public static void main(String[] args) {
                   
                SpringApplication.run(OrderFeignMain80.class);
            }
        }
        
      • 编写service

        //要添加component注解
        @Component
        //这里要添加一个新的注解
        @FeignClient(value = "cloud-payment-service")
        public interface PaymentFeignService {
                   
            @GetMapping("/payment/get/{id}")
            public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
        
        }
        
      • 编写controlelr

        @RestController
        @Slf4j
        public class OrderFeignController {
                   
        
            @Resource
            private PaymentFeignService paymentFeignService;
        
            @GetMapping("/customer/payment/get/{id}")
            public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
                   
                //这里也是只需要调用service的方法就行
                return paymentFeignService.getPaymentById(id);
            }
        }
        
      • 到这里customer服务也写完了

    • 三、discovery and regist(注册与发现)服务

      • pom

        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>
        
      • yml

        server:
          port: 7001
        
        ##搭建集群的话:相互守望,相互注册
        eureka:
          #初始化主机名字
          instance:
            hostname: eureka7001.com  #eureka服务端的实例名字
          client:
            fetch-registry: false
            #不注册自己
            register-with-eureka: false
            #注册的ur,开启集群模式,需要指向对方
            service-url:
              defaultZone: http://eureka7002.com:7002/eureka/
        #      defaultZone: http://eureka7001.com:7001/eureka/
          #关闭自我保护机制
          server:
            enable-self-preservation: false
            eviction-interval-timer-in-ms: 2000
        
      • 配置主启动类

        @SpringBootApplication
        //这里要引入一个注解,才能使eureka生效
        @EnableEurekaServer
        public class EurekaMain7001 {
                   
            public static void main(String[] args) {
                   
                SpringApplication.run(EurekaMain7001.class);
            }
        }
        
      • 到这里就完全结束啦

      • 先把注册服务启动,再把消费者与provider服务启动

      • 访问localhost:/customer/payment/get/1 就能看到信息

  • openFeign超时控制

    • 意思就是在provider端,需要处理3秒钟,但是customer端只能等1秒钟,这样就会报错

    • status 404 reading PaymentFeignService#paymentFeignTimeout()

    • 案例演示:

    • provider的controller添加如下方法

      //模拟超时控制
      @GetMapping("/payment/feign/timeout")
      public String paymentFeignTimeout(){
               
          try {
               
              //模拟处理三秒钟 
              TimeUnit.SECONDS.sleep(3);
          } catch (InterruptedException e) {
               
              e.printStackTrace();
          }
          return serverPort;
      }
      
    • customer的service添加上面方法的一个接口

    • customer的controller添加接口的方法

      @GetMapping("/customer/payment/feign/timeout")
      public String paymentFeignTimeout(){
               
          //openFeign底层是ribbon,客户端默认等待1秒钟,但是支付端要处理三秒钟
          return paymentFeignService.paymentFeignTimeout();
      }
      
    • 那我们需要解决这种问题,feign的超时控制是由ribbon控制的,所以我们可以在yml中配置一下超时控制。解决某些请求确实要超过默认时间,把默认等待时间和默认处理时间调整一致

    • 在customer的yml添加

      #与server同级
      ribbon:
        ReadTimeout:  5000
        ConnectTimeout: 5000
      
  • openFeign日志打印功能

    • 对feign接口的调用情况进行监控和输出

    • 配置yml

      logging:
        level:
          com.atguigu.springcloud.service.PaymentFeignService: debug
      
    • 配置config类

      @Configuration
      public class FeignConfig {
               
          /**
          *feign的日志打印有5中
          FULL:除了HEAD,全部打印
          BASE:仅记录请求方法,URL,响应装代码
          HEAD:除BASE,打印
          NONE:不打印
          */
          @Bean
          Logger.Level feignLoggerLevel(){
               
              return Logger.Level.FULL;
          }
      }
      

你可能感兴趣的:(springcloudH,#,OpenFeign,spring,java,分布式)