Java|从操作系统层面分析 Java IO 演进之路( 六 )
) = 26clone(child_stack=0x7f702cb50fb0 flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID parent_tidptr=0x7f702cb519d0 tls=0x7f702cb51700 child_tidptr=0x7f702cb519d0) = 10067... woker线程(10035 , 第一个连接)
epoll_ctl(13 EPOLL_CTL_ADD 24 {EPOLLIN {u32=24 u64=24) = 0epoll_ctl(13 EPOLL_CTL_MOD 24 {EPOLLIN {u32=24 u64=3226004877247250456) = 0epoll_wait(13 [{EPOLLIN {u32=11 u64=17042151607409573899
8192 1000) = 1 = 1epoll_wait(13 [
8192 1000) = 0 worker线程(10067 , 第二个连接)
epoll_ctl(16 EPOLL_CTL_ADD 26 {EPOLLIN {u32=26 u64=26) = 0epoll_ctl(16 EPOLL_CTL_MOD 26 {EPOLLIN {u32=26 u64=3221483685433835546) = 0epoll_wait(16 [{EPOLLIN {u32=14 u64=17042497300737294350
8192 1000) = 1epoll_wait(16 [
8192 1000) = 0epoll_wait(16 [
8192 1000) = 0 worker线程(10067 , 第二个连接)
epoll_ctl(19 EPOLL_CTL_ADD 27 {EPOLLIN {u32=27 u64=27) = 0epoll_ctl(19 EPOLL_CTL_MOD 27 {EPOLLIN {u32=27 u64=3216966479350071323) = 0 worker线程(8055 , 第四个连接)
epoll_ctl(10 EPOLL_CTL_ADD 28 {EPOLLIN {u32=28 u64=28) = 0epoll_ctl(10 EPOLL_CTL_MOD 28 {EPOLLIN {u32=28 u64=3302604828697427996) = 0 worker线程(10035 , 第五个连接 , 不在clone线程 , 而是复用了第一个epoll对应的worker)
epoll_ctl(13 EPOLL_CTL_ADD 29 {EPOLLIN {u32=29 u64=29) = 0epoll_ctl(13 EPOLL_CTL_MOD 29 {EPOLLIN {u32=29 u64=29) = 0 概括为:
epoll和boss、worker之间的关系:一共有4个worker对应着4个epoll对象 , boss和每个worker都有对应自己的epoll 。 boss根据epoll数量 , 平衡分配连接到每个worker对应的epoll中 。 7 总结
下图通过对系统调用的调查得出 netty 和 kernel 交互图:
初始化直接创建5个epoll , 其中7号为boss使用 , 专门用于处理和客户端连接;其余4个用来给worker使用 , 用户处理和客户端的数据交互 。
work的线程数量 , 取决于初始化时创建了几个epoll , worker的复用本质上是epoll的复用 。
work之间为什么要独立使用epoll?为什么不共享?
为了避免各个worker之间发生争抢连接处理 , netty直接做了物理隔离 , 避免竞争 。 各个worker只负责处理自己管理的连接 , 并且后续该worker中的每个client的读写操作完全由 该线程单独处理 , 天然避免了资源竞争 , 避免了锁 。 worker单线程 , 性能考虑:worker不仅仅要epoll_wait , 还是处理read、write逻辑 , 加入worker处理了过多的连接 , 势必造成这部分消耗时间片过多 , 来不及处理更多连接 , 性能下降 。 8 优缺点
优点
数据处理:netty提供了大量成熟的数据处理组件(ENCODER、DECODER) , HTTP、POP3拿来即用 。 编码复杂度、可维护性:netty充分使得业务逻辑与网络处理解耦 , 只需要少量的BootStrap配置即可 , 更多的集中在业务逻辑处理上 。 性能:netty提供了的ByteBuf(底层Java原生的ByteBuffer) , 提供了池化的ByteBuf , 兼顾读取性能和ByteBuf内存分配(在后续文档中会再做详解) 。 缺点
入门有一定难度 。 五 AIO 1 启动
main线程
epoll_create(256) = 5epoll_ctl(5 EPOLL_CTL_ADD 6 {EPOLLIN {u32=6 u64=11590018039084482566) = 0##创建BOSS 线程(Proactor)clone(child_stack=0x7f340ac06fb0 flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID parent_tidptr=0x7f340ac079d0 tls=0x7f340ac07700 child_tidptr=0x7f340ac079d0) = 22704socket(AF_INET6 SOCK_STREAM IPPROTO_IP) = 8setsockopt(8 SOL_IPV6 IPV6_V6ONLY [0
4) = 0setsockopt(8 SOL_SOCKET SO_REUSEADDR [1
4) = 0bind(8 {sa_family=AF_INET6 sin6_port=htons(9090) inet_pton(AF_INET6 \"::\"sin6_addr) sin6_flowinfo=0 sin6_scope_id=0 28) = 0listen(8 50)accept(8 0x7f67d01b3120 0x7f67d9246690) = -1epoll_ctl(5 EPOLL_CTL_MOD 8 {EPOLLIN|EPOLLONESHOT {u32=8 u64=15380749440025362440) = -1 ENOENT (No such file or directory)epoll_ctl(5 EPOLL_CTL_ADD 8 {EPOLLIN|EPOLLONESHOT {u32=8 u64=15380749440025362440) = 0read(0 22704(BOSS 线程(Proactor))
- 章子怡扎减龄丸子头,短裙露美腿不像生过娃,从影20年笑容依旧甜
- 三星|从“不想买”到“抢着买”,骁龙8+无线充电+IP68防水,下跌600元
- 男子带家传木盒来鉴宝,盒子从没打开过,专家:稳住,两个好消息
- 世界上最孤独的“手”,他握住一棵树长达50年,却从来没有松过手
- 互联互通|哪些无人机适合新手使用?从普宙O2到大疆Mini 3 Pro,一文读懂
- 路由器|WiFi信号增强从简到易,软硬兼施后效果明显
- 关于时间的12件事,比如为什么从三月份起要把你的钟表拨快些?
- Java|干翻小米,红米又出超大杯旗舰,120W+2K直屏+双旗舰芯
- 百度地图|Java程序员应知应会之Maven和Gradle的区别
- javascript|穿戴设备将迎变革,OPPO又增新专利,能提升模式切换效率!
