spring-cloud-commons icon indicating copy to clipboard operation
spring-cloud-commons copied to clipboard

Wish for a way to set the state of `ServiceInstance` to implement stateful `LoadBalancer`

Open jizhuozhi opened this issue 3 years ago • 6 comments

Is your feature request related to a problem? Please describe. I would like to have a more general and efficient way to set the state of ServiceInstance.

Describe the solution you'd like And two methods to ServiceInstance interface, to get and set the value of state with given name

	default Map<String, Object> getStates() {
		return Collections.emptyMap();
	}

Additional context

There are too many load balancing algorithms besides RoundRobin and Random, and some of them are stateful.

Before now I have an opened PR to implement WeightedLoadBalancer (#1111). In this PR, I added a method to the interface to get and record the current weight, but other algorithms can't always record the state this way. And now I want to implement some performance-directed load balancing algorithms that rely on the past performance state of the instance, and some load balancing algorithms may rely on multi-dimensional state.

In order to implement these load balancing algorithms, I would like to have a more general and efficient way to set the state.

jizhuozhi avatar May 23 '22 11:05 jizhuozhi

Hello, @jizhuozhi - there already is a place where instance state is being kept - it's the metadata map. While we could imagine setting state programmatically in a number of formats, any state that we want to put into a service instance must be transferrable back and forth while updating and retrieving instances in Service Discovery. Therefore, a format that will be supported by a number of Service Registry solutions available in the market must be used. The metadata filled is such a data container with existing service registry support.

OlgaMaciaszek avatar Jun 10 '22 16:06 OlgaMaciaszek

In my opinion, all client-side instances are copies of the data in the registry, and the data obtained from the registry must retain the original snapshot and be immutable throughout the life cycle of the instance. So I need to avoid modifying these copies.

But the state context is different. It represents the different states of the current instance at different times in the entire life cycle of the client. It is strongly related to the client, and the instance can reset its state at any time. without considering possible inconsistencies with other clients.

jizhuozhi avatar Jun 10 '22 17:06 jizhuozhi

This is the problem I expressed, what I need is a way to record the state of the instance on the client side, not a global state that requires constant interaction with the registry.

jizhuozhi avatar Jun 10 '22 17:06 jizhuozhi

@jizhuozhi, please provide more details on what client-specific state you would like to store here.

OlgaMaciaszek avatar Jun 13 '22 11:06 OlgaMaciaszek

@jizhuozhi, please provide more details on what client-specific state you would like to store here.

For example, #1111 using currentWeight to hold the dynamic priority and the currentWeight is updated each time choose is called. And in the future, I will implement a dynamic load balancer named EwmaLoadBalancer which using the moving average of latency related with service instance.

They have the common characteristic that they are dynamic, non-global, client-specific.

jizhuozhi avatar Jun 15 '22 06:06 jizhuozhi

Hi, @OlgaMaciaszek . The newlest implementation stores instance-related state in the context where the state needs to be used (such as load balancing), but I still think it makes sense to store generalized state to the instance.

Storing the state separately from the instance will bring additional life cycle management problems. When the instance ends its life cycle due to factors such as caching, the state of the independent storage cannot be cleaned up on time, and there is a potential risk of memory leaks.

jizhuozhi avatar Jul 28 '22 03:07 jizhuozhi

I think this should be considered based on specific use-cases and possibly implemented as specialised subclasses on a use-case-to-use-case basis, such as the WeightedServiceInstance that's being discussed in https://github.com/spring-cloud/spring-cloud-commons/pull/1111.

OlgaMaciaszek avatar Aug 31 '22 12:08 OlgaMaciaszek