查看: 1243|回复: 89

[JAVA] BAT架构师大牛分布式数据搜索实战 基于Elasticsearch作底层架构大数量级搜索实战

  [复制链接]

13

主题

142

帖子

851

积分

Kib

Rank: 3Rank: 3

贡献
-79
技术
106
活跃
26
在线时间
2 小时
擅长技术
思科华为
发表于 2019-5-2 09:51:10 | 显示全部楼层 |阅读模式
BAT架构师大牛分布式数据搜索实战 基于Elasticsearch作底层架构大数量级搜索实战

1.JPG

2.JPG

3.JPG


===============课程目录===============


(0);目录中文件数:1个
├─(1) project.zip
(1)\十三章;目录中文件数:2个
├─(2) 13-1 单元测试覆盖率报告.mp4
├─(3) 13-2 线上线下配置分离.mp4
(2)\十二章;目录中文件数:5个
├─(4) 12-1 业务与功能分析设计.mp4
├─(5) 12-2 Logstash应用.mp4
├─(6) 12-3Logstash应用2.mp4
├─(7) 12-4 数据可视化分析.mp4
├─(8) 12-5 数据可视化分析2.mp4
(3)\十四章;目录中文件数:1个
├─(9) 14-1 课程总结.mp4
(4)\第一章;目录中文件数:3个
├─(10) 1-1导学.mp4
├─(11) 1-2 技术选型介绍.mp4
├─(12) 1-3 学习建议.mp4
(5)\第七章;目录中文件数:5个
├─(13) 7-1 功能与分析设计.mp4
├─(14) 7-2 默认排序实现.mp4
├─(15) 7-3 默认排序实现2.mp4
├─(16) 7-4 其他维度排序实现.mp4
├─(17) 7-5 房源信息详情页.mp4
(6)\第三章;目录中文件数:4个
├─(18) 3-1 环境要求.mp4
├─(19) 3-2 后端框架搭建.mp4
├─(20) 3-3 集成单元测试.mp4
├─(21) 3-4 前端集成.mp4
(7)\第九章;目录中文件数:10个
├─(22) 9-1 业务与功能分析.mp4
├─(23) 9-10 基于百度LBS的云麻点3.mp4
├─(24) 9-2 基于ES的地图点聚合1.mp4
├─(25) 9-3 基于ES的地图点聚合2.mp4
├─(26) 9-4 地图鼠标事件应用.mp4
├─(27) 9-5 基于地址获取经纬度的开发实现.mp4
├─(28) 9-6 基于ES的地图查询功能.mp4
├─(29) 9-7 基于ES的视野数据源绑定.mp4
├─(30) 9-8 基于百度LBS的云麻点.mp4
├─(31) 9-9 基于百度LBS的云麻点2.mp4
(8)\第二章;目录中文件数:2个
├─(32) 2-1 需求分析.mp4
├─(33) 2-2 数据库设计.mp4
(9)\第五章;目录中文件数:4个
├─(34) 5-1 业务与功能分析.mp4
├─(35) 5-2 后台登录功能实现.mp4
├─(36) 5-3 权限控制.mp4
├─(37) 5-4 验证失败逻辑处理.mp4
(10)\第八章;目录中文件数:15个
├─(38) 8-1 业务与功能分析.mp4
├─(39) 8-10 搜索引擎2.mp4
├─(40) 8-11 中文分词-问题描述.mp4
├─(41) 8-12 中文分词2.mp4
├─(42) 8-13 Search-as-you-type.mp4
├─(43) 8-14 小区房源统计功能.mp4
├─(44) 8-15 搜索引擎优化.mp4
├─(45) 8-2 ES与MySQL技术选型.mp4
├─(46) 8-3 索引结构设计.mp4
├─(47) 8-4 索引结构设计2.mp4
├─(48) 8-5 索引构建-核心逻辑.mp4
├─(49) 8-6 索引构建-核心逻辑2.mp4
├─(50) 8-7 索引构建3.mp4
├─(51) 8-8 索引构建4.mp4
├─(52) 8-9 搜索引擎1.mp4
(11)\第六章;目录中文件数:14个
├─(53) 6-1 业务与功能分析.mp4
├─(54) 6-10 房源浏览功能实现2.mp4
├─(55) 6-11 房源浏览功能实现3..mp4
├─(56) 6-12 编辑功能实现.mp4
├─(57) 6-13 编辑功能实现2.mp4
├─(58) 6-14 审核功能实现.mp4
├─(59) 6-2 基于七牛云的图片.mp4
├─(60) 6-3 基于七牛云的图片上传2.mp4
├─(61) 6-4 基于七牛云的图片上传3.mp4
├─(62) 6-5 基于七牛云的图片上传4.mp4
├─(63) 6-6 新增房源信息功能实现.mp4
├─(64) 6-7 新增房源信息功能实现2.mp4
├─(65) 6-8 新增房源信息功能实现3.mp4
├─(66) 6-9 房源浏览功能实现.mp4
(12)\第十一章;目录中文件数:7个
├─(67) 11-1 索引结构优化.mp4
├─(68) 11-2 配置优化.mp4
├─(69) 11-3 基于Nginx实现负载均衡.mp4
├─(70) 11-4 安全控制.mp4
├─(71) 11-5 安全控制2.mp4
├─(72) 11-6基于SpringSchedule的监控任务.mp4
├─(73) 11-7 基于SpringMail的报警系统.mp4
(13)\第十章;目录中文件数:9个
├─(74) 10-1 业务与功能分析.mp4
├─(75) 10-2 免注册登录.mp4
├─(76) 10-3 免注册登录2.mp4
├─(77) 10-4 会员中心.mp4
├─(78) 10-5 用户预约功能.mp4
├─(79) 10-6 用户预约功能2.mp4
├─(80) 10-7 经纪人完成预约功能.mp4
├─(81) 10-8 api权限拦截器.mp4
├─(82) 10-9 基于美洽的客服系统.mp4
(14)\第四章;目录中文件数:5个
├─(83) 4-1 架构设计与分层.mp4
├─(84) 4-2 API结构设计.mp4
├─(85) 4-3 API结构设计2.mp4
├─(86) 4-4 API结构设计.mp4
├─(87) 4-5 功能性页面开发.mp4




购买主题 已有 1 人购买  本主题需向作者支付 180 金币 才能浏览

0

主题

481

帖子

3105

积分

论坛贵宾VIP-永久权限

Rank: 8Rank: 8

贡献
-100
技术
0
活跃
175
在线时间
106 小时
发表于 2019-5-2 10:37:42 | 显示全部楼层
11111111111

3

主题

6417

帖子

4万

积分

Cib

Rank: 13Rank: 13Rank: 13Rank: 13

贡献
0
技术
0
活跃
10349
在线时间
393 小时
发表于 2019-5-2 10:50:43 | 显示全部楼层
谢谢分享,和三通IT一起成长。

1

主题

1896

帖子

1万

积分

Nib

Rank: 11Rank: 11Rank: 11Rank: 11

贡献
0
技术
0
活跃
3024
在线时间
144 小时
发表于 2019-5-2 11:02:37 | 显示全部楼层

谢谢分享,和三通IT一起成长。

0

主题

4659

帖子

3万

积分

Cib

Rank: 13Rank: 13Rank: 13Rank: 13

贡献
0
技术
-1
活跃
7262
在线时间
347 小时
发表于 2019-5-2 12:10:21 | 显示全部楼层

11111111111

0

主题

30

帖子

203

积分

论坛贵宾VIP-永久权限

Rank: 8Rank: 8

贡献
0
技术
0
活跃
38
在线时间
3 小时
发表于 2019-5-2 13:29:56 | 显示全部楼层
这个对seo有帮助吗?

0

主题

1656

帖子

1万

积分

Nib

Rank: 11Rank: 11Rank: 11Rank: 11

贡献
0
技术
0
活跃
2510
在线时间
99 小时
发表于 2019-5-2 14:49:54 | 显示全部楼层
(一)可重入性
可重入性描述这样的一个问题:一个线程在持有一个锁的时候,它内部能否再次(多次)申请该锁。如果一个线程已经获得了锁,其内部还可以多次申请该锁成功。那么我们就称该锁为可重入锁。通过以下伪代码说明:

void methodA(){
    lock.lock(); // 获取锁
    methodB();
    lock.unlock() // 释放锁
}

void methodB(){
    lock.lock(); // 获取锁
    // 其他业务
    lock.unlock();// 释放锁
}
1
2
3
4
5
6
7
8
9
10
11
可重入锁可以理解为锁的一个标识。该标识具备计数器功能。标识的初始值为0,表示当前锁没有被任何线程持有。每次线程获得一个可重入锁的时候,该锁的计数器就被加1。每次一个线程释放该所的时候,该锁的计数器就减1。前提是:当前线程已经获得了该锁,是在线程的内部出现再次获取锁的场景

(二)Lock接口,ReentrantLock说明
2.1 Lock接口说明
Modifier and Type        Method        Description
void        lock()        获取锁
void        lockInterruptibly()        除非当前线程被中断,否则获取锁定
Condition        newCondition()        返回绑定到此Lock实例的新Condition实例
boolean        tryLock()        只有在调用时它是空闲的才能获取锁
boolean        tryLock(long time, TimeUnit unit)        如果在给定的等待时间内空闲并且当前线程未被中断,则获取锁
void        unlock()        释放锁
2.2 ReentrantLock实现说明
ReentrantLock是Lock接口的一个实现类。为了演示Lock接口的方法,我们以ReentrantLock作为示例说明。

2.2.1 lock(),unlock()方法说明
该demo模拟电影院的售票情况,tickets总票数。开启了10个窗口售票,售完为止

public class ReentrantLockDemo01 implements Runnable {

    private Lock lock = new ReentrantLock();

    private int tickets = 200;

    @Override
    public void run() {
        while (true) {
            lock.lock(); // 获取锁
            try {
                if (tickets > 0) {
                    TimeUnit.MILLISECONDS.sleep(100);
                    System.out.println(Thread.currentThread().getName() + " " + tickets--);
                } else {
                    break;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); // 释放所
            }
        }
    }

    public static void main(String[] args) {
        ReentrantLockDemo01 reentrantLockDemo = new ReentrantLockDemo01();
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(reentrantLockDemo, "thread" + i);
            thread.start();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2.2.2 lockInterruptibly()方法说明
从Lock的源码可以看出:lockInterruptibly() 抛出中断异常

void lockInterruptibly() throws InterruptedException;
1
在synchronize关键字中,同步代码块发送阻塞的情况,例如:wait(),sleep(),jion()等情况下,可以被中断。中断并不意味着线程已经终止

代码示例如下:

public class ReentrantLockDemo02 implements Runnable {

    private Lock lock = new ReentrantLock();

    @Override
    public void run() {
        try {
            lock.lockInterruptibly();
            System.out.println(Thread.currentThread().getName() + " running");
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getName() + " finished");
            lock.unlock();
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " interrupted");
        }
    }

    public static void main(String[] args) {
        ReentrantLockDemo02 reentrantLockDemo = new ReentrantLockDemo02();
        Thread thread01 = new Thread(reentrantLockDemo, "thread01");
        Thread thread02 = new Thread(reentrantLockDemo, "thread02");
        thread01.start();
        thread02.start();
        thread02.interrupt();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
输出结果:

thread01 running
thread02 interrupted
thread01 finished
1
2
3
从输出结果可以看出,thread01正常结束程序,thread02被中断程序,执行catch中的代码块

2.2.3 tryLock(),tryLock(long time, TimeUnit unit)方法说明
tryLock()方法立刻返回当前获取情况。

tryLock(long time, TimeUnit unit)等待一定的时间,返回获取情况

public class ReentrantLockDemo03 implements Runnable {

    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        try {
            if (lock.tryLock(2, TimeUnit.SECONDS)) {
                System.out.println(Thread.currentThread().getName() + " 获取当前lock锁");
                TimeUnit.SECONDS.sleep(4);
            } else {
                System.out.println(Thread.currentThread().getName()+ " 获取锁失败");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }


    public static void main(String[] args) {
        ReentrantLockDemo03 reentrantLockDemo = new ReentrantLockDemo03();
        Thread thread01 = new Thread(reentrantLockDemo, "thread01");
        Thread thread02 = new Thread(reentrantLockDemo, "thread02");
        thread01.start();
        thread02.start();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2.2.4 newCondition() 方法说明
目前只是对newCondition()使用方式进行说明,没有深入的分析Condition()的实现源码。
Condition的作用是对锁进行更精确的控制。Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。不同的是,Object中的wait(),notify(),notifyAll()方法是和”同步锁”(synchronized关键字)捆绑使用的;而Condition是需要与”互斥锁”/”共享锁”捆绑使用的。

public class ProducerConsumerTest {

    private Lock lock = new ReentrantLock();

    private Condition addCondition = lock.newCondition();

    private Condition removeCondition = lock.newCondition();

    private LinkedList<Integer> resources = new LinkedList<>();

    private int maxSize;

    public ProducerConsumerTest(int maxSize) {
        this.maxSize = maxSize;
    }


    public class Producer implements Runnable {

        private int proSize;

        private Producer(int proSize) {
            this.proSize = proSize;
        }

        @Override
        public void run() {
            lock.lock();
            try {
                for (int i = 1; i < proSize; i++) {
                    while (resources.size() >= maxSize) {
                        System.out.println("当前仓库已满,等待消费...");
                        try {
                            addCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("已经生产产品数: " + i + "\t现仓储量总量:" + resources.size());
                    resources.add(i);
                    removeCondition.signal();
                }
            } finally {
                lock.unlock();
            }

        }
    }

    public class Consumer implements Runnable {

        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            while (true) {
                lock.lock();
                try {
                    while (resources.size() <= 0) {
                        System.out.println(threadName + " 当前仓库没有产品,请稍等...");
                        try {
                            // 进入阻塞状态
                            removeCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 消费数据
                    int size = resources.size();
                    for (int i = 0; i < size; i++) {
                        Integer remove = resources.remove();
                        System.out.println(threadName + " 当前消费产品编号为:" + remove);
                    }
                    // 唤醒生产者
                    addCondition.signal();
                } finally {
                    lock.unlock();
                }
            }

        }
    }

    public static void main(String[] args) throws InterruptedException {
        ProducerConsumerTest producerConsumerTest = new ProducerConsumerTest(10);
        Producer producer = producerConsumerTest.new Producer(100);
        Consumer consumer = producerConsumerTest.new Consumer();
        final Thread producerThread = new Thread(producer, "producer");
        final Thread consumerThread = new Thread(consumer, "consumer");
        producerThread.start();
        TimeUnit.SECONDS.sleep(2);
        consumerThread.start();
    }
}

0

主题

1656

帖子

1万

积分

Nib

Rank: 11Rank: 11Rank: 11Rank: 11

贡献
0
技术
0
活跃
2510
在线时间
99 小时
发表于 2019-5-2 14:50:11 | 显示全部楼层
可重入锁:ReentrantLock理解使用

0

主题

1656

帖子

1万

积分

Nib

Rank: 11Rank: 11Rank: 11Rank: 11

贡献
0
技术
0
活跃
2510
在线时间
99 小时
发表于 2019-5-2 14:50:28 | 显示全部楼层
可重入锁:ReentrantLock理解使用

0

主题

1656

帖子

1万

积分

Nib

Rank: 11Rank: 11Rank: 11Rank: 11

贡献
0
技术
0
活跃
2510
在线时间
99 小时
发表于 2019-5-2 14:50:46 | 显示全部楼层
可重入锁:ReentrantLock理解使用
使用 高级模式(可批量传图、插入视频等)
您需要登录后才可以回帖 登录 | 立即注册

快速回复 返回顶部 返回列表