Greenwich.SR2版本的Spring Cloud Feign實例


  前面我們了解了Spring Cloud Ribbon和Hystrix,在使用上它們基本上會成隊出現,那么是不是可以把它們組合起來使用?而且我們發現,在服務消費方a-beautiful-client里通過REST調用服務提供方時,會有很多RestTemplate的代碼,這些重復代碼能否簡化掉呢?答案是肯定的,Spring Cloud為我們提供了Feign,就是整合了Ribbon和Hystrix,並且提供了一種聲明式的Web服務客戶端定義方式,讓我們只需要定義好REST接口即可,服務消費方無需再寫實現了。

  我們這次新增一個a-feign-client吧,把它跟a-beautiful-client(參見Greenwich.SR2版本的Spring Cloud Eureka實例)來做一番比較。三板斧祭出:

  1、pom里我們去掉了ribbon和hystrix,只需引入openfeign即可:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>feign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <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-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR2</version>
                <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>

  2、application:

#本機端口
server.port=8764

#本機服務名
spring.application.name=a-feign-client
#服務提供方實例地址
app.service.url=http://A-BOOTIFUL-CLIENT/

#注冊中心地址
eureka.client.service-url.defaultZone=http://localhost:8888/eureka/

#開啟熔斷
feign.hystrix.enabled=true

#負載均衡配置
a-bootiful-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

  主類我們用@EnableFeignClients代替了@EnableCircuitBreaker和@LoadBalance:

package hello;

import hello.service.ConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class FeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
    }
}


@RestController
class ServiceInstanceRestController {

    @Autowired
    private ConsumerService consumerService;

    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/consumer/sayHi")
    public String sayHi(@RequestParam(value = "name") String name, @RequestParam(value = "accessToken", required = false) String accessToken) {
        return name + " say hi: " + consumerService.hello(name);
    }


    @RequestMapping("/service-instances/{applicationName}")
    public List<ServiceInstance> serviceInstancesByApplicationName(
            @PathVariable String applicationName) {
        return this.discoveryClient.getInstances(applicationName);
    }
}

  3、我們改寫一下接口,再新增一個熔斷的服務降級類:

package hello.service;

import hello.service.impl.BackUPCallHi;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Component
@FeignClient(name = "a-bootiful-client", fallback = BackUPCallHi.class)
public interface ConsumerService {
    @RequestMapping("/hello")
    String hello(@RequestParam(value = "name") String name);
}
package hello.service.impl;

import hello.service.ConsumerService;
import org.springframework.stereotype.Component;

@Component
public class BackUPCallHi implements ConsumerService {

    @Override
    public String hello(String name) {
        return "I'm feign hystrix.";
    }
}

  搞定,可以看到原來a-beautiful-client能干的事情,a-feign-client也做到了:

  負載均衡:

 

 

 

  熔斷:

   上面我們看到url后面多了一個accessToken的參數,這個其實是給網關鑒權用的,詳見Greenwich.SR2版本的Spring Cloud Zuul實例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM