电商高并发秒杀1 Tomcat调优

作者: 香沙小熊 | 来源:发表于2020-03-21 11:08 被阅读0次

    1.性能压测框架

    1.1SpringBoot的云端部署
    1.maven打包
    2.上传centos
    3.外挂配置文件

    每个项目从开发到测试再到上线所需要的各种环境是不同的,这就需要维护相应的配置文件,比如properties或yml文件。有了配置文件后就要考虑如何与应用进行集成。

    对于云环境来讲,项目发布需要打成镜像,再进行部署。如果把spring boot项目连同配置文件(变量)一起打入JAR包并不是一个很好的选择,我们的做法是JAR不包含配置文件,待启动镜像和JAR时将配置文件动态赋值给JAR包。

    对于Spring Boot项目,有两种做法可以实现该目的:

    1. --spring.config.location
    java -jar miaosha-1.0-SNAPSHOT.jar --spring.config.location=/usr/local/www/miaosha/application.properties
    
    
    

    要特别注意的是,该命令指定的配置文件会使项目默认的application.properties或application.yml文件失效,换句话说该命令会用指定的配置文件替换application.properties或application.yml文件。

    1. --spring.config.additional-location
    java -jar miaosha-1.0-SNAPSHOT.jar --spring.config.additional-location=/usr/local/www/miaosha/application.properties
    

    顾名思义,该命令用于追加配置文件。原有的application.properties或application.yml文件均有效。

    4.编写deploy脚本启动

    为了避免启动服务后,关闭终端导致服务停止,我们采用依赖脚本处理deploy.sh进行处理。

    nohup java -Xms400m -Xmx400m -XX:NewSize=200m -XX:MaxNewSize=200m -jar miaosha.jar  --spring.config.additional-location=/usr/local/www/java/miaosha/application.properties
    

    当前deploy.sh文件目录下,chmod -R 777 *修改可执行权限,然后启动脚本./deploy.sh &
    执行完会提示:nohup:忽略输入并把输出追加到 nohup.out”,可以使用tail -200f ./nohup.out 查看服务启动的日志输出

    注:

    nohup:LINUX命令用法,不挂断地运行命令
    -Xms400m:初始jvm堆栈大小
    -Xmx400m:最大jvm堆栈大小
    -XX:NewSize=200m:初始jvm新生代大小
    -XX:MaxNewSize=200m:最大新生代大小
    java -jar XXX.jar &
    

    命令结尾没有& ,则变成 java -jar XXX.jar ,表示在当前ssh窗口,可按CTRL + C打断程序运行,或者直接关闭窗口,则程序直接退出
    命令结尾添加& ,则变成 java -jar XXX.jar & ,表示在当窗口关闭时,程序才会中止运行。&代表让该命令在后台执行。

    nohup java -jar XXX.jar > Log.log & 
    

    或者

    nohup java -jar XXX.jar >> Log.log &
    

    命令 nohup java -jar XXX.jar &部分,表示不挂断运行命令,当账户退出或终端关闭时,程序仍然运行。注意,该作业的所有输出被重定向到nohup.out的文件中。
    命令 nohup java -jar XXX.jar > Log.log & 部分,表示不挂断运行命令,当账户退出或终端关闭时,程序仍然运行,并且该作业的所有输出被重定向到Log.log的文件中。“ > Log.log ” 该命令就是指定日志输出的文件。
    ">>"表示将输出以追加的方式重定向到Log.log中。

    nohup java -jar XXX.jar > Log.log 2>&1 & 
    

    或者

    nohup java -jar XXX.jar >> Log.log 2>&1 & 
    

    或者

    nohup java -jar XXX.jar > /dev/null 2>&1 & 
    

    标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
    标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
    标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
    屏蔽输出,起到禁止输出作用:/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
    “> Log.log 2>&1” :表示将 stdout 和 stderr 合并后重定向到 Log.log
    注:
    输出之后,可以使用“jobs”查看一下后台运行的任务。

    1.2使用JMeter发现性能问题
    1. 线程组
    2. Http请求
    3. 查看结果树
    4. 聚合报告
    1.3 发现容量问题
    1. 在安装完jmeter之后,对项目进行性能压测,发现server端的并发线程数上不去;
    image.png
    2. 采用 pstree -p 进程号|wc -l 查看线程数;采用top -H查看机器性能;
    [root@localhost ~]# pstree -p 127762 | wc -l
    218
    
    [root@localhost ~]# top -H
    
    

    cpu使用飙升,load average > 5


    image.png
    • 表象:单机cpu使用率增高,memory占用增加,网路带宽使用增加
    • cpu us :用户空间的cpu使用情况(用户层代码)
    • cpu y:内核空间的cpu使用情况(系统调用)
    • load average:1.5,15分钟load平均值,跟着核数系数,0代表通常,1代表打满 1+代表等待阻塞
    • memory:free空闲时间,used使用内存

    把CPU比喻成一条(单核)马路,进程任务比喻成马路上跑着的汽车,Load则表示马路的繁忙程度:
    Load < 0.7时:系统很闲,马路上没什么车,要考虑多部署一些服务
    0.7 < Load < 1时:系统状态不错,马路可以轻松应对
    Load == 1时:系统马上要处理不多来了,赶紧找一下原因
    Load > 5时:马路已经非常繁忙了,进入马路的每辆汽车都要无法很快的运行

    2.Tomcat性能优化

    查看SpringBoot配置

    • spring-configuration-metadata.json文件下
    • 常看各个节点的配置
    2.1Tomcat的作用

    Tomcat是一个轻量级应用服务器,是支持运行Servlet/JSP应用程序的容器,运行在jvm上,绑定IP地址并监听TCP端口;运行时占用的系统资源小,扩展性好,支持负载平衡与邮件服务等开发应用系统常用的功能;

    在做web项目时多数需要http协议,基于请求和响应,servlet就是在服务器端运行的java程序,通过配置文件拦截你的请求,并进行相应处理,然后展示给你相应界面;Tomcat就可以创建servlet,去运行web项目,相当于一个应用服务器,作为serlet的容器;

    2.2Tomcat的调用过程

    tomcat要能够同时接收多个客户端发来的请求,那么就需要多线程;

    tomcat想要调用servlet就是得到这个servlet对象和类所在地址的映射关系;
    tomcat本身并不知道客户端会访问哪一个servlet,所以tomcat必须要能够动态的去调用servlet对象,那么就需要用到java的反射机制;
    定位到具体的servlet并调用get或post方法并响应客户端;

    2.3Tomcat默认内嵌配置

    打开Springboot项目中,双击shift,搜索spring-configuration-metadata.json文件,可以查看各个节点的配置;

    tomcat默认参数是为开发环境制定,而非适合生产环境,尤其是内存和线程的配置,默认都很低,容易成为性能瓶颈;

    server.tomcat.accept-count:等待队列长度。默认100;
    server.tomcat.max-connections:最大可被连接数,默认10000
    server.tomcat.max-threads:最大工作线程数,默认200
    server.tomcat.min-spare-threads:最小线程数,默认10
    
    默认配置下,连接超过10000后出现拒绝连接情况;
    默认配置下,触发的请求超过200+100后拒绝处理;
    
    2.4定制化内嵌Tomcat开发

    keepAliveTimeout:表示在下次请求过来之前,tomcat保持该连接多久。这就是说假如客户端不断有请求过来,且为超过过期时间,则该连接将一直保持。
    maxKeepAliveRequests:表示该连接最大支持的请求数。超过该请求数的连接也将被关闭(此时就会返回一个Connection: close头给客户端)。

    使用WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>定制化内嵌tomcat配置
    @Component
    public class WebServerConfiguration implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
    
        @Override
        public void customize(ConfigurableWebServerFactory factory) {
            ((TomcatServletWebServerFactory) factory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
                @Override
                public void customize(Connector connector) {
                    Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
                    /**
                     * 定制化keepalivetimeout。设置30秒内没有请求,则服务端自动断开keepalive链接
                     */
                    protocol.setKeepAliveTimeout(30000);
                    /**
                     * 当客户端发送超过10000个请求则自动断开keepalive链接
                     */
                    protocol.setMaxKeepAliveRequests(10000);
    
                }
            });
        }
    }
    
    为什么要设置keepAliveTimeout和maxKeepAliveRequests?

    1.防止连接长时间占用访问资源,以免导致其它客户端请求无法建立连接。
    2.防止DDOS攻击 以免导致服务器拥塞而无法对外提供正常服务

    2.5Tomcat调优

    利用缓存和压缩
    对于静态页面最好是能够缓存起来,这样就不必每次从磁盘上读。这里我们采用了 Nginx 作为缓存服务器,将图片、css、js 文件都进行了缓存,有效的减少了后端 tomcat 的访问。
    可以用 gzip 压缩,其实很多图片也可以用图像处理工具预先进行压缩,找到一个平衡点可以让画质损失很小而文件可以减小很多;

    采用集群,实现横向扩展,那么组建 tomcat 集群是有效提升性能;
    内存调优:设置JVM的一些参数

    -Xmx3550m -最大可用内存;
    -Xms3550m -JVM促使内存为3550m;
    -Xmn2g 年轻代大小为2G;
    -Xss128k -设置每个线程的堆栈大小;
    -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)设置为4,则年轻代与年老代所占比值为1:4;
    -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4;
    -XX:MaxPermSize=16m:设置持久代大小为16m;
    -XX:MaxTenuringThreshold=0:设置垃圾最大年龄;
    

    Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会导致机器暂时间变慢。

    Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。

    Xss 是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等。

    以上三个参数的设置都是默认以Byte为单位的,也可以在数字后面添加[k/K]或者[m/M]来表示KB或者MB。而且,超过机器本身的内存大小也是不可以的,否则就等着机器变慢而不是程序变慢了。

    发现容量问题

    单个Web容器有上限;
    线程数量:4核cpu 8G内存单进程调度线程数800-1000以上后即花费巨大的时间在cpu调度上;
    等待队列长度:队列做缓冲池用,但也不能无限长,消耗内存,出队入队也耗cpu;
    server.tomcat.accept-count=1000
    server.tomcat.max-threads=800
    server.tomcat.min-spare-threads=100
    
    image.png

    Mysql数据库QPS容量问题;
    主键查询:千万级别数据 1-10毫秒
    唯一索引查询:千万级别数据=10-100毫秒
    非唯一索引查询:千万级别数据=100-1000毫秒
    无索引:百万条数据=1000毫秒+

    Mysql数据库TPS容量问题 ;
    非插入更新删除操作:同查询
    插入操作:1W~10W tps(依赖配置优化,后续讲解)

    相关文章

      网友评论

        本文标题:电商高并发秒杀1 Tomcat调优

        本文链接:https://www.haomeiwen.com/subject/jmptyhtx.html