SpringCloud五大神獸快速入門

Spring Cloud

單一應用架構 :主要解決ORM 數據庫訪問層。
垂直應用架構 : 解決分層問題,實現應用的分層開發,提升開發效率。
分佈式應用架構:解決系統間調用問題,引發了SOA(面向服務開發)架構新潮。
SOA治理(Macro Service治理):對面向服務開發和治理同時提出新的挑戰,要求應用能夠做到容易部署、智能路由、服務負載均衡、熔斷等要求,能夠做到對服務的可視化治理等。

伴隨着互聯網的發展,人們對這種微服務的開發的呼聲越來越大,在互聯網的萌芽了兩款重量級的SOA治理框架阿里巴巴Dubbo和SpringFrameWork提供的SpringCloud由於Spring的廣大使用羣體也間接的使的Spring Cloud的市場佔用率一路飆升。阿里巴巴的Dubbo也開始發力,由於阿里巴巴的優秀的技術團隊和國內較高的知名度,也對Dubbo框架的發展起到一定的推廣的作用,但是相比較於SpringCloud而言,dubbo由於易用性上和對程序員的要求都比Spring Cloud要高一些,因此目前很多互聯網公司在做微服務組件開發的時候一般還是使用SpringCloud居多。

Spring Cloud Ribbon 組件 -負載均衡

Spring Cloud Ribbon 是一個基於Http和TCP的客服端負載均衡工具,它是基於Netflix Ribbon實現的。通過SpringCloud的自動配置使得項目可以自動的給RestTemplate添加攔截器。

基於配置文件

  • 在項目中集成ribbon
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    ....
    <!--ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
</dependencies>
  • 配置類中添加@LoadBalanced註解
@SpringBootApplication
public class UserApplciation {
    public static void main(String[] args) {
        SpringApplication.run(UserApplciation.class,args);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

ribbon底層會將RestTemplate進行加強,實質上是對RestTemplate添加攔截器,用於修改URL中的服務名。

  • application.properties
server.port=8887
USER-SERVER.ribbon.listOfServers=localhost:8889,localhost:8888
USER-SERVER.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
  • UserController
@RestController
@RequestMapping(value = "usermanager")
public class UserController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/queryUserById")
    public User queryUserById(@RequestParam(value = "id") Integer id){
        String url="http://USER-SERVER/formUserManager/queryUserById?id={id}";
        return restTemplate.getForObject(url,User.class,id);
    }
}

這裏的缺點是服務器的地址是配置死的,一旦配置的服務節點上線|下線都有可能影響本應用,我們期望該listOfServers可以動態變更,達到服務節點的熱部署。

基於註解類

  • RibbonConfigure
@Configuration
public class RibbonConfigure {
    @Bean
    public ServerList<Server> ribbonServerList(){
        Server server1 = new Server("localhost", 8888);

        Server server2 = new Server("localhost", 8889);
        return new StaticServerList<Server>(server1,server2);
    }

    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }
}

這裏的缺點是服務器的地址是配置死的,一旦配置的服務節點上線|下線都有可能影響本應用,我們期望該ribbonServerList可以動態變更,達到服務節點的熱部署。

  • UserApplciation
@SpringBootApplication
@RibbonClient(name = "USER-SERVICE",configuration = {RibbonConfigure.class})
public class UserApplciation {
    public static void main(String[] args) {
        SpringApplication.run(UserApplciation.class,args);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

  • UserController
@RestController
@RequestMapping(value = "usermanager")
public class UserController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/queryUserById")
    public User queryUserById(@RequestParam(value = "id") Integer id){
        String url="http://USER-SERVER/formUserManager/queryUserById?id={id}";
        return restTemplate.getForObject(url,User.class,id);
    }
}

Spring Cloud Eureka (服務註冊中心)

Spring Cloud Eureka 是 Spring Cloud Netflix 微服務套件中的一部分, 它基於 Netflix Eureka 做了二次封裝, 主要負責完成微服務架構中的服務治理功能。 Spring Cloud 通過爲Eureka 增加了 Spring Boot 風格的自動化配置,我們只需通過簡單引入依賴和註解配置就能讓 Spring Boot構建的微服務應用輕鬆地與 Eureka 服務治理體系進行整合。

Eureka註冊中心集羣構建

  • pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
</parent>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
  • 啓動配置類
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}
  • application-eureka-1.properties
server.port=1111

# 指定當前註冊中心的服務名稱
spring.application.name=eurekaregistry

## 啓用註冊中心主動失效,並且每次主動失效檢測間隔爲5s 默認值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 設置eureka註冊中心的響應更新時間
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60

## 配置註冊中心的主機名
eureka.instance.instance-id = eureka-1
eureka.instance.hostname = CentOSA
## 服務刷新時間配置,每隔這個時間會主動心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服務提供者被認定爲丟失心跳超時,失效多久後被刪除
eureka.instance.lease-expiration-duration-in-seconds=15

## 配置定時獲取|抓取註冊中心的數據時間
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集羣中其他eureka實例,用於本eureka實例的註冊方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-2,zone-3
eureka.client.service-url.zone-2=http://CentOSB:1111/eureka/
eureka.client.service-url.zone-3=http://CentOSC:1111/eureka/
  • application-eureka-2.properties
server.port=1111

# 指定當前註冊中心的服務名稱
spring.application.name=eurekaregistry

## 啓用註冊中心主動失效,並且每次主動失效檢測間隔爲5s 默認值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 設置eureka註冊中心的響應更新時間
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60

## 配置註冊中心的主機名
eureka.instance.instance-id = eureka-2
eureka.instance.hostname = CentOSB
## 服務刷新時間配置,每隔這個時間會主動心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服務提供者被認定爲丟失心跳超時,失效多久後被刪除
eureka.instance.lease-expiration-duration-in-seconds=15

## 配置定時獲取|抓取註冊中心的數據時間
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集羣中其他eureka實例,用於本eureka實例的註冊方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-1,zone-3
eureka.client.service-url.zone-1=http://CentOSA:1111/eureka/
eureka.client.service-url.zone-3=http://CentOSC:1111/eureka/

  • application-eureka-3.properties
server.port=1111

# 指定當前註冊中心的服務名稱
spring.application.name=eurekaregistry

## 啓用註冊中心主動失效,並且每次主動失效檢測間隔爲5s 默認值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 設置eureka註冊中心的響應更新時間
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60

## 配置註冊中心的主機名
eureka.instance.instance-id = eureka-3
eureka.instance.hostname = CentOSC
## 服務刷新時間配置,每隔這個時間會主動心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服務提供者被認定爲丟失心跳超時,失效多久後被刪除
eureka.instance.lease-expiration-duration-in-seconds=15

## 配置定時獲取|抓取註冊中心的數據時間
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集羣中其他eureka實例,用於本eureka實例的註冊方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-1,zone-2
eureka.client.service-url.zone-1=http://CentOSA:1111/eureka/
eureka.client.service-url.zone-2=http://CentOSB:1111/eureka/
  • Maven package指令打包
mvn package 
  • 上傳eurekacloud-1.0-SNAPSHOT.jar到CentOSA、CentOSB、CentOSC
[root@CentOSA ~]# java -jar eurekacloud-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-1
[root@CentOSB ~]# java -jar eurekacloud-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-2
[root@CentOSC ~]# java -jar eurekacloud-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-3
  • 訪問瀏覽器查看Eureka是否啓動成功

Eureka自我保護機制

由於Eureka再設計上遵循AP原則,一旦Eureka服務節點檢測到異常Renews < Renews threshold(心跳閾值< 接收心跳)Eureka會進入自我保護機制。一旦進入自我保護機制,Eureka就會失去剔除失效節點功能(失去檢測功能)。

  • Renews threshold: eureka.server.renewal-percent-threshold= 0.85
    集羣: (2 x n) x eureka.server.renewal-percent-threshold = (2 * 3) *0.85 = 5.1 = 取 5
    單機: 2 × (n+1) × eureka.server.renewal-percent-threshold = 4 * 0.85 = 3.4 取 3
  • 默認自我保護機制是開啓的(推薦選項)
  • eureka.server.enable-self-preservation=true
    如果是單機模式很容易觸發自我保護,因爲
    Renews threshold= 2 (1+1) 0.85 = 3
    Renews (last min) =( 60 / eureka.instance.lease-renewal-interval-in-seconds=30)* 1 = 2
  • 所以如果構建的是單機版本的Eureka,建議大家關閉自我保護機制。

服務提供方註冊服務

  • 發佈服務
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  • 配置服務發佈信息
# 發佈服務
spring.application.name=USER-SERVICE
# 發佈服務實例id
eureka.instance.instance-id=001 
eureka.instance.prefer-ip-address=true
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.instance.lease-expiration-duration-in-seconds=20

# 只單純的註冊服務,並不獲取服務註冊列表信息
eureka.client.register-with-eureka=true
eureka.client.healthcheck.enabled=true
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/

服務引用方引用服務

  • pom.xml
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<!--引入 eureka後,無需再次引入Ribbon-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  • application.peroperties
# 只是單純的獲取註冊中心的註冊信息,並不註冊自己
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/

Spring Cloud Hystrix (熔斷器)

Hystrix是一個延遲和容錯庫,旨在隔離對遠程系統,服務和第三方庫的訪問點,停止級聯故障,並在複雜的分佈式系統中實現彈性,在這些系統中,故障是不可避免的。

熔斷器集成

  • pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
</parent>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
</dependencies>
  • 在需要熔斷的方法是添加@HystrixComand註解
@HystrixCommand
@Override
public Integer sum(Integer x, Integer y) {
    System.out.println("thread:"+Thread.currentThread().getId());
    int b=10/0;
    return (x+y)*2;
}
  • 在啓動類上添加@EnableCircuitBreaker
@SpringBootApplication
@EnableCircuitBreaker
public class HystrixSpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixSpringBootApplication.class,args);
    }
}

線程隔離

默認該方法的執行會啓動新的線程執行和主程序不在一個線程中,因此如果上下文中存在ThreadLocal變量,在該方法中就失效了。因此一般可以通過設置commandProperties註解屬性,設置線程就可以了。

@HystrixCommand(commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE")
    })
@Override
public User queryUserById(Integer id) {
    System.out.println(Thread.currentThread().getId());
    return userDAO.queryById(id);
}

execution.isolation.strategy該屬性的可選值有兩個THREADSEMAPHORE默認值是THREAD.①一般如果一個實例一秒鐘有100個併發,此時因爲頻繁啓動線程的開銷過大此時一般考慮使用SEMAPHORE,②非網絡調用。

Fallback

過在@HystrixCommand中聲明fallbackMethod的名稱可以實現優雅降級,如下所示:

@HystrixCommand(
    fallbackMethod = "failback4Sum",
    // ignoreExceptions = {ArithmeticException.class},
    commandProperties = {
        @HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")
    }
)
@Override
public Integer sum(Integer x, Integer y) {
    System.out.println("thread:"+Thread.currentThread().getId());
    int b=10/0;
    return (x+y)*2;
}
public Integer failback4Sum(Integer x, Integer y,Throwable  e) {
    System.out.println(e.getMessage());
    return x+y;
}

注意要求fallbackMethod方法和目標方法必須在同一個類中,具有相同的參數(異常參數可選)

請求超時熔斷

用戶可以通過設置execution.isolation.thread.timeoutInMilliseconds屬性設置一個方法最大請求延遲,系統會拋出HystrixTimeoutException

@HystrixCommand(
    fallbackMethod = "failback4Sum",
    commandProperties = {
        @HystrixProperty(name="execution.isolation.strategy",value="THREAD"),
        @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "100")
    }
)
@Override
public Integer sum(Integer x, Integer y) {
    try {
        int ms=new Random().nextInt(200);
        System.out.println("sleep:"+ms);
        Thread.sleep(ms);
    } catch (Exception e) {
        System.err.println(e.getMessage());
    }
    return (x+y)*2;
}
public Integer failback4Sum(Integer x, Integer y,Throwable  e) {
    return x+y;
}

熔斷器限流

hystrix dashbord(監測)

  • pom.ml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
  • application.properties
# 開啓健康檢查的所有訪問接口
management.endpoints.web.exposure.include=*
  • HystrixSpringBootApplication
@SpringBootApplication
@EnableCircuitBreaker
@EnableHystrixDashboard
public class HystrixSpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixSpringBootApplication.class,args);
    }
}
@Service
public class UserService implements IUserService {

    public User failback4QueryUserById(Integer id) {
        return new User(-1,"服務降級!");
    }
    @HystrixCommand(
            fallbackMethod = "failback4QueryUserById",
            commandProperties = {
                    @HystrixProperty(name="execution.isolation.strategy",value="THREAD"),
                    @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "1000"),
                    // 時間窗口 必須是 numBuckets的整數倍數
                    @HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value = "10000"),//設置窗口長度10秒
                    @HystrixProperty(name="metrics.rollingStats.numBuckets",value = "10"),//設置窗口滑動間隔1s

                    //閘刀開啓的條件 請求數> 2 && 錯誤率> 50%
                    @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "20"),//設置最小請求次數
                    @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50"),//設置錯誤率50%
                    @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"),// 當全開到半開的時間間隔
            },
            threadPoolProperties = {
                    @HystrixProperty(name="coreSize",value="10"),//設置線程池大小
                    @HystrixProperty(name="queueSizeRejectionThreshold",value = "10")//設置隊列最大等待請求數
            }

    )
    @Override
    public User queryUserById(Integer id) {
        int random = new Random().nextInt(3000);
        try {
            System.out.println("sleep:"+random);
            Thread.sleep(random);
        } catch (InterruptedException e) {

        }
        return new User(id,"user"+id);
    }
}

Spring Cloud OpenFeign(Rest客戶端)

Feign是一個聲明性的Web服務客戶端。它使編寫Web服務客戶端變得更容易。Feign 增加了對Spring MVC註解的支持,並使用了Spring MVC中相同HttpMessageConverters。 Feign集成了Ribbon、Eureka、Hystrix,在使用Feign時提供負載均衡以及容錯的的http客戶端。

快速入門

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

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
</parent>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <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.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
  • application.properties
server.port=9999
# 配置Eureka 攔截參數
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.healthcheck.enabled=true
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/
  • UserFeignControllerClient
@FeignClient(name = "USER-SERVICE")
public interface UserFeignControllerClient {
    @PostMapping(value = "/formUserManager/addUser")
    @ResponseBody
    public void addUser(User user) throws IOException;

    @GetMapping(value = "/formUserManager/queryUserById")
    @ResponseBody
    public User queryUserById(@RequestParam(value = "id") Integer id);

    @GetMapping(value = "/formUserManager/queryUserByPage")
    @ResponseBody
    public Map<String, Object> queryUserByPage(@RequestParam(value = "page", defaultValue = "1") Integer pageNow,
                                               @RequestParam(value = "rows", defaultValue = "10") Integer pageSize,
                                               @RequestParam(value = "column", required = false) String column,
                                               @RequestParam(value = "value", required = false) String value);

    @DeleteMapping(value = "/formUserManager/delteUserByIds")
    @ResponseBody
    public void delteUserByIds(@RequestParam(value = "ids") Integer[] ids);

    @PutMapping(value = "/formUserManager/updateUser")
    @ResponseBody
    public void updateUser(User user) throws IOException;
}
  • FeignSpringBootApplication
@SpringBootApplication
@EnableFeignClients
public class FeignSpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignSpringBootApplication.class,args);
    }
}

配置熔斷

默認Feign沒有開啓熔斷策略,需要用戶在配置文件中指定

  • application.properties
server.port=9999

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.healthcheck.enabled=true
eureka.client.service-url.defaultZone=http://CentOSA:1111/eureka/,http://CentOSB:1111/eureka/,http://CentOSC:1111/eureka/

# 開啓hystrix
feign.hystrix.enabled=true
# 配置服務訪問超時
feign.client.config.USER-SERVICE.connect-timeout=100
feign.client.config.USER-SERVICE.read-timeout=100

  • 修改UserFeignControllerClient,添加failback屬性
@FeignClient(name = "USER-SERVICE",fallback = UserFeignControllerFailBack.class)
public interface UserFeignControllerClient {
    @PostMapping(value = "/formUserManager/addUser")
    @ResponseBody
    public void addUser(User user) throws IOException;

    @GetMapping(value = "/formUserManager/queryUserById")
    @ResponseBody
    public User queryUserById(@RequestParam(value = "id") Integer id);

    @GetMapping(value = "/formUserManager/queryUserByPage")
    @ResponseBody
    public Map<String, Object> queryUserByPage(@RequestParam(value = "page", defaultValue = "1") Integer pageNow,
                                               @RequestParam(value = "rows", defaultValue = "10") Integer pageSize,
                                               @RequestParam(value = "column", required = false) String column,
                                               @RequestParam(value = "value", required = false) String value);

    @DeleteMapping(value = "/formUserManager/delteUserByIds")
    @ResponseBody
    public void delteUserByIds(@RequestParam(value = "ids") Integer[] ids);

    @PutMapping(value = "/formUserManager/updateUser")
    @ResponseBody
    public void updateUser(User user) throws IOException;
}
  • UserFeignControllerFailBack
@Component
public class UserFeignControllerFailBack implements UserFeignControllerClient {
    @Override
    public void addUser(User user) throws IOException {

    }

    @Override
    public User queryUserById(Integer id) {
        User user = new User("故障", false, "***", new Date(), "xxxx");
        user.setId(id);
        return user;
    }

    @Override
    public Map<String, Object> queryUserByPage(Integer pageNow, Integer pageSize, String column, String value) {
        return null;
    }

    @Override
    public void delteUserByIds(Integer[] ids) {

    }

    @Override
    public void updateUser(User user) throws IOException {

    }
}

Hystrix Dashboard

updateUser")
    @ResponseBody
    public void updateUser(User user) throws IOException;
}
  • UserFeignControllerFailBack
@Component
public class UserFeignControllerFailBack implements UserFeignControllerClient {
    @Override
    public void addUser(User user) throws IOException {

    }

    @Override
    public User queryUserById(Integer id) {
        User user = new User("故障", false, "***", new Date(), "xxxx");
        user.setId(id);
        return user;
    }

    @Override
    public Map<String, Object> queryUserByPage(Integer pageNow, Integer pageSize, String column, String value) {
        return null;
    }

    @Override
    public void delteUserByIds(Integer[] ids) {

    }

    @Override
    public void updateUser(User user) throws IOException {

    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章