• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Zookeeper 4 Zookeeper JavaAPI 操作 4.9 模拟12306 售票案例

武飞扬头像
Ding Jiaxiong
帮助1

Zookeeper

【黑马程序员Zookeeper视频教程,快速入门zookeeper技术】

4 Zookeeper JavaAPI 操作

4.9 模拟12306 售票案例

4.9.1 Curator 实现分布式锁 API

在Curator中有五种锁方案:

  • InterProcessSemaphoreMutex:分布式排它锁(非可重入锁)
  • InterProcessMutex:分布式可重入排它锁
  • InterProcessReadWriteLock:分布式读写锁
  • InterProcessMultiLock:将多个锁作为单个实体管理的容器
  • InterProcessSemaphoreV2:共享信号量
4.9.2 分布式锁案例 - 模拟12306 售票

学新通

平时我们 用这些,它们其实都不是 真正出票 的,它们只是代理商

12306 才是真正的出票 的

学新通

12306 不多解释,那个请求量,单机…,肯定会搭 集群的

学新通

代理商访问 12306, 然后12306 访问自己的 数据库【当然数据库 也会做成集群,对外访问接口一个】

资源在谁那儿,分布式锁 就加到 谁那儿,所以肯定是在 12306 上加

学新通

引入Zookeeper 后,12306 就可以作为 Zookeeper 的客户端 【分布式锁 由Zookeeper 提供】

【简单模拟】

先来一个票类

package com.dingjiaxiong.curator;

/**
 * ClassName: Ticket12306
 * date: 2022/11/15 15:18
 *
 * @author DingJiaxiong
 */


public class Ticket12306 implements Runnable{

    private int tickets = 10; //数据库的票数

    @Override
    public void run() {

        //一直对外提供服务
        while (true){
            if (tickets > 0){

                System.out.println(Thread.currentThread()   ":"   tickets);
                tickets --;
            }
        }

    }
}

来一个 新的测试类

package com.dingjiaxiong.curator;

/**
 * ClassName: LockTest
 * date: 2022/11/15 15:17
 *
 * @author DingJiaxiong
 */


public class LockTest {

    public static void main(String[] args) {

        Ticket12306 ticket12306 = new Ticket12306();

        //创建客户端【买票的】
        Thread t1 = new Thread(ticket12306,"携程");
        Thread t2 = new Thread(ticket12306,"飞猪");

        t1.start();
        t2.start();
    }
}

现在直接运行就会 产生 并发问题,看看结果

学新通

很明显这样是不行的

【现在就给 它加上分布式 锁】

package com.dingjiaxiong.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.concurrent.TimeUnit;

/**
 * ClassName: Ticket12306
 * date: 2022/11/15 15:18
 *
 * @author DingJiaxiong
 */


public class Ticket12306 implements Runnable {

    private int tickets = 10; //数据库的票数

    private InterProcessMutex lock;

    public Ticket12306() {

        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);

        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("zookeeper的IP :2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .build();

        client.start();

        lock = new InterProcessMutex(client, "/lock");
    }

    @Override
    public void run() {

        //一直对外提供服务
        while (true) {
            //加个【获取】锁
            try {
                lock.acquire(3, TimeUnit.SECONDS);
                if (tickets > 0) {

                    System.out.println(Thread.currentThread()   ":"   tickets);
                    tickets--;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 释放锁
                try {
                    lock.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

OK,直接重新运行测试类

学新通

这下就不会 冲了

看看命令行 客户端

学新通

多看几次

学新通

就是我们 之前说的 使用临时顺序节点实现的东西

【那就这样吧】

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgackej
系列文章
更多 icon
同类精品
更多 icon
继续加载