自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

原创 异地多活的设计思路

一. 什么是异地多活异地多活是系统高可用的一种解决方案,它通过在多个不同机房建立多个数据中心,并且使这多个数据中心都可以同时在线提供服务来避免当出现机房断电、光纤被挖断等场景出现服务不可用的场景,实现服务高可用,同时这多个数据中心之间需要进行数据相互同步来保证数据的最终一致性。二. 哪些业务需要异地多活,哪些可以做到异地多活通过异地多活实现高可用并不是在所有场景下都可以做到的,通常需要结合业务重要程度,以及业务是否存在全局逻辑,以及异地多活场景中解决全局逻辑的成本来考虑是否需要做异地多活,同时需要考虑

2020-05-30 12:53:32 688

原创 浅析数据高可用之异地多活

一、高可用的解决方案异地多活是服务高可用的一种解决方案,具体为在不同城市建立数据中心,即数据机房,然后各数据中心之间互相同步数据,相对于“冷备”而言,“多活”是指任意一个数据中心宕机了,可以马上切换到另外一个数据中心,继续提供服务,如修改负载均衡器的配置,将流量切换到另外一个机房。除了高可用外,异地多活还可以使不同地区的用户访问不同的数据中心,提高了访问速度,从而提高了用户体验。二、适用的业务类型异地多活一般适合于能容忍数据存在短暂不一致的业务,如用户中心,但是像金钱之类的业务则不太适合,如假

2020-05-27 11:36:07 651

原创 Zookeeper学习(三):脑裂现象与应对策略

脑裂现象脑裂现象主要是指当出现网络分区时,zookeeper集群形成了两个或者多个leader的情况,这时如果两个leader都提供服务,则会出现数据不一致问题。集群出现分区的选举方式当由于网络分区,集群被分离为多个子集群时,则此时原集群的leader失去了半数的follower节点,故需要重新进行leader选举。同时另外的子集群由于没有leader,故也会发起leader选举。此时就需要在可用性和数据一致性方面做出选择。zookeeper针对这种情况,提供了一下三种机制来对可用性和数据一致

2020-05-17 11:03:19 1121

原创 基于双向链表和哈希表(开放地址)实现LRU缓存

一、设计思路1. 数据存储数据存储使用开放地址哈希表,而不是使用链表哈希的方式,从而保证存放最多指定容量的数据。如果发生冲突,则往下查找直到找到一个空位置。对应的数据结构层面,则是使用数组,更确切地说是环形数组,因为当发生冲突时,需要查找除了直接通过 key % 容量capacity 取模之外的所有其他位置一遍,直到找到一个可以存放该键值对的位置。对于数据获取,也是类似的思路。2. LRU特性实现仿照Java的linkedhashmap来维护一个双向链表,每次访问一个节点或者新增一个节点则

2020-05-16 14:04:41 797

原创 Kafka学习(三):服务器broker,生产者与消费者参数配置

2020-03-21 21:42:29 1406

原创 多租户系统设计之权限控制

概述业务层面的隔离是用户可以直接感知的隔离,也是多租户系统必须实现的隔离,在上篇文章中提到的数据隔离主要是针对数据存储层面而言的,用户一般感知不到,所以如“基于数据行的租户唯一标识”方案中,即使存储在相同的数据表也是可以的。在系统设计层面,业务隔离就是需要做好权限控制。基于RBAC模式的权限模型设计多租户系统的权限控制也是基于RBAC模式来设计的,即用户,角色,权限和资源(针对简单业务可以将...

2020-03-13 21:29:54 3128

原创 多租户系统设计之数据存储隔离

一、多租户架构的理解核心定义多租户架构的核心定义包括两点,第一点是一个服务,或者更通俗地讲是一套代码,被多方客户共用,第二点是不同客户之间的数据在逻辑上是隔离的,即每方客户拥有自己独立的数据空间,并在这个独立的数据空间内完成自身的业务行为。其中客户的群体需要根据这个服务的类型来区分,如 Saas 服务提供商的客户一般是不同的企业,而企业内部系统的客户则一般是不同的团队或者是不同的产品业务线。...

2020-03-07 11:20:58 2117

原创 分布式系统设计之限流算法剖析:漏桶与令牌桶

前言限流机制主要用于对流入系统的请求流量进行限制,保证在任何时候进入系统的请求流 量都是可控的。即不能超过系统预设的最大流量值,超过则需要排队等待或者直接拒绝,从 而避免高并发流量全部涌入系统,导致超出了系统的处理能力而出现系统机器宕机和服务不 可用问题。限流机制在实现层面,一般是基于漏桶算法或令牌桶算法来实现的,如下对这两种算法进行具体分析。漏桶算法对于漏桶算法,首先可以抽象为在业务服务...

2019-11-24 10:31:24 1675

原创 分布式系统设计之容错机制

前言由于分布式系统是由多个分布在不同网络节点的子系统或者称为子服务组成,在处理客 户端请求时,服务之间需要通过网络来进行相互调用,所以如果某个服务由于宕机或者其他 原因导致不可用,则服务调用方需要采取一定的容错机制来避免该不可用服务影响了当前服 务的请求处理。即一个服务可能会通过 RPC 调用多个其他服务,如果其中某个服务不可用, 则需要保证另外的多个服务的处理结果,以及当前发起 RPC 服...

2019-11-19 12:03:02 2097

原创 本地缓存与分布式缓存的优缺点、适用场景与实现分析

一、缓存的概念在服务端编程当中,缓存主要是指将数据库的数据加载到内存中,之后对该数据的访问都在内存中完成,从而减少了对数据库的访问,解决了高并发场景中数据库容易成为性能瓶颈的问题;以及基于内存的访问速度高于磁盘的访问速度的原理(数据库读取数据一般需要从磁盘读取),提高了数据的访问速度和程序性能。根据缓存是否与应用进程属于同一进程,可以将内存分为本地缓存和分布式缓存。本地缓存是在同一个进程内的...

2019-10-13 12:16:44 2765

原创 如何自定义一个 SpringBoot 的 starter 包

starter 包与自动配置的概念我们知道 SpringBoot 通过 starter 包引入对应的第三方 jar 包,然后通过自动配置机制来自动创建该第三方 jar 包对应的功能的 bean 对象。如通过引入 spring-boot-starter-data-redis 这个 starter 包并且在 application.properties 属性配置文件配置 Redis 服务器的域名和...

2019-10-04 20:57:51 1718

原创 Nginx七层负载均衡原理解析

一、网络协议:应用层七层负载均衡主要工作在网络七层ISO协议的第七层,即应用层。由于在应用层主要是处理对应的应用层协议的相关数据,如HTTP协议,而无法操作传输层TCP连接相关细节,故在七层负载均衡当中,负载均衡器主要是基于应用层协议的相关数据来进行请求转发,如对于HTTP协议,则主要是基于HTTP的Header头部信息、URL信息、Cookies等信息来进行集群节点的选择。由于负载均衡器需要...

2019-09-22 11:11:29 1837

原创 使用99个线程顺序打印1到99:volatile与synchronized关键字的应用

使用100个线程,顺序打印1到99。基本设计思路是:定义一个全局变量totalNum来控制当前需要打印哪个数字每个线程都使用一个顺序编号num当totalNum与num相等时,打印num,并且在该线程递增num,以便通知下一个线程打印。多线程相关:totalNum使用volatile关键字修饰保证线程可见性;每个线程内部基于synchronized关键字和基于Object类的wait方...

2019-09-21 15:47:53 1797

原创 LVS四层负载均衡原理解析

一、网络层协议网络协议是由七层ISO协议定义,自底向上分为物理层、数据链路层、网络层、传输层、会话层、表现层和应用层。四层负载均衡主要工作在网络七层ISO协议的第四层,即传输层。传输层的代表协议为TCP。相对于网络层,传输层对于数据包的区分,除了包含IP地址外,还包含端口号,并且TCP实现的是通过在不同机器的两个进程之间建立连接来进行通信。二、集群节点选择与连接建立所以四层负载均衡...

2019-09-21 08:05:20 1972

原创 分布式系统设计之高性能、高可用与高并发

概述在现代的互联网应用设计当中,通常会提到应用系统需要达到高性能,高可用和高并发这三“高”目标,其中这三个概念既有联系又有区别。高性能首先高性能是指应用系统对于客户端请求的处理速度快,响应时间短,对于用户来说就是该应用的操作流畅,拥有良好的用户体验。所以高性能是应用系统所需要具备的基本条件,不过不同业务的高性能的定义会有差别,如在线网络游戏需要保证在毫秒级别的响应时间,否则会让用户感觉...

2019-07-27 11:47:02 3384

原创 跨语言RPC框架:Gprc和protobuf的使用例子分析(包含完整项目源码)

概述Grpc是Google开发的一款高性能、跨语言的RPC框架,使用Google的数据序列化框架protobuf作为IDL(接口定义语言)跨语言的服务接口定义,以及数据序列化。在通信层面基于HTTP3.0实现,这是与大多数RPC框架基于TCP实现不一样的,主要原因是HTTP2.0在性能方面有了比较大的提升。除此之外,Grpc的设计的其中一个目的就是提供移动客户端与服务端的RPC调用,所以基于H...

2019-07-21 11:57:53 3405

原创 跨语言RPC框架:Thrift的使用例子解析(包含完整项目源码)

概述Thrift是由FaceBook于2007年开发的一款高性能,跨语言的RPC框架,支持多种不同语言之间的RPC调用,如Java,C++等,以下基于一个HelloWorld项目来展示Thrift框架的基本使用方法,项目的完整代码请参见:Thrift项目:Github thrift-IDLHelloWorld demo项目:Github thrift-demo1. 创建Thrift项目...

2019-07-20 01:03:45 2887

原创 分布式系统设计之负载均衡算法

概述在分布式系统设计当中,一般会对服务进行集群部署,集群中的多个节点提供相同的服务,所以可以将对该服务的请求分发给集群的任意一个节点来处理。为了将请求合理分发给集群的节点进行处理,即既要保证集群的每个节点都能够分配到请求,又能够实现不会给某个节点分配过多请求,导致超过节点处理能力,所以需要基于一定的规则来进行请求分发,这个规则也称为负载均衡算法。以下详细分析几种常见的负载均衡算法的工作原理。...

2019-07-11 23:26:47 2987

原创 分布式系统设计之CAP理论

一、概述CAP理论是美国加州大学的计算机科学家 Eric Brewer 在1998年提出的,该理论主要指出了分布式系统设计中存在两个质量指标:数据强一致性(Consistent)和服务高可用(Avaliability),以及一个不可避免的缺陷:网络分区,以及对应的网络分区容忍(Partition tolerance),其中数据一致性和服务可用性在分布式系统中是不能同时存在的,即要么保证数据的强...

2019-07-07 09:59:23 2528

原创 分布式系统设计概述

概述分布式系统主要用于解决单机在处理高并发请求,海量数据存储和海量数据计算分析时的瓶颈,通过将系统拆分为各个子系统,各个子系统可以在各自的机器上部署从而来实现整个系统的横向拓展。其中针对系统业务的差异,分布式系统设计的思路也会存在差异,以下主要是针对企业级应用服务,数据存储访问,数据计算分析服务来做个分析。1. 企业应用服务集群部署应对高并发请求的处理,同一个服务部署多个节点来解决单...

2019-07-03 11:52:26 3161

原创 Java NIO的三种Reactor线程模型分析

概述在使用Java NIO和多线程来进行高并发Java服务端应用程序设计时,通常是基于Reactor线程模型来设计的。Reactor,即包含一个Java NIO的多路复用选择器Selector的反应堆,当有反应时,即该Selector所管理的某个客户端连接有IO事件过来时,则在当前线程或者分配到其他线程来处理该IO事件。Reactor线程模型通常由接收客户端连接请求的acceptor线程和处...

2019-06-30 14:14:14 3046

原创 JDK1.8源码分析:线程本地变量ThreadLocal的使用与实现原理

一、概述在Java多线程编程当中,对于被多个线程的共享变量,一般的方式是通过加锁,如使用synchronized关键字或者Java并发包的ReentrantLock加锁来实现线程安全,或者该变量在Java并发包存在线程安全的版本实现,如整数Integer对应的AtomicInteger,HashMap对应的ConcurrentHashMap等,则使用对应的线程安全版本的实现。除了以上两种方式...

2019-06-18 14:10:23 4702

原创 Redis队列(三):消息的发布与订阅的C源码实现分析

一、概述在之前的文章分析过,Redis的消息发布与订阅支持基于频道channel的精确订阅与基于模式pattern的模糊订阅,并且是实时的消息传输,不会进行消息存储,如下从源代码来分析Redis的订阅与发布功能的实现,主要在Redis源码的pubsub.c文件定义。二、消息订阅1. 客户端和服务端的订阅存储结构消息订阅主要从客户端client和服务端server两个角度来分析。首先...

2019-06-09 00:49:54 6047

原创 Redis队列(二):消息的发布与订阅PubSub的使用

一、概述消息发布订阅模式在之前的文章中介绍了使用Redis列表这种数据类型来实现一个轻量级的消息队列,不过使用列表实现的消息队列存在一个缺陷就是由于是基于列表实现,所以消息出队列之后则不再存在,所以只能被一个消费者消费一次,不支持多个不同的消费者各消费一次,即不支持消息广播。为了实现消息队列常见的消息发布订阅PubSub模式,在Redis中提供了消息的发布与订阅实现,即消息生产者客户端可以...

2019-06-08 23:32:05 3460

原创 Redis队列(一):基于列表的消息队列的使用

概述在使用层面,Redis提供了用于存放字符串数据的列表这种数据类型,在数据存储容量方面,列表最多可以存放2的32次方减一个字符串元素,即大概40亿左右,不过一般不要存放这么多,否则由于数据是存放在内存中的,可能会撑爆内存。在内部数据结构实现层面,列表主要是基于链表实现的,字符串数据按照插入顺序在链表中排序,其中插入方式可以在链表前面和后面插入。除此之外,Redis还提供了列表的阻塞读取BL...

2019-06-08 18:09:20 4170

原创 RabbitMQ学习(三):高并发、高吞吐量、高可用的集群实现

一、概述高吞吐量与其他中间件产品类似,RabbitMQ也是通过集群的方式来解决单节点在处理海量消息时的性能瓶颈,通过集群的方式来实现高吞吐量,如单个RabbitMQ节点每秒只能处理1000个消息,而通过集群方式拓展,则可以进一步达到每秒10万个消息的处理或者更高的吞吐量。不过RabbitMQ的集群在处理海量消息时,是通过在集群的多个节点建立多个不同的队列来分散消息到多个不同节点的,所以在业...

2019-06-06 01:06:06 4727

原创 RabbitMQ学习(二):高可靠之持久化与高可用之镜像队列

概述RabbitMQ是对内存队列,如Java的阻塞队列BlockingQueue的一种升级,即作为一个进程队列实现不同进程之间的消息通信交互,而内存队列,如BlockingQueue则通常用于实现一个Java进程的不同线程之间的消息通信交互。这也是顺应从单体应用到分布式系统的演变所必须的消息队列的演进,解决了分布式系统不同系统之间的消息传递问题。由于RabbitMQ主要用于实现不同进程或者说...

2019-06-05 01:05:08 2513

原创 RabbitMQ学习(一):RabbitMQ的架构设计与核心组件剖析

概念RabbitMQ是基于erlang语言开发的一个消息队列系统,是对AMQP协议的实现,其中AMQP的全称为Advanced Message Queuing Protocl,即高级消息队列协议,该协议主要用于制定基于队列进行消息传递的一个开放标准。AMQP的核心概念包括:虚拟主机vhost,连接Connection,信道Channel,数据交换器Exchanger,队列Queue,交换器与...

2019-06-04 00:16:57 3808 2

原创 SSL方式连接Netty服务端失败:OpenSslEngine类无法加载NoSuchMethodError异常排查分析

一. netty客户端通过ssl方式连接服务端失败最近在重构项目代码,在测试时在本地通过ssl的方式连接服务端,服务端通过SniHandler处理ssl连接时,报一下异常:2019-05-27 17:32:26,104 110948 [nioEventLoopGroup-3-2] ERROR c.t.p.b.m.h.ChannelDisconnectedHandler(128) - Co...

2019-05-27 22:19:54 4331

原创 Spring的构造函数注入的循环依赖问题

一、循环依赖spring的循环依赖主要是指两个类相互之间通过@Autowired自动依赖注入对方,即类A包含一个类B的对象引用并需要自动注入,类B包含一个类A的对象引用也需要自动注入。对于循环依赖问题,spring根据注入方式的不同,采取不同的处理策略,对于双方都是使用属性值注入或者setter方法注入,则spring可以自动解决循环依赖注入问题,应用程序可以成功启动;对于双方都是使用构造函...

2019-05-26 11:02:18 6909 11

原创 Spring的三种依赖注入方式的使用和源码实现分析

一、自动依赖注入的方式注解类型spring提供了基于注解的属性自动注入特性,其中可以可用的注解包括spring自身提供的@Autowired和@Value,其中@Autowired是我们在项目中最常用来注入对象属性的,@Value注解通常用于注入属性文件properties的值,除此之外还可以使用JSR-330提供的注解@Inject,类型为javax.inject.Inject。如下:...

2019-05-26 00:14:00 5654

原创 Java类加载失败异常:NoClassDefFoundError与ClassNotFoundException

一、NoClassDefFoundError:运行时加载不到类在运行时,需要使用该类时,如调用该类的静态static方法或者创建该类的对象,无法从类路径加载该类而发生错误。无法加载可能类路径和mavne仓库确实是没有这个类,或者该类对当前的类加载器不可见,如tomcat容器中的不同应用使用不同类加载器。出现场景:常出现在:当通过手动安装某个第三方jar包,假如为A包,而A包又引用了另外一个...

2019-05-18 17:33:10 4053 4

原创 Code Review的基本思路

一、业务检查1. 业务流程正确性代码实现的业务流程是否合理,是否按照产品需求设计,或者是否对之前的业务流程有影响。2. 业务的可拓展性如某项业务数据的存储和结构是否能够支持未来业务的变化,如现在是统计A项数据,而未来可能统计与A相关的B项数据。二、设计检查1. 接口和方法设计(1)传参是否合理,如是否存在冗余传参,参数数据类型是否合理;(2)方法内部的相关判断和边界检查是否合理,如...

2019-05-16 11:09:51 3966 1

原创 Zookeeper学习(二):ZAB原子广播和集群leader选举策略

一、概述zookeeper作为分布式系统协调者和管理者,承担着联结分布式系统的各组件来组成一个完整服务的职责,如kafka作为一个分布式集群,在kafka的内部体系结构中包含消息生产者,消费消费者,消息存储broker三个核心组件,kafka通过在zookeeper中维护这三大组件的运作信息,并且这三大组件分别通过zookeeper获取其他组件的运作信息或者获取组件内部其他子组件的运作状态来协...

2019-05-13 00:09:09 7898

原创 Zookeeper学习(一):核心设计与运用场景剖析

概述Zookeeper的设计目的,可以根据它的名字“zoo”和“keeper”推断,即动物园的管理者,而这样命名的起因是很多分布式组件,如Hadoop是大象,tomcat是猫等,故zookeeper是一种分布式协调和分布式组件管理服务,即负责管理和协调一个复杂的分布式系统的各个组件,使得这些组件能够相互协作,共同构成一个分布式系统。具体来说,Zookeeper是Hadoop生态的中的一个用于...

2019-05-12 01:19:34 3643 2

原创 秒杀系统设计思路与实战(含源码实现)

一、限流与降级客户端限流按钮置灰js控制每秒只能发送一个请求站点层限流1. Nginx限流Nginx官方版本限制IP的连接和并发分别有两个模块:limit_req_zone: 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法。limit_req_conn: 用来限制同一时间连接数,即并发限制。2. 站点层限流客户端限流一般可以限制住普通用户,对于高端用户,则可能使...

2019-05-08 22:38:15 13601 19

原创 Kafka学习(二):基于磁盘顺序IO和零拷贝技术实现高性能文件读写

概述Kafka作为一个支持大数据量写入写出的消息队列,由于是基于Scala和Java实现的,而Scala和Java均需要在JVM上运行,所以如果是基于内存的方式,即JVM的堆来进行数据存储则需要开辟很大的堆来支持数据读写,从而会导致GC频繁影响性能。考虑到这些因素,kafka是使用磁盘而不是内存来进行数据存储,并且基于磁盘顺序读写和MMAP技术来实现高性能。存储结构目录与文件结构由...

2019-04-27 22:31:36 5412 5

原创 Kafka学习(一):Kafka的整体架构与核心组件设计剖析

概述Kafka是一个具有高吞吐量,高拓展性,高性能和高可靠的基于发布订阅模式的消息队列,是由领英基于Java和Scala语言开发。通常适合于大数据量的消息传递场景,如日志分类,流式数据处理等。Kafka的体系结构的核心组件包括:消息生产者,消息消费者,基于消息主题进行消息分类,使用Broker集群进行数据存储。同时使用Zookeeper进行集群管理,包括主题的分区信息,分区存放的broker...

2019-04-27 11:26:50 8305 1

原创 maven编译警告解决之-Xlint:unchecked

当我们通过mvn命令来编译代码时,如mvn clean compile,有时会出现WARNING编译警告,如下只是提示某个类,但是没有提示具体哪行代码,提示加上-Xlint:unchecked来查看详细信息。所以根据提示执行命令:mvn clean compile -Xlint:unchecked,但是提示没有lint这个插件,如下:针对以上错误,解决版本就是在maven-co...

2019-04-16 17:17:27 7810 1

原创 MySQL学习(九):SQL查询语句的用法和优化

一、概述MySQL的性能优化可以从机器硬件,如磁盘,内存等;MySQL服务器配置,如线程数,查询缓存等;MySQL的主从分离和分库分表等;SQL语句优化等。其中SQL语句优化是与日常开发密切相关的,而且也是MySQL优化中最重要的一个环节,因为MySQL服务器,机器等的资源是一定的,故当出现性能瓶颈时,首先需要排除是否为SQL执行问题,如通过开启MySQL慢日志统计执行慢的SQL,或者使用p...

2019-04-14 23:38:44 2107

提示
确定要删除当前文章?
取消 删除