Suppose I have the essence of a loan , it has a country field. I would like to react somehow in case of exceeding a certain number of requests per second of time for a controller with a certain value of country . Is there no bicycle way to do this?
- Use Dropwizard Metrics , no need to bike. - Nofate ♦
- @Nofate write this as an answer and attach an example with a solution through this library. - faoxis
2 answers
With Dropwizard Metrics, you can do it like this:
Create
MetricRegistryin the configuration class@Bean public MetricRegistry metricRegistry() { return new MetricRegistry(); }In the controller, we get a counter instance for a specific country, we twist it, if we exceed the threshold RPS, we do something:
public static class MyController { @Autowired private MetricRegistry metricRegistry; public void handleLoan(String country) { Meter meter = metricRegistry.meter(MetricRegistry.name("loan", country)); meter.mark(); if (meter.getOneMinuteRate() > TRESHOLD) { // обрабатываем превышение RPS } // ваша бизнес-логика } }
Meter provides an exponentially-weighted moving average RPS for a minute, five-minute, and fifteen-minute window. If you need another granularity, you com.codahale.metrics.EWMA easily make your own Meter based on the com.codahale.metrics.EWMA class.
- And what will it look like for one second, not minutes? - faoxis
- It will look like a copy of the Meter class, inside which is a
new EWMA(0.63, 1, TimeUnit.SECONDS). - Nofate ♦ - And what to do with the
LongAdderAdapter countin the classMeter? After all, this is an interface at the packet level. - faoxis
The task is too specific to immediately go without a bike :). The surest way to solve, in my opinion, is to make a class that implements business logic for counting and resetting the counter.
public class MetricCounter { //период накопления счетчика вызовов private static Integer periodInSeconds; //начала очередного подсчета периода private static volatile org.joda.time.DateTime lastDtRun; //хранит счетчик запусков за период времени periodInSeconds private static volatile AtomicInteger counter; //если counter станет больше alarmCounter, то hasNextRun() вернет false. private static volatile Integer alarmCounter; //некий метод обертка, который увеличивает счетчик на +1 // и следит за периодами и сбросом счетчика //возвращает true, если укладываемся в показатели, иначе false. public synchronized AtomicBoolean hasNextRun() { } } If all this is also wrapped in your annotations, then it can be quite convenient to use in code.
- This is good, but I need not just to count the time, but to group the elements that are in memory for less than a second and at each moment in time to know how many elements are in each group. - faoxis