Using Hystrix and Sentinel in code example

In this series of articles, we will introduce the ** Alibaba ** open source ** Sentinel Java ** flow control project in comparison with ** Hystrix **.

In my last blog, I compared the two libraries at a high level. Now let's see how to use both while looking at the code example.

Example

The example used here is from this Spring Tutorial (https://spring.io/guides/gs/circuit-breaker/?spm=a2c65.11461447.0.0.7e4717c6AVEkbf). This is a sample app from a famous bookstore.

Before you start, make sure you follow the steps in the original documentation to download and configure the sample app.

The sample can be reused with minor modifications. Sentinel is part of the latest Spring Framework release. Therefore, there are no additional dependency changes.

Let's go directly to read / src / main / java / hello / BookService.java and paste the code below.

@Service
public class BookService {
  private final RestTemplate restTemplate;
  public BookService(RestTemplate rest) {
    this.restTemplate = rest;
  }
  @SentinelResource(value = "readingList", fallback = "reliable")
  public String readingList() {
    URI uri = URI.create("http://localhost:8090/recommended");
    return this.restTemplate.getForObject(uri, String.class);
  }
  public String reliable() {
    return "Cloud Native Java (O'Reilly)";
  }
}

As you can see, I just replaced the @ HystrixCommand annotation with @SentinelResource. The value attribute labels the method you want to apply to the circuit breaker. And the fallback attribute points to the fallbackMethod function. Then add the fallback functionreliable (). This function does the same as the example.

So far, it's pretty close to what Hystrix is doing. However, as mentioned in the previous article, Hystrix directs the operation of the circuit breaker. Once you have pointed out the resource, the conditions for activating the circuit breaker are processed accordingly.

Sentinel, on the other hand, leaves control over to the user, who must create rules to define the conditions. Let's do that and add a rule. You can add it to the end of the file.

DegradeRuleManager.loadRules(Collections.singletonList(
    new DegradeRule("readingList") // resource name
        .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) // strategy
        .setCount(0.5) // threshold
        .setTimeWindow(10) // circuit breaking timeout (in second)
));

I just created a DegradeRule and set the mode to exception rate, threshold to 0.5 (1 out of 2), and recovery time to 10 seconds. DegradeRuleManager loads and enables this rule.

Let's try it out. Only the reading service is started, not the bookstore service. Therefore, it fails every time a request comes in. After two attempts (and two failures), let's see the fallback feature enabled.

Cloud Native Java (O'Reilly)

Now let's start the Bookstore service. After 10 seconds, we'll see the normal response.

Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)

In a production environment, it's actually easier to set this rule using the Sentinel dashboard than to add the rule via code. Below is a screenshot.

image.png

Furthermore

So far, we've seen the same functionality that Hystrix performed. And in reality, Sentinel needs another step. Let's look at an example.

Sentinel allows you to set rules based on different metrics. This example uses QPS.

First, let's look for the main class bookstore / src / main / java / hello / BookstoreApplication.java.

@RestController
@SpringBootApplication
public class BookstoreApplication {
    private static final Logger LOGGER = LoggerFactory.getLogger(BookstoreApplication.class);
    @SentinelResource(value = "readingList", blockHandler = "handleTooManyRequests")
    @RequestMapping(value = "/recommended")
    public String readingList(){
        return "Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)";
    }
    public String handleTooManyRequests(BlockException ex) {
        LOGGER.error("Too many requests: " + ex.getClass().getSimpleName());
        return "Sentinel in Action";
    }
  public static void main(String[] args) {
    SpringApplication.run(BookstoreApplication.class, args);
  }

I've added @ SentinelResource, but I'm using the blockHandler function instead of the fallback function. This function simply prints the message "Sentinel in Action". Now we need to add a new rule when this function is triggered.

FlowRule rule = new FlowRule("readingList")
    .setCount(1);
FlowRuleManager.loadRules(Collections.singletonList(rule));

This rule applies when there is one or more requests per second. Part of this code can be added to the end of the file.

On the first request after we start the BookStore service, we have to get a normal response.

Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)

However, if you make more than one request per second, you should see the blockHandler function kick in.

Sentinel in Action

And after 1 second, you can see the normal reaction again.

image.png

Again, in a real production environment, users can use dashboards to configure and monitor traffic.

wrap up

Sentinel aims to provide users with multiple options for controlling the flow to a service. Doing so requires the user to define the rules via the GUI or code. In addition to QPS, users can control the number of threads and create whitelists for access control. As distributed services become more complex, this model will better meet user demands.

Recommended Posts

Using Hystrix and Sentinel in code example
Encoding and Decoding example in Java
Write code using Ruby classes and instances
Try using Sourcetrail (win version) in Java code
Try using Sourcetrail (macOS version) in Java code
CSRF countermeasure policy and implementation example in REST application using "Spring Boot" + "EXT JS"
LinkedHashMap referenced in insertion order and its usage example
How to convert A to a and a to A using AND and OR in Java
Differences in code when using the length system in Java
Java code sample to acquire and display DBLINK source and destination data in Oracle Database using DBLINK
Example of using vue.config.js
Implement CustomView in code
Implement Thread in Java and try using anonymous class, lambda
How to specify character code and line feed code in JAXB
How to set character code and line feed code in Eclipse
[Ruby] Creating code using the concept of classes and instances
Get error information using DefaultErrorAttributes and ErrorAttributeOptions in Spring Boot 2.3
Create QR code for Google Authenticator using ZXing in Java
Correct the character code in Java and read from the URL
Tips for using Salesforce SOAP and Bulk API in Java
Talk about using Java input wait (Scanner) in VS Code