zoukankan      html  css  js  c++  java
  • 客户端负载均衡Feign之一:申明式服务调用Feign入门示例

    Spring Cloud提供了Ribbon和Feign作为客户端的负载均衡。

    前面使用了Ribbon做客户端负载均衡,使用Hystrix做容错保护,这两者被作为基础工具类框架被广泛地应用在各个微服务的实现中。SpringCloudFeign是将两者做了更高层次的封装以简化开发。它基于Netfix Feign实现,整合了SpringCloud Ribbon和SpringCloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明是的Web服务客户端定义的方式。SpringCloud Feign在NetFixFeign的基础上扩展了对SpringMVC注解的支持,在其实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。简化了SpringCloud Ribbon自行封装服务调用客户端的开发量。

    在Spring Cloud下,使用Ribbon直接注入一个RestTemplate对象即可,此RestTemplate已做好负载均衡的配置;而使用Feign只需定义个注解,有@FeignClient注解的接口,然后使用@RequestMapping注解在方法上映射远程的REST服务,此方法也是做好了负载均衡配置。

    示例一:在Spring cloud Feign中客户端负载均衡是通过Spring cloud Ribbon实现的,下面演示通过Feign实现负载均衡。

    新建一个spring-boot工程,取名为feign-consumer,在它的pom文件引入Feign的起步依赖spring-cloud-starter-feign、Eureka的起步依赖spring-cloud-starter-eureka、Web的起步依赖spring-boot-starter-web,pom代码如下:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.dxz</groupId>
        <artifactId>feign-consumer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.5.RELEASE</version>   <!--配合spring cloud版本 -->
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
        <properties>
            <!--设置字符编码及java版本 -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <!--增加eureka-server的依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
            </dependency>
            <!--增加feign的依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
            <!--用于测试的,本例可省略 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <!--依赖管理,用于管理spring-cloud的依赖 -->
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-parent</artifactId>
                    <version>Brixton.SR3</version>   <!--官网为Angel.SR4版本,但是我使用的时候总是报错 -->
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <!--使用该插件打包 -->
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    在工程的配置文件application.yml文件,指定程序名、端口号、服务注册地址,代码如下:

    spring.application.name=compute-consume-feign
    server.port=2231
    eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

    在程序的启动类,加上@EnableFeignClients注解开启Feign的功能:

    package com.dxz.feign;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableFeignClients
    @EnableDiscoveryClient
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }

    定义一个feign接口,通过@ FeignClient(“服务名”),来指定调用哪个服务。比如在代码中调用了远程服务的接口,代码如下:

    package com.dxz.feign.remote;
    
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @FeignClient("compute-service")
    public interface HelloService {
        
        @RequestMapping(value="/add", method = RequestMethod.GET)
        String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn);
    
    }

    在Web层的controller层,对外暴露一个的API接口,通过上面定义的Feign客户端来消费服务。代码如下:

    package com.dxz.feign.service;
    
    import java.util.concurrent.atomic.AtomicInteger;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.dxz.feign.remote.HelloService;
    
    @RestController
    public class AddConsumerController {
    
        @Autowired
        HelloService helloService;
        
        private AtomicInteger sn = new AtomicInteger(0);
        
        @RequestMapping(value="/feign-consumer", method = RequestMethod.GET)
        public String helloConsumer(@RequestParam Integer a, @RequestParam Integer b) {
            return helloService.hello(a, b, sn.incrementAndGet());
        }
    }

    启动程序,多次访问http://127.0.0.1:2231/feign-consumer?a=1&b=3,浏览器显示:

     

     再观察日志,可以得到之前使用Ribbon时一样的结果,对服务提供方实现了均衡负载。

    二、在Spring cloud Feign同时融合了Spring Cloud Hystrix,下面演示通过Feign实现熔断功能。

    新增一个服务降级处理类:

    复制代码
    package com.dxz.feign.remote;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class HelloServiceFallback implements HelloService {
    
        @Override
        public String hello(Integer a, Integer b, Integer sn) {
            System.out.println("HelloServiceFallback");
            return "fallback";
        }
    
    }
    复制代码

    在服务绑定接口HelloService中,通过@FeignClient注解的fallback属性来指定服务降级处理类:

    复制代码
    package com.dxz.feign.remote;
    
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import com.dxz.feign.DisableHystrixConfiguration;
    
    @FeignClient(name="compute-service", fallback=HelloServiceFallback.class)
    //@FeignClient(name="compute-service",configuration=DisableHystrixConfiguration.class)
    public interface HelloService {
        
        @RequestMapping(value="/add", method = RequestMethod.GET)
        String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn);
    
    }
    复制代码

    测试:

  • 相关阅读:
    3.25训练题
    hdu1495
    poj1426 宽搜
    高斯消元
    codeforces 999E 强联通分量
    hdu4289城市与歹徒 网络流
    蒟蒻的离散化模板
    樱花,素数筛
    【转】分圆问题:一个诡异的数列规律
    hdu1257最少拦截系统 贪心
  • 原文地址:https://www.cnblogs.com/duanxz/p/7516676.html
Copyright © 2011-2022 走看看