自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(122)
  • 收藏
  • 关注

原创 Dubbo扩展点加载机制(SPI)

本章主要内容:• 加载机制概述;• 扩展点注解;• ExtensionLoader 的工作原理;• 扩展点动态编译的实现原理。1加载机制概述Dubbo良好的扩展性与两个方面是密不可分的, 一是整个框架中针对不同的场景, 恰好处地使用了各种设计模式, 二就是本章要介绍的加载机制。 基于Dubbo SPI加载机制, 让整个框架的接口和具体实现完全解耦, 从而奠定了整个框架良好可扩展性的基础。扩展点的特性从Dubbo官方文档中可以知道, 扩展类一共包含四种特性: 自动包装、 自动加载、 自适应和自

2021-01-30 15:09:01 205 2

原创 Dubbo-注册中心

本章主要内容:• 注册中心的工作流程;• 注册中心的数据结构;• 订阅发布的实现;• 缓存机制;• 重试机制;• 设计模式。.1注册中心概述在Dubbo微服务体系中, 注册中心是其核心组件之一。 Dubbo通过注册中心实现了分布式环境中各服务之间的注册与发现, 是各个分布式节点之间的纽带。其中ZooKeeper是官方推荐的注册中心, 在生产环境中有过实际使用, 具体的实现在Dubbo源码的dubbo-registry-zookeeper模块中。.1.1工作流程注册中心的总体流程如图3

2021-01-30 14:07:20 325

原创 Dubbo-高性能RPC通信框架

Dubbo是阿里SOA服务化治理方案的核心框架。编写分布式场景下高并发、 高可扩展的系统对技能的要求很高, 因为其中涉及序列化/反序列化、 网络、 多线程、 设计模式、 性能优化等众多专业知识。 Dubbo框架很好地将这些专业知识做了更高层的抽象和封装, 提供了各种开箱即用的特性。1.图1-5中Provider启动时会向注册中心把自己的元数据注册上去(比如服务IP和端口等)2.Consumer在启动时从注册中心订阅(第一次订阅会拉取全量数据) 服务提供方的元数据3.注册中心中发生数据变更会推

2021-01-28 21:56:09 279 2

原创 Redis-缓存设计

缓存能够有效地加速应用的读写速度, 同时也可以降低后端负载, 对日常应用的开发至关重要。 但是将缓存加入应用架构后也会带来一些问题, 本章将针对这些问题介绍缓存使用技巧和设计方案, 包含如下内容:·缓存的收益和成本分析。·缓存更新策略的选择和使用场景。·缓存粒度控制方法。·穿透问题优化。·无底洞问题优化。·雪崩问题优化。·热点key重建优化。1 缓存的收益和成本收益如下:·加速读写: 因为缓存通常都是全内存的(例如Redis、 Memcache) , 而存储层通常读写性能不够强悍.

2021-01-10 12:00:28 322

原创 Redis Cluster-集群

Redis Cluster是Redis的分布式解决方案, 在3.0版本正式推出, 有效地解决了Redis分布式方面的需求。 当遇到单机内存、 并发、 流量等瓶颈时, 可以采用Cluster架构方案达到负载均衡的目的。 之前, Redis分布式方案一般有两种:·客户端分区方案, 优点是分区逻辑可控, 缺点是需要自己处理数据路由、 高可用、 故障转移等问题。·代理方案, 优点是简化客户端分布式逻辑和升级维护便利, 缺点是加重架构部署复杂度和性能损耗。现在官方为我们提供了专有的集群方案: Redis Cl

2021-01-09 17:50:09 380 4

原创 Redis Sentinel(哨兵) 架构

Redis的主从复制模式下, 一旦主节点由于故障不能提供服务, 需要人工将从节点晋升为主节点, 同时还要通知应用方更新主节点地址, 对于很多应用场景这种故障处理的方式是无法接受的。可喜的是Redis从2.8开始正式提供了Redis Sentinel(哨兵) 架构来解决这个问题。Redis Sentinel是Redis的高可用实现方案, 在实际的生产环境中, 对提高整个系统的高可用性是非常有帮助的。Redis Sentinel的高可用性当主节点出现故障时, Redis Sentinel能自动完成故障

2021-01-09 16:08:38 153

原创 Redis-理解内存

·内存消耗分析。·管理内存的原理与方法。·内存优化技巧。1 内存消耗理解Redis内存, 首先需要掌握Redis内存消耗在哪些方面。 有些内存消耗是必不可少的, 而有些可以通过参数调整和合理使用来规避内存浪费。 内存消耗可以分为进程自身消耗和子进程消耗。需要重点关注的指标有: used_memory_rss和used_memory以及它们的比值mem_fragmentation_ratio。当mem_fragmentation_ratio>1时, 说明used_memory_rs

2021-01-06 20:50:45 141

原创 Redis-阻塞分析

Redis是典型的单线程架构, 所有的读写操作都是在一条主线程中完成的。当Redis用于高并发场景时, 这条线程就变成了它的生命线。 如果出现阻塞, 哪怕是很短时间, 对于我们的应用来说都是噩梦。·内在原因包括: 不合理地使用API或数据结构、 CPU饱和、 持久化阻塞等。·外在原因包括: CPU竞争、 内存交换、 网络问题等。1 发现阻塞当Redis阻塞时, 线上应用服务应该最先感知到, 这时应用方会收到大量Redis超时异常,, 比如Jedis客户端会抛出JedisConnectionEx

2021-01-06 15:51:47 346

原创 Redis-复制

在分布式系统中为了解决单点问题, 通常会把数据复制多个副本部署到其他机器, 满足故障恢复和负载均衡等需求。 Redis也是如此, 它为我们提供了复制功能, 实现了相同数据的多个Redis副本。 复制功能是高可用Redis的基础, 哨兵和集群都是在复制的基础上实现高可用的。·介绍复制的使用方式: 如何建立或断开复制、 安全性、 只读等。·说明复制可支持的拓扑结构, 以及每个拓扑结构的适用场景。·分析复制的原理, 包括: 建立复制、 全量复制、 部分复制、 心跳等。·介绍复制过程中常见的开发和运维问题

2020-12-31 15:35:27 440

原创 Redis-持久化

Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免因进程退出造成的数据丢失问题, 当下次重启时利用之前持久化的文件即可实现数据恢复。1.RDBRDB持久化就是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。1.1触发机制·bgsave命令: Redis进程执行fork操作创建子进程, RDB持久化过程由子进程负责, 完成后自动结束。 阻塞只发生在fork阶段, 一般时间很短。 运行bgsave命令对应的Redis日志如下:* Back.

2020-12-28 17:36:53 3204

原创 Redis-客户端

本章内容如下:·客户端通信协议·Java客户端Jedis·客户端管理·客户端常见异常·客户端案例分析1 客户端通信协议一, 客户端与服务端之间的通信协议是在TCP协议之上构建的。第二,Redis制定了RESP(REdis Serialization Protocol, Redis序列化协议) 实现客户端与服务端的正常交互, 这种协议简单高效, 既能够被机器解析, 又容易被人类识别。1.发送命令格式RESP的规定一条命令的格式如下, CRLF代表"\r\n"。以set hell w

2020-12-24 14:50:06 425

原创 Redis-发布订阅,GEO

1.发布订阅Redis提供了基于“发布/订阅”模式的消息机制, 此种模式下, 消息发布者和订阅者不进行直接通信, 发布者客户端向指定的频道(channel) 发布消息, 订阅该频道的每个客户端都可以收到该消息, 如图3-16所示。 Redis提供了若干命令支持该功能, 在实际应用开发时, 能够为此类问题提供实现方法。1 命令Redis主要提供了发布消息、 订阅频道、 取消订阅以及按照模式订阅和取消订阅等命令。1.发布消息publish channel message下面操作会向channel

2020-12-18 15:01:49 138

原创 Redis-Bitmaps,HyperLogLog

Bitmaps1.数据结构模型

2020-12-17 17:32:34 140

原创 Redis-慢查询、Pipeline、事务

1 慢查询分析慢查询分析: 通过慢查询分析, 找到有问题的命令进行优化。如图3-1所示, Redis客户端执行一条命令分为如下4个部分:1) 发送命令2) 命令排队3) 命令执行4) 返回结果需要注意, 慢查询只统计步骤3) 的时间, 所以没有慢查询并不代表客户端没有超时问题。1.1 慢查询的两个配置参数对于慢查询功能, 需要明确两件事:·预设阀值怎么设置?·慢查询记录存放在哪?Redis提供了slowlog-log-slower-than和slowlog-max-len配置来解

2020-12-14 17:23:51 255

原创 Redis-键管理

本节将按照单个键、 遍历键、 数据库管理三个维度对一些通用命令进行介绍。1 单个键管理1.键重命名rename key newkey下面操作将键python重命名为java:127.0.0.1:6379> set python jedisOK127.0.0.1:6379> rename python javaOK127.0.0.1:6379> get python(nil)127.0.0.1:6379> get java"jedis"如果在rena

2020-11-26 11:34:55 123

原创 Redis-API理解和使用-有序集合(zset)

有序集合相对于哈希、 列表、 集合来说会有一点点陌生, 但既然叫有序集合, 那么它和集合必然有着联系, 它保留了集合不能有重复成员的特性,但不同的是, 有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是, 它给每个元素设置一个分数(score) 作为排序的依据。1 命令1.集合内(1) 添加成员zadd key score member [score member ...]下面操作向有序集合user: ranking添加用户tom和他的分数251:127

2020-11-20 09:45:57 1297

原创 Redis-API理解和使用-集合(set)

集合(set) 类型也是用来保存多个的字符串元素, 但和列表类型不一样的是, 集合中不允许有重复元素, 并且集合中的元素是无序的, 不能通过索引下标获取元素。Redis除了支持集合内的增删改查, 同时还支持多个集合取交集、 并集、 差集, 合理地使用好集合类型, 能在实际开发中解决很多实际问题。1 命令1.集合内操作(1) 添加元素sadd key element [element ...]127.0.0.1:6379> exists myset(integer) 0127.

2020-11-19 09:57:39 308

原创 Redis-API理解和使用-列表(list)

列表(list) 类型是用来存储多个有序的字符串, 如图2-18所示, a、b、 c、 d、 e五个元素从左到右组成了一个有序的列表, 列表中的每个字符串称为元素(element) , 一个列表最多可以存储232-1个元素。 在Redis中, 可以对列表两端插入(push) 和弹出(pop) , 还可以获取指定范围的元素列表、 获取指定索引下标的元素等(如图2-18和图2-19所示) 。 列表是一种比较灵活的数据结构, 它可以充当栈和队列的角色, 在实际开发上有很多应用场景。列表类型有两个特点:第一

2020-11-18 10:48:04 707

原创 Redis-API理解和使用-哈希(hash)

几乎所有的编程语言都提供了哈希(hash) 类型, 它们的叫法可能是哈希、 字典、 关联数组。 在Redis中, 哈希类型是指键值本身又是一个键值对结构, 形如value={{field1, value1}, ...{fieldN, valueN}}, Redis键值对和哈希类型二者的关系可以用图2-14来表示。1.命令(1) 设置值hset key field value下面为user: 1添加一对field-value:127.0.0.1:6379> hset user:.

2020-11-17 15:42:48 207

原创 Redis-API理解和使用-字符串(String)

字符串类型是Redis最基础的数据结构。 首先键都是字符串类型, 而且其他几种数据结构都是在字符串类型基础上构建的, 所以字符串类型能为其他四种数据结构的学习奠定基础。 如图2-7所示, 字符串类型的值实际可以是字符串(简单的字符串、 复杂的字符串(例如JSON、 XML) ) 、 数字(整数、 浮点数) , 甚至是二进制(图片、 音频、 视频) , 但是值最大不能超过512MB。1.常用命令(1) 设置值set key value [ex seconds] [px milliseccond

2020-11-17 09:56:24 149

原创 Redis,API的理解和使用-全局命令

1.全局命令1.1查看所有键keys *下面插入了3对字符串类型的键值对:127.0.0.1:6379> set hello worldOK127.0.0.1:6379> set java jedisOK127.0.0.1:6379> set python redis-pyOKkeys*命令会将所有的键输出:127.0.0.1:6379> keys *1) "python"2) "java"3) "hello"1.2键总数dbsize下

2020-11-16 11:13:14 115

原创 初识Redis

1.Redis特性1.1速度快正常情况下, Redis执行命令的速度非常快, 官方给出的数字是读写性能可以达到10万/秒, 当然这也取决于机器的性能, 但这里先不讨论机器性能上的差异, 只分析一下是什么造就了Redis除此之快的速度, 可以大致归纳为以下四点:Redis的所有数据都是存放在内存中的Redis是用C语言实现的, 一般来说C语言实现的程序“距离”操作系统更近, 执行速度相对会更快。Redis使用了单线程架构, 预防了多线程可能产生的竞争问题作者对于Redis源代码可以说是精打细

2020-09-29 20:53:23 148

原创 Netty:ByteBuf和相关辅助类(二)

1.AbstractReferenceCountedByteBuf从类的名字就可以看出该类主要是对引用进行计数,类似JVM内存回收的对象引用计数器,用于跟踪对象的分配和销毁,做自动内存回收。/** * Abstract base class for {@link ByteBuf} implementations that count references. */public abstract class AbstractReferenceCountedByteBuf extends Abst

2020-09-13 17:39:48 153

原创 Netty:ByteBuf和相关辅助类

1.ByteBuf功能说明数据传输需要使用缓冲区。JDK NIO的ByteBuffer有其局限性,缺点如下:ByteBuffer长度固定,一旦分配完成,它的容量不能动态扩展和收缩,当需要编码的POJO对象大于ByteBuffer的容量时,会发生索引越界异常;ByteBuffer只有一个标志位置的指针position,读写的时候需要手工调用flip()和rewind()等,使用者必须小心谨慎的处理这些API,否则很容易导致程序处理失败;ByteBuffer的API功能有限,一些高级和...

2020-09-12 23:31:17 351

原创 Netty:可靠性

Netty应用场景:1.RPC框架的基础网络通信框架:主要用于分布式节点之间的通信和数据交换,在各个业务领域均有典型的应用,例如阿里的分布式框架Dubbo,消息队列Rocket MQ,大数据处理Hadoop的基础通信和序列化框架Avro。2.私有协议的基础通信框架:Thrift协议,Dubbo协议等;3.公有协议的基础通信框架:HTTP协议,SMPP协议。链路的有效性检测从技术层面看,要解决链路可靠性问题,必须周期性的对链路进行有效性检测。目前最流行和通用的做法就是心跳检测。心跳检测

2020-09-09 22:37:23 214

原创 Netty:高性能之道

1.RPC调用性能模型分析传统RPC调用性能差的三宗罪1.网络传输方式问题。传统的RPC框架或者基于RMI等方式的远程服务调用采用了同步阻塞I/O,当客户端的并发压力大或者网络延时增大之后,同步阻塞I/O会由于频繁的wait导致I/O线程经常性的阻塞,由于线程无法高效工作,I/O处理能力自然下降。采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端连接,接收客户端连接之后,为其创建一个新的线程处理请求消息,处理完成之后,返回应答消息给客户端,线程销毁,这就是一请求一应答

2020-09-09 15:18:38 196

原创 Netty:高级特性

1.Netty逻辑架构1.1 Reactor通信调度层它由一系列辅助类完成,包括Reactor线程NioEventLoop及其父类,NioSocketChannel/NioServerSocketChannel及其父类,ByteBuffer以及由其衍生出来的各种Buffer,Unsafe以及其衍生出来的各种内部类等。该层的主要职责就是监听网络的读写和连接操作,负责将网络层的数据读取到内存缓冲区中,然后触发各种网络事件,例如连接创建,连接激活,读事件,写事件等,将这些事件触发到PipeLine中,

2020-09-09 10:59:20 292

原创 Netty:TCP粘包/拆包问题解决之道

1.TCP粘包/拆包TCP是一个“流”协议,流,就是没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。2.粘包问题的解决策略由于底层TCP无法理解上层的业务数据,所以底层无法保证数据包不被拆分和重组,这个问题只能通过上层的应用协议栈设计来解决,根据业界主流的解决方案,归纳如下:1.消息定长,例

2020-09-07 21:47:58 304

原创 Netty简介

1.Netty是什么Netty是一个高性能,异步事件驱动的NIO框架,基于Java NIO提供的API实现。它提供对TCP,UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知获得IO操作结果。2.Netty应用场景作为当前最流行的NIO框架,Netty在互联网领域,大数据分布式计算领域,游戏行业,通信行业等获得了广泛的应用,业界主流RPC框架,也是用Netty来构建高性能的异步通信能

2020-09-07 11:07:05 82

原创 6 Netty 架构剖析

6.1 逻辑架构Netty 采用了典型的三层网络架构进行设计和开发,逻辑架构如图 6-1 所示:Reactor 通信调度层:它由一系列辅助类完成,包括 Reactor 线程 NioEventLoop 及其父类,NioSocketChannel/ NioServerSocketChannel 及其父类, ByteBuffer 以及由其衍生出来的各种 Buffer,Unsafe 以及其衍生出的各种内部 类等。该层的主要职责就是监听网络的读写和连接操作,负责将网络层的数据读 取到内存缓冲区中,然后触发

2020-07-28 22:37:53 152

原创 5 Netty 线程模型

当我们讨论 Netty 线程模型的时候,一般首先会想到的是经典的 Reactor 线 程模型,尽管不同的 NIO 框架对于 Reactor 模式的实现存在差异,但本质上还是 遵循了 Reactor 的基础线程模型。下面让我们一起回顾经典的 Reactor 线程模型。5.1 Reactor 线程模型5.1.1 Reactor 单线程模型Reactor 单线程模型,是指所有的 I/O 操作都在同一个 NIO 线程上面完成。 NIO 线程的职责如下。• 作为NIO服务端,接收客户端的TCP连接

2020-07-28 21:06:23 230

原创 4 Netty 消息的 发送和接收

Netty 消息的读取和发送都是非阻塞模式,这是它相比于传统 BIO 最大的优势,下面我们一起分析下 Netty 是如何异步的处理读写操作的。4.1 异步读取操作NioEvnetLoop 作为 Reactor 线程,负责轮询多路复用器,获取就绪的通道执行网络的连接、客户端请求接入、读和写。当多路复用器检测到读操作后,执行如下方法:不同的 Channel 对应不同的NioUnsafe:此 处 对 应 的 是 NioByteUnsafe, 下 面 我 们 进 入 它 的 父 类AbstractN

2020-07-27 10:28:31 3410

原创 3 Netty 客户端创建

Netty 为了向使用者屏蔽 NIO 通信的底层细节,在和用户交互的边界做了封装,目的就是为了减少用户开发工作量,降低开发难度。Bootstrap 是 Socket客户端创建工具类,用户通过 Bootstrap 可以方便的创建 Netty 的客户端并发起异步 TCP 连接操作。客户端代码示例:package netty.netty5.client;import java.io.BufferedReader;import java.io.InputStreamReader;import i

2020-07-24 11:22:52 574

原创 2 Netty 服务端创建

当我们直接使用 JDK NIO 的类库开发基于 NIO 的异步服务端时,需要使用到 多 路 复 用 器 Selector、ServerSocketChannel、SocketChannel、ByteBuffer、 SelectionKey 等等,相比于传统的 BIO 开发,NIO 的开发要复杂很多,开发出稳 定、高性能的异步通信框架,一直是个难题。 Netty 为了向使用者屏蔽 NIO 通信的底层细节,在和用户交互的边界做了封 装,目的就是为了减少用户开发工作量,降低开发难度。ServerBoot...

2020-07-23 15:02:30 174

原创 1 Netty 入门

1.1 传统的BIO编程 网络编程的基本模型是 Client/Server 模型,也就是两个进程之间 进行相互通信,其中服务端提供位置信息(绑定的 IP 地址和监听端口),客 户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建立连 接,如果连接建立成功,双方就可以通过网络套接字(Socket)进行通信。 在基于传统同步阻塞模型开发中,ServerSocket 负责绑定 IP 地址, 启动监听端口;Socket 负责发起连接操作。连接成功之后,双方通过输入和 输出流进...

2020-07-22 21:43:42 123

原创 Java Reflection(三):泛型、动态类加载与重载

我常常在一些文章以及论坛中读到说Java泛型信息在编译期被擦除(erased)所以你无法在运行期获得有关泛型的信息。其实这种说法并不完全正确的,在一些情况下是可以在运行期获取到泛型的信息。这些情况其实覆盖了一些我们需要泛型信息的需求。在本节中我们会演示一下这些情况。1.1泛型方法返回类型如果你获得了java.lang.reflect.Method对象,那么你就可以获取到这个方法的泛型返回类型信息package reflection.generic;import java.util.Arra

2020-07-02 12:44:51 358

原创 Java Reflection(二):Getters and Setters、私有变量和私有方法、

1.Getters and Setters使用Java反射你可以在运行期检查一个方法的信息以及在运行期调用这个方法,使用这个功能同样可以获取指定类的getters和setters,你不能直接寻找getters和setters,你需要检查一个类所有的方法来判断哪个方法是getters和setters。首先让我们来规定一下getters和setters的特性:GetterGetter方法的名字以get开头,没有方法参数,返回一个值。SetterSetter方法的名字以set开头,有一个方

2020-07-01 16:52:07 432

原创 Java Reflection(一)Classes、Constructor、变量、方法

1.Classes使用Java反射机制可以在运行时期检查Java类的信息,检查Java类的信息往往是你在使用Java反射机制的时候所做的第一件事情,通过获取类的信息你可以获取以下相关的内容:1.1Class对象在你想检查一个类的信息之前,你首先需要获取类的Class对象。Java中的所有类型包括基本类型(int, long, float等等),即使是数组都有与之关联的Class类的对象。如果你在编译期知道一个类的名字的话,那么你可以使用如下的方式获取一个类的Class对象。Class my

2020-07-01 16:28:26 195

转载 Java NIO(八)Java NIO与IO

Java NIO和IO的主要区别下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异。IO NIO面向流 面向缓冲阻塞IO 非阻塞IO无 选择器面向流与面向缓冲Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能...

2020-06-24 08:32:39 134

转载 Java NIO(七)Pipe

Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。这里是Pipe原理的图示:创建管道通过Pipe.open()方法打开管道。Pipe pipe = Pipe.open();向管道写数据要向管道写数据,需要访问sink通道。Pipe.SinkChannel sinkChannel = pipe.sink();通过调用SinkChannel的write()方法,将数据

2020-06-24 08:31:57 103

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

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