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 2

With Dropwizard Metrics, you can do it like this:

  1. Create MetricRegistry in the configuration class

     @Bean public MetricRegistry metricRegistry() { return new MetricRegistry(); } 
  2. 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 count in the class Meter ? 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