• 声明式服务调用(Feign)九:环境搭建


    简介 

        Feign客户端是一个web声明式http(REST)远程调用工具,提供了接口和注解方式进行调用。springcloud为Feign 整合了Eureka,Ribbon,Hystrix 以提供服务发现、负债均衡还有服务保护能力,同时整合了SpringMVC注解。

    (注意:从Spring Cloud Dalston开始,Feign默认是不开启Hystrix的。因此,如使用Dalston及以上版本请务必额外设置属性:feign.hystrix.enabled=true,否则断路器不会生效)

    Feign原理

    Feign设计思路

    具体详情点击进入

    环境搭建

    示例代码

    建立feign-client子工程,启动注册中心Eureka:7001,provider:8001和provider:8002提供方

    Feign客户端

    建立feign-consumer项目

    1.添加依赖

    为了更好的体现整合了Eureka,Ribbon,Hystrix,我将放入相关依赖包

         <dependencies>
            <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-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
         </dependencies>

    2.application.yml 配置文件

    server:
      port: 9001
    
    spring:
      application:
        name: feign-consumer#客户端注册进eureka服务列表内
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001:7001/eureka
    //开启断路器
    feign:
      hystrix:
        enabled: true

    3.Feign客户端接口

    ProviderRemote类添加@FeignClient注解指定被调用者服务方以及fallback回调类,在服务熔断的时候返回fallback类中的内容。

    package net.riking.springcloud.consumer.feign.remote;
    
    import net.riking.springcloud.consumer.feign.entity.User;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @FeignClient(name = "provider", fallback = ProviderRemoteFallback.class)
    public interface ProviderRemote {
        @GetMapping("/user/provider")
        User provider(@RequestParam String username);
    
        @GetMapping("/user/provider/port")
         String port();
    }
    引申:
    /*
     * Copyright 2013-2016 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.springframework.cloud.openfeign;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.springframework.core.annotation.AliasFor;
    
    /**
     * Annotation for interfaces declaring that a REST client with that interface should be
     * created (e.g. for autowiring into another component). If ribbon is available it will be
     * used to load balance the backend requests, and the load balancer can be configured
     * using a <code>@RibbonClient</code> with the same name (i.e. value) as the feign client.
     *
     * @author Spencer Gibb
     * @author Venil Noronha
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface FeignClient {
    
        /**
         * The name of the service with optional protocol prefix. Synonym for {@link #name()
         * name}. A name must be specified for all clients, whether or not a url is provided.
         * Can be specified as property key, eg: ${propertyKey}.
         */
        @AliasFor("name")
        String value() default "";
    
        /**
         * The service id with optional protocol prefix. Synonym for {@link #value() value}.
         *
         * @deprecated use {@link #name() name} instead
         */
        @Deprecated
        String serviceId() default "";
    
        /**
         * The service id with optional protocol prefix. Synonym for {@link #value() value}.
         */
        @AliasFor("value")
        String name() default "";
        
        /**
         * Sets the <code>@Qualifier</code> value for the feign client.
         */
        String qualifier() default "";
    
        /**
         * An absolute URL or resolvable hostname (the protocol is optional).
         */
        String url() default "";
    
        /**
         * Whether 404s should be decoded instead of throwing FeignExceptions
         */
        boolean decode404() default false;
    
        /**
         * A custom <code>@Configuration</code> for the feign client. Can contain override
         * <code>@Bean</code> definition for the pieces that make up the client, for instance
         * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
         *
         * @see FeignClientsConfiguration for the defaults
         */
        Class<?>[] configuration() default {};
    
        /**
         * Fallback class for the specified Feign client interface. The fallback class must
         * implement the interface annotated by this annotation and be a valid spring bean.
         */
        Class<?> fallback() default void.class;
    
        /**
         * Define a fallback factory for the specified Feign client interface. The fallback
         * factory must produce instances of fallback classes that implement the interface
         * annotated by {@link FeignClient}. The fallback factory must be a valid spring
         * bean.
         *
         * @see feign.hystrix.FallbackFactory for details.
         */
        Class<?> fallbackFactory() default void.class;
    
        /**
         * Path prefix to be used by all method-level mappings. Can be used with or without
         * <code>@RibbonClient</code>.
         */
        String path() default "";
    
        /**
         * Whether to mark the feign proxy as a primary bean. Defaults to true.
         */
        boolean primary() default true;
    
    }
    @interface FeignClient
     
    属性名默认值作用备注
    value 空字符串 调用服务名称,和name属性相同  
    serviceId 空字符串 服务id,作用和name属性相同 已过期
    name 空字符串 调用服务名称,和value属性相同  
    url 空字符串 一般用于调试,可以手动指定@FeignClient调用的地址  
    decode404 false 配置响应状态码为404时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException  
    configuration {} 自定义当前feign client的一些配置 参考FeignClientsConfiguration
    fallback void.class 熔断机制,调用失败时,走的一些回退方法,可以用来抛出异常或给出默认返回数据。 底层依赖hystrix,启动类要加上@EnableHystrix
    path 空字符串 自动给所有方法的requestMapping前加上前缀,类似与controller类上的requestMapping  
    fallbackFactory void.class 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码  
    primary true    

    4.Feign自定义处理返回的回调值

    创建ProviderRemoteFallback类继承与ProviderRemote实现回调的方法

    package net.riking.springcloud.consumer.feign.remote;
    
    import net.riking.springcloud.consumer.feign.entity.User;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ProviderRemoteFallback implements ProviderRemote{
        @Override
        public User provider(String username) {
            User user =new User();
            user.setDescription("系统繁忙,请稍候再试");
            return user;
        }
    
        @Override
        public String port() {
            return "系统繁忙,请稍候再试";
        }
    }

    5.服务接口调用

    package net.riking.springcloud.consumer.feign.controller;
    
    import net.riking.springcloud.consumer.feign.entity.User;
    import net.riking.springcloud.consumer.feign.remote.ProviderRemote;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/user/consumer")
    public class UserConsumerController {
    
    
        @Autowired
        ProviderRemote providerRemote;
    
        @GetMapping
        public User consumer(@RequestParam String username) {
            User user = providerRemote.provider(username);
            user.setDescription("消费服务:"+user.getDescription());
            return  user;
        }
    
    
        @GetMapping("/port")
        public String port() {
            return  "消费服务:"+providerRemote.port() ;
        }
    }

    6.启动FeignConsumerApplication服务

    package net.riking.springcloud.consumer.feign;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients  //开启Feign客户端
    @EnableHystrix        //开启熔断
    public class FeignConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(FeignConsumerApplication.class, args);
        }
    }

    7.验证

    负债均衡

    启动工程后,连续访问:http://localhost:9001/user/consumer/port多次,可以看到如下页面:

    断路器

    关闭provider:8001和provider:8002提供方,访问:http://localhost:9001/user/consumer/port,可以看到如下面的页面:

    这里只测试这一种,其他这里就不演示了

  • 相关阅读:
    给出字符串
    Closest
    最短路计数(spfa)
    Cleaning Shifts
    Mr. Young's Picture Permutations
    Georgia and Bob
    GCD
    Cutting Game
    SP4191 MSKYCODE
    [CQOI2013]新Nim游戏
  • 原文地址:https://www.cnblogs.com/kongliuyi/p/11411278.html
Copyright © 2020-2023  润新知