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即可

       <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件 -->
        <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>
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<Integer, Payment> 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<Payment> paymentSQL(@PathVariable("id") Integer id) {
        Payment payment = hashMap.get(id);
        CommonResult<Payment> 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的配置,再有测试业务类

 <!--SpringCloud openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件 -->
        <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>
        <!--日常通用jar包配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.king.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
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<Payment> fallback(@PathVariable Long id)
    {
        CommonResult<Payment> 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<Payment> paymentSQL(@PathVariable("id") Long id)
    {
        return paymentService.paymentSQL(id);
    }

}

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

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

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

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

我们对@SentinelResource的value值进行流控限制

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

 

对了,多次刷新访问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<Payment> 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<Payment> 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<Payment> paymentSQL(@PathVariable("id") Long id)
    {
        return paymentService.paymentSQL(id);
    }

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


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

2、进行测试~~

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

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

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

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

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值