Sentinel current limiting fuse integrates OpenFeign components

Principle address: Principle explanation address

Service circuit breaker and current limiting

1. Circuit breaker downgrade

Note: Hystrix and sentinel are currently popular circuit breaker degradation components. The following is a function comparison chart:

Service circuit breaker steps:

Sentinel’s separate circuit breaker downgrade will not be described in detail. Here is the integrated circuit breaker implementation of openfeign and sentinel.

Sentinel Feign Example can refer to the documentation: https://github.com/alibaba/spring-cloud-alibaba/blob/2.2.x/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/readme-zh .md

1. Import package

<!-- openfeign dependency, call between services, integrated spring-cloud-starter-loadbalancer package, loadbalancer load balancing is used by default -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Rely on sentinel for circuit breaker and current limiting. The hystrix open source community has been shut down, so choose sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2. Turn on the fuse

feign:
  sentinel:
    enabled: true #Enable sentinel fuse
  client: #It is recommended to set the timeout for feign calls to avoid the default time being too long and causing the request to take too long.
    config:
      default: # for all services
        loggerLevel: BASIC # Log level NONE: No printing BASIC: Print simple information HEADERS: Print head information FULL: Print all information (default NONE)
        connectTimeout: 5000 # Feign's connection establishment timeout, the default is 10 seconds
        readTimeout: 5000 #Feign's request processing timeout, the default is 60 seconds

3. The client writes the feign interface and specifies the fuse callback class.

// This must be scanned by spring and loaded into the container. Openfeign alone can manually set up FeignClientBuilder to build, but after integrating sentinel, the sentinel source code will find this bean from the spring container. If it cannot find it, an error will be reported.

//The first way of writing
@FeignClient(value = "server-auth", path = "/auth", fallbackFactory = AuthDemoClientFallbackFactory.class)
public interface AuthDemoClient {<!-- -->

    @GetMapping("/demo/auth_test1")
    JsonResult test1() throws Exception;

}

//The second way of writing
@FeignClient(value = "server-auth", path = "/auth", fallback = AuthDemoClientFallbackFactory.class)
public interface AuthDemoClient {<!-- -->

    @GetMapping("/demo/auth_test1")
    JsonResult test1() throws Exception;

}

4. Write a circuit breaker callback class

// Corresponds to the first writing method
@Component // This must be added and handed over to the spring container management
public class AuthDemoClientFallbackFactory implements FallbackFactory<AuthDemoClient> {<!-- -->
    @Override
    public AuthDemoClient create(Throwable cause) {<!-- -->
        return new AuthDemoClient() {<!-- -->
            @Override
            public JsonResult test1() throws Exception {<!-- -->
                return JsonResult.getInstant(-1, "auth-client server available");
            }
        };
    }
}

// Corresponds to the second writing method
@Component // This must be added and handed over to the spring container management
public class AuthDemoClientFallbackFactory implements AuthDemoClient {<!-- -->
    @Override
    public JsonResult test1() throws Exception {<!-- -->
        return JsonResult.getInstant(-1, "auth-client server available");
    }
}

5. Start the feignClient by starting the class

// scanBasePackages needs to scan the fallback class
@SpringBootApplication(scanBasePackages = {<!-- -->"cn.zlf.auth"})
// Enable feign call and scan the interface class defined by feign
@EnableFeignClients(basePackages = {<!-- -->"cn.zlf.auth"})
public class DemoServerApplication {<!-- -->
    public static void main(String[] args) {<!-- -->
        SpringApplication.run(DemoServerApplication.class,args);
    }
}

6. Call

//facade encapsulation
@Component
public class AuthDemoClientFacade {<!-- -->

    @Autowired
    private AuthDemoClient authDemoClient;

    public String test1() {<!-- -->
        JsonResult<String> jsonResult = null;
        try {<!-- -->
            jsonResult = authDemoClient.test1();
        } catch (Exception e) {<!-- -->
            throw new BusinessException(e.getMessage());
        }
        if (!jsonResult.isSuccess()) {<!-- -->
            throw new BusinessException(jsonResult.getMsg(), jsonResult.getCode());
        }
        return jsonResult.getData();
    }
}

// test class
@SpringBootTest(classes = DemoServerApplication.class)
@RunWith(SpringRunner.class)
public class DemoSentinelTest {<!-- -->

    @Autowired
    private AuthDemoClientFacade authDemoClientFacade;

    @Test
    public void test1() {<!-- -->
        System.out.println(authDemoClientFacade.test1());
    }
}

2. Current Limitation

Add based on the circuit break in the previous step.

Introduction

Download sentinel dashboard: https://edas-public.oss-cn-hangzhou.aliyuncs.com/install_package/demo/sentinel-dashboard.jar

Install and start on the server:

java -Dcsp.sentinel.log.dir=D:\sentinel\logs \
  -Dserver.port=8859 \
  -Dproject.name=sentinel-dashboard \
  -Dsentinel.dashboard.auth.username=sentinel \
  -Dsentinel.dashboard.auth.password=123456 \
  -Dserver.servlet.session.timeout=7200 \
  -jar .\sentinel-dashboard-1.8.6.jar

Note: Sentinel current limiting has coding methods, annotation methods, and console methods. Here we only explain the console current limiting + Nacos persistence method.

For Sentinel Example, please refer to the documentation: https://github.com/alibaba/spring-cloud-alibaba/blob/2.2.x/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh. md

Current limiting operation steps:

1. Import package

<!-- openfeign dependency, call between services, integrated spring-cloud-starter-loadbalancer package, loadbalancer load balancing is used by default -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Rely on sentinel for circuit breaker and current limiting. The hystrix open source community has been shut down, so choose sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>


    org.springframework.boot
    spring-boot-starter-actuator


    com.alibaba.csp
    sentinel-datasource-nacos

2. Specify the dashboard console

spring:
  cloud:
    sentinel:
      eager: true #Turn on heartbeat
      transport:
        dashboard: 127.0.0.1:8859 #Specify the console address and port number
        clientIp: 127.0.0.1 #Here, if the service and dashboard console are on the same machine, no configuration is required; if they are not on the same machine, the address of the service needs to be configured, and the dashboard will request the health data information on this IP service.
      datasource: #ds1 represents the name of ReadableDataSource, which can be written at will. The nacos after ds1 indicates the type of ReadableDataSource. Currently, five types are supported: file, nacos, zk, apollo, and redis.
        ds1:
          nacos:
            namespace: basic
            server-addr: 127.0.0.1:8848
            username: nacos
            password: nacos
            data-id: demo_sentinel
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow

# Turn on health data
management:
  endpoints:
    web:
      exposure:
        include: '*'

3. Configure current limiting information on Nacos, named demo_sentinel, and the configuration format is JSON.

[
{<!-- -->
"resource": "/test",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"clusterMode": false
}
]
  • resource: resource name, the resource name is the target of the current limiting rule;
  • count: current limiting threshold
  • grade: current limit threshold type, QPS mode (1) or concurrent thread number mode (0), default QPS mode
  • limitApp: call source targeted by flow control
  • strategy: calling relationship current limiting strategy: direct (0), link (1), association (2), the default is based on the resource itself (direct)
  • controlBehavior: flow control effect (direct rejection (0); WarmUp (1); constant speed + queue waiting (2)), does not support current limiting based on the calling relationship, and is directly rejected by default
  • clusterMode: Whether to limit the cluster current, the default is no

4. Customized current limit return value

/**
 * Customize Sentinel’s current limit return value
 */
@Component
@Slf4j
public class SentinelFlowBlockHandler implements BlockExceptionHandler {<!-- -->
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {<!-- -->
        httpServletResponse.setHeader("Content-Type", "application/json;charset=UTF-8");
        try (Writer writer = httpServletResponse.getWriter()) {<!-- -->
            JsonResult<String> instant = JsonResult.getInstant(-1, "The current limit has been reached, please try again later");
            writer.write(JSON.toJSONString(instant));
            writer.flush();
        } catch (Exception e1) {<!-- -->
            log.error("response error, case:" + e1, e1);
        }
    }
}

4. Start the service and start the request. You can see the real-time monitoring chart in the http://127.0.0.1:8859/#/dashboard console.