声明式服务调用(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,可以看到如下面的页面:

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

posted @ 2019-08-26 11:09  空留意  阅读(514)  评论(0编辑  收藏  举报