zoukankan      html  css  js  c++  java
  • Spring Cloud-hystrix Feign(九)

    前面使用ribbon拦截RestTemplate 实现服务的负载均衡 使用Hystrix进行熔断降级请求缓存  用原生的方式 将会有大量的模板代码,feigin就是rabbon和Histrix的整合 同

    使用feign只需要通过接口对服务方的绑定 实现多处调用  

    使用例子

    1.引入Pom依赖

         <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
            <!--开启端点 用于dashboard监控-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>

    2.定义一个接口描述服务信息

    @FeignClient("PROVIDER")
    @RequestMapping("/user")
    public interface UserService {
    
        @RequestMapping(value = "/findById",method = RequestMethod.GET)
        public User findById(@RequestParam("id") Integer id);
        @RequestMapping(value = "/findAll",method = RequestMethod.GET)
        public List<User> findAll();
    
        @RequestMapping(value = "/deleteById",method = RequestMethod.GET)
        public Boolean deleteById(@RequestParam("id")Integer id);
    
        @RequestMapping(value = "/update",method = RequestMethod.POST)
        public Boolean update(@RequestBody User user);
    }

    @FeignClient 是用于服务发现  发现指定服务

    @RequestMapping 为请求指定服务 指定方式

    @RequestBody 表示参数是封装在报文体出传输  服务端 接收也需要打RequestBody

    3.入口类开启Fegin以及服务发现

    @SpringBootApplication
    @EnableFeignClients //开启feigin
    @EnableDiscoveryClient //开启服务发现
    public class SpringCloudFeignConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudFeignConsumerApplication.class, args);
        }
    
    }

    4.通过注入实现调用

    @RestController
    public class UserContorller {
        @Autowired
        UserService  userService;
        @RequestMapping("/findById")
        @ResponseBody
        public User findById(Integer id) {
            return userService.findById(id);
        }
    
        @RequestMapping("/findAll")
        @ResponseBody
        public List<User> findAll() {
            return userService.findAll();
        }
    
        @RequestMapping("/deleteById")
        @ResponseBody
        public Boolean deleteById(Integer id) {
            return userService.deleteById(1);
        }
    
        @RequestMapping("/update")
        @ResponseBody
        public Boolean update() {
            User user=new User();
            user.setId(1);
            user.setName("测试修改");
            User filterUser = userService.findById(user.getId());
            filterUser.setName(user.getName());
            userService.update(filterUser);
            return true;
        }
    }

    继承特性

    将接口定义在服务端 服务消费者通过继承方式实现服务订阅。避免 每个服务消费者 都要重复定义接口描述

    1.新增一个API项目并被服务端和客户端依赖 同时依赖web 因为需要使用springMVC注解对接口描述

    3.pom依赖

     <!--定义接口约束 需要用到springMVC的注解-->
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
            </dependency>
        </dependencies>
        <!--用普通jar打包的方式-->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>attach-sources</id>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>

    jar包打包方式 都改为传统的打包方式 否则 其他依赖会报错 找不到 符号  因为存在2个入口类

    3.api项目添加一个接口描述

    @RequestMapping("/user")
    public interface UserService {
    
        @RequestMapping(value = "/findById",method = RequestMethod.GET)
        public User findById(@RequestParam("id") Integer id);
        @RequestMapping(value = "/findAll",method = RequestMethod.GET)
        public List<User> findAll();
    
        @RequestMapping(value = "/deleteById",method = RequestMethod.GET)
        public Boolean deleteById(@RequestParam("id")Integer id);
    
        @RequestMapping(value = "/update",method = RequestMethod.POST)
        public Boolean update(@RequestBody User user);
    }

    4.更改provider

    @Controller
    @RequestMapping("/user")
    public class UserContorller implements UserService {
        List<User> users;
    
        public UserContorller() {
            users = new ArrayList<>();
            users.add(new User(1, "小明", 1));
            users.add(new User(2, "小香", 0));
            users.add(new User(3, "小方", 0));
            users.add(new User(4, "小张", 0));
            users.add(new User(6, "小李", 0));
    
        }
    
        @RequestMapping("/findById")
        @ResponseBody
        public User findById(Integer id) {
            return users.stream().filter(c -> c.getId().intValue() == id.intValue()).findAny().get();
        }
    
        @RequestMapping("/findAll")
        @ResponseBody
        public List<User> findAll() {
            return users;
        }
    
        @RequestMapping("/deleteById")
        @ResponseBody
        public Boolean deleteById(Integer id) {
            return users.removeIf(c -> c.getId().intValue() == id.intValue());
        }
    
        @RequestMapping("/update")
        @ResponseBody
        public Boolean update(@RequestBody User user) {
            User filterUser = findById(user.getId());
            filterUser.setName(user.getName());
            return true;
        }
    }

    5.更改consumer Service继承api的Service

    @FeignClient("PROVIDER")
    public interface UserService extends com.liqiang.api.UserService {
    }

    6.consumer调用注入Service

    @RestController
    public class UserContorller {
        @Autowired
        UserService  userService;
        @RequestMapping("/findById")
        @ResponseBody
        public User findById(Integer id) {
            return userService.findById(id);
        }
    
        @RequestMapping("/findAll")
        @ResponseBody
        public List<User> findAll() {
            return userService.findAll();
        }
    
        @RequestMapping("/deleteById")
        @ResponseBody
        public Boolean deleteById(Integer id) {
            return userService.deleteById(1);
        }
    
        @RequestMapping("/update")
        @ResponseBody
        public Boolean update() {
            User user=new User();
            user.setId(1);
            user.setName("测试修改");
            User filterUser = userService.findById(user.getId());
            filterUser.setName(user.getName());
            userService.update(filterUser);
            return true;
        }
    }

    继承的缺点   接口修改 会导致调用端的构建失败 不同通过版本控制可以避免 

    Ribbon配置

    全局配置

    通过ribbon.<属性>=..

    ribbon:
      ConnectTimeout: 500
      ReadTimeout=5000

    指定服务配置及重试

    <服务名>.ribbon.<属性>=...  服务名为@FeginClient配置

    #对指定服务设置rabbion全局参数 Fegin接口@FeignClient("PROVIDER")
    PROVIDER:
      ribbon:
        #配置首台服务器重试1次
        MaxAutoRetries: 1
        #配置其他服务器重试两次
        MaxAutoRetriesNextServer: 2
        #链接超时时间
        ConnectTimeout: 500
        #请求处理时间
        ReadTimeout: 2000
        #每个操作都开启重试机制
        OkToRetryOnAllOperations: true

    hystrix配置

    全局配置

    与hystrix配置一样

    #配置断路器超时时间,默认是1000(1秒)
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 12000

    通过指令配置 

    hystrix.command.<commandKey> commandKey默认以方法名作为标识

    禁用hystrix

    全部禁用

    feign:
      hystrix:
        enabled: true #启用hystrix false为禁用 

    指定服务禁用

    @Configuration
    public class DisableHystrixConfiguration {
        @Bean
        @Scope("prototype")
        public Feign.Builder feignBuilder() {
            return Feign.builder();
    
        }
    }
    @FeignClient(value = "PROVIDER",configuration = DisableHystrixConfiguration.class)
    public interface UserService extends com.liqiang.api.UserService {
    }

    服务降级

    1.增加一个Service的接口类

    public class UserServiceFaillBack implements UserService {
        @Override
        public User findById(Integer id) {
            return null;
        }
    
        @Override
        public List<User> findAll() {
            return null;
        }
    
        @Override
        public Boolean deleteById(Integer id) {
            return false;
        }
    
        @Override
        public Boolean update(User user) {
            return false;
        }
    }
    @FeignClient(value = "PROVIDER",configuration = DisableHystrixConfiguration.class,fallback = UserServiceFaillBack.class)
    public interface UserService extends com.liqiang.api.UserService {
    }

    请求压缩

    feign:
      compression:
        request:
          enabled: true  #feign请求gizp压缩 减少网络损耗
        response:
          enabled: true  #feign响应gizp压缩 减少网络损耗
          #启用压缩 压缩指定格式  超过对应大小的才开始压缩
          #feign.compression.request.enabled=true
          #feign.compression.request.mime-types=text/xml,application/xml,application/json #指定格式
          #feign.compression.request.min-request-size=2048 #指定大小

    日志配置

    对服务开启日志输出

    #还需要在application配置Logger.Level  详情区主类去看
    logging:
      level:
        com:
          liqiang:
            feginService:
              HelloExtendService: DEBUG

    还要在主类设置日志界别

    class SpringcloudFeiginConsumerApplication {
    
        /***
         * 日志可选级别
         * • NONE: 不记录任何信息。
         * • BASIC: 仅记录请求方法、URL以及响应状态码和执行时间。
         * • HEADERS: 除了记录BASIC级别的信息之外, 还会记录请求和响应的头信息。
    //     * • FULL: 记录所有请求与响应的明细, 包括头信息、 请求体、 元数据等。
    //     * @return
         */
        @Bean
        public Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL;
        }
        public static void main(String[] args) {
            SpringApplication.run(SpringcloudFeiginConsumerApplication.class, args);
        }
    
    
    }

     

    可能遇到的问题 

    如果遇到feign注解无效,同时配置了scan 包扫描。   可以在@EnableFeignClients("你的feign包")或者application.properties 配置feign.client.package=com.crb.ocms.stock

  • 相关阅读:
    web接口调用
    UISegmentedControl
    CocoaPods安装和使用教程
    NSTimeInterval
    OC-NSString从文件中读取字符串
    XMPP(mac)方案二 ejabberd 服务器搭建 (转载)
    监听 IOS响应式编程框架ReactiveCocoa(RAC)使用示例(转载)
    iOS开发-文件管理
    OC中NSString 的常用方法 (转载)
    NSAttributedString
  • 原文地址:https://www.cnblogs.com/LQBlog/p/10150056.html
Copyright © 2011-2022 走看看