背景
最近要开始新房子的装修了,正好对目前的家里使用的网络方案也不是很满意,借着这个机会,整理一下网络的方案,也会分开说说不同场景选型的一些方案。
前几年做家庭方案的时候,基本上上限就是千兆网络,在很长一段时间,全屋无线+有线全千兆网络是家装网络的天花板。但在2023年的今天,如果你想要打造一套战未来的基础网络设施,我会推荐你考虑2.5G的网络环境,甚至10G,也就是万兆网络。
本文介绍家庭网络的理论方案,包括无线方案、永久链路的选择等等方面介绍。
目前的业务场景中,有这样的需求:给上游提供一个批量接口,然后在本系统中,将批量请求拆成单独的请求,每个请求使用一个单独的新线程进行简单包装后,调用下游进行处理,而下游提供的服务由于处理逻辑较多,所以响应速度不快,需要大约大几百毫秒。
目前提供给上游的接口,最多一批处理一百个任务,目前每个任务都会拆成一个单独的线程,也就是上游的一次调用最多会占用100个线程,如果当前系统最大支持nQPS,下游接口的平均RT为m秒,那么光这一个接口,就需要线程池中提供100nm个线程。
例:单机支持500QPS,下游每个接口响应时间为0.1s,那么waybilltemplate在这一个接口上就需要100 * 100 * 0.1 = 1000个线程。
对于下游来说,渲染性能可以不断优化或通过扩容解决流量增长的问题,可以假设平均响应RT不变,此处暂且不考虑。而对于本系统来说,随着流量上涨,在不扩容情况下,单机QPS将会逐步上涨,也就意味着上文计算的线程数将不断上涨。。
线程对于操作系统来说是非常昂贵的资源,对于Java应用来说,Java线程与操作系统线程是一一对应的关系,线程数不断增长主要有两个问题:
平时我们在写单测时,因为需要测试一些业务类,不可避免在业务类中会访问外部存储资源,例如数据库、外部接口等。如果编写了依赖外部资源的单测,在运行时不可避免有两个问题:
在很多Git管理的项目中,会配置一些自动化的流水线,可能在每一次提交或MR后会全量跑一遍所有单测,一个大项目可能动辄几百几千个单测方法,如果每一个都要去访问外部资源,那么一次流程走完会浪费很多时间;其次外部数据不稳定,原来A状态的数据变成了B状态,单测可能就无法通过了,这样对单测的维护也造成了很大的困难。
鉴于上述原因,单测不应该依赖外部的数据源,我们的单测中如果需要是调用访问外部数据源的方法,最好的办法就行进行mock。
Java项目中,在这里推荐一个mock数据的神器——Mockito
,以及它的升级版PowerMockito
。
在Spring
中,如果我们需要从IOC
容器中获取一个对象,在不考虑自动注入的场景,可以通过调用BeanFactory#getBean(String)
方法。
这个方法不但承担了从容器中取出已创建好的对象这一个职责,容器在启动的时候,依次初始化所有需要实例化的对象时,也调用了这个对象,所以我们可以判断这个方法应该有两个功能:
其中第一点的实现方式很容易猜到,应该是有一个Map
对象,其中存储了beanName
与bean
的映射关系,在调用getBean
方法时,从Map
中查询,如果存在该对象,则直接返回。
所以本文主要分析第二种情况,当bean
不存在时,是如何进行初始化的。
为了更加深入理解bean
初始化的过程,本文还会解释如下几个问题,读者可以带着这几个问题进行阅读:
bean
初始化相关的扩展接口是如何实现的?bean
循环引用的情况如何处理?bean
互相依赖(depend-on)如何处理?Singleton
和Prototype
在实现上的差别是什么?