自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(59)
  • 资源 (2)
  • 论坛 (1)

原创 Dubbo——协议详解

Dubbo协议详解Dubbo协议设计参考了现有TCP/IP协议。一次RPC调用包括协议头和协议体两个部分。16字节长的报文头部主要携带了魔法数(0xdabb),以及当前请求报文是否是Request、REsponse、心跳和事件的信息,请求时也会携带当前报文体内序列化协议编号。除此之外还携带了请求状态,以及请求唯一标识和报文体长度。Dubbo协议字段解析:偏移比特位字段描述作用0~7魔数高位存储的是魔法数高位(0xda00)8~15魔数低位存储的是魔法数低位(0xb

2020-06-30 22:38:21 85

原创 Dubbo——服务消费的实现原理

单注册中心消费原理整体RPC的消费原理: ReferenceCnofig ↓ Protocol ----> Dubbo、injvm等 ↓ Invoker -----> DubboInvoker等 ↓ ProxyFactoy -----> Javassist、JDK动态代理 ↓ Ref在整体上看,Dubbo框架做服务消费也分为两大部分:第一部分通过持有远程服务实例生成In

2020-06-30 16:25:55 77

原创 Dubbo——服务暴露的实现原理

配置承载初始化不管在服务暴露还是服务消费场景下,Dubbo框架都会根据优先级对配置信息做聚合处理,目前默认覆盖策略主要遵循以下几点规则:-D 传递给JVM参数优先级最高,比如-Ddubbo.protocol.port=20880。代码或XML配置优先级次高,比如Spring中XML文件制定<dubbo:protocol port="20880"/>。配置文件优先级最低,比如dubbo.properties文件制定dubbo.protocol.port=20880。一般推荐使用dub

2020-06-30 12:08:42 91

原创 Dubbo——扩展点动态编译的实现

扩展点动态编译的实现Dubbo SPI的自适应特性让整个框架非常灵活,而动态编译又是自适应特性的基础,因为动态生成的自适应类只是字符串,需要通过编译才能得到真正的Class。虽然我们可以使用反射来动态代理一个类,但是在性能上和直接编译好的Class会有一定差距。Dubbo SPI通过代码的动态生成,并配合动态编译器,灵活地在原始类基础上创建新的自适应类。总体结构Dubbo中有三种代码编译器,分别是JDK编译器、Javassist编译器和AdaptiveCompiler编译器。这几种编译器都实现了Com

2020-06-29 20:43:30 36

原创 Dubbo——ExtensionFactory的实现原理

ExtensionFactory的实现原理RegistryFactory工厂类通过@Adaptive({"protocol"})注解动态查找注册中心实现,根据URL中的protocol参数动态选择对应的注册中心工厂,并初始化具体的注册中心客户端。而实现这个特性的ExtensionLoader类,本身又是通过工厂方法ExtensionFactory创建的,并且这个工厂接口上也有SPI注解,还有多个实现。AdaptiveExtensionFactory这个实现类工厂上有@Adaptive注解。因此,Ada

2020-06-29 18:30:10 67

原创 Dubbo——ExtensionLoader的工作原理

ExtensionLoader的工作原理

2020-06-29 17:15:54 57

原创 Dubbo——扩展点注解

扩展点注解:@SPI@SPI注解可以使用在类、接口和枚举类上,Dubbo框架中都是使用在接口上。它的主要作用就是标记这个几口是一个Dubbo SPI接口,即是一个扩展点,可以有多个不同的内置或用户定义的实现。运行时需要通过配置找到具体的实现类。可以看到SPI注解有一个value属性,通过这个属性,我们可以传入不同的参数来设置这个接口额默认实现类。例如,我们可以看到Transporter接口使用Netty作为默认实现:Dubbo中很多地方通过getExtension(Class<T>

2020-06-29 00:03:07 53

原创 Dubbo——注册中心缓存机制、重试机制

缓存机制缓存的存在就是用空间换取时间,如果每次远程调用都要从注册中心获取一次可调用的服务列表,则会让注册中心承受巨大的流量压力。另外,每次额外的网络请求也会让整个系统的性能下降。因此,Dubbo的注册中心实现了通用的缓存机制,在抽象类AbstractRegistry中实现。消费者或服务治理中心获取注册信息后会做本地缓存。内存中会有一份,保存在Properties对象里,磁盘上也会持久化一份文件,通过file对象引用。在AbstractRegistry抽象类中有如下定义:内存中的缓存notifie

2020-06-28 22:27:54 241 1

原创 Dubbo——基于API实现

基于API实现Dubbo框架大部分场景都会在Spring中使用,但是不局限于这种场景。除了XML和注解的方式,Dubbo框架还支持API的方式。虽然大部分场景不会直接使用API的方式暴露和消费服务,但是在某些场景下API非常有用。比如开发网关类的应用,需要动态消费不同版本的服务,通过API方式,可以根据前端请求参数构造不同版本的服务实例等。接口:public interface EchoService { String echo(String message);}基于API编写服务器

2020-06-28 15:53:40 59

原创 Dubbo——基于注解实现

接口:public interface EchoService { String echo(String message);}基于注解的服务端:通过注解暴露服务,只需要在服务接口上标注@Service注解即可:import com.alibaba.dubbo.config.annotation.Service;import com.alibaba.dubbo.rpc.RpcContext;import com.alibaba.dubbo.samples.echo.api.Echo

2020-06-28 14:04:49 91

原创 Fork/Join——ForkJoinPool核心方法(二)

12.方法public boolean isShutdown()的使用public class Demo3 { public static void main(String[] args) throws InterruptedException { Runnable runnable = new Runnable() { @Override public void run() { try {

2020-06-25 21:02:20 77

原创 Fork/Join——ForkJoinPool核心方法(一)

ForkJoinPool核心方法1.方法public vod execute(ForkJoinTask<?> task)的使用在ForkJoinPool.java类中的execute()方法是以异步的方式执行任务。public class MyRun1 { public static void main(String[] args) { try { ForkJoinPool pool = new ForkJoinPool();

2020-06-25 18:16:14 77

原创 Fork/Join——分治编程

Fork/Join在JDK1.7版本中提供了Fork/Join 并行执行任务框架,它的主要作用是把大任务分割成若干个小任务,再对每个小任务得到的结果进行汇总,此种开发方法也叫分治编程,分治编程可以极大地利用CPU资源,提高任务执行的效率,也是目前与多线程有关的前沿技术。Fork-Join分治编程与类结构在JDK中并行执行框架Fork-Join使用了“工作窃取( work- stealing)”算法,它是指某个线程从其他队列里窃取任务来执行,那这样做有什么优势或者目的是什么呢?比如要完成一个 比较

2020-06-25 12:35:33 60

原创 Java并发——ScheduledExecutorService

ScheduledExecutorService类 Scheduledexecutor Service的主要作用就是可以将定时任务与线程池功能结合使用。ScheduledThreadPoolExecutor使用Callable延迟运行public class MyCallableAA implements Callable<String> { @Override public String call() throws Exception { try {

2020-06-24 20:33:43 71

原创 Java并发——CompletionService

CompletionService接口CompletionService的功能是以异步的方式生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与处理任务分离开来进行处理。使用submit执行任务,使用take取得已完成的任务,并按照完成这些任务的时间顺序处理它们的结果。接口 Completion Service的结构比较简洁,仅有一个实现类 Executor Completion Service,该类的构造方法如图所示。从构造方法的声明中可以发现,类 Executor Completion

2020-06-24 14:14:56 78

原创 Java并发——Future和Callable

Future和CallableCallable和Runnable主要区别为:Callable接口的call)方法可以有返回值,而Runnable接口的run()方法没有返回值。Callable 接口的call0)方法可以声明抛出异常,而Runnable接口的run()方法不可以声明抛出异常。执行完Callable接口中的任务后,返回值是通过Future 接口进行获得的。get()和ExecutorService中的submit()和isDone()的使用方法submit()不仅可以传人Cal

2020-06-24 11:36:23 55

原创 Java并发——ThreadPoolExecutor详解(二)

工厂ThreadFactory+execute()+UncaughtExceptionHandler处理异常public class Run4 { public static void main(String[] args) { ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 99999, 9999L, TimeUnit.SECONDS, new LinkedBlockingDeque<R

2020-06-23 17:32:02 103

原创 Java并发——ThreadPoolExecutor详解(一)

ThreadPoolExecutor类ThreadPoolExecutor可以非常方便地创建线程池对象,而不需要程序员设计大量的new实例化Thread相关的代码。构造:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)corePoolSize:池中所保存的线程数,包括空闲线程,也就

2020-06-23 13:44:31 68

原创 Java并发——Phaser详解

PhaserPhaser中文翻译为相位器。它与CountDownLatch非常相似,允许我们协调线程的执行。与CountDownLatch相比,它具有一些额外的功能。Phaser是在线程动态数需要继续执行之前等待的屏障。在CountDownLatch中,该数字无法动态配置,需要在创建实例时提供。arriveAndAwaitAdvanve()方法:方arriveAndAwaitAdvanceo的作用与 CountDownLatch类中的awai()方法大体一样,通过从方法的名称解释来看, arriv

2020-06-22 23:28:14 175

原创 Java并发——Exchanger

ExchangerExchanger的功能可以使2个线程之间传输数据,它比生产者/消费者模式使用的 wait/notify要更加方便。exchange()阻塞的特性:public class ThreadA extends Thread{ private Exchanger<String> exchanger; public ThreadA(Exchanger<String> exchanger) { this.exchanger = exch

2020-06-22 20:30:21 49

原创 Java并发——Semaphore

SemaphoreSemaphore即信号、信号系统。此类的主要作用就是限制线程并发的数量,如果不限制线程并发的数量,则CPU的资源很快就被耗尽,每个线程执行的任务是相当缓慢,因为CPU要把时间片分配给不同的线程对象,而且上下文切换也要耗时,最终造成系统运行效率大幅降低,所以限制并发线程的数量还是非常有必要的。Semaphore的同步性public class Service { private Semaphore semaphore = new Semaphore(1); publ

2020-06-22 01:05:43 53

原创 Netty——预置的ChannelHandler和编解码器(二)

空闲的连接和超时

2020-06-17 13:58:48 76

原创 Netty——预置的ChannelHandler和编解码器(一)

预置的ChannelHandler和编解码器Netty 为许多通用协议提供了编解码器和处理器,几乎可以开箱即用,这减少了你在那些相 当繁琐的事务上本来会花费的时间与精力。在本章中,我们将探讨这些工具以及它们所带来的好 处,其中包括 Netty 对于 SSL/TLS 和 WebSocket 的支持,以及如何简单地通过数据压缩来压榨 HTTP,以获取更好的性能。通过SSL/TLS保护Netty应用程序为了支持 SSL/TLS,Java 提供了 javax.net.ssl 包,它的 SSLContext 和

2020-06-17 00:50:04 58

原创 Netty——编解码器

什么是编解码器每个网络应用程序都必须定义如何解析在两个节点之间来回传输的原始字节,以及如何将其和 目标应用程序的数据格式做相互转换。这种转换逻辑由编解码器处理,编解码器由编码器和解码 器组成,它们每种都可以将字节流从一种格式转换为另一种格式。那么它们的区别是什么呢?如果将消息看作是对于特定的应用程序具有具体含义的结构化的字节序列——它的数据。编码器是将消息转换为适合于传输的格式(最有可能的就是字节流);解码器则是将 网络字节流转换回应用程序的消息格式。因此,编码器操作出站数据,而解码器处理入站

2020-06-16 21:55:25 67

原创 Netty——EmbeddedChannel类

EmbeddedChannel类Netty 提供了它所谓的 Embedded 传输,用于测试 ChannelHandler。这个传输是一种特殊的 Channel 实现— EmbeddedChannel— 的功能,这个实现提供了通过 ChannelPipeline 传播事件的简便方法。这个想法是直截了当的:将入站数据或者出站数据写入到 EmbeddedChannel 中,然后检 查是否有任何东西到达了 ChannelPipeline 的尾端。以这种方式,你便可以确定消息是否已 经被编码或者被解码过了,以及

2020-06-16 16:00:29 70

原创 Netty——Bootstrap类

Bootstrap类引导类的层次结构包括一个抽象的父类和两个具体的引导子类:相对于将具体的引导类分别看作用于服务器和客户端的引导来说,记住它们的本意是用来支撑不同的应用程序的功能的将有所裨益。也就是说,服务器致力于使用一个父 Channel 来接受来自客户端的连接,并创建子 Channel 以用于它们之间的通信;而客户端将最可能只需要一个 单独的、没有父 Channel 的 Channel 来用于所有的网络交互。(正如同我们将要看到的,这也适用于无连接的传输协议,如 UDP,因为它们并不是每个连接都需

2020-06-16 01:33:47 65

原创 Netty——EventLoop和线程模型

线程模型概述基本的线程池化模式可以描述为:从池的空闲线程列表中选择一个 Thread,并且指派它去运行一个已提交的任务(一个Runnable 的实现);当任务完成时,将该 Thread 返回给该列表,使其可被重用。虽然池化和重用线程相对于简单地为每个任务都创建和销毁线程是一种进步,但是它并不能 消除由上下文切换所带来的开销,其将随着线程数量的增加很快变得明显,并且在高负载下愈演 愈烈。此外,仅仅由于应用程序的整体复杂性或者并发需求,在项目的生命周期内也可能会出现 其他和线程相关的问题。Eve

2020-06-15 17:51:56 71

原创 Netty——ChannelHandlerContext

ChannelHandlerContext接口ChannelHandlerContext 代表了 ChannelHandler 和 ChannelPipeline 之间的关 联,每当有 ChannelHandler 添加到 ChannelPipeline 中时,都会创建 ChannelHandler- Context。ChannelHandlerContext 的主要功能是管理它所关联的 ChannelHandler 和在 同一个 ChannelPipeline 中的其他 ChannelHandler 之

2020-06-15 15:34:05 68

原创 Netty——ChannelHandler和ChannelPipeline

ChannelHandlerChannel的生命周期:Interface Channel 定义了一组和 ChannelInboundHandler API 密切相关的简单但 功能强大的状态模型,下表列出了 Channel 的这 4 个状态:当这些状态发生改变时,将会生成对应的事件。 这些事件将会被转发给 ChannelPipeline 中的 ChannelHandler,其可以随后对它们做出响应。ChannelHandler的生命周期:在 ChannelHandler 被添加到 Channe

2020-06-15 13:08:51 58

原创 Netty——ByteBuf的API

ByteBuf正如前面所提到的,网络数据的基本单位总是字节。Java NIO 提供了 ByteBuffer 作为它 的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐。Netty 的 ByteBuffer 替代品是 ByteBuf,一个强大的实现,既解决了 JDK API 的局限性, 又为网络应用程序的开发者提供了更好的 API。Netty 的数据处理 API 通过两个组件暴露——abstract class ByteBuf 和 interface ByteBufHolder。优点:它可以被

2020-06-15 10:15:50 74

原创 Netty——传输API

传输API传输 API 的核心是 interface Channel,它被用于所有的 I/O 操作。Channel 类的层次结构如图所示:如图所示,每个 Channel 都将会被分配一个 ChannelPipeline 和 ChannelConfig。 ChannelConfig 包含了该 Channel 的所有配置设置,并且支持热更新。由于特定的传输可能 具有独特的设置,所以它可能会实现一个 ChannelConfig 的子类型。(请参考 ChannelConfig 实现对应的 Javadoc。)

2020-06-14 21:33:53 76

原创 ChannelHandler和ChannelPipeline

ChannelHandler接口从应用程序开发人员的角度来看,Netty 的主要组件是 ChannelHandler,它充当了所有 处理入站和出站数据的应用程序逻辑的容器。这是可行的,因为ChannelHandler 的方法是 由网络事件触发的。事实上,ChannelHandler 可专 门用于几乎任何类型的动作,例如将数据从一种格式转换为另外一种格式,或者处理转换过程 中所抛出的异常。举例来说,ChannelInboundHandler 是一个你将会经常实现的子接口。这种类型的 ChannelHand

2020-06-14 16:31:53 51

原创 TCP——粘包/拆包

TCP粘包/拆包TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想想河里的流水,它们是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。粘包/拆包问题说明假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是不确定的,故可能存在以下4种情况。服务端分两次读取到了两个独

2020-06-14 14:26:21 59

原创 Nginx——防盗链的配置

防盗链盗链是指有一些不良网站,为了在不增加成本的前提下扩充自己站点的内容,直接盗用其他网站的资源链接,而大部分用户又不会发现。这样的做法一方面损害了原网站的合法利益,另一方面又加重了原网站服务器的流量负担图片防盗链图片是一个网站中最容易被盗取的资源,如何使用Nginx来保护图片不被盗链呢?在讲解之前,首先要了解HTTP请求消息中的一个名称为referer的字段,它用于保存当前网页的来源URL地址。当用户打开一个含有图片内容的网页时,浏览器会在图片的请求消息中将网页的URL放在referer中,从而使图

2020-06-13 01:15:48 46

原创 Nginx——重写与重定向

重写与重定向在实际网站运营的过程中,为了能够在修改网站结构或域名后,避免造成网站中的链接或在其他网站中的外链失效,以及提高该网站在搜索引擎的收录量和排名等目的。通常会采用URL重写与重定向,在增强网站专业化的同时,为用户提供更加舒适的使用体验。rewrite模块概述重写与重定向功能是现在大多数Web服务器都支持的一项功能,相对于其他产品而言,Nginx中的rewrite模块提供的功能在配置上更加的灵活自由,可定制性非常的高。它的实现方式也非常的简单,只需要通过rewrite指令根据Nginx提供的全局

2020-06-13 00:41:01 192

原创 Nginx——网页压缩传输

gzip压缩技术gzip(GNU-ZIP)是一种压缩技术,经过gzip压缩后,页面大小可以变为原来的30%甚至更小。这样,用户浏览页面的时候速度会快得多。gzip 网页压缩的实现需要浏览器和服务器的支持,如图:从图可以看出,gzip压缩的过程,首先在服务器端压缩,然后传到浏览器端后解压。当浏览器支持gzip解压时,会在请求消息头中包含Accept-Encoding:gzip,这样Nginx就会向浏览器发送经过gzip后的内容,同时在响应消息头中加人Content-Encoding:gzip,声明这是g

2020-06-13 00:07:58 49

原创 Nginx——缓存配置

缓存配置对于一个含有大量内容的网站来说,随着访问量的增多,对于经常被用户访问的内容,若每一次都要到后端服务器中获取,会给服务器造成很大的压力。为此,利用反向代理服务器对访问频率较多的内容进行缓存,有利于节省后端服务器的资源。Nginx 提供了两种Web缓存方式,一种是永久性缓存,另一种是临时性缓存。缓存实现原理Web缓存服务器位于内容源Web服务器和客户端之间,当客户端用户访问一个URL时,Web缓存服务器就会请求相应的内容源Web服务器,并将响应的信息缓存至内存或磁盘;然后,当下一个请求到来时,如果

2020-06-12 22:14:11 72

原创 Nginx——虚拟主机、设置目录列表、子配置文件引入

虚拟主机虚拟主机技术是指在一台物理主机服务器上划分出多个磁盘空间,每个磁盘空间都是一台虚拟主机,每台虛拟主机都可以独立对外提供Web服务,且互不干扰。在外界看来,虚拟主机就是一台独立的服务器主机,这就意味着用户能够利用虚拟主机把多个不同域名的网站部署在同一台服务器上,而不必再为建立一个网站单独购买一台服务器,既解决了维护服务器技术的难题,同时又极大地节省了服务器硬件成本和相关的维护费用。例如,在一台物理主机服务器(10.20. 30. 40)上划分出多台虚拟主机,同时在每台虚拟主机上部署并运行一个网站,

2020-06-12 17:56:32 126

原创 Nginx——访问日志、错误日志、日志文件切割

访问日志访问日志主要用于记录客户端访问 nginx的每一个请求,格式可通过 log format指令进行自定义,存储路径、缓存大小等可使用 access log指令设置。通过访问日志的配置,可以记录用户IP、访问时间、请求方式、响应状态、地域来源、跳转来源、使用终端等信息。1. 查看默认访问配置:打开Nginx的配置问价nginx.conf,找到log_fromat与access_log指令的默认配置,具体如下:上述第1~3行用于设置访问日志的格式,main表示访问日志格式名称,用户可以自定义。其

2020-06-12 13:48:05 148

原创 Nginx——访问控制

访问控制访问控制是网络安全防范和保护的主要策略,其任务是保证网络资源不被非法访问。Nginx作为Web服务器的后起之秀,也提供了访问控制的功能。它可以根据实际需求,对用户可以访问和禁止的目录进行限制。下面将对Nginx提供的权限控制指令以及典型的应用进行详细讲解。权限控制指令Nginx中提供了两个用于配置访问权限控制的指令,分别为allow和deny。从其名称就可以看出,allow用于设置允许访问的权限deny用于设置禁止访问的权限。在使用时,权限指令后只需跟上允许或禁止的IP、IP段或all即可。其

2020-06-12 00:40:29 49

vuedevtools安装.zip

用于Chrome本地安装vue-devtools,无脑安装!!!! 安装过程: 1.Chrome=》设置=》更多工具=》扩展程序 2.打开开发者模式 3.加载已解压的扩展程序=》选择解压后的文件夹 4.重启浏览器 5.如果失败,在加载后的vuedevtools设置页面开启“允许访问文件网址”

2019-10-27

软考历年真题.zip

2009年开始一直到2018年,历年的软考中级-软件设计师真题。历年的上午+下午真题,全部为PDF格式。题目清晰,完整。

2019-09-09

吴声子夜歌的留言板

发表于 2020-01-02 最后回复 2020-01-02

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