关于并发下的优化有很多,接下来总结一下并一一实践测试一下:
读操作:
首先是单机优化:
1.数据库方面:优化语句,避免出现模糊查询、多表逗号等。
2.数据库方面:读操作:给数据库加索引,增加查询速度。
3.数据库方面:增加数据库socket连接数、增大缓存等。
4.容器方面:增加tomcat等待队列长度、线程数等。
5.容器方面:与客户端建立长连接
接下来转为集群:
6.nginx反向代理负载均衡
7.nginx建立长连接
8.加入缓存并使用redis
9.加入nginx lua读取缓存
10.静态资源cdn加速
11.使用爬虫使页面静态化并cdn加速
接下来是秒杀交易方面的优化:
12.数据库方面:写操作:mybatis批量写操作,减少sql预编译的时间。
13.加入mq、使用事务型消息进行扣减库存等操作
14.发放有限秒杀令牌根据商品数量、售罄情况来控制流量
15.使用线程池,依靠队列和下游拥塞窗口程度调整队列进行泄洪。
16.加入验证码
17.使用guava的RateLimiter进行类似令牌桶来限流
主要进行这些的压测,并找到最好的优化方法。
先不考虑带宽问题,所以在本机搭虚拟机,测试配置为:
mysql版本:
数据量:
jdk:
压测工具:jmeter
下面开测
单机:
基础(非主键无索引):
1000个线程,20次
跑到中间停了,实在惨不忍睹。
加一个普通索引(另一个百万级表不加):
由于主键自增,所以不测唯一索引了
1000个线程,20次
还是到中间就停了,但还是可以看出,还是有一丢丢提高的。
两张表都加索引:
1000个线程,20次
tps瞬间上来了, 可见索引的重要性。
查询使用主键(只有一张表使用,另一张表无法使用主键,仍用普通索引):
可以看到,使用主键的时候没有使用索引的效率高。但一般情况下,主键都会比普通索引效率高,因此我们通过单表查询验证下:
主键查询:
普通索引查询:
确实普通索引快一些,我的猜测是,如果ID为主键,则会创建一个基于主键的聚簇索引,在大数据情况下,一个索引键值可能会对应一个或多个数据页,这使得一个id将扫描更多的数据页才能取出id值。而对于普通索引而言,可以直接通过索引查,所以速度要比主键更快。当然这个问题还有待深入研究。
增加数据库socket连接数、缓存等:
值得注意的地方有两个:
innodb_data_file_path配置的时候,需要删掉原来的,或重新定位一个地方。
删除/var/lib/mysql下的ib_logfile0和ib_logfile1。
连接时长略微有些变化,当然这些数值还是需要经过测试进行合理调整的。
单机的容器优化:
没有加参数和加过参数,运行时线程数:
再加上长连接呢?
-
/**
-
* 当spring容器内没有TomcatEmbeddedServletContainerFactory这个bean时,会把此bean加载进spring容器中
-
*/
-
@Component
-
public
class WebServerConfiguration implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
-
@Override
-
public void customize(ConfigurableWebServerFactory factory) {
-
//使用对应工厂类定制化tomcat connector
-
((TomcatServletWebServerFactory) factory).addConnectorCustomizers(
new TomcatConnectorCustomizer() {
-
@Override
-
public void customize(Connector connector) {
-
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
-
//定制化keepalivetimeout,30秒
-
protocol.setKeepAliveTimeout(
30000);
-
//客户端发送超过10000个请求自动断开
-
protocol.setMaxKeepAliveRequests(
400);
-
}
-
});
-
}
-
}
tps反而下来了,所以关于Http11NioProtocol后面还需研究。
转载:https://blog.csdn.net/haozi_rou/article/details/105477951