Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I solve "Reached the maximum number of URI tags for http.client.requests" warning?

I receive this warning on my app. I am reading rfidtags from about 30 readers at the same time. Each time a tag comes in I am hitting the database to see if its in there. I have a rest api that I am using. So I use a rest template to hit the rest api. Any ideas on how to solve this? Thanks!

Here's some of my code:

private void vehicleRequests(List<Maybevehicle> vehicles){
    //process list of unique tags to see if they are in the database and linked to a vehicle
    List<Maybevehicle> foundMaybeVehs= new ArrayList<>();
    List<Maybevehicle> notFound=new ArrayList<>();
     if(!vehicles.isEmpty()){
             for (Maybevehicle v: vehicles){
                Future<Maybevehicle> r=aService.batchVehTags(v);

                try{
                    Maybevehicle m=r.get(2000, TimeUnit.SECONDS);
                    if(r.isDone()){
                        if (!(m.getB().getVin().equals("notindb"))){
                            foundMaybeVehs.add(m);
                        }
                        }
                    }
                }catch(InterruptedException | ExecutionException | TimeoutException e){

                }
             }

              if(!foundMaybeVehs.isEmpty()){
                 addLocation(foundMaybeVehs);
             }
     }else{
         log.info("no vehicles to check.");
     }

}       


@Override
public Future<Maybevehicle> batchVehTags(Maybevehicle v) {
    Future<Maybevehicle> future=null;
         try{
                 SimpleTaskMaybeveh task=new SimpleTaskMaybeveh(v, appRestTemplate);
                  future=dbService.submit(task);

             }catch(Exception e){
                    e.printStackTrace();
                 }

            return future;
        }




}

public class SimpleTaskMaybeveh implements Callable<Maybevehicle>{

private RestTemplate appRestTemplate;
private Maybevehicle veh;

public SimpleTaskMaybeveh(Maybevehicle veh, RestTemplate appRestTemplate){
    this.veh=veh;
    this.appRestTemplate=appRestTemplate;
}

@Override
public Maybevehicle call(){
  String url="http://url/"+veh.getB().getRfidtag();
    String authString= "";
    byte[] encodedAuth= Base64.encodeBase64(authString.getBytes(Charset.forName("US-ASCII")));
    String authHeader="Basic "+new String(encodedAuth);
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    headers.set("Authorization", authHeader);
    HttpEntity<Bmwvehiclemain> requestEntity=new HttpEntity <Bmwvehiclemain>(headers);
    ResponseEntity<Bmwvehiclemain> results=appRestTemplate.exchange(url, HttpMethod.GET, requestEntity, Bmwvehiclemain.class);
    try{
        Bmwvehiclemain n=results.getBody();
        Maybevehicle d=new Maybevehicle(n,veh.getNewtaglocation());
        return d;
    }catch(Exception e){
        Maybevehicle notveh=new Maybevehicle("notindb");
        return notveh;
    }
}

}
like image 893
Roro Avatar asked Feb 28 '19 16:02

Roro


1 Answers

So, the Spring application collects metrics on all inbound and outbound API calls. These metrics may be queried to see how many times a certain URL has been called.

In your public Maybevehicle call() method, you are building the url by appending to a String. This will put every URL with a unique rfidtag in its own URI tag bucket.

In order to avoid this problem, you can use a uriVariables map:

String url = “http://url/{rfidtag}”;
Map<String, ?> uriVariables = new HashMap<>();
uriVariables.put(“rfidtag”, veh.getB().getRfidtag();
…
ResponseEntity<Bmwvehiclemain> results = appRestTemplate
        .exchange(url, HttpMethod.GET, requestEntity, Bmwvehiclemain.class, uriVariables);

This lets Spring collect metrics on http://url/{rfidtag} instead of having a URI tag for http://url/rfidtag1, http://url/rfidtag2, http://url/rfidtag3, and so forth.

This should reduce the number of URI tags your application is creating.

The default value for the maximum number of URI tags is 100. If you want metrics on more than that, you can customize it by setting its property value to something else. For example, my Spring application is configured with my projectname-ws/src/main/resources/config/application.yml file. In this file I could put something like

management:
  metrics:
    web:
      client:
        max-uri-tags: 200
      server:
        max-uri-tags: 200

to increase the maximum number of URI tags used for metrics.

If you simply don’t want the Reached the maximum number of URI tags for http.client.requests warning, you can put

@SpringBootApplication(exclude = HttpClientMetricsAutoConfiguration.class)

at the top of whatever class you run your application from which will rid you of the warning message but probably not resolve the underlying issue.

like image 97
Paul Avatar answered Oct 24 '22 03:10

Paul