There are two ways to design software: one is to make the software too simple and obviously free from defects; the other is to make the software too complex and free from obvious defects.
->Return to Column Directory <-
Code download address: https://github.com/f641385712/netflix-learning
Catalog
Preface
The last article introduced Ribbon as a whole, and my little buddy may have the same feeling as me: knowing what Ribbon is about is big, just understanding the status, not being down-to-earth.The advantage of Java libraries is that they are open source, which greatly reduces the difficulty of learning (you can grasp them as a whole from the design context without relying on memory alone).
From the beginning of this article, Ribbon will start from API source, with examples to explain, one by one way to crack, step by step, a comprehensive analysis of Ribbon.Because Ribbon won't find an alternative technology for a while, and there is little information to learn about it in China, I hope this series of articles will help you.
text
ribbon-core is Ribbon's core package on which any other package depends.The Jar package only defines a public API and does not work on its own, so you can think of it as a public abstraction.
<dependency> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-core</artifactId> <!-- Version number is 2 as specified above.3.0 Version, keep and Spring Cloud Dependency Consistency --> <version>${ribbon.version}</version> </dependency>
As you can see from the diagram, there is no concept of load balance in the core package, nor is there any concept of http in it, so core is a highly abstract package: independent of lb and protocol.
Note: Ribbon's source code has a specification for naming classes - > Interfaces must start with I, such as IClient, followed by IRule, IPing, etc.
IClient
Ribbon needs to be able to send requests in order to load balance, and this is its most core interface, around which all other components are designed and built, including LB.
The interface represents a client that can execute a single Request: send a Request request Request, get a Response response, and note that no protocol is bound (http, tcp, udp, file protocol, local calls are all broadband).
public interface IClient<S extends ClientRequest, T extends IResponse> { // Execute the request and return the response public T execute(S request, IClientConfig requestConfig) throws Exception; }
There are no implementations of this interface in the core package, as follows under Spring Cloud:
ClientRequest
Represents a generic client request object that applies to all communication protocols.The object is immutable.
public class ClientRequest implements Cloneable { // Requested URI protected URI uri; protected Object loadBalancerKey = null; // Is it retryable?true: the request can be retried false: the request cannot be retried protected Boolean isRetriable = null; // Outside incoming configurations can override the built-in IClientConfig configurations protected IClientConfig overrideConfig; ... // Omit various constructors ... // Live various get methods.Note: There is no set method because the instance is immutable // Determine if the request can be retried (important) public boolean isRetriable() { return (Boolean.TRUE.equals(isRetriable)); } ... // Create a ** new ** ClientRequest with a new URI // It clones a new ClientRequest(this) new instance using the clone method first // Subclass replication is recommended to provide more effective implementation. public ClientRequest replaceUri(URI newURI) { ClientRequest req; try { req = (ClientRequest) this.clone(); } catch (CloneNotSupportedException e) { req = new ClientRequest(this); } req.uri = newURI; return req; } }
There are no subclasses in the core package.The inheritance map under Spring Cloud is as follows:
IResponse
Client Framework Response Interface, please note that it is an interface and Request request is a class.
public interface IResponse extends Closeable { // Get entities from the response.If it's the Http protocol, it's the Body body // Payload is the only name here because it's not related to the protocol public Object getPayload() throws ClientException; public boolean hasPayload(); // True if the response is considered successful, for example, 200 response codes for the http protocol. public boolean isSuccess(); public URI getRequestedURI(); // Response Headers public Map<String, ?> getHeaders(); }
Small details: This interface is not like getStatus'way of getting response status codes because it is not related to the protocol and response status codes are exclusive to Http.
There is no implementation of this interface in the core package, as in Spring Cloud:
Local Test Environment Setup
Based on the principle that the main method is the entry to all programs, that any component can be tested locally, and that Ribbon's core design is protocol independent, the instructions on Ribbon's core are done using unit tests (non-integrated tests), which I believe will help you learn load balancing even more.
Description: This environment builds tests that focus on the core part, namely ribbon-core and ribbon-loadbalancer, because they are both protocol inertia-free and network inertia-free, so they can be tested locally and everything can be tested.
- Customize MyClient implementation
/** * A Client without Load Balancing * * @author yourbatman * @date 2020/3/14 22:09 */ public class MyClient implements IClient<ClientRequest, MyResponse> { @Override public MyResponse execute(ClientRequest request, IClientConfig requestConfig) throws Exception { MyResponse response = new MyResponse(); response.setRequestUri(request.getUri()); return response; } }
- Customize MyResponse Implementation
public class MyResponse implements IResponse { private URI requestUri; public void setRequestUri(URI requestUri) { this.requestUri = requestUri; } @Override public Object getPayload() throws ClientException { return "ResponseBody"; } @Override public boolean hasPayload() { return true; } // Always Success @Override public boolean isSuccess() { return true; } @Override public URI getRequestedURI() { return requestUri; } @Override public Map<String, ?> getHeaders() { return null; } @Override public void close() throws IOException { } }
- The most basic test case showcase:
@Test public void fun1() throws Exception { // client Configuration IClientConfig clientConfig = DefaultClientConfigImpl.getClientConfigWithDefaultValues("YourBatman"); // Client client, used to send requests (using ClientConfig configuration) // Because wood has LB function, it doesn't matter if you want IClientConfig or not MyClient client = new MyClient(); // Execute the request and get a response MyResponse response = client.execute(createClientRequest(), null); System.out.println(response.isSuccess()); }
Console output: true.This is the simplest local test environment where you will expand more test case s later
Configure key management
As an open source library, you need to use configuration to improve its flexibility, so Ribbon also has its own set of configuration management, with its core API documented in the core package.It needs to manage a large number of recognized configuration keys, which is how Robbon manages keys.
IClientConfigKey
Used to define the key used by IClientConfig, note that it is only a key, not a k-v.
// Note: Generic interfaces public interface IClientConfigKey<T> { // String representation for Hash public String key(); // Types of key s, such as Integer.class // If not specified, it is automatically determined by the generic type public Class<T> type(); }
A simple and crude understanding of this interface: it means the same thing as a normal Object key.It has a subclass: CommonClientConfigKey, which records some common keys (too many, 40 +).
CommonClientConfigKey
It is an abstract class, so IClientConfigKey appears as its anonymous subclass.
public abstract class CommonClientConfigKey<T> implements IClientConfigKey<T> { public static final IClientConfigKey<String> AppName = new CommonClientConfigKey<>("AppName"){}; public static final IClientConfigKey<String> Version = new CommonClientConfigKey<>("Version"){}; public static final IClientConfigKey<Integer> Port = new CommonClientConfigKey<>("Port"){}; ... // Because there are so many, public static final IClientConfigKey<Integer> ConnectTimeout = new CommonClientConfigKey<Integer>("ConnectTimeout"){}; public static final IClientConfigKey<Integer> ReadTimeout = new CommonClientConfigKey<Integer>("ReadTimeout"){}; ... // Because there are so many, // This key is used the most: specify the Server address in the form of configuration (you can specify more than one) public static final IClientConfigKey<String> ListOfServers = new CommonClientConfigKey<String>("listOfServers") {}; }
Description: The meaning of configuration is an integral part of any program, so what exactly does each key mean?What is the default value?What is the effect?This is explained specifically in the Configuration section topics that follow
This class maintains many constants of public static s internally so that they can be used directly outside.But no amount of it can cover all of it, so this class also provides a way to customize how key s are constructed:
CommonClientConfigKey: // Create an IClientConfigKey instance from the string name public static IClientConfigKey valueOf(final String name) { // First check the keys cache to see if it already exists and return directly if it already exists for (IClientConfigKey key: keys()) { if (key.key().equals(name)) { return key; } } // If not, create a new return return new IClientConfigKey() { @Override public String key() { return name; } @Override public Class type() { return String.class; } }; }
Expenditure here is a small "Bug": The newly created key is not put in the cache, is it actually better to put it in??
Example
@Test public void fun1() { IClientConfigKey key1 = CommonClientConfigKey.valueOf("YourBatman"); IClientConfigKey key2 = CommonClientConfigKey.valueOf("YourBatman"); System.out.println(key1.key()); System.out.println(key1 == key2); }
Console Output:
YourBatman
false
Visibly, key s of the same String type are built twice, resulting in two different instances of IClientConfigKey, which is not memory friendly most of the time, which is why I think it's a small "bug" above.
summary
This paper introduces the core API: IClient in ribbon-core package, and establishes a local test environment, which provides basic support for the subsequent addition of load balancing logic.Additionally, we know that Ribbon manages keys using the IClientConfigKey interface abstraction and manages 40+ commonly used keys that are internally identifiable for ease of use using CommonClientConfigKey.
The first part of the core API for ribbon-core begins with this and continues below.
statement
The original is not easy, the code is not easy. Thank you for your compliment, collection and attention.Sharing this article with your circle of friends is allowed, but you refuse to copy it.You can also invite you to join my family of Java engineers and architects to learn and communicate.
- [Enjoy Netflix]1, Apache Commons Configuration: Configuration Management Specialist near you
- [Enjoy Netflix]2. Apache Commons Configuration event monitoring mechanism and hot update using ReloadingStrategy
- [Enjoy Netflix]3. Apache Commons Configuration 2.x New Event-Listening Mechanism
- [Enjoy Netflix]4, Apache Commons Configuration 2.x File Locator and FileHandler
- [Enjoy Netflix] Five, Apache Commons Configuration 2.x Different Builder Mode: Configuration Builder
- [Enjoy Netflix]6, Apache Commons Configuration 2.x Quick Build Tools Parameters and Configurations
- [Enjoy Netflix] 7. How does Apache Commons Configuration 2.x achieve hot loading/hot updating of files?
- What are the differences between Apache Commons Configuration 2.x and Enjoy Netflix 1.x?
- [Enjoy Netflix]9, Archaius Configuration Management Library: First Experience and Basic API Details
- [Enjoy Netflix]10. Archaius's Extended Implementation of Configuration, the Core API for Commons Configuration
- [Enjoy Netflix] 11, Archaius Configuration Manager and Dynamic Property Support
- [Enjoy Netflix]12, Archaius Dynamic Attribute DynamicProperty Principle Detailed (Important)
- [Enjoy Netflix]13, Archaius Attribute Abstract Property and ProertyWrapper Details
- [Enjoy Netflix] 14. How does Archaius provide configuration support for multi-environment, multi-region, and multi-cloud deployments?
- Integration of [Enjoy Netflix] 15, Archaius and Spring Cloud: spring-cloud-starter-netflix-archaius
- [Enjoy Netflix]16, Hystrix Circuit Breaker: First Experience and Introduction to RxJava
- [Enjoy Netflix]17, Hystrix attribute abstraction and Archaius integration for configuration externalization and dynamic
- [Enjoy Netflix]18, Hystrix Configuration: Global Configuration and Instance Configuration
- [Enjoy Netflix]19, Hystrix plug-in mechanism: SPI interface introduction and HystrixPlugins details
- [Enjoy Netflix]20, Hystrix Cross-Thread Data Transfer Solution: HystrixRequestContext
- [Enjoy Netflix]21, Hystrix Indicator Data Collection (Preheating): Sliding Window Algorithm (with code examples)
- [Enjoy Netflix] 22. Hystrix Event Source and Event Flow: HystrixEvent and HystrixEventStream
- [Enjoy Netflix] 23, Hystrix bucket counter: BucketedCounterStream
- [Enjoy Netflix] 24, Hystrix statistics in sliding window: BucketedRollingCounterStream, HealthCountsStream
- [Enjoy Netflix]25, Hystrix Cumulative Statistics Flow, Distribution Flow, Maximum Concurrent Flow, Configuration Flow, Function Flow (with code examples)
- [Enjoy Netflix] 26, Hystrix Indicator Data Collector: HystrixMetrics (data source of HystrixDashboard)
- [Enjoy Netflix] 27. What is Hystrix half-open?HystrixCircuitBreaker Details
- [Enjoy Netflix]28, Hystrix Event Counts and Execution Result
- [Enjoy Netflix]29, Hystrix Executable, HystrixObservable and HystrixInvokableInfo
- [Enjoy Netflix]30, Hystrix fallback/demotion logic source interpretation: getFallback OrThrowException
- [Enjoy Netflix]31, Hystrix triggers fallback demotion logic 5 cases and code examples
- [Enjoy Netflix] 32. Why doesn't Hystrix trigger a melt when it throws a HystrixBadRequestException exception?
- [Enjoy Netflix]33. How do Hystrix call thread pool resources when it executes the target method?
- [Enjoy Netflix]34, Hystrix Target Method Execution Logical Source Interpretation: executeCommandAndObserve
- [Enjoy Netflix] 35, Hystrix execution process master set: AbstractCommand detailed
- [Enjoy Netflix]36, Hystrix Request Command: HystrixCommand and HystrixObservableCommand
- Introduction to Source Ribbon - Client Load Balancer