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.
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.
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.
Again, in a real production environment, users can use dashboards to configure and monitor traffic.
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