Package org.apache.solr.client.solrj.impl

# Class LBSolrClient

java.lang.Object
org.apache.solr.client.solrj.SolrClient
org.apache.solr.client.solrj.impl.LBSolrClient

All Implemented Interfaces:
  `Closeable`, `Serializable`, `AutoCloseable`

Direct Known Subclasses:
  `LBAsyncSolrClient`

public abstract class LBSolrClient extends SolrClient
This "LoadBalanced Http Solr Client" is a load balancing wrapper around an Http Solr Client. This is useful when you have multiple Solr endpoints and requests need to be Load Balanced among them.

Do NOT use this class for indexing in leader/follower scenarios since documents must be sent to the correct leader; no inter-node routing is done.

In SolrCloud (leader/replica) scenarios, it is usually better to use `CloudSolrClient`, but this class may be used for updates because the server will forward them to the appropriate leader.

It offers automatic failover when a server goes down, and it detects when the server comes back up.

Load balancing is done using a simple round-robin on the list of endpoints. Endpoint URLs are expected to point to the Solr "root" path (i.e. "/solr").

>      SolrClient client = new LBSolrClient.Builder(httpSolrClient,
>              new LBSolrClient.Endpoint("http://host1:8080/solr"), new LBSolrClient.Endpoint("http://host2:8080/solr"))
>          .build();

Users who wish to balance traffic across a specific set of replicas or cores may specify each endpoint as a root-URL and core-name pair. For example:

>      SolrClient client = new LBSolrClient.Builder(httpSolrClient,
>              new LBSolrClient.Endpoint("http://host1:8080/solr", "coreA"),
>              new LBSolrClient.Endpoint("http://host2:8080/solr", "coreB"))
>          .build();

If a request to an endpoint fails by an IOException due to a connection timeout or read timeout then the host is taken off the list of live endpoints and moved to a 'dead endpoint list' and the request is resent to the next live endpoint. This process is continued till it tries all the live endpoints. If at least one endpoint is alive, the request succeeds, and if not it fails.

Dead endpoints are periodically healthchecked on a fixed interval controlled by `LBSolrClient.Builder#setAliveCheckInterval(int, TimeUnit)`. The default is set to one minute.

When to use this?
This can be used as a software load balancer when you do not wish to set up an external load balancer. Alternatives to this code are to use a dedicated hardware load balancer or using Apache httpd with mod_proxy_balancer as a load balancer. See Load balancing on Wikipedia

See Also:
  - Serialized Form

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`static class`
`LBSolrClient.Builder<C extends HttpSolrClientBase>`
`static class`
`LBSolrClient.Endpoint`
A Solr endpoint for `LBSolrClient` to include in its load-balancing
`static class`
`LBSolrClient.EndpointIterator`
`protected static class`
`LBSolrClient.EndpointWrapper`
`static class`
`LBSolrClient.Req`
`static class`
`LBSolrClient.Rsp`

## Nested classes/interfaces inherited from class org.apache.solr.client.solrj.SolrClient

`SolrClient.SolrClientFunction<C extends SolrClient,R>`

## Field Summary

Fields
Modifier and Type
Field
Description
`protected long`
`aliveCheckIntervalMillis`
`protected ResponseParser`
`parser`
`protected RequestWriter`
`requestWriter`
`protected static final Set<Integer>`
`RETRY_CODES`
`protected static final String`
`UPDATE_LIVE_SERVER_MESSAGE`
`protected final Map<String,LBSolrClient.EndpointWrapper>`
`zombieServers`

### Fields inherited from class org.apache.solr.client.solrj.SolrClient

`defaultCollection`

## Constructor Summary

Constructors
Modifier
Constructor
Description
`protected`
`LBSolrClient(List<LBSolrClient.Endpoint> solrEndpoints)`
`protected`
`LBSolrClient(LBSolrClient.Builder<?> builder)`

## Method Summary

Modifier and Type
Method
Description
`void`
`addSolrServer(LBSolrClient.Endpoint endpoint)`
`void`
`close()`
`protected LBSolrClient.EndpointWrapper`
`createServerWrapper(LBSolrClient.Endpoint endpoint)`
`protected Exception`
`doRequest(LBSolrClient.Endpoint baseUrl, LBSolrClient.Req req, LBSolrClient.Rsp rsp, boolean isNonRetryable, boolean isZombie)`
`protected abstract SolrClient`
`getClient(LBSolrClient.Endpoint endpoint)`
`ResponseParser`
`getParser()`
`RequestWriter`
`getRequestWriter()`
`protected void`
`makeServerAZombie(LBSolrClient.Endpoint endpoint)`
`protected Exception`
`makeServerAZombie(LBSolrClient.Endpoint endpoint, Exception e)`
`protected void`
`makeServerAZombie(LBSolrClient.EndpointWrapper wrapper)`
`static String`
`normalize(String server)`
`protected LBSolrClient.EndpointWrapper`
`pickServer(LBSolrClient.EndpointWrapper[] aliveServerList, SolrRequest<?> request)`
Pick a server from list to execute request.
`String`
`removeSolrServer(LBSolrClient.Endpoint endpoint)`
`LBSolrClient.Rsp`
`request(LBSolrClient.Req req)`
Tries to query a live server from the list provided in Req.
`NamedList<Object>`
`request(SolrRequest<?> request, String collection)`
Tries to query a live server.
`NamedList<Object>`
`request(SolrRequest<?> request, String collection, Integer numServersToTry)`
`protected void`
`reviveZombieServer(LBSolrClient.Endpoint endpoint)`
`protected void`
`updateAliveList()`

### Methods inherited from class org.apache.solr.client.solrj.SolrClient

`add, add, add, add, add, add, add, add, add, add, addBean, addBean, addBean, addBean, addBeans, addBeans, addBeans, addBeans, addBeans, addBeans, commit, commit, commit, commit, commit, commit, deleteById, deleteById, deleteById, deleteById, deleteById, deleteById, deleteById, deleteById, deleteByQuery, deleteByQuery, deleteByQuery, deleteByQuery, getById, getById, getById, getById, getById, getById, getById, getById, getContext, getDefaultCollection, optimize, optimize, optimize, optimize, optimize, optimize, ping, ping, query, query, query, query, queryAndStreamResponse, queryAndStreamResponse, queryAndStreamResponse, request, rollback, rollback`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Details

### UPDATE_LIVE_SERVER_MESSAGE

protected static final String UPDATE_LIVE_SERVER_MESSAGE

See Also:
  - Constant Field Values

### RETRY_CODES

protected static final Set<Integer> RETRY_CODES

### zombieServers

protected final Map<String,LBSolrClient.EndpointWrapper> zombieServers

### aliveCheckIntervalMillis

protected long aliveCheckIntervalMillis

### parser

protected volatile ResponseParser parser

### requestWriter

protected volatile RequestWriter requestWriter

## Constructor Details

### LBSolrClient

protected LBSolrClient(LBSolrClient.Builder<?> builder)

### LBSolrClient

protected LBSolrClient(List<LBSolrClient.Endpoint> solrEndpoints)

## Method Details

### updateAliveList

protected void updateAliveList()

### createServerWrapper

protected LBSolrClient.EndpointWrapper createServerWrapper(LBSolrClient.Endpoint endpoint)

### normalize

public static String normalize(String server)

### request

public LBSolrClient.Rsp request(LBSolrClient.Req req) throws SolrServerException, IOException
Tries to query a live server from the list provided in Req. Servers in the dead pool are skipped. If a request fails due to an IOException, the server is moved to the dead pool for a certain period of time, or until a test request on that server succeeds.

Servers are queried in the exact order given (except servers currently in the dead pool are skipped). If no live servers from the provided list remain to be tried, a number of previously skipped dead servers will be tried. Req.getNumDeadServersToTry() controls how many dead servers will be tried.

If no live servers are found a SolrServerException is thrown.

Parameters:
  `req` - contains both the request and the list of servers to query
Returns:
  the result of the request
Throws:
  `IOException` - If there is a low-level I/O error.
  `SolrServerException`

### doRequest

protected Exception doRequest(LBSolrClient.Endpoint baseUrl, LBSolrClient.Req req, LBSolrClient.Rsp rsp, boolean isNonRetryable, boolean isZombie) throws SolrServerException, IOException

Throws:
  `SolrServerException`
  `IOException`

### getClient

protected abstract SolrClient getClient(LBSolrClient.Endpoint endpoint)

### getParser

public ResponseParser getParser()

### getRequestWriter

public RequestWriter getRequestWriter()

### reviveZombieServer

protected void reviveZombieServer(LBSolrClient.Endpoint endpoint)

### makeServerAZombie

protected void makeServerAZombie(LBSolrClient.EndpointWrapper wrapper)

### makeServerAZombie

protected void makeServerAZombie(LBSolrClient.Endpoint endpoint)

### makeServerAZombie

protected Exception makeServerAZombie(LBSolrClient.Endpoint endpoint, Exception e)

### addSolrServer

public void addSolrServer(LBSolrClient.Endpoint endpoint)

### removeSolrServer

public String removeSolrServer(LBSolrClient.Endpoint endpoint)

### request

public NamedList<Object> request(SolrRequest<?> request, String collection) throws SolrServerException, IOException
Tries to query a live server. A SolrServerException is thrown if all servers are dead. If the request failed due to IOException then the live server is moved to dead pool and the request is retried on another live server. After live servers are exhausted, any servers previously marked as dead will be tried before failing the request.

Specified by:
  `request` in class `SolrClient`
Parameters:
  `request` - the SolrRequest.
  `collection` - the collection to execute the request against
Returns:
  response
Throws:
  `IOException` - If there is a low-level I/O error.
  `SolrServerException` - if there is an error on the server

### request

public NamedList<Object> request(SolrRequest<?> request, String collection, Integer numServersToTry) throws SolrServerException, IOException

Throws:
  `SolrServerException`
  `IOException`

### pickServer

protected LBSolrClient.EndpointWrapper pickServer(LBSolrClient.EndpointWrapper[] aliveServerList, SolrRequest<?> request)
Pick a server from list to execute request. By default, servers are picked in round-robin manner, custom classes can override this method for more advance logic

Parameters:
  `aliveServerList` - list of currently alive servers
  `request` - the request will be sent to the picked server
Returns:
  the picked server

### close

public void close()