Web应用单点压力测试调优-第5季

 

各项配置:

my.cnf

 

 

[client]
port		= 3306
socket		= /tmp/mysql.sock

[mysqld]

port		= 3306
socket		= /tmp/mysql.sock
skip-external-locking
key_buffer_size = 16M
max_allowed_packet = 1M
myisam_sort_buffer_size = 8M
log-bin=mysql-bin
binlog_format=mixed

server-id	= 1

#update start
max_connections=1500
query_cache_size=16M
default-storage-engine=INNODB
#table_cache=256
tmp_table_size=8M
thread_cache_size=8
read_buffer_size=64K
read_rnd_buffer_size = 256K
net_buffer_length = 8K
table_open_cache = 32
sort_buffer_size = 256K
innodb_additional_mem_pool_size=2M
innodb_flush_log_at_trx_commit=0
innodb_log_buffer_size=4M
innodb_buffer_pool_size=32M
innodb_log_file_size=128M
innodb_thread_concurrency=1
#update over

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

 

 

Tomcat配置

catalina.sh

JAVA_OPTS="-server -XX:PermSize=82M -XX:MaxPermSize=82M -Xss256k -Xms450m -Xmx450m -Xmn300m -XX:SurvivorRatio=6 -Xverify:none -XX:MaxTenuringThreshold=15 -XX:+UseFastAccessorMethods -XX:+UseAdaptiveSizePolicy -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.137.233"

 

 

 

server.xml连接器(因为瓶颈不在连接器,所以暂未使用apr连接器)


 程序中的连接池配置

 

 

 

jdbc.driverClass=com.mysql.jdbc.Driver
#jdbc.jdbcUrl=jdbc:mysql://192.168.137.200:3306/story?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSize=128&prepStmtCacheSqlLimit=512&autoReconnect=true
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/story?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSize=32&prepStmtCacheSqlLimit=256&autoReconnect=false&metadataCacheSize=16&maintainTimeStats=false&cacheResultSetMetadata=true&useNewIO=true&emptyStringsConvertToZero=false&maxRows=30
jdbc.user =root
jdbc.password=111111
jdbc.miniPoolSize=300
jdbc.maxPoolSize=1500
jdbc.initialPoolSize=300
jdbc.maxIdleTime = 120000
jdbc.acquireIncrement=30
jdbc.acquireRetryAttempts = 40
jdbc.acquireRetryDelay=120000
jdbc.testConnectionOnCheckin = true
jdbc.automaticTestTable = test
jdbc.idleConnectionTestPeriod = 30000
jdbc.checkoutTimeout=65000

 

 

调整8-将热点数据news的数据集list缓存到HashMap

 

这是最后的办法了,没有办法的办法,简单缓存数据集到本地内存。这里假设热点数据是news数据集,关键代码如下

		String sqlString = sql.toString()+rowStartIdxAndCount[0]+rowStartIdxAndCount[1];
		readLock.lock();
		if(cache.containsKey(sqlString)){
			readLock.unlock();
			return cache.get(sqlString);
		}else{
			readLock.unlock();
			writeLock.lock();
			List list = (List) quaryGridListPrepare(sql.toString(),
					NewsBean.class, rowStartIdxAndCount[0], rowStartIdxAndCount[1]);
			cache.put(sqlString, list);
			writeLock.unlock();
			return list;
		}
		
		/*
		return (List) quaryGridListPrepare(sql.toString(),
				NewsBean.class, rowStartIdxAndCount[0], rowStartIdxAndCount[1]);
				*/

	}
	
	private Map> cache = new HashMap>();
	private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	private Lock readLock = rwl.readLock();
	private Lock writeLock = rwl.writeLock();

 

 

之后再将mysql的配置修改,将资源调小一点(其实最大连接数也可以调小)

 

#update start
max_connections=1500
query_cache_size=16M
default-storage-engine=INNODB
#table_cache=256
tmp_table_size=8M
thread_cache_size=8
read_buffer_size=64K
read_rnd_buffer_size = 256K
net_buffer_length = 8K
table_open_cache = 16
sort_buffer_size = 256K
innodb_additional_mem_pool_size=2M
innodb_flush_log_at_trx_commit=0
innodb_log_buffer_size=4M
innodb_buffer_pool_size=16M
innodb_log_file_size=128M
innodb_thread_concurrency=1
#update over

 JVM再多一点点内存空间

 

 

JAVA_OPTS="-server -XX:PermSize=82M -XX:MaxPermSize=82M -Xss256k -Xms480m -Xmx480m -Xmn320m -XX:SurvivorRatio=4 -Xverify:none -XX:MaxTenuringThreshold=20 -XX:+UseFastAccessorMethods -XX:+UseAdaptiveSizePolicy -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.137.233"

 

 

1500并发,准备9s循环6次。

 

走势图


Web应用单点压力测试调优-第5季_第1张图片
 报告

 



 

 

平稳后,TPS上升到了267/S。平均在250~270之间

 

这里是一个理想的场景,实际情况是:根据日志,进行离线分析(hadoop)可以分析出哪些表是热点表,哪些sql是热点sql,哪些数据是热点数据。之后利用缓存策略,再将其缓存。再利用读写锁,进行缓存操作,TPS上升上去。此刻场景仅仅将news表作为热点表,其实不科学也不严谨,不过表明一点,此方案在内存十分有限的情况下,可行。只不过得权衡缓存数据的大小,以便让缓存的命中率(hit count)高一些,别浪费哪些内存资源。

JVM堆内存走势(因新生代空间比例较大,所以波浪较为明显)


Web应用单点压力测试调优-第5季_第2张图片
 

 

 

到底哪些数据应该放入缓存,这是一个长期的监控数据分析后得出的结论。根据经验估算,此单点机器所有功能都用上后,缓存再稍微改造成普适性接口,基本TPS可以平均维持在100/s左右的数值。

 

调优顺序(根据场景,制定不同时期的2/8原则):http请求数>数据库连接>数据库优化>日志IO节省>Java业务代码优化>JVM优化>热点数据缓存>操作系统内核参数优化,之后在根据此顺序迭代进行(如果你是个吞吐量达人)。其中MysqlSql语句、缓存机制、操作系统内核参数还有进一步优化的余地。

 

(未完,待续)

 

标记:23页,阶段性总结之前

 

你可能感兴趣的:(经验总结,java,tomcat,jvm,linux,调优)