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