天天看點

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

8.SentinelResource配置

①按資源名稱限流

(1)建立controller
package com.hry.springcloud.alibaba.controller;


import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RateLimitController {
    @GetMapping(value = "/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource(){
        return new CommonResult(200,"按資源名稱限流測試OK",new Payment(202L,"serial001"));
    }

    public CommonResult handleException(BlockException exception){
        return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服務不可用");
    }
}

           
(2)建立流控規則
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流
(3)測試
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

②按資源名稱限流

(1)在RateLimitController添加方法
@GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl(){
        return new CommonResult(200,"按url限流測試OK",new Payment(2020L,"serial002"));
    }
           
(2)建立流控規則
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流
(3)測試
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

③問題

跟之前的Hystrix一樣

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

④客戶自定義限流處理邏輯

(1)建立CustomerBlockHandler類
package com.hry.springcloud.alibaba.handler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;

public class CustomerBlockHandler {
    public static CommonResult handlerException(BlockException exception){
        return new CommonResult(1234567,"按客戶自定義全局-----Global-----1");
    }

    public static CommonResult handlerException2(BlockException exception){
        return new CommonResult(7654321,"按客戶自定義全局-----Global-----2");
    }
}

           
(2)在RateLimitController添加方法
@GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class,   //指定我們剛才建立的類
            blockHandler = "handlerException2")               //使用第二個方法處理
    public CommonResult customerBlockHandler(){
        return new CommonResult(200,"自定義",new Payment(2020L,"serial003"));
    }
           
(3)建立流控規則
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流
(4)測試
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

9.服務熔斷

Sentinel+Ribbon+OpenFeign+fallback

Ribbon:

①Sentinel服務熔斷無配置

(1)cloudalibaba-provider-payment9003,cloudalibaba-provider-payment9004

這個與9002相似不同處下面會給出,其他直接複制原來的9002即可

controller

package com.hry.springcloud.alibaba.controller;

import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;

@RestController
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    public static HashMap<Long, Payment> hashMap = new HashMap<>();

    //模拟dao層  偷懶
    static {
        hashMap.put(1001L,new Payment(1001L,"1001abcd"));
        hashMap.put(1002L,new Payment(1002L,"1002abcd"));
        hashMap.put(1003L,new Payment(1003L,"1003abcd"));
    }

    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
        Payment payment = hashMap.get(id);
        CommonResult<Payment> result = new CommonResult<Payment>(200,"from MySQL , serverPort: "+serverPort,payment);
        return result;
    }
}

           
(2)cloudalibaba-consumer-nacos-order84

與83相似,沒有給出的的都與83内容一緻。

yml

server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置nacos位址
    sentinel:
      transport:
        #配置sentinel dashboard位址
        dashboard: localhost:8080
        #預設8719端口,端口被占用會自動從8719開始依次+1開始掃描,直至找到未被占用的端口
        port: 8719
service-url: 
  nacos-user-service: http://nacos-payment-provider
           

controller

package com.hry.springcloud.alibaba.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
public class CircleBreakerController {
    public static final String SERVICE_URL = "http://nacos-payment-provider";

    @Resource
    private RestTemplate restTemplate;

    @RequestMapping(value = "/consumer/fallback/{id}")
    @SentinelResource(value = "fallback") //不配置的
    public CommonResult<Payment> fallback(@PathVariable("id") Long id){
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL+"/paymentSQL/"+id,CommonResult.class,id);

        if (id == 1004){
            throw new IllegalArgumentException("IllegalArgumentException , 非法參數異常......");
        }else if (result.getData() == null){
            throw new NullPointerException("NullPointerException , 該ID沒有對應記錄,空指針異常");
        }
        return result;
    }
}

           
(3)測試
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

1004

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

其他

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

②Sentinel服務熔斷隻配置fallback

(1)修改controller

修改

添加方法

public CommonResult<Payment> handlerFallback(@PathVariable("id") Long id,Throwable e){
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(444,"handlerFallback兜底方法 , 異常"+e.getMessage(),payment);
    }
           
(2)測試
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

③Sentinel服務熔斷隻配置blockHandler

(1)修改controller

修改

添加方法

public CommonResult<Payment> blockHandler(@PathVariable("id") Long id, BlockException blockException){
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(4444,"blockHandler-sentinel限流,無此流水 , blockException"+blockException.getMessage(),payment);
    }
           
(2)添加流控規則(或降級規則都可)
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流
(3)測試

可以看到,流量異常能夠處理,但是運作時異常無法解決,是預設的

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

④Sentinel服務熔斷配置fallback和blockHandler

(1)修改controller
(2)添加流控規則(或降級規則都可)
SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流
(3)測試

這次完美了

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

①-④注解:

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

⑤Sentinel服務熔斷exceptionsToIgnore

(1)修改controller 在注解中添加exceptionsToIgnore 并指定哪些 異常
(2)測試

我們配置忽略非法參數異常之後找1004,會正常報錯。進到error page

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

OpenFeign:

①Sentinel服務熔斷OpenFeign

(1)修改84的yml

添加配置

#激活
feign:
  sentinel:
    enabled: true
           
(2)修改84的主啟動類

添加注解

(3)修改84的業務類

建立service包

建立接口PaymentService

package com.hry.springcloud.alibaba.service;

import com.hry.springcloud.alibaba.service.Impl.PaymentServiceImpl;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "nacos-payment-provider",fallback = PaymentServiceImpl.class)
public interface PaymentService {

    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}

           

建立實作類PaymentServiceImpl

package com.hry.springcloud.alibaba.service.Impl;

import com.hry.springcloud.alibaba.service.PaymentService;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.stereotype.Component;

@Component
public class PaymentServiceImpl implements PaymentService {
    @Override
    public CommonResult<Payment> paymentSQL(Long id) {
        return new CommonResult<>(55555,"服務降級傳回---來自PaymentServiceImpl",new Payment(id,"error"));
    }
}

           

修改controller,添加如下代碼

@Resource
    private PaymentService paymentService;

	@GetMapping(value = "/consumer/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
        return paymentService.paymentSQL(id);
    }
           

(4)測試

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

關閉9003,服務降級

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

10.幾個熔斷架構比較

SpringCloud學習筆記16——進階篇之SpringCloud Alibaba Sentinel實作熔斷與限流

繼續閱讀