背景

最近要开始新房子的装修了,正好对目前的家里使用的网络方案也不是很满意,借着这个机会,整理一下网络的方案,也会分开说说不同场景选型的一些方案。

前几年做家庭方案的时候,基本上上限就是千兆网络,在很长一段时间,全屋无线+有线全千兆网络是家装网络的天花板。但在2023年的今天,如果你想要打造一套战未来的基础网络设施,我会推荐你考虑2.5G的网络环境,甚至10G,也就是万兆网络。

本文介绍家庭网络的理论方案,包括无线方案、永久链路的选择等等方面介绍。

阅读全文 »

背景

目前的业务场景中,有这样的需求:给上游提供一个批量接口,然后在本系统中,将批量请求拆成单独的请求,每个请求使用一个单独的新线程进行简单包装后,调用下游进行处理,而下游提供的服务由于处理逻辑较多,所以响应速度不快,需要大约大几百毫秒。

目前提供给上游的接口,最多一批处理一百个任务,目前每个任务都会拆成一个单独的线程,也就是上游的一次调用最多会占用100个线程,如果当前系统最大支持nQPS,下游接口的平均RT为m秒,那么光这一个接口,就需要线程池中提供100nm个线程。

例:单机支持500QPS,下游每个接口响应时间为0.1s,那么waybilltemplate在这一个接口上就需要100 * 100 * 0.1 = 1000个线程。

分析

对于下游来说,渲染性能可以不断优化或通过扩容解决流量增长的问题,可以假设平均响应RT不变,此处暂且不考虑。而对于本系统来说,随着流量上涨,在不扩容情况下,单机QPS将会逐步上涨,也就意味着上文计算的线程数将不断上涨。。

线程对于操作系统来说是非常昂贵的资源,对于Java应用来说,Java线程与操作系统线程是一一对应的关系,线程数不断增长主要有两个问题:

  1. 每个线程占用固定大小的内存,线程越多,消耗内存越多。默认情况下,一个线程将分配最多1MB的栈空间
  2. 虽然此处为IO密集型场景,但是线程数过多时,仍会导致CPU资源大量浪费在线程切换过程中。由于大量线程堆积势必会导致CPU load快速增长,直至影响到RT
阅读全文 »

为什么要进行mock数据

平时我们在写单测时,因为需要测试一些业务类,不可避免在业务类中会访问外部存储资源,例如数据库、外部接口等。如果编写了依赖外部资源的单测,在运行时不可避免有两个问题:

  1. 启动或运行慢
  2. 外部数据不稳定,可能会导致单测运行结果与预期不符

在很多Git管理的项目中,会配置一些自动化的流水线,可能在每一次提交或MR后会全量跑一遍所有单测,一个大项目可能动辄几百几千个单测方法,如果每一个都要去访问外部资源,那么一次流程走完会浪费很多时间;其次外部数据不稳定,原来A状态的数据变成了B状态,单测可能就无法通过了,这样对单测的维护也造成了很大的困难。

鉴于上述原因,单测不应该依赖外部的数据源,我们的单测中如果需要是调用访问外部数据源的方法,最好的办法就行进行mock。

Java项目中,在这里推荐一个mock数据的神器——Mockito,以及它的升级版PowerMockito

阅读全文 »

为什么要强调SpringBoot中的BeanDefinition加载过程?

在阅读很多相对比较旧的讲解Spring容器的书籍或文章时,由于当时SpringBoot并不是很盛行,甚至还没有SpringBoot,导致对于Spring容器启动的讲解并没有提到与SpringBoot容器启动过程的差异,导致很多读者默认为这两者是一样的。

事实上,在容器启动时,传统的配置式的Spring项目与使用了SpringBoot的项目在启动时大体上是相近的,但是区别也还是不小的,本文要提到的BeanDefinition 加载过程中是其中一个例子。

阅读全文 »

初始BeanFactory

Spring中,如果我们需要从IOC容器中获取一个对象,在不考虑自动注入的场景,可以通过调用BeanFactory#getBean(String)方法。

这个方法不但承担了从容器中取出已创建好的对象这一个职责,容器在启动的时候,依次初始化所有需要实例化的对象时,也调用了这个对象,所以我们可以判断这个方法应该有两个功能:

  1. 如果容器中存在该对象,则直接返回
  2. 如果容器中不存在该对象,则创建

其中第一点的实现方式很容易猜到,应该是有一个Map对象,其中存储了beanNamebean的映射关系,在调用getBean方法时,从Map中查询,如果存在该对象,则直接返回。

所以本文主要分析第二种情况,当bean不存在时,是如何进行初始化的。

为了更加深入理解bean初始化的过程,本文还会解释如下几个问题,读者可以带着这几个问题进行阅读:

  1. Spring支持的扩展接口一文中提到的跟bean初始化相关的扩展接口是如何实现的?
  2. 如果两个bean 循环引用的情况如何处理?
  3. 如果两个bean互相依赖(depend-on)如何处理?
  4. SingletonPrototype在实现上的差别是什么?
阅读全文 »