??xml version="1.0" encoding="utf-8" standalone="yes"?>
1、memcached的基本设|?/strong>
1Q启动Memcache的服务器?
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid
-d选项是启动一个守护进E,
-m是分配给Memcache使用的内存数量,单位是MBQ我q里?0MBQ?
-u是运行Memcache的用P我这里是rootQ?
-l是监听的服务器IP地址Q如果有多个地址的话Q我q里指定?jin)服务器的IP地址192.168.0.200Q?
-p是设|Memcache监听的端口,我这里设|了(jin)12000Q最好是1024以上的端口,
-c选项是最大运行的q发q接敎ͼ默认?024Q我q里讄?56Q按照你服务器的负蝲量来讑֮Q?
-P是设|保存Memcache的pid文gQ我q里是保存在 /tmp/memcached.pidQ?/p>
2Q如果要l束Memcacheq程Q执行:(x)
# kill `cat /tmp/memcached.pid`
哈希法?/font>L长度的二q制值映ؓ(f)固定长度的较?yu)二q制|q个的二进制值称为哈希倹{哈希值是一D|据唯一且极其紧凑的数DCŞ式。如果散列一D|文而且哪怕只更改?/p> D落的一个字母,随后的哈希都生不同的倹{要扑ֈ散列为同一个值的两个不同的输入,在计上是不可能的?/p> 2、一致性Hash法的目的有两点Q一是节点变动后其他节点受媄(jing)响尽可能;二是节点变动后数据重新分配尽可能均衡 ?/strong> 3、ؓ(f)什么要q行 memcached Q?/strong> 如果|站的高?gu)量很大q且大多数的讉K?x)造成数据库高负荷的状况下Q?memcached 能够减轻数据库的压力?/p> 4、适用memcached的业务场景? 1Q如果网站包含了(jin)讉K量很大的动态网,因而数据库的负载将?x)很高。由于大部分数据库请求都是读操作Q那么memcached可以显著地减数据库负蝲?/p> 2Q如果数据库服务器的负蝲比较低但CPU使用率很高,q时可以~存计算好的l果Q?computed objects Q和渲染后的|页模板Qenderred templatesQ?/p> 3Q利用memcached可以~存session数据、(f)时数据以减少对他们的数据库写操作?/p> 4Q缓存一些很但是被频繁讉K的文件?/p> 5Q缓存Web 'services'Q非IBM宣扬的Web ServicesQ译者注Q或RSS feeds的结??/p> 5、不适用memcached的业务场景? 1Q缓存对象的大小大于1MB Memcached本n׃是ؓ(f)?jin)处理庞大的多媒体(large mediaQ和巨大的二q制块(streaming huge blobsQ而设计的? 2Qkey的长度大?50字符 3Q虚拟主Z让运行memcached服务 如果应用本n托管在低端的虚拟U有服务器上Q像vmware, xenq类虚拟化技术ƈ不适合q行memcached。Memcached需要接和控制大块的内存,如果memcached理的内?/p> 被OS?hypervisor交换出去Qmemcached的性能大打折扣?/p> 4Q应用运行在不安全的环境? Memcached为提供Q何安全策略,仅仅通过telnet可以访问到memcached。如果应用运行在׃n的系l上Q需要着重考虑安全问题?/p> 5Q业务本w需要的是持久化数据或者说需要的应该是database 6、能够遍历memcached中所有的item吗? 不能Q这个操作的速度相对~慢且阻塞其他的操作Q这里的~慢时相比memcached其他的命令)(j)。memcached所有非调试Qnon-debugQ命令,例如add, set, get, fulsh{无?/p> memcached中存储了(jin)多少数据Q它们的执行都只消耗常量时间。Q何遍历所有item的命令执行所消耗的旉Q将随着memcached中数据量的增加而增加。当其他命o(h)因ؓ(f){待Q遍历所 有item的命令执行完毕)(j)而不能得到执行,因而阻塞将发生?/p> 集群的相关问?/font> 7、memcached是怎么工作的? Memcached的高性能源于两阶D哈希(two-stage hashQ结构。Memcached像一个巨大的、存储了(jin)很多<key,value>对的哈希表。通过keyQ可以存储或查询L的数据?客户?/p> 可以把数据存储在多台memcached上。当查询数据Ӟ客户端首先参考节点列表计出key的哈希|阶段一哈希Q,q而选中一个节点;客户端将h发送给选中的节点,然后 memcached节点通过一个内部的哈希法Q阶D二哈希Q,查找真正的数据(itemQƈq回l客L(fng)。从实现的角度看Qmemcached是一个非d的、基于事件的服务器程序?/p> 8、memcached最大的优势是什么? Memcached最大的好处是它带来了(jin)极佳的水q_扩展性,特别是在一个巨大的pȝ中。由于客L(fng)自己做了(jin)一ơ哈希,那么我们很容易增加大量memcached到集中。memcached 之间没有怺通信Q因此不?x)增?memcached的负载;没有多播协议Q不?x)网l通信量爆炸(implodeQ?/p> 9、memcached和MySQL的query cache相比Q有什么优~点Q?/strong> ~点Q?/p> 1Q相比MySQL的query cacheQ把memcached引入应用中需要不的工作量。MySQL的query cacheQ可以自动地~存SQL查询的结果,被缓存的SQL查询可以被反复、快速的执行?/p> 优点Q?/p> 1Q当修改表时QMySQL的query cache?x)立刻被hQflushQ。当写操作很频繁ӞMySQL的query cache?x)经常让所有缓存数据都失效?/p> 2Q在多核CPU上,MySQL的query cache?x)遇到扩展问题(scalability issuesQ。在多核CPU上,query cache?x)增加一个全局锁(global lockQ? ׃需要刷新更多的~存数据Q速度 ?x)变得更慢?/p> 3Q在MySQL的query cache中,是不能存储Q意的数据的(只能是SQL查询l果Q。利用memcachedQ我们可以搭建出各种高效的缓存。比如,可以执行多个独立的查询,构徏Z?/p> 用户对象Quser objectQ,然后用户对象缓存到memcached中。而query cache是SQL语句U别的,不可能做到这一炏V在的|站中,query cache?x)有所帮助Q但随着|站规模?/p> 增加Qquery cache的弊大于利?/p> 4Qquery cache能够利用的内存容量受到MySQL服务器空闲内存空间的限制。给数据库服务器增加更多的内存来~存数据Q固然是很好的。但是,有了(jin)memcachedQ只要?zhn)有空闲的?/p> 存,都可以用来增加memcached集群的规模,然后(zhn)就可以~存更多的数据?/p>10、memcached和服务器的local cacheQ比如PHP的APC、mmap文g{)(j)相比Q有什么优~点Q?/strong> 1Q首先,local cache面(f)着严重的内存限Ӟ能够利用的内存容量受刎ͼ单台Q服务器I闲内存I间的限制?/p> 2Qlocal cache有一Ҏ(gu)memcached和query cache都要好,那就是它不但可以存储L的数据,而且没有|络存取的gq。因此,local cache的数据查询更快。考虑把highly common的数据放在local cache中吧。如果每个页面都需要加载一些数量较?yu)的数据Q可以考虑把它们放在local cached?/p> 3Qlocal cache~少集体失效Qgroup invalidationQ的Ҏ(gu)。在memcached集群中,删除或更C个key?x)让所有的观察者觉察到。但是在local cache? 我们只能通知所有的服务?/p> hcacheQ很慢,不具扩展性)(j)或者仅仅依赖缓存超时失效机制?/p> 11、memcached的cache机制是怎样的? Memcached主要的cache机制是LRUQ最q最用Q算?时失效。当(zhn)存数据到memcached中,可以指定该数据在~存中可以呆多久Which is forever, or some time in the future。如果memcached的内存不够用?jin),q期的slabs?x)优先被替换Q接着p到最老的未被使用的slabs?/p> 12、memcached如何实现冗余机制Q?/strong> 不实玎ͼMemcached应该是应用的~存层,从设计本w来京就不带有Q何冗余机制。如果一个memcached节点失去?jin)所有数据,应该可以从数据源Q比如数据库Q再ơ获取到数据。应 用系l应该可以容忍节点的失效。如果担?j)节点失效?x)大大加重数据库的负担Q那么可以采取一些办法。比如?zhn)可?strong>增加更多的节?/strong>Q来减少丢失一个节点的影响Q,热备节点Q在其他?/p> 点down?jin)的时候接IPQ等{?/p> 13、memcached如何处理定w的? 在节点失效的情况下,集群没有必要做Q何容错处理。如果发生了(jin)节点失效Q应对的措施完全取决于用戗?/p> 节点失效Ӟ下面列出几种Ҏ(gu)供?zhn)选择Q?/p> 1Q忽略它Q?在失效节点被恢复或替换之前,q有很多其他节点可以应对节点失效带来的媄(jing)响?/p> 2Q把失效的节点从节点列表中移除。做q个操作千万要小?j)!在默认情况下Q余数式哈希法Q,客户端添加或U除节点Q会(x)D所有的~存数据不可用!因ؓ(f)哈希参照的节点列表变?/p> ?jin),大部分key?x)因为哈希值的改变而被映射刎ͼ与原来)(j)不同的节点上?/p> 3Q启动热备节点,接管失效节点所占用的IP。这样可以防止哈希紊乱(hashing chaosQ?/p> 4Q如果希望添加和U除节点Q而不影响原先的哈希结果,可以使用一致性哈希算法(consistent hashingQ?/p> 5Q两ơ哈希(reshingQ。当客户端存取数据时Q如果发C个节点down?jin),再做一ơ哈希(哈希法与前一ơ不同)(j)Q重新选择另一个节点(需要注意的Ӟ客户端ƈ没有把down 的节点从节点列表中移除,下次q是有可能先哈希到它Q。如果某个节Ҏ(gu)好时坏,两次哈希的方法就有风险了(jin)Q好的节点和坏的节点上都可能存在脏数据(stale dataQ?/p> 14、如何将memcached中item扚w导入导出Q?/strong> 不应该这样做QMemcached是一个非d的服务器。Q何可能导致memcached暂停或瞬时拒l服务的操作都应该值得深思熟虑。向memcached中批量导入数据往往不是(zhn)真正想?/p> 的!惌看,如果~存数据在导出导入之间发生了(jin)变化Q?zhn)需要处理脏数据?jin);如果~存数据在导出导入之间过期了(jin)Q?zhn)又怎么处理q些数据呢? 因此Q批量导出导入数据ƈ不像惌中的那么有用。不q在一个场景倒是很有用。如果?zhn)有大量的从不变?的数据,q且希望~存很快热(warmQv来,扚w导入~存数据是很有帮?/p> 的?/p> 15、但是我实需要把memcached中的item扚w导出导入Q怎么办?Q?/strong> 如果需要批量导出和导入Q最可能的原因一般是重新生成~存数据需要消耗很长的旉或者数据库坏了(jin)让?zhn)饱受痛苦?/p> 如果一个memcached节点down?jin)让?zhn)很痛苦Q那么必d数据库做一些优化工作。比如处?惊群"问题Q?memcached节点都失效了(jin)Q反复的查询让数据库不堪重负Q或者存在优化不 好的查询{。Memcached q不是逃避优化查询的借口和方案?/p> q里l出一些提C:(x) 使用MogileFSQ或者CouchDB{类似的软gQ在存储itemQ把item计算出来qdump到磁盘上。MogileFS可以很方便地覆写itemQƈ提供快速地讉K。甚臛_以把MogileFS中的item ~存在memcached中,q样可以加快d速度?MogileFS+Memcached的组合可以加快缓存不命中时的响应速度Q提高网站的可用性? 重新使用MySQL。MySQL?InnoDB主键查询速度非常快。如果大部分~存数据都可以放到VARCHAR字段中,那么主键查询的性能更好。从memcached中按key查询几乎{h(hun)?/p> MySQL的主键查询:(x)key 哈希?4-bit的整敎ͼ然后数据存储到MySQL中。?zhn)可以把原始(不做哈希Q的key存储都普通的字段中,然后建立二索引来加快查?..key被动地失效, 扚w删除失效的keyQ等{?/p> 没有w䆾认证机制Qmemcached是运行在应用下层的YӞw䆾验证应该是应用上层的职责Q。memcached的客L(fng)和服务器端之所以是轻量U的Q部分原因就是完全没有实现n份验 证机制。这Pmemcached可以很快地创建新q接Q服务器端也无需M配置。如果?zhn)希望限制讉KQ?zhn)可以使用防火墙,或者让memcached监听unix domain socket?/p> 17、memcached的多U程是什么?如何使用它们Q?/strong> U程是定律Qthreads ruleQ!在Steven Grimm和Facebook的努力下Qmemcached 1.2?qing)更高版本拥有?jin)多线E模式。多U程模式允许memcached能够充分利用多个CPUQƈ?/p> CPU之间׃n所有的~存数据。memcached使用一U简单的锁机制来保证数据更新操作的互斥。相比在同一个物理机器上q行多个memcached实例Q这U方式能够更有效地处理multi gets。如果系l的负蝲q不重,那么不需要启用多U程工作模式。如果?zhn)在运行一个拥有大规模g的、庞大的|站Q将体验到看到多U程的好处。更多信息请参见Q?/p> http://code.sixapart.com/svn/memcached/trunk/server/doc/threads.txt ?/p> 单地ȝ一下:(x)命o(h)解析Qmemcached在这里花?jin)大部分旉Q可以运行在多线E模式下。memcached内部Ҏ(gu)据的操作是基于很多全局锁的Q因此这部分工作不是多线E的Q。未 来对多线E模式的改进Q将U除大量的全局锁,提高memcached在负载极高的场景下的性能?/p> 18、memcached能接受的key的最大长度是多少Q?/strong> memcached能接受的key的最大长度是250个字W。需要注意的是,250是memcached服务器端内部的限制。如果用的Memcached客户端支?key的前~"或类似特性,那么key Q前~+原始keyQ的最大长度是可以过250个字W的。推荐用较短的keyQ这样可以节省内存和带宽?/p> 19、memcached对item的过期时间有什么限Ӟ item对象的过期时间最长可以达?0天。memcached把传入的q期旉Q时间段Q解释成旉点后Q一旦到?jin)这个时间点Qmemcached把item|ؓ(f)失效状态,q是一个简单但 obscure的机制?/p> 20、memcached最大能存储多大的单个itemQ?/strong> memcached最大能存储1MB的单个item。如果需要被~存的数据大?MBQ可以考虑在客L(fng)压羃或拆分到多个key中?/p> 21、ؓ(f)什么单个item的大被限制?M byte之内Q?/strong> 单的回答Q因为内存分配器的算法就是这L(fng)?/p> 详细的回{:(x) 1QMemcached的内存存储引擎,使用slabs来管理内存。内存被分成大小不等的slabs chunksQ先分成大小相等的slabsQ然后每个slab被分成大相{chunksQ不同slab的chunk大小 是不相等的)(j)。chunk的大依ơ从一个最数开始,按某个因子增长,直到辑ֈ最大的可能倹{如果最gؓ(f)400BQ最大值是1MBQ因子是1.20Q各个slab的chunk的大依ơ是Q?/p> slab1 - 400BQslab2 - 480BQslab3 - 576B ...slab中chunk大Q它和前面的slab之间的间隙就大。因此,最大D大,内存利用率越低。Memcached必须为每个slab预先分配?/p> 存,因此如果讄?jin)较(yu)的因子和较大的最大|?x)需要ؓ(f)Memcached提供更多的内存?/p> 2Q不要尝试向memcached中存取很大的数据Q例如把巨大的网|到mencached中。因为将大数据load和unpack到内存中需要花费很长的旉Q从而导致系l的性能反而不好。如?/p> 实需要存储大?MB的数据,可以修改slabs.cQPOWER_BLOCK的|然后重新~译memcachedQ或者用低效的malloc/free。另外,可以使用数据库、MogileFS{方案代?/p> Memcachedpȝ?/p> 22、可以在不同的memcached节点上用大不{的~存I间吗?如果q么做之后,memcached能够更有效地使用内存吗? Memcache客户端仅Ҏ(gu)哈希法来决定将某个key存储在哪个节点上Q而不考虑节点的内存大。因此,可以在不同的节点上用大不{的内存作ؓ(f)~存I间。但是一般可以这样做 Q拥有较多内存的节点上可以运行多个memcached实例Q每个实例用的内存跟其他节点上的实例相同?/p> 23、什么是二进制协议,是否需要关注? 二进制协议尝试ؓ(f)端提供一个更有效的、可靠的协议Q减客L(fng)/服务器端因处理协议而生的CPU旉。根据Facebook的测试,解析ASCII协议是memcached中消耗CPU旉最多的 环节?/p> 24、memcached的内存分配器是如何工作的Qؓ(f)什么不适用malloc/freeQ?Z要用slabsQ?/strong> 实际上,q是一个编译时选项。默认会(x)使用内部的slab分配器,而且实应该使用内徏的slab分配器。最早的时候,memcached只用malloc/free来管理内存。然而,q种方式不能?/p> OS的内存管理以前很好地工作。反复地malloc/free造成?jin)内存碎片,OS最l花费大量的旉L找连l的内存块来满malloc的请求,而不是运行memcachedq程。slab分配器就?/p> Z(jin)解决q个问题而生的。内存被分配q划分成chunksQ一直被重复使用。因为内存被划分成大不{的slabsQ如果item的大与被选择存放它的slab不是很合适的话,׃(x)费一些内存?/p> 25、memcached是原子的吗? 所有的被发送到memcached的单个命令是完全原子的。如果?zhn)针对同一份数据同时发送了(jin)一个set命o(h)和一个get命o(h)Q它们不?x)?jing)响对斏V它们将被串行化、先后执行。即使在多线E模 式,所有的命o(h)都是原子的。然是,命o(h)序列不是原子的。如果首先通过get命o(h)获取?jin)一个itemQ修改了(jin)它,然后再把它set回memcachedQ系l不保证q个item没有被其他进E?/p> QprocessQ未必是操作pȝ中的q程Q操作过。memcached 1.2.5以及(qing)更高版本Q提供了(jin)gets和cas命o(h)Q它们可以解决上面的问题。如果用gets命o(h)查询某个key的itemQ?/p> memcached?x)返回该item当前值的唯一标识。如果客L(fng)E序覆写?jin)这个itemq想把它写回到memcached中,可以通过cas命o(h)把那个唯一标识一起发送给memcached。如果该item 存放在memcached中的唯一标识与?zhn)提供的一_(d)写操作将?x)成功。如果另一个进E在q期间也修改?jin)这个itemQ那么该item存放在memcached中的唯一标识会(x)改变Q写操作׃(x) p|?/p> 性能和客L(fng)库方面的问题 26、memcached没有我的database快,Z么? 在一对一比较中,memcached可能没有SQL查询快。但是,q不是memcached的设计目标。Memcached的目标是可~性。当q接和请求增加的时候,memcached的性能比 大多数数据库查询好。可以先在高负蝲的环境(q发的连接和hQ中试(zhn)的代码Q然后再军_memcached是否适合(zhn)?/p> 27、用不同的客户端库Q可以访问到memcached中相同的数据吗? 从技术上_(d)是可以的。但是可能会(x)遇到下面三个问题Q?/p> 1Q不同的库采用不同的方式序列化数据。D个例子,perl的Cache::Memcached使用Storable来序列化l构复杂的数据(比如hash references, objects, {)(j)。其他语a的客L(fng)库很 可能不能dq种格式的数据。如果?zhn)要存储复杂的数据q且惌多种客户端库dQ那么?zhn)应该以简单的string格式来存储,q且q种格式可以被JSON、XML{外部库解析?/p> 2Q从某个客户端来的数据被压羃?jin),从另一个客L(fng)来的却没被压~?/p> 3Q各个客L(fng)库可能用不同的哈希法Q阶D一哈希Q。在q接到多个memcached服务器端的情况下Q客L(fng)库根据自w实现的哈希法把key映射到某台memcached上。正是因?/p> 不同的客L(fng)库用不同的哈希法Q所以被Perl客户端库映射到memcached A的keyQ可能又?x)被Python客户端库映射到memcached BQ等{。Perl客户端库q允ؓ(f)每台 memcached指定不同的权重(weightQ,q也是导致这个问题的一个因素?/p> q里有一文章很好地解释?jin)它的用处?x)http://www.last.fm/user/RJ/journal/2007/04/10/392555 ?/p> 客户端可以通过"前缀"来给key讄一个域Q命名空_(d)(j)。例如,在一个共享主机的环境中,可以客户姓名作?前缀"Qؓ(f)key创徏一个特定的域。在存储数据的时候,"前缀"可以用在 key上,但是不应该参与哈希计。目前,memcached自己q没有实现针对复杂结构数据的序列化方法,JSON则是一U被q泛使用的对象序列化格式?/p> 哈希 / 键分?/strong> 29、什么时候失效的数据会(x)从缓存中删除Q?/strong> memcached 使用懒失效,当客L(fng)h数据Ҏ(gu)Q?memcached 在返回数据前?x)检查失效时间来定数据Ҏ(gu)否已l失效。同样地Q当d一个新的数据项Ӟ如果~存已经满了(jin)Q?memcached ׃(x)先替换失效的数据,然后才是~存中最用的数据V? 命名I间 30、memcached 不支持命名空间。以下提供几U模仿命名空间的方式Q?/strong> 1Q用键的前缀模仿命名I间Q在真实的键之前加入有意义的前缀? 2Q用命名I间删除数据:(x)管 memcached 不支持用Q何类型的通配W或命名I间来完成删除操作,但是可以采用一些技巧来替代Q? ?PHP 中用一个叫 foo 的命名空_(d)(x)$ns_key = $memcache->get("foo_namespace_key"); // if not set, initialize it if($ns_key=false) $memcache->set("foo_namespace_key", rand(1, 10000)); $my_key = "foo_".$ns_key."_12345"; 清除命名I间Q?memcache->increment("foo_namespace_key"); 应用设计 31、在设计应用Ӟ可以通过Memcached~存那些内容Q?/strong> 1Q缓存简单的查询l果Q?/strong>查询~存存储?jin)给定查询语句对应的整个l果集,最合适缓存那?strong>l常被用刎ͼ但不?x)改变?SQL 语句Ҏ(gu)询到的结果集Q比如蝲入特定的qo(h)内容?/strong> $key = md5('SELECT * FROM rest_of_sql_statement_goes_here'); if ($memcache->get($key)) { ` return $memcache->get($key);` }else { ` // Run the query and transform the result data into your final dataset form` ` $result = $query_results_mangled_into_most_likely_an_array` ` $memcache->set($key, $result, TRUE, 86400); // Store the result of the query for a day` ` return $result;` } CQ如果查询语句对应的l果集改变,该结果集不会(x)展现出来。这U方法不L有用Q但它确实让工作变得比较快? 2Q缓存简单的Z行的查询l果Q?/strong>Z行的~存?x)检查缓存数据key的列表,那些在缓存中的行可以直接被取出,不在~存中的行将?x)从数据库中取出q以唯一的键为标识缓存v来,最 后加入到最l的数据集中q回。随着旉的推U,大多数数据都?x)被~存Q这也意味着相比与数据库Q查询语句会(x)更多C memcached 中得到数据行。如果数据是相当?rn)态的Q我们可 以设|一个较长的~存旉? Z行的~存模式对下面这U搜索情늉别有?/strong>Q数据集本n很大或是数据集是从多张表中得刎ͼ而数据集取决于查询的输入参数但是查询的结果集之间的有重复部分? 比如Q如果你有用?A Q?B Q?C Q?D Q?E 的数据集。你ȝM张显C用?A Q?B Q?E 信息的页面。首先, memcached 得到 3 个不同的键,每个对应一个用户去~存中查找,全部? 命中。然后就到数据库中用 SQL 查询得到 3 个用L(fng)数据行,q缓存他们? 现在Q你又去点击另一张显C显C?C Q?D Q?E 信息的页面。当你去查找 memcached Ӟ C Q?D 的数据ƈ没有被命中,但我们命中了(jin) E 的数据。然后从数据库得?C Q?D 的行数据Q缓 存在 memcached 中。至此以后,无论q些用户信息怎样地排列组合,M关于 A Q?B Q?C Q?D Q?E 信息的页面都可以?memcached 得到数据?jin)? 3Q缓存的不只?SQL 数据Q可以缓存最l完成的部分昄面Q以节省CPU计算旉 例如正在制作一张显C用户信息的面Q你可能得到一D关于用L(fng)信息Q姓名,生日Q家庭住址Q简介)(j)Q然后你可能?x)?XML 格式的简介信息{化ؓ(f) HTML 格式或做其他的一些工 作。相比单独存储这些属性,你可能更愿意存储l过渲染的数据块。那时你可以简单地取出被预处理后的 HTML 直接填充在页面中Q这栯省了(jin)宝贵?CPU 旉? 32、用分层的~存 memcached 可以高速处理大量的~存数据Q但是还是要Ҏ(gu)pȝ的情况考虑l护多层的缓存结构。例如除?jin)memcached~存之外Q还可以通过本地~存Q如ehcache、oscache{)(j)? 立v多~存。例如,可以采用本地~存~存一些基本数据,例如量但访问频J的数据Q如产品分类Q连接信息,服务器状态变量,应用配置变量{)(j)Q缓存这些数据ƈ让他们尽可能? 接近处理器是有意义的 , q样可以帮助减少生成面的时_(d)q且?memcached 失效的情况下可以增加可靠性? 33、当数据更新旉要更新缓?/strong> 用户~辑?jin)自q信息Q当保存信息到数据库Ӟ需要更新缓存中的数据或是简单地删除老的数据。如果马上更新数据,要防止从数据库读取那些刚刚更新过的数据。当用户?fn)惯性地重新 载入自己的用户信息来认是否修改成功Ӟ数据从~存中直接取出,q时他们获得?jin)最新的数据? 34、模拟带锁的d命o(h) 如果你实在需要锁Q你可以通过“添加”命令模仉K的功能。尽在未命中的情况下它不是那么有用Q但如果你用它缓存^常的数据Q应用服务器池的元数据)(j)那还是有用的? 比如Q你要更新键 A ? 1. d一?"lock:A" 的键Q这个键有一个持l几U的q期旉Q够长以你能完成计算和更斎ͼ也不要很长,因ؓ(f)如果锁进E挂?jin),q个键不?x)立即释放?j) 2. 如果d操作成功?jin),你就拥有了(jin)锁Q从~存获取?A 的数据;利用客户端程序更Ҏ(gu)据;更新~存?A 的数据;删除?"lock:A" 。如果你不需要立卛_ơ更斎ͼp它存?gu)zȝ到失效? 3. 如果d操作p|Q说明有取了(jin)锁。这时让应用做些合适的事,比如q回老数据,{待后重试,或是其他的? 以上q些操作cM MySQL ?GET_LOCK ?timeout D|成 0 。没有办法在 memcached 中通过互斥锁模?GET_LOCK() ?timeout 操作? 35、预热你的缓?/strong> 如果你有一个很高访问率的站点,q且你正惛_入故障恢复功能或是其他全新的功能Q你最l可能会(x)到I缓存的问题。一开始缓存是I的Q然后一大群人点M的站点,在填充缓存的q? E中Q你的数据库可能?x)承受不住压力。ؓ(f)?jin)解册一问题Q你可以试试M可行的方法来 " 温暖 " 你的Memcached。方法:(x)可以写一些脚本来~存通用的页面;也可以写一个命令行? h填充~存。你可以在高峰时d~存里填充一些内宏V? 参考网? http://shwangking-126-com.iteye.com/blog/284937 [root@localhost conf]# netstat –ntlp netstat命o(h)Q显C网l状?/p> 参数Q?/p> n 直接使用IP地址Q而不通过域名服务?/p> t 昄TCP传输协议的连U状?/p> l 昄监控中的服务器的Socket p 昄正在使用Socket的程序识别码和程序名U?/p> 2、查看Apache是否安装以及(qing)安装路径和版?/strong> 命o(h)Q?font color="#000000">Apachectl –v
]]>
[root@localhost apache]# apachectl -v
Server version: Apache/2.2.15 (Unix)
Server built: Jul 7 2011 11:27:40
通过q个命o(h)可以获得当前部v的Apache的版本和发行旉?/p>
如果用rpm安装Q可用rpm –d httpd命o(h)查看是否已经安装q?/p>
3、查扑֮装的指定E序
1Q如果是rpm套gQ可用:(x)
[root@localhost apache]# rpm -qa | grep xxx
其中Q?/p>
q 使用询问模式Q当遇到M问题Ӟrpm指o(h)?x)先询问用?/p>
a 查询所有套?/p>
2Q如果是源码安装的,可以用:(x)
whereis xxx
4、RPM套g基本操作
1Q安?rpm 套g
命o(h)Qrpm -ihv
例子Qrpm -ihv bind-8.2.1-7.i386.rpm
2Q更新rpm套g
命o(h)Qrpm -Uhv
例子Qrpm -Uhv bind-8.2.1-7.i386.rpm
3Q查询已安装的rpm 套g
命o(h)Qrpm -qa | grep xxx
例子Qrpm -qa | grep bind rpm -e
4Q删?rpm 套g
命o(h)Qrpm –e
例子Qrpm -e bind-8.2.1-7.i386.rpm
注意: 删除服务前应先停?/p>
5Q强制删除rpm套g
命o(h): rpm -e –nodeps xxxxxx.rpm
rpm参数说明Q?/p>
e 删除指定的套?/p>
i 昄套g的相关信?/p>
h 套g安装时列出标?/p>
v 昄指o(h)执行q程
U 升指定的套件档
nodeps 不考虑包间的依赖关p?/p>
5、查扄序进E?/strong>
1Qps -ef | grep xxx
ps命o(h)Q报告程序状?/p>
参数Q?/p>
-e 昄所有终端机下执行的E序
-f 昄UID,PPIP,C与STIME栏位
例子Qps -ef | grep httpd
2Qnetstat –ntlp
说明请参考前面的介绍?/p>
6、杀死Linuxq程
1Qkill pid
注释Q标准的kill命o(h)通常都能辑ֈ目的。终止有问题的进E,q把q程的资源释攄pȝ。然而,如果q程启动?jin)子q程Q只杀ȝq程Q子q程仍在q行Q因此仍消耗资源。ؓ(f)?jin)防止这些所谓的“僵进E”,应确保在杀ȝq程之前Q先杀d所有的子进E?/p>
2Qkill -l pid
注释Q当使用该选项Ӟkill命o(h)也试图杀L留下的子q程。但q个命o(h)也不是总能成功,或许仍然需要先手工杀dq程Q然后再杀ȝq程?/p>
3Qkill -temp ppid
注释Q给父进E发送一个TERM信号Q试图杀d和它的子q程?/p>
4Qkillall httpd
注释Qkillall命o(h)杀d一q程l内的所有进E。其允许指定要终止的q程的名Uͼ而非PID?/p>
5Qkill -HUP PID
注释Q该命o(h)让Linux和缓的执行进E关闭,然后立即重启。在配置应用E序的时候,q个命o(h)很方便,在对配置文g修改后需要重启进E时可以执行此命o(h)?/p>
5Qkill -9 PID
注释Q终极大招。这个强大和危险的命令迫使进E在q行时突然终止,q程在结束后不能自我清理。危xDpȝ资源无法正常释放Q一般不推荐使用Q除非其他办法都无效。由于只?/p>
通过l止父进E来消除僵尸q程Q因此当使用此命令时Q一定要通过ps -ef认没有剩下M僵尸q程。如果僵进E被init收养Q问题就比较严重?jin)。杀死initq程意味着关闭pȝ?/p>
如果pȝ中有僵尸q程Qƈ且其父进E是initQ而且僵尸q程占用?jin)大量的pȝ资源Q那么就需要在某个时候重启机器以清除q程表了(jin)?
7、常用的防火墙操作(iptablesQ?/strong> [root@localhost httpd-2.2.22]# /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT [root@localhost httpd-2.2.22]# /sbin/iptables -I INPUT -p tcp --dport 443 -j ACCEPT [root@localhost httpd-2.2.22]# /etc/init.d/iptables save q样重启计算机后,防火墙默认便开放了(jin)80?43端口? 也可以通过以下方式不重启计机Q完成规则的dQ? #/etc/init.d/iptables restart 查看防火墙信息:(x) #/etc/init.d/iptables status 关闭防火墙服务:(x) #/etc/init.d/iptables stop 怹关闭防火墙:(x) #chkconfig –level 35 iptables off 参考文章:(x) 1、CentOS Linux防火墙配|及(qing)关闭 一、对于GC的性能其实主要考虑以下两个斚wQ?/strong> 1、吞吐率throughput【工作时_(d)不包括GC的时_(d)(j)占总运行的旉比?/p> 2、暂停pauseQGC发生时应用程序无法响应用L(fng)hQ?/p> 二、对于GC的性能可以从以下方面考虑Q?/strong> 1、整个堆I间 对于Server端的应用E序Q有以下最?jng)_践:(x) 1Q对于JVM分配可能多的内存空间?/p> 2Q固定堆I间的大,Xms和Xmx设ؓ(f)一L(fng)倹{如果让JVM自行控制堆空间大的话,虚拟机启动时分配的堆I间比较?yu),如果在程序运行过E中q需要初始化很多对象Q虚?/p> 机就必须重复地增加内存,造成GC频率的增加?/p> 3Q横向增加服务器的数量,为程序服务的JVM内存总量也随着增大?/p> 2、新生代 从整体上看,新生代越大,minor GC׃(x)少。但׃我们一般是固定的堆内存I间Q因此更大的新生代也意味着更小的老生代,更小的老生代会(x)带来更多的Full GC(Full GC?x)伴?/p> 有minor GC)?/p> 参数NewRatio反映的是新生代和老生代的大小比例。NewSize和MaxNewSize反映的是新生代空间的下限和上限,这两个DZ样就固定?jin)新生代的大(或者直接通过指定 Xms、Xmx和Xmn的大来固定新生代的大小Q。SurvivorRatio可以指定survivor区的大小QSurvivorRatio是eden区和survior区的大小比例?/p> 一般而言Qserver端的app?x)有以下最?jng)_践:(x) 1Q首先固定heapI间的大,然后讑֮最佳的新生代空间的大小Q? 2Q如果堆I间固定后,增加新生代的大小意味着减小老生代的大小。因此在调节时应特别留意Q让老生代至能够保?0%-20%的空余空_(d)q能够容Ux有live的对象?/p> 三、最?jng)_践:(x) 1Q年M大小的选择 响应旉优先的应?/strong>Q尽可能增大新生代的大小Q直到接q系l的最低响应时间限?Ҏ(gu)实际情况选择)。在此种情况下,新生代收集发生的频率也是最的。同Ӟ减少到达q老代 的对象,从而减Full GC的发生几率? 吞吐量优先的应用Q?/strong>可能增大新生代的大,可能到达Gbit的程度。因为对响应旉没有要求Q垃圾收集可以ƈ行进行,一般适合8CPU以上的应用系l? 避免讄q小Q?/strong>当新生代讄q小时会(x)DQ?、minor GC的次数更加频J?nbsp; 2、可能导致minor GC对象直接q入老生代,如果此时老生代满??x)触发Full GC. 2Q年老代大小选择 响应旉优先的应?/strong>Q老生代用ƈ发收集器QCMS GCQ,所以其大小需要小?j)设|,一般要考虑q发?x)话率和会(x)话持箋旉{一些参数。如果堆讄了(jin),可以?x)Ş成内存碎片,?/p> 回收频率以及(qing)应用暂停。而用传l的标记清除方式Q如果堆讄大了(jin),则需要较长的攉旉。最优化的方?一般需要参考以下数据获得:(x)q发垃圾攉信息、永久代q发攉ơ数、传 lGC信息、花在新生代和老生代回收上的时间比例? 吞吐量优先的应用Q一般吞吐量优先的应用都有一个很大的新生代和一个较?yu)的老生代。原因是q样可以可能回收掉大部分短期对象,减少中期的对象,而老生代尽存放长期存活对象?/p> 3Q其?/strong> 较小堆引L(fng)片问题Q?/strong>因ؓ(f)老生代的q发攉器用标记清除算法,所以不?x)对堆进行压~。当攉器回收时Q它?x)把盔R的空间进行合qӞq样可以分配l较大的对象。但是,?/p> 堆空间较?yu)时Q运行一D|间以后,׃(x)出现"片"Q如果ƈ发收集器找不到够的I间Q那么ƈ发收集器会(x)停止Q然后用传l的标记清除方式q行回收。如果出?片"Q可能需?/p> q行如下配置Q?/p> -XX:+UseCMSCompactAtFullCollectionQ用ƈ发收集器?开启对q老代的压~?/p> -XX:CMSFullGCsBeforeCompaction=0Q上面配|开启的情况下,q里讄多少ơFull GC?对年老代q行压羃?/p> ?4位操作系l?/strong>Linux?4位的jdk?2位jdk要慢一些,但是吃得内存更多Q吞吐量更大? XMX和XMS讄一样大Q?/strong>MaxPermSize和MinPermSize讄一样大Q这样可以减M~堆大小带来的压??/strong> 使用CMS GC的好处是用尽量少的新生代Q经验值是128MQ?56MQ?然后老生代利用CMSq行攉Q?q样能保证系l低延迟的吞吐效?/strong>?实际上CMS GC的收集停时间非常的短, 2G的内存大U?0Q?0ms的应用程序停时间?/p> 减少E序停顿旉Q系l停的旉可能是GC的问题也可能是程序的问题Q多用jmap和jstack查看或者killall -3 javaQ然后查看java控制台日志,能看出很多问题。有一ơ,|站H然 很慢Q利用jstack一看,原来是自己写的URLConnectionq接太多没有释放造成的?/p> E序应用~存的问题:(x)如果E序应用?jin)缓存,那么老生代应该设|的大一些,~存的HashMap不应该无限制增长Q徏议采用LRU法的Map做缓存,LRU MapQ例如Jakarta Commons中提供的org.apache.commons.collections.map.LRUMapQ的最大长度也要根据实际情况设定? 采用q发回收Ӟ新生代小一点,老生代要大,因ؓ(f)老生代用的是q发回收Q即使时间长点也不会(x)影响其他E序l箋q行Q网站不?x)停ѝ?/strong> JVM 参数的设|?/strong>(特别?–Xmx –Xms –Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold{参数的讄没有一个固定的公式Q需要根据PV、老生代实际数据、新生代GCơ数{?/p> 多方面来衡量。ؓ(f)?jin)避免promotion faildQ可能会(x)Dxmn讄偏小Q也意味着新生代GC的次C(x)增多Q处理ƈ发访问的能力下降{问题。每个参数的调整都需要经q详l的性能试Q?/p> 才能扑ֈ特定应用的最佳配|?/p> 打印GC日志Q调试的时候设|一些打印参敎ͼ?XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.logQ这样可 以从gc.log里看Z些问题出来?/p> 4Qpromotion failedQ晋升失败)(j)Q?/strong>W一个原因是担保I间不够Q担保空间里的对象还不应该被Ud到老生代,但新生代又有很多对象需要放入担保空_(d)W二个原因是老生代没有够的I间接纳来自新生代的对象Q这两种情况都会(x)转向Full GCQ网站停时间较ѝ? 解决Ҏ(gu)案一Q? W一个原因我的最l解军_法是L担保I间Q设|?XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0卛_Q第二个原因我的解决办法是设|? CMSInitiatingOccupancyFraction为某个|假设70Q,q样老生代空间到70%时就开始执行CMSQ老生代有_的空间接Ux自新生代的对象? Ҏ(gu)一的改q方?/strong>Q? Ҏ(gu)一中没有用到担保空_(d)所以老生代容易满QCMS执行?x)比较频J。我改善?jin)一下,q是用担保空_(d)但是把担保空间加大,q样也不?x)有promotion failed。具体操作上Q?2位Linux?4位Linux好像不一P64位系l似乎只要配|MaxTenuringThreshold参数QCMSq是有暂停。ؓ(f)?jin)解x停问题和promotion failed问题Q最后我讄- XX:SurvivorRatio=1 Qƈ把MaxTenuringThresholdLQ这样即没有暂停又不?x)有promotoin failedQ而且更重要的是,老生代和怹代上升非常慢Q因为好多对象到不了(jin)q老代? 被回收了(jin)Q,所以CMS执行频率非常低,好几个小时才执行一ơ,q样Q服务器都不用重启了(jin)? -Xmx4000M -Xms4000M -Xmn600M -XX:PermSize=500M -XX:MaxPermSize=500M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log 5QCMSInitiatingOccupancyFractiongXmn的关pd?/strong> 上面介绍?jin)promontion faild产生的原因是EdenI间不的情况下Eden与From survivor中的存活对象存入To survivor区时QTo survivor区的I间不Q再ơ晋升到old gen区, 而old gen区内存也不够的情况下产生?jin)promontion faild从而导致full gc。那可以推断出:(x)eden+from survivor < old gen区剩余内存时Q不?x)出现promontion faild的情况,卻I(x) (Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)>=[Xmn-Xmn/(SurvivorRatior+2)] q而推断出Q?/p> CMSInitiatingOccupancyFraction <={(Xmx-Xmn)-[Xmn-Xmn/(SurvivorRatior+2)]}/(Xmx-Xmn)*100 例如Q? 当Xmx=128 Xmn=36 SurvivorRatior=1?CMSInitiatingOccupancyFraction<=((128.0-36)-(36-36/(1+2)))/(128-36)*100 =73.913 当Xmx=128 Xmn=24 SurvivorRatior=1?CMSInitiatingOccupancyFraction<=((128.0-24)-(24-24/(1+2)))/(128-24)*100=84.615? 当Xmx=3000 Xmn=600 SurvivorRatior=1?nbsp; CMSInitiatingOccupancyFraction<=((3000.0-600)-(600-600/(1+2)))/(3000-600)*100=83.33 当CMSInitiatingOccupancyFraction低于70% 需要调整Xmn或SurvivorRatior倹{? 四、内存泄露的分析 HPjmeter是一个GC的图形化分析工具,׃囑֏以看出GC始终无法回收heap内存I间Q以使heap内存I间的用量持箋升高Q明昑֭在内存泄露的可能性。定位内存泄Ԍ可以? 成dump文gQƈ利用MATq行分析Q查扑֎因? 内存分析工具Q? 详细信息可参考文?a >http://qa.taobao.com/?p=14264? JVM内存状况查看Ҏ(gu)?qing)工P(x)http://www.51testing.com/html/58/n-237858.html 使用 Eclipse Memory Analyzer q行堆{储文件分析:(x)http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html?ca=drs- 参考文献:(x) 1?a >JVMpd?JVM参数讄、分?/a> http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html 2?a >一个典型的OutOfMemory分析q程 http://hbase.iteye.com/blog/1356450 3、用MAT分析内存泄露 http://qa.taobao.com/?p=14264 4、JVM内存状况查看Ҏ(gu)和分析工?nbsp; http://www.51testing.com/html/58/n-237858.html 5、?Eclipse Memory Analyzer q行堆{储文件分析:(x)http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html?ca=drs- 1、Java虚拟行时的数据区 2、常用的内存区域调节参数 -XmsQ初始堆大小Q默认ؓ(f)物理内存?/64(<1GB)Q默?MinHeapFreeRatio参数可以调整)IZ堆内存小?0%ӞJVM׃(x)增大堆直?Xmx的最大限?/p> -XmxQ最大堆大小Q默?MaxHeapFreeRatio参数可以调整)IZ堆内存大?0%ӞJVM?x)减堆直?-Xms的最限?/p> -XmnQ新生代的内存空间大,注意Q此处的大小是(eden+ 2 survivor space)。与jmap -heap中显C的New gen是不同的。整个堆大小=新生代大?+ 老生代大?+ 怹代大? -XX:SurvivorRatioQ新生代中Eden区域与Survivor区域的容量比|默认gؓ(f)8。两个SurvivorZ一个Eden区的比gؓ(f)2:8,一个Survivor区占整个q轻代的1/10?/p> -XssQ每个线E的堆栈大小。JDK5.0以后每个U程堆栈大小?M,以前每个U程堆栈大小?56K。应Ҏ(gu)应用的线E所需内存大小q行适当调整。在相同物理内存?减小q个D生成更多的线E。但是操作系l对一个进E内的线E数q是有限制的Q不能无限生成,l验值在3000~5000左右。一般小的应用, 如果栈不是很深, 应该?28k够用的,大的应用使用256k。这个选项Ҏ(gu)能影响比较大,需要严格的试。和threadstacksize选项解释很类?官方文档g没有解释,在论坛中有这样一句话:"-Xss is translated in a VM flag named ThreadStackSize”一般设|这个值就可以?jin)?/p> -XX:PermSizeQ设|永久代(perm gen)初始倹{默认gؓ(f)物理内存?/64?/p> -XX:MaxPermSizeQ设|持久代最大倹{物理内存的1/4?/p> 3、内存分配方?/strong> 1Q堆上分?nbsp; 2Q栈上分?nbsp; 3Q堆外分配(DirectByteBuffer或直接用Unsafe.allocateMemory,但不推荐q种方式Q?/p> 4、监控方?/strong> 1Q系l程序运行时可通过jstat –gcutil来查看堆中各个内存区域的变化以及(qing)GC的工作状态; 5Q断代法可用GC汇?/strong> 一、新生代可用GC 1Q串行GC(Serial Copying)Qclient模式下默认GC方式Q也可通过-XX:+UseSerialGC来强制指定;默认情况?eden、s0、s1的大通过-XX:SurvivorRatio来控Ӟ默认?Q含? 默认情况下,仅在TLAB或eden上分配,只有两种情况下会(x)在老生代分配:(x) 默认情况下,触发Minor GCӞ(x) 默认情况下,新生代对象晋升到老生代的规则Q?/p> 1、经历多ơminor gc仍存?gu)zȝ对象Q可通过以下参数来控Ӟ(x)以MaxTenuringThresholdgؓ(f)准,默认?5?br> 2、to space放不下的Q直接放入老生代; 2Qƈ行GCQParNewQ:(x)CMS GC旉认采用,也可采用-XX:+UseParNewGC强制指定Q垃圑֛收的时候采用多U程的方式?/p> 3Qƈ行回收GC(Parallel Scavenge)Qserver模式下默认的GC方式Q也可采?XX:+UseParallelGC强制指定Qeden、s0、s1的大可通过-XX:SurvivorRatio来控Ӟ但默认情况下
]]>
]]>
在保证堆大小不变的情况下Q增大新生代?会(x)减小老生代大。此值对pȝ性能影响较大,Sun官方推荐配置为整个堆?/8?/p>
2Q启动时可添?XX:+PrintGCDetails –Xloggc:<file>输出到日志文件来查看GC的状况;
3Qjmap –heap可用于查看各个内存空间的大小Q?/p>
为eden:s0的比例,启动后可通过jmap –heap [pid]来查看?/p>
1、需要分配的内存大小过eden space大小Q?
2、在配置?jin)PretenureSizeThreshold的情况下Q对象大大于此倹{?/p>
之前Minor GC晋到old的^均大?< 老生代的剩余I间 < eden+from Survivor的用空间。当HandlePromotionFailure为trueQ则仅触发minor gcQ如为falseQ则触发full GC?/p>
?XX:InitialSurivivorRatio为准Q此值默认ؓ(f)8Q?strong>代表的ؓ(f)新生代大?: s0
默认情况下,当TLAB、eden上分配都p|Ӟ判断需要分配的内存大小是否 >= eden space的一半大,如是q接在老生代上分配Q?/p>
默认情况下的垃圾回收规则Q?/p>
1、在回收前PS GC?x)先(g)之前每ơPS GCӞ晋升到老生代的q_大小是否大于老生代的剩余I间Q如大于则直接触发full GCQ?br> 2、在回收后,也会(x)按照上面的规则进行检?/p>
默认情况下的新生代对象晋升到老生代的规则Q?br> 1、经历多ơminor gc仍存?gu)zȝ对象Q可通过以下参数来控Ӟ(x)AlwaysTenureQ默认falseQ表C只要minor GC时存?gu)z,晋升到老生代;NeverTenureQ默认falseQ表C永不晋升到老生代;上面两个都没讄的情冴下Q如UseAdaptiveSizePolicyQ启动时以InitialTenuringThresholdg为存?gu)zL数的阈|在每ơps gc后会(x)动态调_(d)如不使用UseAdaptiveSizePolicyQ则以MaxTenuringThreshold为准?br> 2、to space放不下的Q直接放入老生代?/p>
在回收后Q如UseAdaptiveSizePolicyQPS GC?x)根据运行状态动态调整eden、to以及(qing)TenuringThreshold的大。如果不希望动态调整可讄-XX:-UseAdaptiveSizePolicy。如希望跟踪每次的变化情况,可在启劢参数上增加:(x) PrintAdaptiveSizePolicy?/p>
二、老生代可用GC
1、串行GC(Serial Copying)Qclient方式下默认GC方式Q可通过-XX:+UseSerialGC强制指定?/p>
触发机制汇总:(x)
1Qold genI间不Q?br> 2Qperm genI间不Q?br> 3Qminor gc时的(zhn)观{略Q?br> 4Qminor GC后在eden上分配内存仍然失败;
5Q执行heap dumpӞ
6Q外部调用System.gcQ可通过-XX:+DisableExplicitGC来禁止?/p>
2、ƈ行回收GC(Parallel Scavenge)Q?server模式下默认GC方式Q可通过-XX:+UseParallelGC强制指定Q?q行的线E数为当cpu core<=8 ? cpu core : 3+(cpu core*5)/8或通过-XX:ParallelGCThreads=x来强制指定。如ScavengeBeforeFullGC为trueQ默认|(j)Q则先执行minor GC?/p>
3、ƈ行CompactingQ可通过-XX:+UseParallelOldGC强制指定?/p>
4、ƈ发CMSQ可通过-XX:+UseConcMarkSweepGC来强制指定。ƈ发的U程数默认ؓ(f):( q行GCU程?3)/4Q也可通过ParallelCMSThreads指定?/p>
触发机制Q?br> 1、当老生代空间的使用到达一定比率时触发Q?/p>
Hotspot V 1.6中默认ؓ(f)65%Q可通过PrintCMSInitiationStatisticsQ此参数在V 1.5中不能用Q来查看q个值到底是多少Q可通过CMSInitiatingOccupancyFraction来强制指定,默认值ƈ不是赋值在?jin)这个gQ是Ҏ(gu)如下公式计算出来的:(x) ((100 - MinHeapFreeRatio) +(double)(CMSTriggerRatio * MinHeapFreeRatio) / 100.0)/ 100.0; 其中,MinHeapFreeRatio默认|(x) 40 CMSTriggerRatio默认|(x) 80?/p>
2、当perm gen采用CMS攉且空间用到一定比率时触发Q?/p>
perm gen采用CMS攉需讄Q?XX:+CMSClassUnloadingEnabled Hotspot V 1.6中默认ؓ(f)65%Q可通过CMSInitiatingPermOccupancyFraction来强制指定,同样Q它是根据如下公式计出来的Q?(100 - MinHeapFreeRatio) +(double)(CMSTriggerPermRatio* MinHeapFreeRatio) / 100.0)/ 100.0; 其中QMinHeapFreeRatio默认|(x) 40 CMSTriggerPermRatio默认|(x) 80?/p>
3、HotspotҎ(gu)成本计算军_是否需要执行CMS GCQ可通过-XX:+UseCMSInitiatingOccupancyOnly来去掉这个动态执行的{略?br> 4、外部调用了(jin)System.gcQ且讄?jin)ExplicitGCInvokesConcurrentQ需要注意,在hotspot 6中,在这U情况下如应用同时用了(jin)NIOQ可能会(x)出现bug?/p>
6、GCl合
1Q默认GCl合
2Q可选的GCl合
7、GC监测
1Qjstat –gcutil [pid] [intervel] [count]
2Q?verbose:gc // 可以辅助输出一些详l的GC信息Q?XX:+PrintGCDetails // 输出GC详细信息Q?XX:+PrintGCApplicationStoppedTime // 输出GC造成应用暂停的时?br>-XX:+PrintGCDateStamps // GC发生的时间信息;-XX:+PrintHeapAtGC // 在GC前后输出堆中各个区域的大;-Xloggc:[file] // GC信息输出到单独的文g中,都加上,q个消耗不大,而且Ҏ(gu)问题和调优有很大的帮助。gc的日志拿下来后可使用GCLogViewer或gchistoq行分析?br>3Q图形化的情况下可直接用jvisualvmq行分析?/p>
4Q查看内存的消耗状?/p>
Q?Q长期消耗,可以直接dumpQ然后MAT(内存分析工具)查看卛_
Q?Q短期消耗,囑Ş界面情况下,可用jvisualvm的memory profiler或jprofiler?/p>
8、系l调优方?/strong>
步骤Q?、评估现?2、设定目?3、尝试调?4、衡量调?5、细微调?/strong>
讑֮目标Q?/strong>
1Q降低Full GC的执行频率?
2Q降低Full GC的消耗时_(d)
3Q降低Full GC所造成的应用停时_(d)
4Q降低Minor GC执行频率Q?br>5Q降低Minor GC消耗时_(d)
例如某系l的GC调优目标Q降低Full GC执行频率的同Ӟ可能降低minor GC的执行频率、消耗时间以?qing)GC对应用造成的停时间?/p>
衡量调优Q?/strong>
1、衡量工?br>1Q打印GC日志信息Q?XX:+PrintGCDetails –XX:+PrintGCApplicationStoppedTime -Xloggc: {文g名} -XX:+PrintGCTimeStamps
2QjmapQ(׃每个版本jvm的默认值可能会(x)有改变,q是用jmap首先观察下目前每个代的内存大、GC方式Q??br>3Q运行状늛工P(x)jstat、jvisualvm、sar 、gclogviewer
2、应攉的信?br>1Qminor gc的执行频率;full gc的执行频率,每次GC耗时多少Q?br>2Q高峰期什么状况?
3Qminor gc回收的效果如何?survivor的消耗状况如何,每次有多对象会(x)q入老生代?
4Qfull gc回收的效果如何?Q简单的memory leak判断Ҏ(gu)Q?br>5Q系l的load、cpu消耗、qps or tps、响应时?/p>
QPS每秒查询率:(x)是对一个特定的查询服务器在规定旉内所处理量多少的衡量标准。在因特|上Q作为域名服务器的机器性能l常用每U查询率来衡量。对应fetches/secQ即每秒的响应请求数Q也x最大吞吐能力?br>TPS(Transaction Per Second)Q每U钟pȝ能够处理的交易或事务的数量?/p>
试调优Q?/strong>
注意Java RMI的定时GC触发机制Q可通过Q?XX:+DisableExplicitGC来禁止或通过 -Dsun.rmi.dgc.server.gcInterval=3600000来控制触发的旉?/p>
1Q降低Full GC执行频率 ?通常瓉
老生代本w占用的内存I间׃直偏高,所以只要稍微放点对象到老生代,full GC?jin)?br>通常原因Q系l缓存的东西太多Q?br>例如Q用oracle 10g驱动时preparedstatement cache太大Q?br>查找办法Q现执行Dump然后再进行MAT分析Q?/p>
Q?QMinor GC后L有对象不断的q入老生代,D老生代不断的?br>通常原因QSurvivor太小?br>pȝ表现Q系l响应太慢、请求量太大、每ơ请求分配的内存太多、分配的对象太大...
查找办法Q分析两ơminor GC之间到底哪些地方分配?jin)内存?br>利用jstat观察Survivor的消耗状况,-XX:PrintHeapAtGCQ输出GC前后的详l信息;
对于pȝ响应慢可以采用系l优化,不是GC优化的内容;
Q?Q老生代的内存占用一直偏?br>调优Ҏ(gu)Q① 扩大老生代的大小Q减新生代的大或调大heap?大小Q;
减少new注意对minor gc的媄(jing)响ƈ且同时有可能造成full gcq是严重Q?br>调大heap注意full gc的时间的廉Qcpu够强(zhn)嘛Qos?2 bit的吗Q?br>?E序优化Q去掉一些不必要的缓存)(j)
Q?QMinor GC后L有对象不断的q入老生?br>前提Q这些进入老生代的对象在full GC时大部分都会(x)被回?br>调优Ҏ(gu)Q?br>?降低Minor GC的执行频率;
?让对象尽量在Minor GC中就被回收掉Q增大Eden区、增大survivor、增大TenuringThresholdQ注意这些可能会(x)造成minor gc执行频繁Q?br>?切换成CMS GCQ老生代还没有满就回收掉,从而降低Full GC触发的可能性;
?E序优化Q提升响应速度、降低每ơ请求分配的内存?/p>
Q?Q降低单ơFull GC的执行时?br>通常原因Q老生代太大了(jin)...
调优Ҏ(gu)Q?Q是q行GC吗? 2Q升UCPU 3Q减Heap或老生?/p>
Q?Q降低Minor GC执行频率
通常原因Q每ơ请求分配的内存多、请求量?br>通常办法Q?Q扩大heap、扩大新生代、扩大eden。注意点Q降低每ơ请求分配的内存Q横向增加机器的数量分担h的数量?/p>
Q?Q降低Minor GC执行旉
通常原因Q新生代太大?jin),响应速度太慢?jin),D每次Minor GC时存?gu)zȝ对象?br>通常办法Q?Q减点新生代吧Q?Q增加CPU的数量、升UCPU的配|;加快pȝ的响应速度
l微调整Q?/strong>
首先需要了(jin)解以下情况:(x)
?当响应速度下降到多或h量上涨到多少Ӟpȝ?x)宕掉?/p>
?参数调整后系l多久会(x)执行一ơMinor GCQ多久会(x)执行一ơFull GCQ高峰期?x)如何?/p>
需要计的量:(x)
①每ơ请求^均需要分配多内存?pȝ的^均响应时间是多少呢?h量是多少、多常时间执行一ơMinor GC、Full GCQ?/p>
②现有参CQ应该是多久一ơMinor GC、Full GCQ对比真实状况,做一定的调整Q?/p>
必杀技Q提升响应速度、降低每ơ请求分配的内存Q?/p>
9、系l调优D?/strong>
现象Q?、系l响应速度大概?00msQ?、当pȝQPS增长?0Ӟ机器每隔5U就执行一ơminor gcQ每?分钟执行一ơfull gcQƈ且很快就一直full GC?jin)?、每ơFull gc后旧生代大概?x)消?00MQ有点多?jin)?/p>
解决Ҏ(gu)Q解决Full GCơ数q多的问?/p>
Q?Q降低响应时间或hơ数Q这个需要重构,比较ȝ(ch)Q——这个是l极Ҏ(gu)Q往往能够利的解决问题,因ؓ(f)大部分的问题均是q序自w造成的?/p>
Q?Q减老生代内存的消耗,比较靠谱Q——可以通过分析Dump文gQjmap dumpQ,q利用MAT查找内存消耗的原因Q从而发现程序中造成老生代内存消耗的原因?/p>
Q?Q减每ơ请求的内存的消耗,貌似比较靠谱Q——这个是市(jng)蜃楼Q没有太好的办法?/p>
Q?Q降低GC造成的应用暂停的旉——可以采用CMS GS垃圾回收器。参数设|如下:(x)
-Xms1536m -Xmx1536m -Xmn700m -XX:SurvivorRatio=7 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection
-XX:CMSMaxAbortablePrecleanTime=1000 -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC
Q?Q减每ơminor gc晋升到old的对象。可选方法:(x)1Q?调大新生代?Q调大Survivor?Q调大TenuringThreshold?/p>
调大SurvivorQ当前采用PS GCQSurvivor space?x)被动态调整。由于调整幅度很,D?jin)经常有对象直接转移C(jin)老生代;于是止Survivor区的动态调整了(jin)Q?XX:-UseAdaptiveSizePolicyQƈ计算Survivor Space需要的大小Q于是l观察,q做微调…。最l将Full GC推迟?时1ơ?/p>
10、垃圑֛收的实现原理
内存回收的实现方法:(x)1Q引用计敎ͼ(x)不适合复杂对象的引用关p,其是@环依赖的场景?Q有向图TracingQ适合于复杂对象的引用关系场景QHotspot采用q种。常用算法:(x)Copying、Mark-Sweep、Mark-Compact?/p>
Hotspot从root set开始扫描有引用的对象ƈ对Referencecd的对象进行特D处理?br> 以下是Root Set的列表:(x)1Q当前正在执行的U程Q?Q全局/?rn)态变量;3QJVM HandlesQ?QJNI ?Java Native Interface 】HandlesQ?/p>
另外Qminor GC只扫描新生代Q当老生代的对象引用?jin)新生代的对象时Q会(x)采用如下的处理方式:(x)在给对象赋引用时Q会(x)l过一个write barrier的过E,以便(g)查是否有老生代引用新生代对象的情况,如有则记录到remember set中。ƈ在minor gcӞremember set指向的新生代对象也作为root set?/p>
新生代串行GC(Serial Copying)Q?/strong>
新生代串行GC(Serial Copying)完整内存的分配策略:(x)
1Q首先在TLABQ本地线E分配缓冲区Q上试分配Q?br> 2Q检查是否需要在新生代上分配Q如需要分配的大小于PretenureSizeThresholdQ则在edenZq行分配Q分配成功则q回Q分配失败则l箋Q?br> 3Q检查是否需要尝试在老生代上分配Q如需要,则遍历所有代q检查是否可在该代上分配Q如可以则进行分配;如不需要在老生代上试分配Q则l箋Q?br> 4Q根据策略决定执行新生代GC或Full GCQ执行full gc时不清除soft RefQ?br> 5Q如需要分配的大小大于PretenureSizeThresholdQ尝试在老生代上分配Q否则尝试在新生代上分配Q?br> 6Q尝试扩大堆q分配;
7Q执行full gcQƈ清除所有soft RefQ按步骤5l箋试分配?nbsp;
新生代串行GC(Serial Copying)完整内存回收{略
1Q检查to是否为空Q不为空q回falseQ?br> 2Q检查老生代剩余空间是否大于当前eden+from已用的大,如大于则q回trueQ如于且HandlePromotionFailure为trueQ则(g)查剩余空间是否大于之前每ơminor gc晋到老生代的q_大小Q如大于q回trueQ如于q回false?br> 3Q如上面的结果ؓ(f)falseQ则执行full gcQ如上面的结果ؓ(f)trueQ执行下面的步骤Q?br> 4Q扫描引用关p,活的对象copy到to spaceQ如对象在minor gc中的存活ơ数过tenuring_threshold或分配失败,则往老生代复Ӟ如仍然复制失败,则取决于HandlePromotionFailureQ如不需要处理,直接抛出OOMQƈ退出vmQ如需处理Q则保持q些新生代对象不动;
新生代可用GC-PS
完整内存分配{略
1Q先在TLAB上分配,分配p|则直接在eden上分配;
2Q当eden上分配失败时Q检查需要分配的大小是否 >= eden space的一半,如是Q则直接在老生代分配;
3Q如分配仍然p|Q且gc已超q频率,则抛出OOMQ?br> 4Q进入基本分配策略失败的模式Q?br> 5Q执行PS GCQ在eden上分配;
6Q执行非最大压~的full gcQ在eden上分配;
7Q在旧生代上分配Q?br> 8Q执行最大压~full gcQ在eden上分配;
9Q在旧生代上分配Q?br> 10Q如q失败,回到2?/p>
最(zhn)惨的情况,分配触发多次PS GC和多ơFull GCQ直到OOM?/p>
完整内存回收{略
1Q如gc所执行的时间超q,直接l束Q?br> 2Q先调用invoke_nopolicy
2.1 先检查是不是要尝试scavengeQ?br> 2.1.1 to space必须为空Q如不ؓ(f)I,则返回falseQ?br> 2.1.2 获取之前所有minor gc晋到old的^均大,q对比目前eden+from已用的大小Q取更小的一个|如老生代剩余空间小于此|则返回falseQ如大于则返回trueQ?br> 2.2 如不需要尝试scavengeQ则q回falseQ否则l;
2.3 多线E扫描活的对象,q基亍copying法回收Q回收时相应的晋升对象到旧生代;
2.4 如UseAdaptiveSizePolicyQ那么重新计to space和tenuringThreshold的|q调整?br> 3Q如invoke_nopolicyq回的是falseQ或之前所有minor gc晋到老生代的q_大小 > 旧生代的剩余I间Q那么l下面的步骤Q否则结束;
4Q如UseParallelOldGCQ则执行PSParallelCompactQ如不是UseParallelOldGCQ则执行PSMarkSweep?/p>
老生代ƈ行CMS GCQ?/strong>
优缺点:(x)
1Q?大部分时候和应用q发q行Q因此只?x)造成很短的暂停时_(d)
2QQ动垃圾,没办法,所以内存空间要E微大一点;
3Q内存碎片,-XX:+UseCMSCompactAtFullCollection 来解冻I
4Q?争抢CPUQ这GC方式pP
5Q多ơremarkQ所以ȝgc旉?x)比q行的长Q?br> 6Q内存分配,free list方式Qso性能E差Q对minor GC?x)有一点媄(jing)响;
7Q和应用q发Q有可能分配和回收同Ӟ产生竞争Q引入了(jin)锁,JVM分配优先?/p>
11、TLAB的解?/strong>
堆内的对象数据是各个U程所׃n的,所以当在堆内创建新的对象时Q就需要进行锁操作。锁操作是比较耗时Q因此JVM为每个线在堆上分配了(jin)一块“自留地”——TLAB(全称是Thread Local Allocation Buffer)Q位于堆内存的新生代Q也是Eden区。每个线E在创徏新的对象Ӟ?x)首先尝试在自己的TLAB里进行分配,如果成功p回,p|?jin)再到共享的Eden区里ȝL(fng)间。在U程自己的TLAB区域创徏对象p|一般有两个原因Q一是对象太大,二是自己的TLAB区剩余空间不够。通常默认的TLAB区域大小是Eden区域?%Q当然也可以手工q行调整Q对应的JVM参数?XX:TLABWasteTargetPercent?
参考文献:(x)
1、Sun JDK 1.6 GCQGarbage CollectorQ?nbsp; 作者:(x)毕玄
1、业丅R总集成商、监理单位、承建单位、品供货单位的沟通协调问题。首先,在与业主的沟通方面,最初较为乱,主要原因是没有Ş成统一的沟通结构与机制Q在最初的q三个月的时间里D目推进速度非常~慢。经与业d位沟通,制定?jin)工E的沟通方案,建立?jin)沟通组l结构。主要内Ҏ(gu)在业d位方面徏立了(jin)目实施办,目实施办对部领导组成的目办负责,明确?jin)项目办与实施办的责任,由实施办协调信息中?j)各处室共同推q项目工作;q且在信息中?j)内部推?#8220;承诺?#8221;也就是各处室均对工程的徏讑ֆ容进行承诺ƈ与W效挂钩。其ơ,总集成商、ȝ理商与实施办沟通,实施办与相关处室沟通,承徏商与产品供货单位在技术上接受总集成商的指gU束Q在程的规范性上接受ȝ理商的指gU束Q在业务上接受信息中?j)负责处室的U束。由此,通过沟通方案徏立与推行Q项目的沟通协调方面才q入?jin)正轨,目的推q速度明显加快?
2、用户单位对目的支持度{方面的问题。某些用户单位对所的项目ƈ没有强烈的需求,持可有可无或最好没有的态度Q但在工E的初设中这些项目又是必d讄内容。因此,在项目的实施的过E中Q这写用户单位对目的各工作均持消极态度Q得项目无法正常推q。例如,有些用户单位不组l本单位人员配合需求调研,不组l下属各省单位q行pȝ试运行,不组l本单位人员q行用户试{。对于这些问题往往pȝ承徏商方面已无法推动Q需要通过实施办与目办层面与用户单位沟通协商一致后才能l箋开展工作?
3、部本目与省U项目的协调推进问题。由于在工程的可研中包含各省的项目徏设,各省的进度对整体目的最l验收具有制U作用。目前,各省的徏设情况各不一_(d)有的已经完成Q有的正在徏设过E中Q有的资金尚未批复。。?
二、技术架构方?/strong>
1、应用系l部|架构问题。在09q底的时候,在应用系l部|架构出C(jin)一?#8220;互联|区应用pȝ讉KOracle RAC数据库时断时l问?#8221;Q此问题先后持箋??个月Q制U了(jin)目的徏设进度(期间采用?jin)其他方式,量减少了(jin)损失?j)。原?Q在q行整体应用pȝ部v架构设计Ӟ未q行相应产品的招标,因此无法明确具体的品(各品在具体的实现层面有差别Q这些差别可能媄(jing)响部|架构的实现Q。原?Q各厂商均具有专业领域的知识背景Q但对各知识领域之间的把握较?yu),因此很可能在边缘领域出现问题。原?Q由于本目为大型的?sh)子政务目Q涉?qing)的专业知识领域和技术手D非常繁杂,在设计与试q程中非常困难。在实施办与总集的M协调下,l过多次的评审与大量的测试,对应用系l部|架构进行了(jin)调整Q问题成功解决。此c问题的解决Ҏ(gu)是由总集成商牵头Q召集相关的承徏单位Q如|络集成商、安全集成商、数据库提供商。。。共同讨论分析,制定问题的排查方案,q按照方案查N题的原因。待问题的原因查找清楚后Q再由总集成商召集相关承徏商共同讨论提?gu)x法,l实施办审核通过Q如重大技术问题可由实施办召集专家q行评审定Q?
2、部分系l试q行阶段性能低下与生产环境问题排查困隄。一斚wQ工E所用到的技术非常复杂,采用?jin)大量的讑֤Q如 Oralce RAC集群Q存储,IBM型机、负载均衡集等Q此U环境很难有一个企业(如承建单位或W三Ҏ(gu)试单位)(j)复制。因此,无论是承建单位还是第三方试单位所q行的测试均无法完全反映生环境下的性能指标。另一斚wQ此U生产环境也是初ơ搭建,其技术可行性只停留在理论层面,期间的技术细节无法完全在设计阶段考虑刎ͼ只能通过一D|间的pȝ试运行才能够暴露与完善。当?dng)如果能够在系l进行初步设计时Q能够考虑搭徏一套与生环境完全或基本一致的试环境Q此问题能够很方便的进行解冻I也就是可以在试环境中进行应用系l的压力试与问题排查,待系l稳定后q满用戯求时Q再系l迁U至正式的生产环境中Q这U方式可以最大程度的保持生环境的稳定性?/p>
以下内容l合?jin)其他网友发表的内容Q首先再ơ表C感谢?/p>
假设一个系l有2000个用者(对于一般的企业pȝQ这个概忉|较简单,是指数据库中的用户LQ但对于|站型的pȝ而言Q相对较为复杂,一般ؓ(f)注册用户和游客的dQ,也就是说Q该pȝ的用hL?000名,q个概念表示的是“pȝ用户?#8221;。如果该pȝh“ 在线l计”功能Q该功能一般用于记录系l中所有已l登录的用户Q当然如果有一些系l功能同时也提供l未d的用户用,那么未登录的当前使用者也应记录进来)(j)Q如果根据此l计l果得到最高峰时有500人在U,那么q个500是所说的“同时在线用户?#8221;?
Ҏ(gu)对业务ƈ发用h的定义,q?00是整个pȝ使用时最大的业务q发用户数。当?dng)?00q个数值只是表明在最高峰时刻?00个用L(fng)录了(jin)pȝQƈ不表C实际服务器承受的压力。因为服务器承受的压力还与具体的用户讉K模式相关。例如,考察具体的某一个时间点Q在q?00?#8220;同时在线用户?#8221;中,其中40%的用户在较有兴致地看pȝ公告Q注意:(x)“?#8221;q个动作是不?x)对服务端生Q何负担的Q,20%的用户在填写复杂的表|对用户填写的表格来说Q只有在“提交”的时L?x)向服务端发送请求,填写q程是不Ҏ(gu)务端构成压力的)(j)Q?0%部分用户在发呆(也就是什么也没有做)(j)Q剩下的 20%用户在不停地从一个页面蟩转到另一个页?#8212;—在这U场景下Q可以说Q只?0%的用L(fng)正对服务器构成了(jin)压力。因此,从上面的例子中可以看出,服务器实际承受的压力不只取决于业务ƈ发用hQ还取决于用L(fng)业务场景?
在实际的性能试工作中,试人员一般比较关?j)的是业务ƈ发用hQ也是从业务角度关注究竟应该设|多个q发数比较合理,因此Q在后面的讨ZQ也是主要针对业务ƈ发用hq行讨论Q?font color="#ff0000">而且Z(jin)方便Q直接将业务q发用户数称为ƈ发用h?/font>
Q?Q?计算q_的ƈ发用hQ?C = nL/T
Q?Q?q发用户数峰|(x) C’ ≈ C+3根号C
公式Q?Q中C是^均的q发用户敎ͼn是login session的数量;L是login session的^均长度;T指考察的时间段长度?
公式Q?Q给Z(jin)q发用户数峰值的计算方式Q其中C’指ƈ发用h的峰|C是公式Q?Q中得到的^均的q发用户数。该公式的得出是假设用户的login session产生W合泊松分布而估得到的?
实例Q?
假设有一个OApȝQ该pȝ?000个用Pq_每天大约?00个用戯讉K该系l,对一个典型用h_(d)一天之内用户从d到退?gu)pȝ的^均时间ؓ(f)4时Q在一天的旉内,用户只在8时内用该pȝ?
则根据公式(1Q和公式Q?Q,可以得到Q?
C = 400*4/8 = 200
C’≈200+3*根号200 = 242
以下是测试所需的一些常用公式,仅供参?/p>
F=VU * R / T R = T / TS
其中F为吞吐量QVU表示虚拟用户个数QR表示每个虚拟用户发出的请求数QT表示性能试所用的旉QTS为用h考时??/p>
1 、搭配草Eѝ蓝图两U用法的步骤?/span>
1Q?span style="FONT: 7pt 'Times New Roman'">
先画?/span> UML 草稿2Q?span style="FONT: 7pt 'Times New Roman'">
?/span> CASE 工具用正向工E{出程序码大纲3Q?span style="FONT: 7pt 'Times New Roman'">
修改E序?/span>4Q?span style="FONT: 7pt 'Times New Roman'">
定期从程序码?/span> CASE 工具用反向工E{?/span> UML 设计模型?/span> UML 视ؓ(f)草稿是在?/span> [ 选择?/span> ] 。选择主要的模块进行讨论?/span>
?/span> UML 视ؓ(f)蓝图是在?/span> [ 完整?/span> ] 。这U做法可以用在所?/span> [ l节 ] 的工作上Q也可以针对特定的部分化?gu)图?/span>
模型驱动开发架构( Model Driven Architecture Q?/span> MDA Q:(x) MDA ?/span> UML 视ؓ(f)E序语言的标准用法?/span> MDA 开发分Z个主要部分,模型建立者会(x)负责产生于^台无关的模型 Q?/span> Platform Independent Model Q?/span> PIM Q, PIM 代表与Q何与特定格式无关?/span> UML 模型。然后工具可以把 PIM 转换为^台特有模型( PSM Q, PSM 是在某个特定执行环境之上的模型,其他工具可以?/span> PSM 转换为某个^C上的E序码?/span>
UML 的创造者认?/span> UML 的本质在于超模型Q图仅仅是超模型的展现而已?/span>
个h推荐?span lang="EN-US">UML作ؓ(f)草稿的用法,
UML2.0
中的囑օ有如?span lang="EN-US">11U:(x)
1?span style="FONT: 7pt 'Times New Roman'">
zd图(activity diagramQ?span lang="EN-US">2?span style="FONT: 7pt 'Times New Roman'">
cdQ?span lang="EN-US">Class diagramQ?/span>3?span style="FONT: 7pt 'Times New Roman'">
合作图( communicationdiagram diagram Q:(x)对象件的互动情ŞQ焦点在q接关系?/span>4?span style="FONT: 7pt 'Times New Roman'">
元g图(component diagramQ元件结构与q接关系
5?span style="FONT: 7pt 'Times New Roman'">
合成l构Q?span lang="EN-US">composite structureQ类别在执行期的合成情ŞQ?span lang="EN-US">UML2
新增
Q?/span>
6?span style="FONT: 7pt 'Times New Roman'">
配置图(deployment diagramQ将工作成果配置到节点上
7?span style="FONT: 7pt 'Times New Roman'">
互动概图Q?span lang="EN-US">interaction overview diagramQ合时序图与活动图两者(UML2新增Q?/span>
8?span style="FONT: 7pt 'Times New Roman'">
对象图(object diagramQ?/span>
9?span style="FONT: 7pt 'Times New Roman'">
套g图(package diagramQ编译器的阶层结?/span>
10?span style="FONT: 7pt 'Times New Roman'">
时序图(sequence diagramQ对象间的互动情形,焦点在信息的先后序?span lang="EN-US">
11?span style="FONT: 7pt 'Times New Roman'">
状态机图(state machine diagramQ说明事件在对象中的生命力,如何改变状?span lang="EN-US">
12?span style="FONT: 7pt 'Times New Roman'">
时序图(timing diagrameQ对象间的互动情形(UML2新增Q?span lang="EN-US">
13?span style="FONT: 7pt 'Times New Roman'">
用例图(use case diagrameQ说明用者如何与pȝq行交互
?/SPAN>Q?/SPAN>JCL提供一个日志接口,同时兼顾轻量U和不依赖于具体的日志实现工兗?/SPAN>
入门Q?/SPAN>JCL有两个基本的抽象c:(x)Log(基本U录?/SPAN>)?/SPAN>LogFactory(负责创徏Log实例)?/SPAN>JCLL日志工具的过E如下:(x)
一?SPAN style="FONT: 7pt 'Times New Roman'"> L当前?/SPAN>factory中名?/SPAN>org.apache. commons.logging.Log配置属性的倹{?/SPAN>
二?SPAN style="FONT: 7pt 'Times New Roman'"> Lpȝ属性中名叫org.apache.commons.logging.Log的倹{?/SPAN>
三?SPAN style="FONT: 7pt 'Times New Roman'"> 如果应用E序?/SPAN>CLASSPATH中有Log4j,q是用相关的包装c(wrapperQ类Q?/SPAN>Log4JloggerQ?/SPAN>.
四?SPAN style="FONT: 7pt 'Times New Roman'"> 如果应用E序q行?/SPAN>jdk1.4的系l中Q用相关的包装c?/SPAN>(JDK1.4logger).
五?SPAN style="FONT: 7pt 'Times New Roman'"> 使用易日志包装类Q?/SPAN>SimpleLogQ?/SPAN>.
使用logging:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyClass{
private static Log log=LogFactory.getLog(this.CLASS);
………………………?o:p>
}
q些日志信息被送往日志器,如上例中?/SPAN>log?/SPAN>
Log接口中的Ҏ(gu)Q?/SPAN>
定义日志信息的别,按严重性有Q?/SPAN>
log.fatal(Object message);
log.fatal(Object message,Throwable t);
log.error(Object message);
log.error(Object message,Throwable t);
log.warn(Object message);
log.warn(Object message,Throwable t);
log.info(Object message);
log.info(Object message,Throwable t);
log.debug(Object message);
log.debug(Object message,Throwable t);
log.trace(Object message);
log.trace(Object message,Throwable t);
fatal:非常严重的错误,Dpȝl止。期望这cM息被立即昄到状态控制台上?/SPAN>
Error:其他q行期错误或不是预期的条件。期望这cM息被立即昄到状态控制台上?/SPAN>
Warn:使用?jin)不赞成使用?/SPAN>API、非常拙劣的使用?/SPAN>API、‘几乎就是错误’其他运行期不合需要和不合预期的状态(但没必要其UCؓ(f)错误Q。期望这cM息被立即昄到状态控制台上?/SPAN>
Info:q行期生的有意义的事g。期望这cM息被立即昄到状态控制台上?/SPAN>
Debug:pȝ程中的l节信息。期望这cM息仅被写入日志文件中?/SPAN>
Trace:更加l节的信息。期望这cM息仅被写入日志文件中?/SPAN>
用于代码保护(表示如果启用?jin)某U日志信息?/SPAN>)Q?/SPAN>
log.isFatalEnabled();
log.isErrorEnabled();
log.isWarnEnabled();
log.isInfoEnabled();
log.isDebugEnabled();
log.isTraceEnabled();
通常情况下,记录器的U别不低?/SPAN>info,通常情况?/SPAN>debug信息不应被写?/SPAN>log文g中?/SPAN>
工作机理Q?/SPAN>
一?SPAN style="FONT: 7pt 'Times New Roman'">
二?SPAN style="FONT: 7pt 'Times New Roman'"> 异常处理Q?/SPAN>JCL Log接口没有实现M异常处理Q对接口的实现必L获ƈ处理异常?/SPAN>
记录器的讄Q?/SPAN>log4j?/SPAN>JCL的首选记录器Q?/SPAN>
参数 |
值域 |
默认?/SPAN> |
说明 |
Log4j.configuration |
|
Log4j.properties |
指定配置文g的名?/SPAN> |
Log4j.rootCategory |
Priority[,appender].* |
|
讑֮根记录器U别 |
Log4j.logger. |
Debug,info,trace,error,fatal |
讑֮ |
|
Log4j.appender. |
priority |
指定U录讑֤ |
|