SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示

所有代码都在github上:https://github.com/demonruin/cloud2020/tree/master

Sentinel集成Ribbon:

1、准备服务提供者cloudalibaba-nacos-provider-payment9001,cloudalibaba-nacos-provider-payment9002,主要是端口不一样,其他一致,下面附上pom、yml和主业务类代码,这里自己建module即可

       
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
server:
  port: 9001

spring:
  application:
    name: nacos-provider-payment
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

#暴露所有端点,和actuator监控有关
management:
  endpoints:
    web:
      exposure:
        exclude: "*"
package com.king.springcloud.controller;

import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
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;

/**
 * created by king on 2020/5/8 12:38 下午
 */
@RestController
@Slf4j
public class PaymentController {

    @Value("${server.port}")
    private String serverPort;


    /**
     * 此方法与接口是为了测试sentinel的fallback服务降级
     * @param id
     * @return
     */
    public static HashMap hashMap = new HashMap();

    static {
        hashMap.put(1, new Payment(1L, "28a8c1e3bc2742d8848569891fb42181"));
        hashMap.put(2, new Payment(2L, "bba8c1e3bc2742d8848569891ac32182"));
        hashMap.put(3, new Payment(3L, "6ua8c1e3bc2742d8848569891xt92183"));
    }

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


}

主启动类就是正常的主启动类

package com.king.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * created by king on 2020/5/8 12:08 下午
 */
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderPaymentMain9001 {
    public static void main(String[] args) {
            SpringApplication.run(NacosProviderPaymentMain9001.class,args);
        }
}

2、主要是构建服务消费者微服务,这里pom中添加nacos/sentinel/openFeing等依赖,yml中添加nacos和sentinel的配置,再有测试业务类

 
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-sentinel
        
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            com.king.springcloud
            cloud-api-commons
            1.0-SNAPSHOT
            compile
        
server:
  port: 83

spring:
  application:
    name: nacos-consumer-order
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
package com.king.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * created by king on 2020/5/8 4:01 下午
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NacosConsumerOrderMain83 {
    public static void main(String[] args) {
        SpringApplication.run(NacosConsumerOrderMain83.class, args);
    }
}

业务类CircleBreakerController

package com.king.springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import com.king.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
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;

/**
 * created by king on 2020/5/29 11:19 上午
 */
@RestController
@Slf4j
public class CircleBreakerController {
    private static  String SERVICE_URL="http://nacos-provider-payment/";
    @Resource
    private RestTemplate restTemplate;



    @RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback") //没有配置
    //@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
    //@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
//    @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
//            exceptionsToIgnore = {IllegalArgumentException.class})
    public CommonResult fallback(@PathVariable Long id)
    {
        CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id, CommonResult.class,id);

        if (id == 4) {
            throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
        }else if (result.getData() == null) {
            throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }
    //本例是fallback
    public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);
    }
    //本例是blockHandler
    public CommonResult blockHandler(@PathVariable  Long id, BlockException blockException) {
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);
    }

    //==================OpenFeign===================
    @Resource
    private PaymentService paymentService;

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

}

3、此时测试代码准备完毕,进行测试

  • 当@SentinelResource(value = "fallback") //没有其他任何配置的时候,根据代码处理,
    • 当我们id=1或2或3时,是能正常响应的
    • 当我们id=4时,会IllegalArgumentException,非法参数异常....
    • 当我们id=5时,会NullPointerException,该ID没有对应记录,空指针异常

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第1张图片

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第2张图片

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第3张图片

  • 当@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
    • 当我们id=1或2或3时,是能正常响应的
    • 当我们id=4时,会有 handlerFallback来处理异常
    • 当我们id=5时,会有 handlerFallback来处理异常

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第4张图片

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第5张图片

  • 当@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
    • 当我们id=1或2或3时,1qps是能正常响应的,快速访问会触发流控规则,返回自定义的处理方法结果
    • 当我们id=4时,1qps是能正常响应的,快速访问会触发流控规则,返回自定义的处理方法结果
    • 当我们id=5时,1qps是能正常响应的,快速访问会触发流控规则,返回自定义的处理方法结果

我们对@SentinelResource的value值进行流控限制SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第6张图片

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第7张图片

  • 当@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class})
    • 当我们id=1或2或3时,1qps是能正常响应的,快速访问会触发流控规则,返回自定义的处理方法结果
    • 当我们id=4时,因为exceptionsToIgnore = {IllegalArgumentException.class},忽略了这个异常,所以1qps访问还是会正常报错页面的,快速访问会触发流控规则,返回自定义的处理方法结果
    • 当我们id=5时,1qps是能正常响应的,快速访问会触发流控规则,返回自定义的处理方法结果

 

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第8张图片SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第9张图片

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第10张图片

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第11张图片

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第12张图片

对了,多次刷新访问id=1的时候,会有Ribbon的轮训功能,会轮训请求9001和9002端口的服务~~~~~~~

至此是Sentinel集成Ribbon的案例,及@SentinelResource的fallback演示~~

 

Sentinel集成OpenFeign

1、在上述基础上,添加feign调用接口代码:

带@FeignClient注解的业务接口 :PaymentService接口

package com.king.springcloud.service;

import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * created by king on 2020/5/29 1:30 下午
 */
@FeignClient(value = "nacos-provider-payment", fallback = PaymentServiceFallback.class)
public interface PaymentService {
    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult paymentSQL(@PathVariable("id") Long id);
}

fallback = PaymentServiceFallback.class  :PaymentServiceFallback处理方法:注意加@Component注解

package com.king.springcloud.service;

import com.king.springcloud.entities.CommonResult;
import com.king.springcloud.entities.Payment;
import org.springframework.stereotype.Component;

/**
 * created by king on 2020/5/29 1:33 下午
 */
@Component
public class PaymentServiceFallback implements PaymentService{
    @Override
    public CommonResult paymentSQL(Long id) {
        return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
    }
}

controller中的fengin代码上面已经粘贴了,现在附上主要代码

 //==================OpenFeign===================
    @Resource
    private PaymentService paymentService;

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

在yml文件中添加  激活Sentinel对Feign的支持


feign:
  sentinel:
    enabled: true # 激活Sentinel对Feign的支持

2、进行测试~~

①、正常请求接口,能正常访问,返回结果

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第13张图片

②、测试83调用9001,此时故意关闭9001微服务提供者,看83消费侧自动降级,不会被耗死

SpringCloud Alibaba之Sentinel集成Ribbon/OpenFeign案例演示_第14张图片

此时调用了服务降级,说明OpenFeign的fallback处理逻辑生效了~~

至此Sentinel对OpenFeign的集成案例演示完毕~~

 

 

 

 

你可能感兴趣的:(SpringCloud,SpringCloud,Alibaba,Springboot,sentinel,Ribbon,OpenFeign,Feign,fallback)