- 博客(259)
- 收藏
- 关注
原创 zookeeper的leader选举机制
leader选举是zookeeper中最重要的技术之一,也是保证分布式数据一致性的关键所在。leader选举分为服务器启动时选举和服务器运行期间选举。服务器启动时期的leader选举Leader 选举的时候,需要注意的一点是,隐式条件便是 ZooKeeper 的集群规模至少是2台机器,这里我们以3台机器组成的服务器集群为例。在服务器集群初始化阶段,当有一台服务器(我们假设这台机器的 myid 为1,因此称其为 Server1)启动的时候,它是无法完成 Leader 选举的,是无法进行 Leader 选举
2021-04-27 16:21:29
1632
1
原创 zookeeper和ZAB协议
相信很多小伙伴会认为zookeeper是Paxos算法的一个实现,其实不是这样子的。zookeeper并没有完全采用Paxos算法,而是使用了一种成为zookeeper Atomic Broadcase(ZAB,zookeeper原子消息广播协议)的协议作为其数据一致性的核心算法。ZAB协议ZAB协议是为zookeeper专门设计的一种支持崩溃恢复的原子广播协议。基于该协议zookeeper实现了一种主备模式的系统架构来保持集群中各个副本之间数据一致性,zookeeper使用一个单一的主进程来接受并处理
2021-04-25 14:19:49
1399
原创 初识zookeeper
zookeeper从何而来ZooKeeper 最早起源于雅虎研究院的一个研究小组。在当时,研究人员发现,在雅虎内部很多大型系统基本都需要依赖一个类们似的系统来进行分布式协调,但是这些系统往往都存在分布式单点向题。所以雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架,以便让开发人员将精力集中在处理业务逻辑上。关于"ZooKeeper"这个项目的名字,其实也有一段趣闻。在立项初期,考虑到之前内部很多项目都是使用动物的名字来命名的(例如著名的 Pig 项目),雅虎的工程师希望给这个项目也取一个动物
2021-04-25 11:04:15
1374
原创 干货!手把手教你搭建高可用架构
1. 系统集群式部署单点系统,一旦出故障整个系统都瘫痪,非常酸爽,所以在大型系统中都采用集群部署,某台实例出现了问题直接踢掉负载就好了,不必担心系统是单点这种尴尬场景。尤其是在电商系统中大促的场景下,都会有一些备份机器,担心机器不够用那么直接扩容吧。2. 减少系统间依赖在系统里尽量的避免外部依赖、第三方依赖等,毕竟命运掌握在自己手里才是最有把握的。试想一种场景,如果因为你依赖的外部服务挂了导致自己的服务大面积出错,那真正尴尬的才是你自己啊。3. 重试策略大型系统中通过网络进行rpc、http调用难
2021-04-22 22:06:27
1952
2
原创 一致性协议之2PC和3PC
在分布式系统中每一个机器节点都可以知道自己在进行事务操作过程中的结果是成功还是失败,但是也无法得知其他节点的操作结果。因此当一个事务需要跨越多个节点的时候,为了保证事务的ACID的特性,这个时候就需要引入一个"协调者"的组件来统一调度所有节点的逻辑,这些被调度的节点被称为"参与者"。协调者负责调度参与者的执行逻辑,并最终决定这些参与者是否要把事务真正的提交。2PC2PC,是Two-Phase-Commit的缩写,即二阶段提交,是计算机网络尤其是在数据库领域内,为了基于分布式系统架构下的所有节点在进行事务
2021-04-14 11:39:27
1706
原创 不能不知道的分布式基础理论
大型网站为什么要使用分布式服务单点服务虽然开发方便,但是随着业务的扩充很容易遇到瓶颈,降低系统的可用性。单点服务没有服务拆分的概念,排查问题不是很方便,遇到问题需要从头开始,增加了排查问题的成本。分布式系统会按照模块划分,解耦服务之间的依赖性,排查问题方便,降低排查问题的成本,从而提高了系统的可用性。单点服务的交付周期较长,一旦出现问题就会延长交付时间。分布式系统可以按照模块进行交付。按照模块划分之后,可以加快开发速度,每个业务模块的开发人员只需要专注所负责模块。但是分布式体统的设计也带来了一定的
2021-03-24 14:55:19
2633
原创 浅析Java的线程和Golang的协程
Java的多线程线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,Java的多线程是通过JMM(共享内存模型)来实现的。大部分的操作系统都是利用时间片轮转的抢占式调度方式,线程需要利用操作系统的调度算法在用户态和内核态来回切换,线程的切换是非常浪费资源的,所以Java的线程池在工作中才那么常用,也是面试中无法绕过的坎。程序一般不会直接去使用内核线程,而是去使用内核线程的一种高级接口——轻量级进程(Lightweight Pro
2021-03-22 15:36:33
3646
转载 传统架构 vs 云原生架构,谈谈为什么我们需要云原生架构?
本文转载自阿里巴巴中间件微信公众号:https://mp.weixin.qq.com/s/zOlQ07dCLRy_cHTTai6V1g
2021-03-19 09:50:52
2841
转载 256变4096:分库分表扩容如何实现平滑数据迁移?
本来转载自微信公众号「阿里技术」,原文地址:https://mp.weixin.qq.com/s/Lg1HF1FmD44roo8_H5aaDQ。
2021-03-02 09:37:43
3389
原创 超详细的SpringBoot+MySQL读写分离方案
在互联网应用中,大部分都是读多写少的场景,设置两个库,主库和读库,主库的职能是负责写,从库主要是负责读,可以建立读库集群,通过读写职能在数据源上的隔离达到减少读写冲突、释压数据库负载、保护数据库的目的。主从数据源的配置通过@ConfigurationProperties注解,可以将配置文件(一般命名为:application.yml)里的属性映射到具体的类属性上,从而读取到写入的值注入到具体的代码配置中,按照习惯大于约定的原则,主库我们都是注为master,从库注为slave,接着需要配置sessio
2021-02-26 11:54:49
4389
3
原创 关于TCC你可能不了解的细节
说到TCC大家可能并不陌生,但是也有一些小伙伴只是听到过,简单的了解过一些概念并没有实践过,所以对于有些细节还是不够了解。TCC作为分布式事务的一种具有强实时性保证的解决方案,其主要思想在于资源预留。在一切顺利的情况下,一阶段TRY还是很容易理解的。只不过为了保证在各种异常场景下,TCC都能够正常的工作,会添加不少异常处理手段。为了把两个阶段的行为梳理清楚,绘制了下面的流程图作为总结。一阶段TRY二阶段 CONFIRM/CANCEL分布式事务需要解决的问题幂等问题:TC重复调用二阶段解决:
2021-02-18 16:43:41
4334
原创 云原生这么火,你再不了解就out了
伴随云计算的滚滚浪潮,云原生(Cloud Native)的概念应运而生,云原生很火,火得一塌糊涂,都2021年了,如果你还不懂云原生,那真的out了。云原生是过去几年里云计算最火的用词之一。几乎每一个云计算的产品厂商都会把自己的产品与云原生联系在一起。但是到底这个词是什么意思,它的具体含义是什么,其实却是非常含糊的。云原生这个词最早在2014年左右起源于Pivotal。Pivotal是一家做PaaS服务的公司。之后在2015年夏天,Linux基金会创建了云原生基金会CNCF。CNCF在宣布成立时也没有一个
2021-02-05 14:26:09
4427
1
原创 接口幂等性这么重要,我们该怎么保证幂等性?
什么是幂等性想象一下这样的场景,用户在商城下单买东西,然后发起支付,钱已经扣成功了,但是由于网络超时或其它一些原因导致商城未能正常得到支付结果。用户又重新发起支付,如果支付服务没有幂等性保证,就会导致重复扣款,对用户来说就是极差的体验。通用的讲,服务在处理一条数据请求时,根据具体的业务场景判断,如果同一条数据请求有且仅能被处理一次,那么就需要对这条数据请求的处理保证幂等性,避免重复处理。常见错误方法加分布式锁加锁只能限制并发,但最终还是会被执行到,如果没有幂等性保证就会重复处理。先从数据库
2021-01-14 10:30:26
5196
1
转载 分库分表之 Sharding-JDBC 中间件,看这篇真的够了!
原文地址:https://mp.weixin.qq.com/s/98pAEnP2FsY3WyhhWIPYZg
2021-01-11 15:29:20
5030
原创 MVCC和InnoDB行锁
简单介绍下MVCC的原理每个事务开启时,都会被分配到一个全局唯一且递增的事务id,即trx_id,当每次事务对某些数据行进行修改时,都会将事务自身的trx_id记录在数据行的隐藏列上。在事务开启的那一刻,MVCC机制会为事务生成一个当前mysql服务器上所有事务的快照。这个快照是按照如下方式实现的:将当前服务端活跃的全部事务id记录在set中当前活跃的事务最小id记为min_trx_id当前活跃的事务最大id记为max_trx_id当进行一次普通查询的时候,根据数据行上的trx_id进行判断。
2020-12-22 17:28:22
5524
原创 互联网中慢SQL优化手段
一个再完美的架构,也会因为一个慢SQL导致系统直接崩溃。最近在做一个比较有意思的工作,优化系统中的慢SQL,整个过程我是很享受的,往往很多慢SQL都是系统中调用非常频繁的接口,这让我对业务更加熟悉,整个优化过程下来对系统和团队的帮助是非常大的,自己针对这次优化历程总结了一些经验和个人心得,希望可以帮到有需要的小伙伴。了解MySQL执行过程图片来源于《高性能MySQL》pdf版。从图片中可以清楚的看到:客户端发送一条查询给服务器;服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果
2020-12-10 20:53:58
5457
原创 大厂都在使用的分库分表方案
想必各位小伙伴在面试大厂的时候都遇到过这个面试题,要是提前有准备还好,没准备的话可能就被打了个措手不及,本文将从为什么使用分库分表技术、分库分表的基本概念、分库分表的好处以及分库分表的注意事项来聊一聊这个话题。数据库架构演变刚开始我们只用单机数据库就够了,随后面对越来越多的请求,我们将数据库的写操作和读操作进行分离, 使用主库(Master)负责写,使用多个从库副本(Slaver Replication)负责读,从库从主库同步更新数据,保持数据一致。架构上就是数据库主从同步。从库可以水平扩展,所以更多的
2020-11-15 16:37:51
5920
原创 互联网中常见优化手段
你有没有想过,为什么跨行转账要告诉你2小时内到账,而不是立即到账?为什么抖音那么多用户同时在使用,却很少出现崩溃的情况?电商网站是如何支撑住双十一全国人民买买买的?性能优化对一个产品的重要性不言而喻,它直接影响网站的用户留存率,APP在商店的评分和用户粘性。一个响应慢的应用,即便它功能再强大,也留不住用户。性能优化对一个程序员同样非常重要——如果你是一个有追求的程序员的话。我们说,大多数人的职业生涯发展都应该是一个T字型,要在某一方面有深度,也要有广度。而性能优化,恰恰是一个既需要深度,又需要广度的话题
2020-11-06 22:08:15
6646
6
原创 为什么使用DDD?
DDD为什么火了?第一次听到DDD这个词是在几年前。乍一听感觉像TDD(测试驱动开发),但其实它们完全是两回事。当时看了一篇介绍DDD的博客,一大篇专业术语,搞得云里雾里,便没有深究下去了。虽然DDD早在2003年就提出了,但一直没有火起来。直到最近两年才慢慢被大家熟知。深究其原因,我觉得有三方面:第一方面,DDD是解决复杂软件问题的,而之前的软件大多没有很复杂的逻辑,不用DDD也能玩得转;第二方面,DDD一直没有很好的落地指导,一直到《实现领域驱动设计》这本书的问世,为DDD的落地打开了大门;
2020-10-17 23:13:54
8029
原创 浅析限流算法
计数器计数器算法的思想很简单,每当一个请求到来时,我们就将计数器加一,当计数器数值超过阈值后,就拒绝余下请求。一秒钟后,我们将计数器清零,开始新一轮的计数。计数器算法简单粗暴,易于实现。但是缺点也是有的,也就是所谓的"突刺现象"。举例说明一下,假如我们给计数器设置的阈值为100。系统瞬间内(比如10毫秒内)有200个请求到来,这个时候计数器只能放过其中的100个请求,余下的100个请求全部被拒绝掉。如果第二秒内没有请求到来,那么系统就处于空闲状态。也就是上一秒忙的要死,这一秒又闲的要死。如果我们能用一个容
2020-09-28 17:54:09
6398
原创 浅析HashSet源码
对于 HashSet 而言,它是基于 HashMap 实现的,底层采用 HashMap 来保存元素,所以如果对 HashMap 比较熟悉了,那么学习 HashSet 也是很轻松的。HashSet是一个无重复数据的集合,存放的数据也是无序的。构造方法// HashSet底层是通过HashMap来实现的,所以具有HashMap的一切特性private transient HashMap<E,Object> map;// 无参构造方法public HashSet() { map =
2020-09-10 14:54:14
6650
原创 浅析LinkedHashMap源码
上一篇文章对HashMap的重要属性和常用方法进行了详细的分析,LinkedHashMap很多东西都直接继承自HashMap,所以本文只分析一些LinkedHashMap的特性。LinkedHashMap通过维护双向链表解决了HashMap不能保持顺序插入和顺序遍历的问题,在一些场景下,这个特性很有用,比如缓存、LRU算法等。链表建立的过程因为LinkedHashMap直接继承自HashMap,数据插入的过程也是直接使用的是HashMap的方法,但是却不负责链表的维护。链表的建立过程是在插入键值对节点时
2020-09-09 18:17:55
6642
原创 HashMap源码详细分析(JDK1.8)
HashMap是我们日常开发中最最最常用的集合之一,本文通过对HashMap中重要属性和常用的方法进行分析,但是由于HashMap的源码有两千多行,所以只针对部分源码进行分析。HashMap的构造函数从源码中可以看到,HashMap的构造方法有四个,构造方法做的事情也比较简单,都是初始化一些变量loadFactor、threshold。 // 无参的构造方法是使用场景最多的 public HashMap() { this.loadFactor = DEFAULT_LOAD_FA
2020-09-08 23:34:35
6964
原创 不得不看的LinkedList源码分析
之前分析了一下ArrayList的源码,这篇文章继续分析LinkedList,LinkedList同样是我们平时工作中最常用的集合之一。LinkedList都有哪些特点LinkedList的底层是通过双向链表实现的LinkedList逻辑上是连续的(因为LinkedList开辟的内存不是连续的),是通过存放上一个节点的引用和下一个节点的引用来实现有序的链表相对于ArrayList来说,LinkedList查询元素的速度较慢,新增和删除元素的速度较快;但是在指定位置新增元素效率较慢,时间复杂度为O(
2020-09-04 16:26:19
6854
原创 一看就明白的ArrayList源码分析
ArrayList是我们平时开发中最常用的集合之一,本文通过源码来解析一下ArrayList的底层实现原理。ArrayList都有哪些特点ArrayList底层是通过定长数组实现的ArrayList存放的数据是有序且可重复的,且允许存入空值ArrayList是非线程安全的,在多线程环境下可能会出现ConcurrentModificationException由于ArrayList是基于定长数组实现的,所以可以保证在复杂度为O(1)的情况下完成查找数据ArrayList默认大小是0,在第一次存放
2020-09-03 20:27:12
7272
原创 深入理解单元测试
作为一个程序员,或多或少听说过单元测试,但很多小伙伴还没有在实际项目中用到。究其原因,可能是对单元测试有一些误解,比如:写单元测试需要花费更多的时间,我每天写产品代码都要加班,哪来时间写测试;写单元测试收益不大,还不是一样有bug;写单元测试有负担,改产品代码的结构,还得去改测试代码。先尝试解答这几个问题。写单元测试会花费更多的时间,这点描述其实不准确。准确地说,写单元测试需要花费更多写代码的时间,这点没什么可说的,毕竟要多写一些测试代码。但一个程序员,做一个需求的时候,花在纯写代码的时间
2020-08-30 20:16:46
7399
原创 NIO之旅Selector
之前的文章介绍了Buffer和Channel,今天这篇文章简单聊一下Selector。Selector是NIO中最为重要的组件之一,我们常常说的多路复用器就是指的Selector组件。Selector组件用于轮询一个或多个NIO Channel的状态是否处于可读、可写。通过轮询的机制就可以管理多个Channel,也就是说可以管理多个网络连接。轮询机制首先,需要将Channel注册到Selector上,这样Selector才知道需要管理哪些Channel接着Selector会不断轮询其上注册的Ch
2020-08-20 18:30:09
7417
原创 NIO之旅Buffer
在上一篇文章中聊了一下Channel,这篇文章聊一下Java NIO中的另一个重要的组件:Buffer。Buffer的概念首先我们先看一下Buffer的类图,Buffer在java.nio中被定义为抽象类:Buffer被称为内存缓冲区,本质上也是内存中的一块,我们可以将数据写入内存中,之后从这块内存中读取数据。也可以将这个块内存封装成NIO Buffer对象,并提供一组常用的方法,方便对这块内存进行读写操作。在Java NIO中,所有的数据都要经过Buffer,我们可以将Buffer理解为一个数组
2020-08-18 22:38:45
7697
原创 NIO之旅Channel
Java NIO中有三个重要的组件Channel、Buffer、Selector,本篇文章主要讲解NIO中的Channel组件。Channel的基本概念Channel是Java NIO核心概念之一,翻译过来就是“通道”的意思,在使用上,通道需和缓存类(ByteBuffer)配合完成读写等操作。一个Channel对象其实就对应了一个IO连接。在NIO中,基本所有的IO操作都是从Channel开始的,Channel通过Buffer(缓冲区)进行读写操作。channel.read()表示读取通道中数据到
2020-08-14 17:56:26
7730
原创 Java中的BIO通信模型
在上一篇Linux和Java中的I/O模型中介绍了NIO、BIO模型,本篇文章讲解一下多线程+BIO的通信模型。主流的web服务器Tomcat就是多线程+BIO的通信模型的代表者。原理图Server端Server端即接收消息的那一端。BIO是一种阻塞IO,也就是说,当前线程会一直阻塞,直到接受到消息。所以通常会使用多个线程来配合,即每来一个IO连接,都新启一个线程去处理。但由于在Java中,线程是一种比较宝贵的资源,所以一般会使用线程池来复用线程资源。public class Server {
2020-08-10 10:39:15
7782
原创 Linux和Java中的I/O模型
在了解Java中的I/O模型之前,我们来了解一下Linux中的I/O模型。用户空间和内核空间Linux为了保证系统安全,把内存分为了两种空间,分别是用户空间和内核空间。只有内核空间可以直接调用硬件(比如磁盘,网卡等)。而我们一般的进程是在用户空间的,位于用户空间的进程是不能直接调用硬件的,而是通过系统调用来请求内核空间协助完成IO操作。那内核空间是怎么协助的呢?内核空间会为每个IO设备维护一个缓冲区buffer(比如文件系统IO,就是页缓存page cache)。内核收到来自用户空间的进程的系统调用
2020-08-09 21:46:59
8168
原创 原来Spring是这样解决循环依赖的
什么是循环依赖通常来说,Spring循环依赖的场景一般是单例Bean。几个Bean之间的循环依赖@Componentpublic class A { @Autowired private B b;}@Componentpublic class B { @Autowired private C c;}@Componentpublic class C { @Autowired private A a;}自己依赖自己@Com
2020-08-07 11:53:17
7982
原创 面试官:说说你了解哪些JDK自带的命令行工具
不看不知道,一看吓一跳,原来JDK自带了这么多工具,本文主要介绍一下工作中常用的JDK工具以及使用方法和使用场景。
2020-07-16 16:28:51
9997
原创 面试官:说说你了解的OOM异常以及解决方案
在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区都会发生OOM异常的可能,本文通过几个例子来了解一下虚拟机常见的OOM异常。本文的代码参考《深入理解Java虚拟机(第二版)》Java堆溢出Java堆用于存储对象实例,只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免避免垃圾回收清除对象,那么这些对象达到最大堆的容量限制之后就会产生内存溢出异常。设置VM参数,方便导出dump文件分析-Xms20m //JVM初始分配的内存20m-Xmx20m
2020-07-15 10:55:23
10318
转载 线上服务的FGC问题排查,看这篇就够了!
原文链接:https://mp.weixin.qq.com/s/I1fp89Ib2Na1-vjmjSpsjQ
2020-07-13 18:16:38
581
转载 单核CPU, 1G内存,也能做JVM调优吗?
原文链接:https://mp.weixin.qq.com/s/zgZvKtoLJi-p-WqFk68lCw
2020-07-13 17:23:19
634
1
转载 小白搞懂了GC全过程,全靠阿里专家12张图
原文链接:https://mp.weixin.qq.com/s/KWxW66XtsiEnjb0sqL-isg
2020-07-13 16:48:14
9385
2
原创 一看就懂的Java对象四种引用方式总结
这应该是一道很常见的面试题,但是有些小伙伴也不一定能很好的说清楚Java对象四种引用方式,这边文章总结Java四种引用方式,希望可以帮到有缘人,哈哈。强引用StrongReference这种方式是平时工作中应用最多的一种引用方式。其特点是只要GC Root可达,就不会被回收,及时内存空间不足了,也只会抛出OOM的异常,并不会被回收。通常的用法就是Objec obj = new Object()。如果想中断或者回收强引用对象,可以显式地将引用赋值为null,这样的话JVM就会在合适的时间,进行垃圾回收。
2020-07-06 16:50:50
9654
原创 Guava Cache的应用
maven依赖<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.1-jre</version></dependency>应用首先定义这个Cache。public class GlobalCache { private static GlobalCache
2020-07-02 18:28:18
967
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅