文章目录

  • netty
  • 1:环境配置
    • 与其他对比
    • future缺陷
  • 2:结构
  • 3:设计模式 delay
    • 策略模式 todo
    • 责任链模式 todo
    • 单例模式模式 todo
    • 装饰者模式
      • ReplayingDecoder todo
    • 观察者模式 todo
    • 迭代器模式 todo
    • 工厂模式 todo
    • 组合模式
  • 4:netty源码解析
    • Channel todo
    • Future todo
    • ChannelHandler todo
      • ChannelInboundHandler
        • 释放buf
      • Decoder
        • ByteToMessageDecoder
        • ReplayingDecoder
        • MessageToMessageDecoder
        • 其它decoder
        • LengthFieldBasedFrameDecoder
      • Encoder
        • MessageToByteEncoder
        • MessageToMessageEncoder
      • 编码解码器
    • ChannelOutboundHandler
      • 释放buf
    • ChannelHandlerContext
    • ChannelPipeline todo
    • EventLoop
    • ByteBuf
      • 池化
      • 浅层复制
    • 序列化
      • 文件启动
      • maven插件启动
      • 内置protobuf序列化
    • protobuf语法
  • 5:常见问题 todo
    • 如何实现断线重连
    • 如何实现长连接心跳保活机制
    • 如何解决epoll空轮训导致cpu100%的bug
    • 对空闲线程心跳的处理
    • 粘包&拆包
      • 原理
      • 解决方法
    • ByteBuf内存泄漏问题排查
  • 6:内存模型 todo
    • AIO
    • NIO
    • BIO
    • mmap
    • zero-copy
  • 7:线程模型 todo
    • Reactor
  • 8:protobuf编解码机制 todo
  • 9:Reactor响应式编程 todo
  • 10:手写IM
  • 参考

netty

1:环境配置

  1. 注释所有
   <!-- <module>all</module>-->
<!--    <module>resolver-dns-native-macos</module>--><!--    <module>transport-native-unix-common-tests</module><module>transport-native-unix-common</module><module>transport-native-epoll</module><module>transport-native-kqueue</module>--><!--  <module>testsuite</module><module>testsuite-autobahn</module><module>testsuite-http2</module><module>testsuite-osgi</module><module>testsuite-shading</module><module>testsuite-native</module><module>testsuite-native-image</module><module>testsuite-native-image-client</module><module>testsuite-native-image-client-runtime-init</module><module>transport-blockhound-tests</module>-->

注释${tcnative.classifier}

更改maven jdk编译版本

<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>

2:跳过运行时error

3:关闭校验

checkstyle.xml

4:maven deprecation 错误

<!--   <showDeprecation>true</showDeprecation>-->
<!--    <module>microbench</module>-->

5: 修改jdk版本

<!-- JDK12 NEW -->
<profile><id>java1.8</id><activation><jdk>16</jdk></activation><properties><!-- Not use alpn agent as Java11+ supports alpn out of the box --><argLine.alpnAgent /><argLine.java9.extras /><!-- Export some stuff which is used during our tests --><argLine.java9>--illegal-access=deny ${argLine.java9.extras}</argLine.java9><forbiddenapis.skip>true</forbiddenapis.skip><!-- Needed because of https://issues.apache.org/jira/browse/MENFORCER-275 --><enforcer.plugin.version>3.0.0-M3</enforcer.plugin.version><!-- 1.4.x does not work in Java10+ --><jboss.marshalling.version>2.0.5.Final</jboss.marshalling.version><!-- This is the minimum supported by Java12+ --><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><!-- pax-exam does not work on latest Java12 EA 22 build --><skipOsgiTestsuite>true</skipOsgiTestsuite></properties>
</profile>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YnxPakO9-1639712908078)(C:\Users\GIGA25\Desktop\学习\image-20210514225811386.png)]

6:程序包sun.misc不存在

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GCHXS96j-1639712908080)(C:\Users\GIGA25\Desktop\学习\image-20210514230131104.png)]

7:注释异常

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D8mQwDSz-1639712908081)(C:\Users\GIGA25\Desktop\学习\image-20210514230247691.png)]

与其他对比

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8jcshz5k-1639712908082)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210518131114680.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zlrMMHqf-1639712908083)(C:\Users\GIGA25\Desktop\学习\image-20210518131124117.png)]

Callable call = 》 run Runnable

Future继承run作为callable桥接类

future缺陷

join:无法获取结果

future:获取结果线程需要阻塞

最终结果:通过Guava异步回调获取结果处理

2:结构

EventLoopGroup
EventLoop  Executor   ,Reactor,绑定一个线程和Selector
SocketChannel   :NioServerSocketChannel   channel  包含SelectableChannel
ChannelHandler
ChannelPipeline
ChannelFuture  :因为所有操作都是异步的,所以future返回结果
ChannelPipeline
ByteBuf            buffer

handler n-》1 pipeline 1-》1 Channel n - 》1 EventLoop n - 》 1 EventLoopGroup

EventLoop 1 -》 1 Thread

3:设计模式 delay

策略模式 todo

责任链模式 todo

单例模式模式 todo

装饰者模式

ReplayingDecoder todo

观察者模式 todo

迭代器模式 todo

工厂模式 todo

组合模式

CombinedChannelDuplexHandler

4:netty源码解析

Channel todo

Future todo

对Future增强,调用以非阻塞处理回调的结果

引入GenericFutureListener,表示异步执行完成的监听器。采用监听器模式,监听异步任务执行从而执行回调方法。

ChannelHandler todo

ChannelInboundHandler

ChannelInboundHandlerAdapterSimpleChannelInboundHandler类,在这里顺便说下它们两的区别吧。 继承SimpleChannelInboundHandler类之后,会在接收到数据后会自动release掉数据占用的Bytebuffer资源。并且继承该类需要指定数据格式。 而继承ChannelInboundHandlerAdapter则不会自动释放,需要手动调用ReferenceCountUtil.release()等方法进行释放。继承该类不需要指定数据格式。 所以在这里,个人推荐服务端继承ChannelInboundHandlerAdapter,手动进行释放,防止数据未处理完就自动释放了。而且服务端可能有多个客户端进行连接,并且每一个客户端请求的数据格式都不一致,这时便可以进行相应的处理。 客户端根据情况可以继承SimpleChannelInboundHandler类。好处是直接指定好传输的数据格式,就不需要再进行格式的转换了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BE7E1JVF-1639712908084)(C:\Users\GIGA25\Desktop\学习\image-20210513215652796.png)]

  • HttpRequestDecoder 即把 ByteBuf 解码到 HttpRequest 和 HttpContent。

  • HttpResponseEncoder 即把 HttpResponse 或 HttpContent 编码到 ByteBuf。

  • HttpServerCodec 即 HttpRequestDecoder 和 HttpResponseEncoder 的结合。

  • HttpObjectAggregator 即通过它可以把 HttpMessage 和 HttpContent 聚合成一个 FullHttpRequest 或者 FullHttpResponse (取决于是处理请求还是响应),而且它还可以帮助你在解码时忽略是否为“块”传输方式。因此,在解析 HTTP POST 请求时,请务必在 ChannelPipeline 中加上 HttpObjectAggregator。
    
handlerAdded:  ch.pipeline().addLast(inHandler); 触发
channelRegistered:通道注册完成后,成功绑定NioEventLoop线程后,会调用fireChannelRegistered,触发通道注册事件
channelActive:当通道激活完成后(所有的业务处理器添加,注册的异步任务完成,并且NioEventLoop线程绑定的异步任务完成),会调用fireChannelActive,触发通道激活事件
channelRead:当通道缓冲区可读,会调用fireChannelRead,触发通道可读事件
channelReadComplete:通道缓冲区读完,调用fireChannelReadComplete,触发通道读完事件channelInactive:连接断开或不可用(当通道的底层连接已经不是ESTABLISH状态,或者底层连接已经关闭时),调用fireChannelInactive,触发连接不可用
exceptionCaught:抛出异常,调用fireExceptionCaught,触发异常捕获事件handlerRemoved:netty移除通道上所有的业务处理器

释放buf

若继承ChannelInboundHandlerAdapter,

//手动释放
in.release();
//调用父类释放
super.channelRead(ctx,msg);  会调用末端TailHandler末尾处理器自动释放缓冲区

SimpleChannelInboundHandler释放

//手动释放
in.release();
实现channelRead0方法,使用自动释放

Decoder

ByteToMessageDecoder

解码器:为入站处理器

作用:将byteBuf解码成pojo,负责ByteBuf的释放.

实现方式:解码数据放入out集合后,父类不断循环遍历每个out元素执行后续handler.

ReplayingDecoder

第一个接收byte默认直接内存缓冲区.

使用ReplayingDecoder,该类装饰了buffer,在缓冲区真的读数据时,会判断长度是否够,不够异常.然后捕获,等下次IO事件到时读取.

作用:

  • 在读取ByteBuf缓冲区之前,检查缓冲区是否足够字节。

  • 整数的分包解码器。

//保存当前解码器在解码过程中的当前阶段,默认null
private S state;
读断点指针,当读数据时,一旦可读数据不够,则抛出异常之前,会将读指针还原之前checkPoint.下次读取从checkPoint读取
private int checkpoint = -1;

缺点:

  1. 不是所有byteBuf被ReplayingDecoder支持
  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QRlTft4V-1639712908085)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210527210647090.png)]

MessageToMessageDecoder

作用:将pojo转换另一种pojo,实参需要指定入站消息pojo类型

public class Integer2StringDecoder extends MessageToMessageDecoder<Integer> {@Overrideprotected void decode(ChannelHandlerContext ctx, Integer msg, List<Object> out) throws Exception {//子类执行完后,将遍历out所有元素.逐个发送给下站Inbound入站处理器out.add(String.valueOf(msg));}
}

其它decoder

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6nNqQBUp-1639712908086)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210527221907390.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sx3tlzPM-1639712908087)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210527221923194.png)]

LengthFieldBasedFrameDecoder

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMGnmavK-1639712908087)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210529170102094.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TfRQKApN-1639712908088)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210529171245023.png)]

Encoder

MessageToByteEncoder

编码器:流水线从后向前执行。

作用:将pojo编码成byte

MessageToMessageEncoder

作用:将pojo编码成pojo,存入out,将遍历每个元素向前执行handler

编码解码器

ByteToMessageCodec

配套提供编码解码器

CombinedChannelDuplexHandler

通过组合方式,自定义编码解码器

ChannelOutboundHandler

bind:监听地址,完成底层io通道的ip地址绑定,若使用Tcp,则只能服务端用
connect:连接服务端,如果使用TCP传输协议,只作用客户端
disconnect:断开与服务端连接,如果使用TCP传输协议,只作用客户端
close:主动关闭通道

释放buf

HeadHandler释放

ChannelHandlerContext

表示ChannelHandler和ChannelPipeline 之间关联

作用

  1. 获取上下文所关联netty组件实例,如关联的通道,关联的流水线,上下文内部handler业务处理器实例等
  2. 入站和出站处理方法

和ChannelHandler和ChannelPipeline不同,如果用ChannelHandlerContext则只会从当前的节点开始执行Handler业务处理器,并传播到同类型处理器的下一节点.

ChannelPipeline todo

双向链表

支持热插拔:动态删除,增加流水线上处理器

addFirst(String name, ChannelHandler handler); 头部添加handler
addLast(String name, ChannelHandler handler); 尾部添加handler
addBefore(String baseName, String name, ChannelHandler handler); 在baseName处理器的前面添加handler
addAfter(String baseName, String name, ChannelHandler handler);在baseName处理器的后面添加handler

EventLoop

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-umrXsJ0M-1639712908088)(C:\Users\GIGA25\Desktop\学习\image-20210518231730078.png)]

ByteBuf

池化

​ 创建一个buf池,需要buf从池拿出,不需要则放回.然后通过引用计数方式来维护释放分配

计数=0则:

  1. Pooled池化Buf放入池中,等待下次分配
  2. 未池化buf,若是堆,则被jvm回收,若是直接内存类型,调用本地方法释放外部内存
UnpooledByteBufAllocator / PooledByteBufAllocator :采用jemalloc高效内存分配策略

读取和写入索引分开,目前javanio是flip/clean来切换读写模式,而netty不一样,通过维护2套读写索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dRennwFa-1639712908089)(C:\Users\GIGA25\Desktop\学习\image-20210520192227151.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9wAeaCBv-1639712908090)(C:\Users\GIGA25\Desktop\学习\image-20210520192701813.png)]

创建完一个buf,引用计数=1,为0表示buf没有任何进程引用,占用的内存需要回收
refCnt:获取引用次数
retain:引用次数+1,引用为0,在此引用抛出异常
release:释放引用次数-1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vOMGAn9L-1639712908091)(C:\Users\GIGA25\Desktop\学习\image-20210520225040444.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEQMRw4O-1639712908091)(C:\Users\GIGA25\Desktop\学习\image-20210520225048609.png)]

浅层复制

slice():返回buf可读部分切片
slice(int index, int length):指定位置切片
duplicate():全部浅层复制.不会改变源引用计数.读写指针,最大容量与源一样.
存在问题,buf释放资源了,浅层复制的就不能读写了。可通过调用一次retain()增加引用.使用浅层buf后释放.

序列化

protobuf

// [开始声明]
syntax = "proto3";
//定义protobuf的包名称空间
package com.crazymakercircle.netty.protocol;
// [结束声明]// [开始 java 选项配置]  在生成proto文件中消息的pojo类和builder(构造者)的java代码时,将java代码放入指定package
option java_package = "io.netty.example.chapter2.protocol";
option java_outer_classname = "MsgProtos"; //在生成proto文件所对应的java代码时,所生成的java外部类的名称.
// [结束 java 选项配置]// [开始 消息定义]
//message定义消息结构体,对应javapojo类
message Msg {uint32 id = 1;  // Unique ID number for this person.  表示字段类型,字段名,排序位置string content = 2;
}// [结束 消息定义]

文件启动

下载protoc3.6.1.exe

执行命令

./protoc3.6.1.exe ./Msg.proto --java_out=./

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5c1MAATA-1639712908091)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210529211845429.png)]

maven插件启动

<build><plugins><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.5.0</version><extensions>true</extensions><configuration><!--proto文件路径--><protoSourceRoot>${project.basedir}/protobuf</protoSourceRoot><!--目标路径--><outputDirectory>${project.build.sourceDirectory}</outputDirectory><!--设置是否在生成java文件之前清空outputDirectory的文件--><clearOutputDirectory>false</clearOutputDirectory><!--临时目录--><temporaryProtoFileDirectory>${project.build.directory}/protoc-temp</temporaryProtoFileDirectory><!--protoc 可执行文件路径--><protocExecutable>${project.basedir}/protobuf/protoc3.6.1.exe</protocExecutable></configuration><executions><execution><goals><goal>compile</goal><goal>test-compile</goal></goals></execution></executions></plugin></plugins></build>

执行compile命令执行

引入maven,

    <dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.6.1</version></dependency>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lxMV7Nu1-1639712908092)(C:\Users\GIGA25\Desktop\学习\image-20210529212415741.png)]

内置protobuf序列化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UPSnkyuK-1639712908092)(C:\Users\GIGA25\Desktop\学习\image-20210529220406559.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RinNFflg-1639712908093)(C:\Users\GIGA25\Desktop\学习\image-20210529220434560.png)]

protobuf语法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cdTBM1x0-1639712908093)(C:\Users\GIGA25\Desktop\学习\image-20210529222923160.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u0yAwYAl-1639712908094)(C:\Users\GIGA25\Desktop\学习\image-20210529222947566.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AulSvCaL-1639712908094)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210529224804141.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WLHxfZ32-1639712908095)(C:\Users\GIGA25\Desktop\学习\image-20210529224812222.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l0oBNyum-1639712908095)(C:\Users\GIGA25\Desktop\学习\image-20210529224826781.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ckEG8J3l-1639712908096)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210529230837562.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZPuxgeQO-1639712908096)(C:\Users\GIGA25\Desktop\学习\image-20210529224942036.png)]

5:常见问题 todo

如何实现断线重连

如何实现长连接心跳保活机制

如何解决epoll空轮训导致cpu100%的bug

对空闲线程心跳的处理

粘包&拆包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qli5dbHZ-1639712908096)(C:\Users\GIGA25\Desktop\学习\image-20210529184144792.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IDOtBNAu-1639712908097)(C:\Users\GIGA25\Desktop\学习\image-20210529184152981.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zc99j5H5-1639712908097)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210529184222240.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nSd5TokL-1639712908098)(C:\Users\GIGA25\AppData\Roaming\Typora\typora-user-images\image-20210529184242089.png)]

原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nuA6mH7f-1639712908098)(C:\Users\GIGA25\Desktop\学习\image-20210529185946057.png)]

解决方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8U3GzdlF-1639712908099)(C:\Users\GIGA25\Desktop\学习\image-20210529190040320.png)]

ByteBuf内存泄漏问题排查

6:内存模型 todo

AIO

NIO

BIO

mmap

zero-copy

7:线程模型 todo

Reactor

8:protobuf编解码机制 todo

9:Reactor响应式编程 todo

10:手写IM

1:指定协议

参考

https://netty.io/4.1/api/index.html netty-api

https://netty.io/wiki/related-articles.html

https://www.iocoder.cn/Netty/Netty-collection/

https://www.bianchengquan.com/article/597368.html

https://github.com/sanshengshui/netty-learning-example

https://www.cnblogs.com/sanshengshui/p/9774746.html

https://segmentfault.com/a/1190000007282789

https://mp.weixin.qq.com/s?__biz=MzIxMDAwMDAxMw==&mid=2650725011&idx=1&sn=741b290093788f820cbb61905cc214bb&chksm=8f613b71b816b26775629757c9aec632ce645f8cdee5848e056300b09f1874a28205ed54151b&mpshare=1&scene=23&srcid=&sharer_sharetime=1570838084571&sharer_shareid=12ae0c9c538778cd36ca6e4500b81b6f#rd

​ github https://github.com/fuzhengwei/itstack-demo-netty

Netty实战 <人邮><工信>

Java高并发核心编程 卷1:NIO、Netty、Redis、ZooKeeper <机械工业出版社]>

​ github:https://gitee.com/crazymaker/crazy_tourist_circle__im

Netty权威指南 <李林峰> <电子工业出版社>

Netty进阶之路跟着案例学Netty 李林锋 <电子工业出版社>

Netty 4核心原理与手写RPC框架实战 <电子工业出版社>

​ github https://github.com/gupaoedu-tom/netty4-samples

Netty原理解析与开发实战

Netty4开发手册

Netty手册

Netty5.0架构剖析和源码解读

https://www.52doc.com/download/7341 下载所有电子书

**《 Java 高并发 三部曲 》****

https://www.cnblogs.com/crazymakercircle/p/9904544.html

理论场景实践

netty4.0源码解析(持续更新)相关推荐

  1. solrlucene3.6.0源码解析(三)

    solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...

  2. 锚框、交并比和非极大值抑制(tf2.0源码解析)

    锚框.交并比和非极大值抑制(tf2.0源码解析) 文章目录 锚框.交并比和非极大值抑制(tf2.0源码解析) 一.锚框生成 1.锚框的宽高 2.锚框的个数 3.注意点(★★★) 4.tf2.0代码 二 ...

  3. Vue2.0源码解析——编译原理

    Vue2.0源码解析--编译原理 前言:本篇文章主要对Vue2.0源码的编译原理进行一个粗浅的分析,其中涉及到正则.高阶函数等知识点,对js的考察是非常的深的,因此我们来好好啃一下这个编译原理的部分. ...

  4. Heritrix 3.1.0 源码解析(八)

    本文接着分析存储CrawlURI curi的队列容器,最重要的是BdbWorkQueue类及BdbMultipleWorkQueues类 BdbWorkQueue类继承自抽象类WorkQueue,抽象 ...

  5. Heritrix 3.1.0 源码解析(六)

    本文分析BdbFrontier对象的相关状态和方法 BdbFrontier类继承自WorkQueueFrontier类   WorkQueueFrontier类继承自AbstractFrontier类 ...

  6. Heritrix 3.1.0 源码解析(十一)

    上文分析了Heritrix3.1.0系统是怎么添加CrawlURI curi对象的,那么在系统初始化的时候,是怎么载入CrawlURI curi种子的呢? 我们回顾前面的文章,在我们执行采集任务的la ...

  7. Heritrix 3.1.0 源码解析(三十四)

    本文主要分析FetchFTP处理器,该处理器用于ftp文件的下载,该处理器的实现是通过封装commons-net-2.0.jar组件来实现ftp文件下载 在FetchFTP处理器里面定义了内部类Soc ...

  8. Heritrix 3.1.0 源码解析(十四)

    我在分析BdbFrontier对象的void schedule(CrawlURI caURI).CrawlURI next() .void finished(CrawlURI cURI)方法是,其实还 ...

  9. 基于8.0源码解析:startService 启动过程

    基于8.0源码解析:startService 启动过程 首先看一张startService的图,心里有个大概的预估,跟Activity启动流程比,Service的启动稍微简单点,并且我把Service ...

最新文章

  1. Java项目:前后端分离网上手机商城平台系统设计和实现(java+vue+redis+springboot+mysql+ssm)
  2. REST、SOAP、protocolbuf、thrift、avro
  3. Git的安装(附安装包)
  4. 高通8155车载芯片_WEY来“摩卡”云首秀,搭载高通8155芯片
  5. 布局优化之ViewStub、Include、merge使用分析
  6. java voip 的sip服务器搭建_用树莓派搭建低成本VOIP服务器与电话系统
  7. 计算机按姓氏笔画顺序排序规则,【姓氏文化】按姓氏笔画排序的原则
  8. 如何打造一款火遍国内外的自走棋手游?我们跟《战歌竞技场》的美术和程序聊了聊
  9. 改善民生 住有所居(加快经济发展方式转变)
  10. C++ 函数调用过程中栈区的变化——(栈帧、esp、ebp)
  11. python数值运算m op n_M OP N数值运算问题
  12. 数据库连接池使用场景,工作原理和实现步骤
  13. Java 并发编程 常见面试总结
  14. linux线程调用完类就退出,linux下 c中怎么让才能安全关闭线程 和 linux线程退出时执行的程序(线程清理处理程序)简单例子...
  15. VR全景的拍摄与制作
  16. 超强视频剪切工具Boilsoft Video Splitter7.02.2中文免费绿色版_我是亲民_新浪博客...
  17. 数据结构与算法 各类数图概念集合
  18. Perl语言开发工具(持续整理)
  19. 江苏机考-信息技术基础部分总结
  20. 10进制计数器Verilog编程

热门文章

  1. js关闭一个html页面跳转,js如何关闭当前页面
  2. Xilinx IDDR与ODDR原语的使用
  3. conductor event 和wait 分析及测试记录
  4. 常用数据库设计规范总结
  5. Linux下C语言判断文件是否存在
  6. mx350显卡天梯图_2020最新显卡高清天梯图
  7. Linux查看ip地址时,只显示127.0.0.1
  8. linux查看IP、域名、端口的网络是否相通
  9. java毕业生设计中学生作文大赛管理平台计算机源码+系统+mysql+调试部署+lw
  10. 【PDAF原理简介】