Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Ribbon

2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

Most people do not understand the knowledge of this "how to use Ribbon" article, so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "how to use Ribbon" article.

Introduction to the basic use of Ribbon

Ribbon is a client-side load balancing tool that encapsulates Netflix Ribbon components and provides client-side load balancing capabilities.

The most important thing to understand Ribbon is to understand the concept of client. The so-called client load balancer tool is different from Nginx (server load balancer). Ribbon is not an independent service and does not store a service list. When you need load balancer, you will obtain the registration service list through the application, and then use the list for load balancing and invocation.

Nginx independent process does load balancing, and forwards requests to different services through load balancing strategy.

Client load balancing, by saving the service list information on the client, and then invoking the load balancing policy to apportion the invocation of different services.

Basic use

There are two ways to load balance Ribbon.

Combine Ribbon+RestTemplate with RestTemplate

Combine with OpenFeign

Core sub-module of Ribbon

Ribbon-loadbalancer: load balancing API that can be used independently or with other modules

Core API of ribbon-core:Ribbon

Order Service Integration Ribbon

Order service invokes commodity service

The configuration process is divided into two steps.

Import ribbon's dependencies in the order service

Org.springframework.cloud spring-cloud-starter-netflix-ribbon

Configure RestTemplate

Order service invokes commodity service

The link that the order service calls the commodity service cannot be written as the ip+ port number, but needs to be written as the service name of the commodity service

Restart order service test load balancer

The process of implementing simple version of Ribbon load balancing

The request sent by RestTemplate is the service name http://nacos-product/product/getProductById/1

Get the RestTemplate of the @ LoadBalanced annotation tag

RestTemplate adds an interceptor to intercept when a http call is made using RestTemplate

According to the service name in url and its own load balancing policy, find an ip+ port number localhost:8802 to be invoked in the service list of ordering service.

Access the target service and get the returned result

The list of services is actually a map

Ribbon load balancing principle [understand] get the RestTemplate of @ LoadBalanced annotation tag.

Ribbon saves the RestTemplate of all @ LoadBalanced annotations to a List collection. The specific source codes are as follows:

@ LoadBalanced@Autowired (required = false) private List restTemplates = Collections.emptyList ()

The specific source code location is in LoadBalancerAutoConfiguration.

RestTemplate adds an interceptor

Interceptor is not a function of Ribbon

RestTemplate adding an interceptor requires two steps, the first is to define an interceptor, and the second is to add the defined interceptor to the RestTemplate.

Define an interceptor

You can intercept requests by implementing the ClientHttpRequestInterceptor API. The source code of this API is as follows:

Public interface ClientHttpRequestInterceptor {/ * implements this method and completes the logical content after intercepting the request within the method. * for ribbon, the operation of selecting a service from the * service cluster according to specific rules and initiating a request to the service is completed in this method. * / ClientHttpResponse intercept (HttpRequest request, byte [] body, ClientHttpRequestExecution execution) throws IOException;}

The corresponding implementation class in ribbon is LoadBalancerInterceptor. The specific source code is as follows:

Public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {private LoadBalancerClient loadBalancer; private LoadBalancerRequestFactory requestFactory; / / omit the constructor code. @ Override public ClientHttpResponse intercept (final HttpRequest request, final byte [] body, final ClientHttpRequestExecution execution) throws IOException {final URI originalUri = request.getURI (); String serviceName = originalUri.getHost (); / * intercept the request and call the loadBalancer.execute () method * to complete the server selection inside the method. Initiates a request to the selected server * and gets the return result. * / return this.loadBalancer.execute (serviceName, requestFactory.createRequest (request, body, execution);}} add interceptor to RestTemplate

RestTemplate inherits InterceptingHttpAccessor and provides methods to acquire and add interceptors in InterceptingHttpAccessor. The specific source code is as follows:

Public abstract class InterceptingHttpAccessor extends HttpAccessor {/ * all interceptors are saved as a List collection. * / private List interceptors = new ArrayList (); / * * set the interceptor. * / public void setInterceptors (List interceptors) {this.interceptors = interceptors;} / * get the current interceptor. * / public List getInterceptors () {return interceptors;} / / omit part of the code.}

With these two methods, we can add the LoadBalancerInterceptor we just defined to the RestTemplate identified by the @ LoadBalanced annotation. The specific source code is as follows (LoadBalancerAutoConfiguration) omit part of the code:

Public class LoadBalancerAutoConfiguration {/ * get all restTemplate * / @ LoadBalanced @ Autowired (required = false) private List restTemplates = Collections.emptyList () with @ LoadBalanced annotation; / * create the implementation class of the SmartInitializingSingleton interface. Spring calls back the afterSingletonsInstantiated () * method of the implementation class after all * singleton Bean initialization is complete. In this method, ribbon's custom interceptor LoadBalancerInterceptor is added for all * RestTemplate identified by the @ LoadBalanced annotation. * / @ Bean public SmartInitializingSingleton loadBalancedRestTemplateInitializer (final List customizers) {return new SmartInitializingSingleton () {@ Override public void afterSingletonsInstantiated () {for (RestTemplate restTemplate: LoadBalancerAutoConfiguration.this.restTemplates) {for (RestTemplateCustomizer customizer: customizers) {customizer.customize (restTemplate);} } / * create a custom Ribbon interceptor LoadBalancerInterceptor * only if there is no spring-retry under the current classpath. * so LoadBalancerInterceptor is the default Ribbon interceptor for * requests. * / @ Configuration @ ConditionalOnMissingClass ("org.springframework.retry.support.RetryTemplate") static class LoadBalancerInterceptorConfig {@ Bean public LoadBalancerInterceptor ribbonInterceptor (LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) {return new LoadBalancerInterceptor (loadBalancerClient, requestFactory);} / * add interceptor specific method. First get the current interceptor collection (List) * then add the loadBalancerInterceptor to the current collection * and finally put the new collection back into the restTemplate. * / @ Bean @ ConditionalOnMissingBean public RestTemplateCustomizer restTemplateCustomizer (final LoadBalancerInterceptor loadBalancerInterceptor) {return new RestTemplateCustomizer () {@ Override public void customize (RestTemplate restTemplate) {List list = new ArrayList (restTemplate.getInterceptors ()); list.add (loadBalancerInterceptor); restTemplate.setInterceptors (list) }}

Now that you know the basics of how ribbon intercepts requests, let's take a look at how Ribbon selects server.

An Overview of the principle of Ribbon selecting server

From the above introduction, we know that ribbon will use LoadBalancerInterceptor as an interceptor to intercept when making a request. The LoadBalancerClient.execute () method is called in the interceptor, and the code for this method is as follows:

@ Overridepublic T execute (String serviceId, LoadBalancerRequest request) throws IOException {/ * the process of creating loadBalancer can be understood as the process of assembling the rules for selecting services (IRule), * list of service clusters (ServerList), verifying service viability (IPing) and other features * (loading the configuration class RibbonClientConfiguration). It should be noted that * this process is not carried out at startup, but will be processed only when a request arrives. * / ILoadBalancer loadBalancer = getLoadBalancer (serviceId); / * * select a specific Server according to ILoadBalancer. * the selection process is based on IRule, IPing, ServerList * as a reference. * / Server server = getServer (loadBalancer); if (server = = null) {throw new IllegalStateException ("No instances available for" + serviceId);} RibbonServer ribbonServer = new RibbonServer (serviceId, server, isSecure (server, serviceId), serverIntrospector (serviceId) .getmetadata (server); return execute (serviceId, ribbonServer, request);}

We know from the code that we first create an ILoadBalancer, which is the core class of Ribbon. It can be understood that it includes the rules of selecting services (IRule), the list of service clusters (ServerList), verifying whether the services are alive (IPing) and so on. At the same time, it also has the ability to select a specific service from the service cluster according to these characteristics. Server server = getServer (loadBalancer); this line of code is to select and give a specific server. Finally, the internal execute method is called, and the method code is as follows (only the core code is retained):

@ Overridepublic T execute (String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) throws IOException {try {/ / initiate calls T returnVal = request.apply (serviceInstance); statsRecorder.recordStats (returnVal); return returnVal;} catch (IOException ex) {statsRecorder.recordStats (ex); throw ex;} catch (Exception ex) {statsRecorder.recordStats (ex); ReflectionUtils.rethrowRuntimeException (ex);} return null;}

Next, take a look at what the request.apply (serviceInstance) method does (in LoadBalancerRequestFactory):

@ Overridepublic ClientHttpResponse apply (final ServiceInstance instance) throws Exception {HttpRequest serviceRequest = new ServiceRequestWrapper (request, instance, loadBalancer); / / omit part of the code. / * to initiate a real request. * / return execution.execute (serviceRequest, body);}

Let's see the principle of the overall process here, and then let's review the whole process with a picture:

First, get the RestTemplate of all @ LoadBalanced annotations (which can be understood as those RestTemplate with Ribbon load balancer enabled), and then add Ribbon's default interceptor LoadBalancerInterceptor to RestTemplate, so that it will intercept when you use RestTemplate to initiate http requests. When a request is initiated, ribbon's default interceptor will first create an ILoadBalancer (including the rules for selecting services (IRule), the list of service clusters (ServerList), verifying whether the service is alive (IPing), and so on. At the code level, it means loading the RibbonClientConfiguration configuration class. Then use ILoadBalancer to select a service from the service cluster, and finally send a request to that service.

Ribbon load balancing rules

Reference: https://www.jianshu.com/p/79b9cf0d0519

Default load balancing rules for Ribbon

According to the above Ribbon principle, we can know that the IRule API is responsible for the implementation of load balancer, as shown below:

The characteristic of the rule name is that AvailabilityFilteringRule filters out the backend Server marked circuit tripped that has been failed to connect, and filters out those highly concurrent backend Server or uses an AvailabilityPredicate to include the logic of filtering server. In fact, it is to check the running status of each server recorded in status. BestAvailableRule selects a minimum concurrent request server, and examines server one by one. If Server is tripped, skip RandomRule and randomly select a ServerResponseTimeWeightedRule that has been discarded. The same WeightedResponseTimeRuleWeightedResponseTimeRule weight is weighted according to the response time, the longer the response time is, the smaller the weight is, and the less likely it is to be selected. RetryRule adds a retry mechanism to the selected load balancing strategy. If the selection of Server is not successful within a configuration period, it has been trying to use subRule to select an available ServerRoundRobinRule polling option, poll index, and select the default load balancing policy of ServerZoneAvoidanceRule corresponding to the index. That is, compound judging the performance of the region where Server is located and the availability of Server, choosing Server, which is similar to polling (RandomRule) in an environment where there is no region.

Where RandomRule stands for random policy, RoundRobinRule for polling policy, WeightedResponseTimeRule for weighted policy, BestAvailableRule for minimum number of requests policy, and so on.

Random source code:

Polling source code:

Modify default custom rules

The default is that polling can be modified to any rule.

Modified to random algorithm

Create a RestTemplate instance with load balancing function

[@ Bean] (https://my.oschina.net/bean)@LoadBalancedpublic RestTemplate restTemplate () {return new RestTemplate ();}

When you use RestTemplate for rest operation, you will automatically use the load balancer policy, and it will add LoadBalancerInterceptor as an interceptor to the RestTemplate. The purpose of this interceptor is to use load balancing.

The polling policy is used by default, and if you want to use other policies, specify the IRule implementation, such as:

[@ Bean] (https://my.oschina.net/bean)public IRule ribbonRule () {return new BestAvailableRule ();}

This approach also works for OpenFeign.

Modified to load balance according to the weight configured by Nacos

Configure the weight of the cluster in nacos

In the project, choose to use NacosRule

Optimization of Hunger loading in Ribbon

Ribbon defaults to lazy loading, which means that the client is created only when the call is made

Ribbon: eager-load: # enable ribbon hunger loading enabled: true # configure user-center to use ribbon hunger load, multiple clients: user-center parameters tuning separated by commas

Mainly adjust the timeout of the request, whether to retry

If the business is not idempotent, it is recommended to turn off the retry: ribbon.MaxAutoRetriesNextServer=0

# the default time for refreshing servelist from the registry is 30 seconds, the timeout for connection per msribbon.ServerListRefreshInterval=15000# request defaults to 1 second, and that for processing msribbon.ConnectTimeout=30000# requests defaults to 1 second Unit msribbon.ReadTimeout=30000# retries all operation requests. If this MaxAutoRetries is not configured, it will not work. Default false#ribbon.OkToRetryOnAllOperations=true# retries for the current instance default ribbon.MaxAutoRetries=1# switch instance retries default 1ribbon.MaxAutoRetriesNextServer=0

If the MaxAutoRetries=1 and MaxAutoRetriesNextServer=1 requests respond within 1 second, try again on the same server for more than 1 second, and if it still times out or fails, request a retry from other services.

Then the timeout of the whole ribbon request process is: ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1)

The above is about the content of this article on "how to use Ribbon". I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report