6月13日升级,做了两点性能调整:
A、构架方案从Jboss直接连接f5并处理https请求,切换到apache连接f5,并处理https请求,jboss通过AJP协议连接apache
B、优化URLConnection连接代码,连接idstorage时重用http长连接。(以前每次连接idstorage,需要重新开启socket)(keep-alive request number 可以在server.xml中设置,默认为100次连接后,断开socket,可以设置为-1)
线上jboss比较:
升级前 |
升级后 |
|
信息获取时间点 |
6月12日 |
6月17日 |
线上服务运行时间 |
18天 |
3天 |
抽样机器地址 |
OAuth3 |
OAuth3 |
内存占用大小(注a) |
1549M |
130M |
垃圾回收占用时间(注b) |
21925秒 = 1%的运行时间 |
35秒 占0.01%运行时间 |
与Idstorage服务的socket连接数量 |
154(注c) |
7 |
超过1秒的jboss请求访问数(注d) |
877(总共日志61W行) |
196(总共日志30W行) |
超过1秒的idstorage请求 |
19 |
2 |
注a:这里的内存大小,是通过jmap统计的内存中对象大小总和值。而不是top中的内存值。
注b:通过jstat –gcutil pid得出。命令可查看当前jvm各个区占用内存大小,各个区的回收次数和回收时间。
升级前jboss的内存分析:
S0S1 E OP YGC YGCTFGC FGCT GCT
0.000.00 27.93 82.89 50.45 92965 1907 16200420017 21925
从上面的数据看出,O=82.89代表内存中的老生命对象已经占用了1.7G old区的大部分,已经不够用了,因此做了16W次old区的full gc,而full gc是非常耗时的,结果就是cpu花在gc上的时间很多。
升级后jboss内存分析:
S0S1 E OP YGC YGCTFGC FGCT GCT
0.000.00 5.69 4.44 49.005134 32.784 52.796 35.580
从上面数据可以看出,O=4.44,内存占用非常小,而full gc才做了5次,因此jboss的整体gc负担非常轻。
注c:154个中包括因为换socket后,原先断开的socket状态变为TIME_WAIT。所以不代表当前有154个idstorage socket连接。
注d:
升级前877个resp slow分部:
92 /innerapi/oauth/access_token_cap
233 /innerapi/oauth/access_token_xauth_yunos_open (这个因为rsa解密本来就慢)
56 /openapi/id/aliyunid
371/scripts/jquery-1.5.2.min.js
其它省略
升级后196个resp slow分布:
9 /innerapi/id/aliyunid_cookie
9 /innerapi/oauth/access_token_xauth_mobile_alipay
162/innerapi/oauth/access_token_xauth_yunos_open(这个因为rsa解密本来就慢)
5 /login/check_need_captcha_code.htm
其它省略
1、jboss自带的connector去处理https请求,会很吃内存
从下面的数据可以看出,jboss处理https后,内存中大头都是跟https处理有关的java类。使用apache处理https,jboss走ajp后,那些top10中跟https有关的java类一下子全部消失了。
使用jboss处理https后,内存top10:
num#instances #bytes class name
----------------------------------------------
1: 1822210 262398240com.sun.net.ssl.internal.ssl.SSLSessionImpl
2: 4019327 261938120[B
3: 1934867 216756080[Ljava.util.Hashtable$Entry;
4: 2211842 123863152java.lang.ref.SoftReference
5: 1934789 123826496java.util.Hashtable
6: 1975065 116832368[C
7: 1823220 116686080java.lang.ref.Finalizer
8: 2209820 106071360sun.misc.CacheEntry
9: 2008420 80336800java.lang.String
10: 1822212 58310800[Ljava.security.cert.X509Certificate;
使用apache处理https,jboss走AJP协议,内存top10:
num#instances #bytesclass name
----------------------------------------------
1: 102839 14294832[C
2: 91504 13474952<constMethodKlass>
3: 91504 10993376<methodKlass>
4: 8321 9818256<constantPoolKlass>
5: 20663 8170376[Ljava.lang.Object;
6: 143119 7296656<symbolKlass>
7: 14708 6795360[B
8: 8321 6587904<instanceKlassKlass>
9: 7099 5881120<constantPoolCacheKlass>
10: 139130 5565200java.lang.String
11: 14792 5107400[I
12: 78727 5038528java.util.TreeMap$Entry
13: 15604 2851728[Ljava.util.HashMap$Entry;
14: 17245 2621240java.lang.reflect.Method
15: 4056 2394520<methodDataKlass>
16: 38105 1829040java.util.HashMap$Entry
17: 8965 1649560java.lang.Class
2、jboss处理https的对象,都会跑到old区。
在测试平台,尝试以:
-Xmx2g -Xms2g -Xmn1g -XX:+UseParNewGC-XX:+UseConcMarkSweepGC
试图将new区放大到1g,看看相关垃圾是否会在newgc中处理掉,因为newgc的处理比较快,这样变相减轻了jboss负担。
跑了8个小时后,结果是:
S0S1 E OP YGC YGCTFGC FGCT GCT
0.0043.20 9.4299.64 40.181226 58.384 2436 974.099 1032.483
O = 99.64,意味着1g的old区已经完全不够用了,于是8小时内发生了4千多次fullgc,jboss总内存达到1160M。
没有达到在newgc中将其回收的目的。
如下为对比数据
总共内存2g,old区1g |
总共内存2g,old区1.7g |
|
运行时间 |
12小时 |
12小时 |
内存占用 |
1160M |
1744M |
Gc时间 |
5453秒(其中fullgc4912次,5394秒) |
220秒 |
超过1秒请求数 |
10685 |
1355 |
3、通过jboss native模块,使用APRConnecotr,jboss可直接处理https请求
Jboss native模块,其实是对apr本地lib的一个java包装,通过这个技术,java类中可以调用本地aprlib接口,处理ssl和网络请求,最终通过openssl处理https,这样和apache处理https一样了。
通过这种方法,可以让jboss直接走f5,直接处理https,且内存占用也很小。
跑了1天半时间下,jboss内存状态:
S0S1 E OP YGC YGCTFGC FGCT GCT
29.360.00 31.96 12.5030.51 8150 104.400 265.235 109.636
总共内存大小264M,这样jboss的负担也很轻。
缺点:jboss native不是jboss自带的模块,需要额外安装,不是很方便维护。
4、jboss直接走http通道,效率也很高
Jboss http connector |
Jboss https connector |
|
运行时间 |
8小时 |
8小时 |
内存占用 |
118M |
1.1G |
Gc时间 |
14秒 |
1032秒 |
超过1秒的请求数 |
239 |
3708 |