Skip to main content

第01章 实例

第1章 实例

一、实例池

  • 实例池的数量一定有上限的,不可能运行每一个用户上来都能创建一个对象,否则DDos攻击的时候内存直接爆炸。
  • 假设我们只能创建两个对象,这样内存就不会爆炸了。那是怎么服务于多个用户呢?
  • 假设A用户来了,我们创建一个实例A,然后B来了创建一个B,现在实例池满了。这些实例包括数据现在所在位置都是内存里面!
  • C来了之后,根据最近最少使用的算法,把A从内存里面换出,落到硬盘上面,然后创建一个C的实例。
  • 这样就哪怕限制了实例的数量,也可以服务多个用户。

因此,系统尽量要无状态的,避免有状态的服务。比如说我们要统计一个网站在线用户的数量,这样所有用户公用的一个域就是count:反应用户数量,而不是一个用户来了就要创建一个对象,这样就是无状态的。但是有状态的就需要针对每个用户维护一个session,占用空间,所以尽可能的少或者避免。

二、scope

  • singleton:代价最小,没有换进换出,是默认的操作,相当于只有一个单例
  • prototype:不指定协议,每次请求都会创建一个实例
  • request:特指通过http协议,每次请求都会创建一个实例
  • session:在一个session中,只创建一个实例

三、数据库连接的数量

  • 假如要支持10万用户,需要在连接池里面配置多少数据库连接?
  • 连接池的数量connections=((core_count×2)+effective_spindle_count)connections = ((core\_count \times 2) + effective\_spindle\_count)
  • 为什么:线程来回切换过程需要时间,假如配很多的数据库连接,会导致很多的线程切换的时间,反而降低效率
  • 让数据库连接的数量和CPU核心的数量差不多或者两倍(超线程)的时候,这样线程上下文切换的时候就会少,比较好
  • 因为CPU处理完之后,在把内存的东西写硬盘的时候写的过程,CPU是空闲的时候,所以还加上有效的硬盘的数量。
  • 所以假如4核心2硬盘的服务器,就只需要十个数据库连接,就可以为十万的用户服务了
  • 为什么呢:连接池看的不是客户端的数量,而是机器硬件的配置,让需要获取连接的线程在那里等待,然后逐一处理即可。
  • 那如果有100万用户的时候该怎么办?这时候不应该增加数据库连接的数量,而是应该增加机器的数量,每个机器上有一定数量的数据库的连接!