Make writing a habit together! This is the 14th day of my participation in the “Gold Digging Day New Plan · April More Text Challenge”. Click here for more details.
Background the problem
For some mainstream frameworks at present, most of them may choose the architecture of Spring Cloud microservices and extract different modules into independent microservices.
For example, Ruoyi, an open source version of Ruoyi-Cloud, has many microservices.
In the image above, for example, there are seven microservices.
Then there is the problem that if each developer, to run the entire project locally, there must be at least seven JVMS open. That puts a lot of pressure on a programmer’s computer to run seven JVMS at once.
This is really a big problem!! T_T
Don’t panic, let’s figure it out!! ^_^
We had this idea:
1. We can deploy a complete set of Ruoyi-Cloud services in the company’s test environment.
2. Each developer, locally, just runs the microservices he needs to develop.
3. The Ruoyi-Cloud microservice can be loaded onto the company’s test environment when it needs to be moved to another microservice
This idea, is not very diao!!
So the idea is, how do you implement this feature?
To achieve this function, you need to have a deep understanding of the Spring Cloud micro-service system!!
The microservice architecture has a significant effect: we can dynamically add and remove service nodes. These changes do not require our business code to handle the logic, but are managed by the Spring Cloud microservice architecture.
In that case, we have to mention the concept of load balancing,
Baidu encyclopedia is quoted as follows:
Load Balance refers to balancing loads (work tasks) and allocating them to multiple operation units, such as FTP server, Web server, enterprise core application server, and other main task servers, to cooperatively complete work tasks.
In the same way, our service node is the operation unit here!!
Since we have more than one operation unit, then we have to use every operation unit, otherwise you deploy, but not to use, that is a waste of resources!!
Then we make all the operation units available, and this is the role of load balancing!! ^_^
Do not know so parse, big guy, can get (may parse is not very right, do not spray!!)
Since it’s load balancing, right? How does the Spring Cloud system achieve load balancing?
The underlying implementation is today’s leading character, Ribbon.
Ribbon Spring Cloud Ribbon is a set of client load balancing tools based on Netflix Ribbon. It provides the following functions
Load balancing
- Fault tolerance
- Support for multiple protocols (HTTP, TCP, UDP) in asynchronous and reactive models
- Caching and batching
Ok, back to our topic of the day:
How to use Ribbon to achieve collaborative development of Nacos?
Collaborative development description
First look at the architecture diagram:
Here, the problem to be solved is:
API gateway, how to select system, Job, Gen and other services?
System, how to select services such as Job and Gen?
Rewrite the Ribbon’s load balancing policy.
The Ribbon’s load balancing strategy:
- RoundRobinRule (default)
- RandomRule random
- WeightedResponseTimeRule Weighted polling
- .
In microservice development, such as Ruoyi-Cloud development, I develop a System microservice, and other microservices I may deploy on the company server.
There are many people involved in the development of the System service. During gateway route access, there are many instances of the System service. How can we ensure that certain routes are routed to the instance of the current developer?
This is really a big problem, then how do I deal with this problem, don’t panic, and listen to the brothers one way!! ^_^
Rewrite the Ribbon’s load balancing policy as follows:
1. Preferentially request local services
2. If the service is not available locally, you can choose preferred service in the corporate environment.
3. Polls existing services randomly because there is no local service or company service
The final architecture is as follows:
In this way, there is no fear of this problem.
Collaborative development implementation
- The custom
Load Balancing Policy
@slf4j public class CustomNacosRule extends AbstractLoadBalancerRule {/** * public String SERVER_HOST_IP; public CustomNacosRule() { this.SERVER_HOST_IP = IpUtils.getIpAddress(); Log.info (" local service IP {}", SERVER_HOST_IP); } @Autowired private NacosDiscoveryProperties discoveryProperties; @override public void initWithNiwsConfig(IClientConfig IClientConfig) {} /** * This method implements the load balancing policy ** @param key * @return */ @Override public Server choose(Object key) {try {// Priority load balancing IP String priorIp = global.getPriorIP (); BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer(); String serviceName = loadbalancer.getName (); // Obtain the instance name of the current service. / / for nacos client service registry found API NamingService NamingService = discoveryProperties. NamingServiceInstance (); / / all the service Instance through namingService access to current registered List < Instance > allInstances = namingService. GetAllInstances (serviceName); If (CollectionUtils.isEmpty(allInstances)) {log.warn(" No instance in service {}", serviceName); return null; } List<Instance> instanceList = new ArrayList<>(); // (1) for (Instance Instance: AllInstances) {if (StringUtils. EndsWithIgnoreCase (instance. GetIp (), SERVER_HOST_IP)) {the debug (" preferred local service instance - {} ", instance.getInstanceId()); instanceList.add(instance); } } Instance chooseInstance = null; if (instanceList.size() > 0) { chooseInstance = ExtendBalancer.getHostByRandomWeight2(instanceList); return new NacosServer(chooseInstance); } // (2) for (Instance Instance: AllInstances) {if (StringUtils. EndsWithIgnoreCase (instance. GetIp (), priorIp)) {the debug (" preferred IP service instance - {} ", instance.getInstanceId()); instanceList.add(instance); } } if (instanceList.size() > 0) { chooseInstance = ExtendBalancer.getHostByRandomWeight2(instanceList); return new NacosServer(chooseInstance); } / / (3), random IP services if (instanceList. The size () = = 0) {chooseInstance = ExtendBalancer. GetHostByRandomWeight2 (allInstances); The log. The debug (" random service instance - {} ", chooseInstance. GetInstanceId ()); } return new NacosServer(chooseInstance); } catch (NacosException e) { e.printStackTrace(); return null; }}}Copy the code
- Configure the load balancing policy to take effect
@Configuration
@RibbonClients(defaultConfiguration = GlobalRibbonConfig.class)
public class CustomRibbonConfig {
}
Copy the code
@Configuration Public class GlobalRibbonConfig {@bean public IRule getRule() {// Implement a load balancing policy with a weighted local IP address priority return new CustomNacosRule(); }}Copy the code
Ok, approximate implementation, that’s it!! ^_^
Then we can have fun writing code!! ^_^