Micro Service -- Nacos configuration management model

Keywords: Microservices intellij-idea

1. How to start Nacos in IDEA?




2. The Nacos configuration center is down. Can our service still read the configuration information?

You can obtain the configuration information of the configuration center from the memory. After the client obtains the configuration information, it will store a copy of the configuration information in the local memory
Stored locally by Map objects

2.1 long polling

The client sends a request to the Nacos configuration center every 30s to pull the configuration information wait29.5s
When there is no configuration update, the client will wait in the queue of the Nacos server
Send request every XX seconds 👉 Scheduled task scheduling

2.2 how to implement scheduled task scheduling in Java?

2.2.1 scheduled task scheduling for single thread execution

  • Timer object (import java.util.Timer;)
    When creating an object, a thread will be created, and a task queue will be allocated to the thread for sequential execution
  • TimerTask task execution object
package com.jt.common.util;

import java.util.Timer;
import java.util.TimerTask;

/*Single thread timed task tool class*/
public class TimerUtils {
    public static void main(String[] args) {
        //1. Build execution task object
        Timer timer=new Timer();/*When an object is created, a thread is created and a task queue is assigned to the thread*/
        //2. Build task object
        TimerTask task1=new TimerTask() {
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis());
            }
        };
        //3. Perform tasks regularly
        timer.schedule(task1, 1000, 1000);
    }
}

Realization effect

End task

timer.cancle();

  • Defect: cannot execute concurrently, because only one thread executes multiple tasks. Whoever comes first will execute first

2.2.2 multithreaded execution of scheduled tasks

expand
Timer ScheduledExecutorService multi-threaded task scheduling, sending timed heartbeat in the Nacos registry, and configuring the central data to pull regularly
Task scheduling framework quartz

3.Nacos configuration management model - namespace

  • Function of configuration management model: distinguish configuration and manage configuration. You can locate a configuration set through Namespace, group and Data ID

3.1 new namespace


3.2 clone configuration center


3.3 modify the configuration information of dev

3.4 configuring backend yml files

server:
  port: 8082
spring:
  application:
    name: sca-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #If nacos and your service are on the same computer, the default service is local, which can be omitted
      config:
        server-addr: localhost:8848 #Address of configuration center
        file-extension: yml #Add configuration center configuration format
        namespace: 1ec9fffa-c171-458d-815d-502a52daf446 #Specify namespace
logging:
  level:
    com.jt: debug #Configure the log level in com.jt package and sub package. The default is info

public configuration information

dev configuration information

test result

Note: read the configuration center information of the specified namespace, that is, the configuration information of the SCA provider name in dev
If no namespace is specified, it defaults to public space

4.Nacos configuration management model - grouping design

4.1 new group configuration


4.2 configuring the group id

4.3 create a new Controller layer

package com.jt.provider.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RefreshScope
@RestController
public class ProviderCacheController {
    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/provider/cache")
    public String doUseLocalCache(){
        return "useLocalCache'value is   "+useLocalCache;
    }
}

Realization effect

  • ArrayList thread is unsafe
  • Vector thread safe but poor performance pessimistic lock
  • CopyOnWriteArrayList (JDK1.5) guarantees the thread safety lock of the collection
  • mysql uses pessimistic locks

4.4 double check lock mechanism

package com.jt.common.thread;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class SyncTests {

    //private static List<String> cache=new Vector<>();
    //CopyOnWriteArrayList is a thread safe List collection that allows multiple threads to perform concurrent updates, but only one update succeeds
    private static List<String> cache=new CopyOnWriteArrayList<>();//CAS (comparison and exchange)

    //    public synchronized static List<String> selectAll(){
//        if (cache.isEmpty()) {
//              System.out.println("Get Data From Database");
//              List<String> data = Arrays.asList("A", "B", "C");
//              cache.addAll(data);
//        }
//        return cache;
//    }
    public static List<String> selectAll(){
        if(cache.isEmpty()) {//A,B,C,D
            synchronized (cache) {
                if (cache.isEmpty()) {
                    System.out.println("Get Data From Database");
                    List<String> data = Arrays.asList("A", "B", "C");
                    cache.addAll(data);
                }
            }
        }
        return cache;
    }

    public static void main(String[] args) {
        //System.out.println(Thread.currentThread().getName());
        Thread t1=new Thread(){
            @Override
            public void run() {
                System.out.println(selectAll());
            }
        };
        Thread t2=new Thread(){
            @Override
            public void run() {
                System.out.println(selectAll());
            }
        };
        Thread t3=new Thread(){
            @Override
            public void run() {
                System.out.println(selectAll());
            }
        };
        Thread t4=new Thread(){
            @Override
            public void run() {
                System.out.println(selectAll());
            }
        };
        Thread t5=new Thread(){
            @Override
            public void run() {
                System.out.println(selectAll());
            }
        };
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}
//Build a local cache object (based on an object in the jvm to store the data obtained from the database)
    private List<String> cache=new CopyOnWriteArrayList<>();
    @RequestMapping("/provider/cache02")
    public  List<String> doUseLocalCache02(){
        if(cache.isEmpty()){
            synchronized (cache) {
                if (cache.isEmpty()) {//Thread-A,Thread-B,...
                    System.out.println("==Get data from database==");
                    //Suppose that this part of the classification information is obtained from the database, but I don't want to look it up from the database every time I get the classification information
                    List<String> cates = Arrays.asList("Category-A", "Category-B", "Category-C");
                    cache.addAll(cates);
                }
            }
        }
        return cache;
    }//Production level

false in configuration

Realization effect


redis distributed cache
lruCache local cache + distributed cache

5.Nacos configuration management model - reading of shared configuration

5.1 new configuration

5.2 modifying configuration files

5.3 new Conreoller floor

package com.jt.provider.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class ProviderSecretController {
    @Value("${app.secret:123456}")
    private String secret;
    @GetMapping("/provider/doGetSecret")
    public String doGetSecret(){
        return "the secret is"+secret;
    }
}

Realization effect

summary

  • Three elements of configuration management model: namespace (group) (dataId)
  • Why are there shared configurations??? Many configurations have some commonalities
  • How to understand namespaces??? Define the scope of some configurations and manage the configurations by category
  • Why grouping??? Different activities have different configurations in the same environment
  • How to reference shared configurations??? Use shared configurations
  • Premise of thread safety: multiple threads + shared data set + is it atomic operation
  • How to understand double check lock in thread concurrency??? Performance + security
  • CopyOnWriteArrayList thread safe

Posted by tonga on Tue, 26 Oct 2021 01:13:43 -0700