Lock: we have contacted in multithreading. The function is to prevent the current resources from being accessed by other threads! My diary can't be seen by others. So lock it in the safe
When I open the lock and take away the diary, others can use the safe
The "herding effect" caused by using traditional locks in zookeeper: 1000 people create nodes, only one person can succeed, and 999 people need to wait!
Sheep are a very scattered organization. Usually, they rush left and right blindly together, but once one sheep moves, the other sheep will rush up without thinking, regardless of the wolves nearby and the better grass not far away. Herding is a metaphor that people have a herd mentality. Herd mentality can easily lead to blind obedience, and blind obedience often falls into scams or fails.
Avoid "herding" and zookeeper uses distributed locks
- All requests come in and create a temporary order node under / lock. Rest assured that zookeeper will help you number and sort
- Determine whether you are the smallest node under / lock
- Yes, acquire lock (create node)
- No, listen to the nodes at the ego level in front
- Obtain the lock request, process the business logic, release the lock (delete the node), and the latter node is notified (the younger one dies, and you} become the youngest)
- Repeat step 2
1. Implementation steps
1.1 initializing the database
Create the database zkproduct and use the default character set utf8
-- Commodity list create table product( id int primary key auto_increment, -- Item number product_name varchar(20) not null, -- Trade name stock int not null, -- stock version int not null -- edition ) insert into product (product_name,stock,version) values('lucky charm-empty cart -a grand prix',5,0)
-- Order form create table `order`( id varchar(100) primary key, -- Order No pid int not null, -- Item number userid int not null -- User number )
1.2 erection works
Set up the ssm framework, for inventory table - 1 and order table + 1
See github for specific code
1.3 start up test
- Start two projects with port numbers 8001 and 8002 respectively
- Using nginx for load balancing
1.3 use JMeter} to simulate sending 10 http requests within 1 second
Download address: http://jmeter.apache.org/download_jmeter.cgi
- Check the test results and all 10 requests are successful
- Check the database, and the stock becomes - 5 (data result error caused by concurrency)
1.4 zookeeper client provided by apahce
It is very troublesome to implement distributed client class based on zookeeper's original ecology. We use apahce to provide a zookeeper} client to implement it
Curator: h ttp://curator.apache.org/
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> <!-- Netizens voted the most awesome version --> </dependency>
recipes is a complete collection of curator genealogy, which includes zookeeper and framework
1.5 add the logic code of distributed lock in the control layer
@Controller public class ProductAction { @Autowired private ProductService productService; private static String connectString = "192.168.204.141:2181,192.168.204.142:2181,192.168.204.143:2181"; @GetMapping("/product/reduce") @ResponseBody public Object reduce( int id) throws Exception { // Retry strategy (try once in 1000 milliseconds, up to 3 times) RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); //1. Create curator tool object CuratorFramework client= CuratorFrameworkFactory.newClient(connectString, retryPolicy); client.start(); //2. Create an "internal mutex" based on the tool object InterProcessMutex lock = new InterProcessMutex(client, "/product_"+id); try { //3. Lock lock.acquire(); productService.reduceStock(id); }catch(Exception e){ if(e instanceof RuntimeException){ throw e; } }finally{ //4. Release the lock release(); } return "ok"; } }
Test again and solve the concurrency problem!
Excerpt from hook education JAVA series courses