小菜鸟

java菜鸟号正在起航

TCP 流量控制详解

TCP 的流量控制机制是为了防止发送方发送数据的速率过快,导致接收方因缓冲区不足而无法及时处理,最终造成数据丢失。其核心是通过滑动窗口机制动态调整发送方的发送速率,实现点对点的数据传输平衡。

滑动窗口的基本概念

  • 窗口:指接收方当前能够接收的数据量(以字节为单位),由接收方告知发送方。
  • 滑动:随着数据的接收和确认,窗口的范围会动态变化(向前 “滑动”)。

发送方的发送窗口大小受限于接收方的接收窗口大小,确保发送的数据量不超过接收方的处理能力。

接收窗口与发送窗口的交互

  1. 接收方的接收窗口(rwnd)
    接收方在 TCP 报文中的窗口字段(Window Size)告知发送方自己的接收缓冲区剩余容量。例如:
    • 接收方初始缓冲区大小为 1000 字节,已用 300 字节,则rwnd = 700,表示最多还能接收 700 字节。
  2. 发送方的发送窗口
    发送方的发送窗口大小 ≤ 接收方的接收窗口大小(rwnd)。发送方只能发送窗口内的数据,未被确认的数据需暂存,等待接收方确认后才能从窗口中移除。
  3. 窗口滑动的触发
    • 接收方处理完数据后,缓冲区空闲空间增加,会通过 ACK 报文更新 rwnd。
    • 发送方收到新的 rwnd 后,调整发送窗口大小并 “滑动” 窗口(将已确认的数据移出窗口,未发送的新数据纳入窗口)。

零窗口与窗口探测

  • 零窗口(rwnd=0):当接收方缓冲区满时,会告知发送方rwnd=0,此时发送方需暂停发送数据。
  • 窗口探测:发送方在收到零窗口后,会定期发送窗口探测报文(携带 1 字节数据),接收方若缓冲区有空闲,会在回复中更新 rwnd,发送方据此恢复发送。

与拥塞控制的区别

  • 流量控制:仅关注接收方的处理能力(点对点),通过接收窗口(rwnd)调节。
  • 拥塞控制:关注网络链路的负载(全局),通过慢启动、拥塞避免等算法调节发送速率。

两者结合确保 TCP 在复杂网络环境中既能高效传输,又能避免数据丢失。

OpenFeign 集成 OkHttp:提升服务调用性能的实践

OpenFeign 默认使用 JDK 原生的HttpURLConnection作为 HTTP 客户端,但其缺乏连接池支持,频繁创建和关闭连接会导致性能损耗。通过集成 OkHttp(一款高效的 HTTP 客户端),可利用连接池复用 TCP 连接,显著提升微服务间调用的效率。

为什么选择 OkHttp?

OkHttp 作为成熟的 HTTP 客户端,相比HttpURLConnection有以下优势:

  • 连接池支持:复用 TCP 连接,减少三次握手开销;
  • 异步请求:支持非阻塞 IO,提升并发处理能力;
  • 自动重连:对 transient 错误(如连接超时)自动重试;
  • 拦截器机制:便于添加日志、加密等统一处理逻辑;
  • 高效的缓存策略:支持 HTTP 缓存,减少重复请求。

OpenFeign 集成 OkHttp 的步骤

1. 引入依赖

pom.xml中添加feign-okhttp依赖(OpenFeign 与 OkHttp 的桥接组件):

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
    <!-- 版本由Spring Cloud依赖管理自动匹配,无需手动指定 -->
</dependency>

2. 开启 OkHttp 支持

在配置文件中启用 OpenFeign 对 OkHttp 的支持(默认关闭):

阅读全文 »

hexo博客增加板娘

网上看到一个人也是用hexo写的博客,他的博客右下角有个二次元小姐姐,看着倒是不错的。我也是用的hexo,我是不是也可以加上,bing一下,看看这是怎么实现的?

发现是使用的插件来实现的,操作还是蛮简单的

先安装插件

npm install --save hexo-helper-live2d

这个要使用国内的镜像,不然下载不下来,我使用的是淘宝镜像

npm config set registry https://registry.npmmirror.com

然后在hexo的_config.yml中增加live2d的配置

阅读全文 »

next主题数学公式问题

我写的都是一些编程相关的文章,有些文章里是存在数学公式的,我在Typora软件中写的时候显示的是对的,但是hexo将markdown转为html后在页面上就没有数学公式的格式了。

查找next配置发现有一个渲染数学公式的配置

math:
  # Default (true) will load mathjax / katex script on demand.
  # That is it only render those page which has `mathjax: true` in Front-matter.
  # If you set it to false, it will load mathjax / katex srcipt EVERY PAGE.
  # 设置为true,就只渲染那些配置了mathjax: true的页。如果设置为false,会渲染所有页,影响性能
  per_page: true
  # npm install hexo-renderer-kramed --save
  # hexo-renderer-pandoc (or hexo-renderer-kramed) required for full MathJax support.
  mathjax:
    enable: true
    # See: https://mhchem.github.io/MathJax-mhchem/
    mhchem: false
阅读全文 »

内存与磁盘:协同运作的存储层级

在计算机系统中,内存(主存)和磁盘(辅存)是构成存储层级的核心部件,它们通过互补的特性解决了 “速度、容量、成本” 的三角难题。 “8G 内存运行 10G 游戏” 的场景,正是两者协同工作的典型案例,背后涉及关键技术和原理:

突破内存容量限制的核心:虚拟内存与局部性原理

局部性原理:程序运行的 “潜规则”

程序在执行时,并非同时需要所有数据,而是呈现出明显的局部性:

  • 时间局部性:最近访问的数据(如游戏角色的坐标、当前场景的纹理)在短期内可能再次被使用。
  • 空间局部性:访问某一数据时,其相邻数据(如同一地图区块的相邻像素)也大概率被访问。

例如,10G 的游戏中,真正需要实时加载到内存的可能只是当前关卡的模型(2-3G)、音效缓存(几百 MB)和运行逻辑(几百 MB),其余未激活的关卡、冗余资源可暂存到磁盘。

虚拟内存技术:内存与磁盘的 “无缝衔接”

操作系统通过虚拟内存技术,将磁盘空间 “冒充” 为内存的一部分,实现 “小内存运行大程序”:

  • 地址映射:程序看到的是连续的 “虚拟地址空间”(如 10G),但实际只有部分映射到物理内存(8G),其余映射到磁盘的 “交换区”(Swap 分区)。
  • 页置换机制:当内存不足时,系统通过算法(如 LRU,最近最少使用)将最久未访问的 “内存页”(通常 4KB 大小)写入磁盘,再将新需要的页从磁盘读入内存。这个过程对程序透明,仿佛拥有了 10G 内存。

内存(RAM):高速但易失的 “临时工作台”

为什么是 “随机存取”?

阅读全文 »
0%