欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-23 18:23:21
...

 

各项配置:

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连接器)

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="45000"
               redirectPort="8443" maxHttpHeaderSize="4096" disableUploadTimeout="true" enableLookups="false" bufferSize="4096" />

 程序中的连接池配置

 

 

 

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<NewsBean> list = (List<NewsBean>) quaryGridListPrepare(sql.toString(),
					NewsBean.class, rowStartIdxAndCount[0], rowStartIdxAndCount[1]);
			cache.put(sqlString, list);
			writeLock.unlock();
			return list;
		}
		
		/*
		return (List<NewsBean>) quaryGridListPrepare(sql.toString(),
				NewsBean.class, rowStartIdxAndCount[0], rowStartIdxAndCount[1]);
				*/

	}
	
	private Map<String,List<NewsBean>> cache = new HashMap<String,List<NewsBean>>();
	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季
            
    
    博客分类: 经验总结 javatomcatjvmlinux调优 
 报告

 


Web应用单点压力测试调优-第5季
            
    
    博客分类: 经验总结 javatomcatjvmlinux调优 
 

 

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

 

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

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


Web应用单点压力测试调优-第5季
            
    
    博客分类: 经验总结 javatomcatjvmlinux调优 
 

 

 

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

 

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

 

(未完,待续)

 

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

 

  • Web应用单点压力测试调优-第5季
            
    
    博客分类: 经验总结 javatomcatjvmlinux调优 
  • 大小: 23.6 KB
  • Web应用单点压力测试调优-第5季
            
    
    博客分类: 经验总结 javatomcatjvmlinux调优 
  • 大小: 9 KB
  • Web应用单点压力测试调优-第5季
            
    
    博客分类: 经验总结 javatomcatjvmlinux调优 
  • 大小: 21.4 KB