前言
随着硬件性能的大大提高, 很多情况我们的应用即使写的简单粗暴些, 系统也可以可用的, 只是极端情况下会暴露出问题, 这也就是对于系统稳定性追求的价值所在, 另一个我们充分利用资源, 不造成资源的浪费也可以减少集群所需要的机器数量节约成本.
资源有限性场景
应用存储有限性
内存是一种高速, 造价昂贵的存储设备, 而磁盘速度较慢造价低廉. 内存是通过电流来实现存储, 磁盘是通过磁记录来实现存储. 所以电脑断电后, 内存中的数据会丢失, 而磁盘中的数据在不损坏的情况下可以长久保留
内存有限性
java 内存模型里又有一些模型概念, 其中最常见的就是在 new Object() 的时候使用的堆内存, 内存本身是有限的, 堆内存就更小一些, 所以我们在日常编程中需要考虑堆内存的有限性, 不是一个对象多大都能承载. 比如类似的代码就有可能会造成 jvm 一直回收不了导致内存溢出:
List userNamedCodogList =newArrayList<>();
while(response.hasNext()) {
userNamedCodogList.addAll(response.getUserList());
response = queryUserList();
}
这种从接口读取用户列表, 然后添加到 userlist 里, 如果查询很多次, list 一直释放不了, 系统就会挂掉了, 甚至简单如:
List userNamedCodogList = userDao.selectList("name","codog");
如果结果集特别多也会挂掉
其实除了考虑堆内存还得考虑方法栈等内存模型, 但是一般经过良好测试的正常写代码不会造成栈溢出的, 一般只有递归的调用容易发生这类问题, 但是这时候一般 CPU 也会先显示出来异常了
磁盘有限性
相对于内存, 磁盘确实大很多, 所以一般不怎么出问题, 但是在使用磁盘的时候要注意一些日积月累的问题, 比如一些程序临时文件的定期及时清理等, 如 excel 新版本就会在内存中保留一个窗口的数据, 其他的都是在磁盘上的临时文件
网络带宽有限性
这个主要考虑到接口的定义和使用, 比如定义一个拉取一段时间内注册的用户的接口:
ListqueryUserByTimeRange(Range
这就要考虑到用户列表很多的时候, 网络传输是不是会造成问题, 其实好的方式是改成分页的接口
另外比如 Get 方法的请求参数不能过大, 不然就无法传输的问题, 这时候一开始就需要写成 Post,,,,,
还有比如应用程序上传文件的服务器和应用代码的服务器需要隔离开, 不然会导致因为大量的人上传图片导致正常的应用功能无法接收到用户的接口请求, 对于这种一般的公司会提供专门的文件服务器用来承接文件, 使用 key 与应用程序进行沟通
CPU有限性
其实应用程序很少是 CPU 机器密集型的, 所以 CPU 很少是瓶颈, 主要是需要注意比如设置线程池的时候不能设置的太大, 不然 CPU 会频繁切换线程, 正事干的反而慢了