简栈文化

Java技术人的成长之路~


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

四张图带你了解Tomcat系统架构

发表于 2020-06-04 | 更新于: 2020-08-02 | 分类于 Tomcat
俗话说,站在巨人的肩膀上看世界,一般学习的时候也是先总览一下整体,然后逐个部分个个击破,最后形成思路,了解具体细节,Tomcat的结构很复杂,但是 Tomcat 非常的模块化,找到了 Tomcat最核心的模块,问题才可以游刃而解,了解了Tomcat的整体架构对以后深入了解Tomcat来说至关重要! 一、Tomcat顶层架构先上一张Tomcat的顶层结构图(图A),如下: Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务。 Service主要包含两个部分:Connector和Container。从上图中可以看出 Tomcat 的心脏就是这两个组件,他们的作用如下: 1、Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转化; 2、Container用于封装和管理Servlet,以及具体处理Request请求; 一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但是 ...
阅读全文 »

神器的布隆过滤器

发表于 2020-06-03 | 更新于: 2020-08-02 | 分类于 布隆过滤器 , Redis
什么是布隆过滤器本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。 相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。 实现原理HashMap 的问题讲述布隆过滤器的原理之前,我们先思考一下,通常你判断某个元素是否存在用的是什么?应该蛮多人回答 HashMap 吧,确实可以将值映射到 HashMap 的 Key,然后可以在 O(1) 的时间复杂度内返回结果,效率奇高。但是 HashMap 的实现也有缺点,例如存储容量占比高,考虑到负载因子的存在,通常空间是不能被用满的,而一旦你的值很多例如上亿的时候,那 HashMap 占据的内存大小就变得很可观了。 还比如说你的数据集存储在远程服务器上,本地服务接受输入,而数据集非常大不可能一次性读进内存构建 HashMap 的时候,也会存在问题。 布隆过滤器数据结构 布隆过滤器是一个 bit 向量或者说 bit 数组,长这样: 数组 ...
阅读全文 »

你是否真的能把单例模式给写好?

发表于 2020-06-02 | 更新于: 2020-08-02 | 分类于 Java
当你看到这个标题的时候,以为我是一个标题党?(其实也是…) 但是你真的不能小瞧这个单例模式,不信的话,你可以继续往下看。 小白些单例模式1234567891011121314151617181920212223/** * Created with vernon-test * * @description: 设计模式-单例模式 * @author: chenyuan * @date: 2020/6/7 * @time: 9:25 PM */public class Singleton { private static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); System.out.println("我开始new对象了~ ...
阅读全文 »

分布式锁用Redis还是Zookeeper?

发表于 2020-06-01 | 更新于: 2020-08-02 | 分类于 Java
为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景。 为什么用分布式锁?系统 A 是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。 由于系统有一定的并发,所以会预先将商品的库存保存在 Redis 中,用户下单的时候会更新 Redis 的库存。 此时系统架构如下: 但是这样一来会产生一个问题:假如某个时刻,Redis 里面的某个商品库存为 1。 此时两个请求同时到来,其中一个请求执行到上图的第 3 步,更新数据库的库存为 0,但是第 4 步还没有执行。 而另外一个请求执行到了第 2 步,发现库存还是 1,就继续执行第 3 步。这样的结果,是导致卖出了 2 个商品,然而其实库存只有 1 个。 很明显不对啊!这就是典型的库存超卖问题。此时,我们很容易想到解决方案:用锁把 2、3、4 步锁住,让他们执行完之后,另一个线程才能进来执行第 2 步。 按照上面的图,在执行第 2 步时,使用 Java 提供的 Synchronized 或者 ReentrantLock 来锁住,然后在第 4 步执行完之 ...
阅读全文 »

Linux Rsync 增量同步与快速删除

发表于 2020-05-15 | 更新于: 2020-08-02 | 分类于 Linux
增量同步rsync [args] SRC [DEST]情形:同时维护着两份不同的data_center,但以old_data_center为标准。因为权限的缘故没有开启rsync自动同步,只是每隔一段时间手动同步一下。SRC和DEST都是采用mount形式,如果每一次都完整地copy,耗时很长,这时候就想到采用增量同步的方法,因为两份data_center同时由不同人维护,所以内容略有不同,data_center同步的时候不光要完全同步old_data_center的所有内容,而且要删除自身多余的内容,保持完全一致。 123rsync -a --delete --progress /old_vip_data_center/test_envs/trainer/resource /vip_data_center/test_envs/trainer/resource/ –delete: 删除DEST端存在但是SRC端不存在的文件,如果不使用此参数,则DEST端会同步SRC端的文件,但DEST端已有的文件不受影响。 快速删除大量文件 先建一个空目录,随便位置 1mkdir /local/e ...
阅读全文 »

JVM深入理解-内存调优与GC日志

发表于 2020-05-14 | 更新于: 2020-12-29 | 分类于 Java
CPU飚高分析一般可以使用 ps -Lfp pid ps -mp pid -o THREAD, tid, time top -Hp pid 12345678910[root@redis webapps]# top -Hp 22272top - 10:09:30 up 9 days, 22:10, 1 user, load average: 0.00, 0.00, 0.00Tasks: 30 total, 0 running, 30 sleeping, 0 stopped, 0 zombieCpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%stMem: 3923196k total, 3795588k used, 127608k free, 153056k buffersSwap: 6160376k total, 0k used, 6160376k free, 3079244k cached PID USER PR ...
阅读全文 »

JSR269插件化注解API

发表于 2020-05-13 | 更新于: 2020-08-03 | 分类于 Java
背景一直在使用Lombok以及MapStruct,但是对于它们能够在编译阶段直接生成实例代码却没有仔细了解过。最近刚好在部门内做了一次分享,也在这里对具体原理做一个详细阐述。 Lombok以及MapStruct实现大体思路Lombok以及MapStruct都是通过在目标代码上标记注解,编译器能够根据注解生成对应的实现代码。比如Lombok在属性上标记@Getter,那么在这个Java Bean内就会生成对应属性的get方法。 本质上来说,不管是Lombok或者MapStruct,都是通过Java的一个标准API来实现的;这个API即为Pluggable Annotation Processing API,简称为JSR269。 JSR269借用JSR269官方原文定义(附带原文地址:https://jcp.org/en/jsr/detail?id=269): J2SE 1.5 added a new Java language mechanism “annotations” that allows annotation types to be used to annotate clas ...
阅读全文 »

Hello World调试Hotspot

发表于 2020-05-12 | 更新于: 2020-08-02 | 分类于 JDK
本地安装GDB12345678brew install gdb➜ ~ gdb --versionGNU gdb (GDB) 9.1Copyright (C) 2020 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. 除了这个,在Mac系统系统里面还要配置证书相关的操作。 按入下步骤创建代码签名的证书: 打开 Keychain Access 应用程序(/Applications/Utilities/Keychain Access.app) 执行菜单 钥匙串访问 -> 证书助理 -> 创建证书 填写如下信息: 名称:gdb_codesign 身份类型:自签名根 ...
阅读全文 »

一次性把多线程搞吐

发表于 2020-05-11 | 更新于: 2021-02-01 | 分类于 Java
1.什么是进程?进程是系统中正在运行的一个程序,程序一旦运行就是进程。 进程可以看成程序执行的一个实例。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。 2.什么是线程?是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 3.线程的实现方式?1.继承Thread类 2.实现Runnable接口 3.使用Callable和Future 4.Thread 类中的start() 和 run() 方法有什么区别?1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包 ...
阅读全文 »

深夜里安静的编译一个OpenJDK8,坑太多

发表于 2020-05-10 | 更新于: 2020-08-02 | 分类于 Java
Mac系统安装1234利用brew search查找mercurial➜ ~ brew search mercurial安装➜ ~ brew install mercuria Linux系统安装1sudo apt install mercurial 安装openjdk8添加代理一般在下载代码的时候都会很慢,故先配置好代理。我这里是V2Ray。 123456vim /usr/local/etc/mercurial/hgrc[http_proxy]host=127.0.0.1:8001[https_proxy]host=127.0.0.1:8001 下载jdk8u的代码123456hg clone https://hg.openjdk.java.net/jdk8u/jdk8u openjdk8chmod u+x get_source.shchmod u+x configure./get_source.sh # 下载全部源代码 ./configure --with-freetype-include=/usr/local/include/freetype2 --with-f ...
阅读全文 »
上一页1…345…15下一页
Vernon

Vernon

149 日志
66 分类
87 标签
RSS
GitHub E-Mail
© 2021 Vernon
由 Hexo 强力驱动
|
主题 — NexT.Gemini v6.0.4