月度归档:2019年03月

阿里云线上java应用cpu100%问题处理


2019年3月26日 18:43:00   1,911 次浏览

最近这两天一直收到监控告警提示,告警周期都很短也就持续几分钟所以就忽略了。后面再次出现告警的时候总觉得不正常,于是开始排查原因。

从监控中可以看出cpu使用率一直在居高不下的状态,最高使用率达到93%。

简单分析下可能出问题的地方,分为5个方向:

  1. 系统本身代码问题
  2. 内部下游系统的问题导致的雪崩效应
  3. 上游系统调用量突增
  4. http请求第三方的问题
  5. 机器本身的问题

 

查看日志,没有发现什么明显的错误日志,初步排除代码逻辑处理错误。只发现有个job在处理zip压缩包?接下来继续分析

2019-03-26 18:06:22 |-INFO  [pool-554-thread-8] in  c.f.trip.abc.runable.ElongPriceRefresh - updateEnd!
2019-03-26 18:06:25 |-INFO  [pool-554-thread-4] in  c.f.trip.abc.runable.ElongPriceRefresh - updateEnd!
2019-03-26 18:06:26 |-INFO  [pool-554-thread-3] in  c.f.trip.abc.runable.ElongPriceRefresh - updateEnd!
2019-03-26 18:06:26 |-INFO  [scheduler_Worker-5] in  com.xxx.trip.abc.job.ElongRateUpdateJob - 总线程数:12;
2019-03-26 18:06:41 |-INFO  [scheduler_Worker-5] in  com.xxx.trip.abc.job.ElongRateUpdateJob - 总线程数:12;
2019-03-26 18:06:48 |-INFO  [pool-554-thread-7] in  c.f.trip.abc.runable.ElongPriceRefresh - updateEnd!
2019-03-26 18:06:56 |-INFO  [scheduler_Worker-5] in  com.xxx.trip.abc.job.ElongRateUpdateJob - 总线程数:11;
2019-03-26 18:07:00 |-INFO  [scheduler_Worker-1] in  com.xxx.trip.abc.job.AuditCancelJob - audit cancel job start...
2019-03-26 18:07:00 |-INFO  [scheduler_Worker-7] in  c.f.trip.abc.job.AirPortTransferSmsJob - start AirPortTransferSmsJob ...
2019-03-26 18:07:00 |-INFO  [scheduler_Worker-7] in  c.f.trip.abc.job.AirPortTransferSmsJob - end AirPortTransferSmsJob ...
2019-03-26 18:07:00 |-INFO  [scheduler_Worker-3] in  c.f.t.s.train.abc.impl.TrainOrderServiceImpl - tip orders is empty
2019-03-26 18:07:03 |-INFO  [scheduler_Worker-1] in  com.xxx.trip.abc.job.AuditCancelJob - audit cancel job end!
2019-03-26 18:07:11 |-INFO  [scheduler_Worker-5] in  com.xxx.trip.abc.job.ElongRateUpdateJob - 总线程数:11;
2019-03-26 18:07:20 |-INFO  [pool-554-thread-9] in  c.f.trip.abc.runable.ElongPriceRefresh - updateEnd!
2019-03-26 18:07:26 |-INFO  [scheduler_Worker-5] in  com.xxx.trip.abc.job.ElongRateUpdateJob - 总线程数:10;
2019-03-26 18:07:28 |-INFO  [scheduler_Worker-9] in  com.xxx.trip.abc.job.QiantaoMinpriceJob - try again count :2,url = http://www.xxxx.com:7001/CF100296__hotelPrice_-1183552046.zip

上top工具,好家伙进程PID28204 cpu飙到168,下一步就是定位java线程拿出jstatck来分析。

查看线程top -Hp 28204 ,这里一共跑了600个线程,找到下面几个最高的线程,28210,28775,29475,29473,29468

将线程id转换为16进制 printf “%x\n”  线程ID

使用jstatck查看线程堆栈信息

jstack命令打印线程堆栈信息,命令格式:jstack pid |grep  -A 10 tid

难道是这个线程影响cpu上升的吗? 赶紧联系开发人员一起查看。

开发说这个流式读取写入缓冲区,文件大小500M,左右,读取会比较慢,40分钟左右读完。每次任务跑完一次至少一个半小时

既然开发这样说了我表示怀疑的态度去看了一下配置文件,这分明是10分钟跑一次啊。让开发给个合适的值,修改后重启服务

cpu现在使用时60%,在观察几天看看。

Dstat-监控Linux下系统资源性能统计工具


2019年3月25日 13:20:02   2,832 次浏览
什么是Dstat ?

stat是一个功能强大,灵活多变的工具,类似于 vmstat、iostat、mpstat,所不同的是,可以监控多个系统指标,如 CPU、网络、内存、中断等,可以将结果显示到终端,也可保存到文件。另外,该程序是通过 Python 实现的。

Dstat用法:

dstat [-afv] [options..] [delay [count]]

常用选项:
-c, –cpu
统计CPU状态,包括 user, system, idle (空闲等待时间百分比), wait (等待磁盘IO),
hardware interrupt (硬件中断), software interrupt (软件中断) 等;
-d, –disk
统计磁盘读写状态,主要包括了读写信息;
-l, –load
统计系统负载情况,包括1分钟、5分钟、15分钟平均值;
-m, –mem
统计系统物理内存使用情况,包括used, buffers, cache, free;
-s, –swap
统计swap已使用和剩余量;
-n, –net
统计网络使用情况,包括接收和发送数据;
-p, –proc
统计进程信息,包括runnable、uninterruptible、new;
-N eth1,total
统计eth1接口汇总流量;
-r, –io
统计I/O请求,包括读写请求;
-y, –sys
统计系统信息,包括中断、上下文切换;
-t
显示统计时时间,对分析历史数据非常有用;
–fs
统计文件打开数和inodes数;

如何安装

在CentOS和Redhat中

yum install dstat -y

dstat不支持python3,如果你的系统中使用了python3需要修改dstat文件头部改为python2

< 11 NGINX-1 - [root]: ~ > # which dstat
/usr/bin/dstat

< 11 NGINX-1 - [root]: ~ > # vim /usr/bin/dstat
#!/usr/bin/python2.7
### This program is free software; you can redistribute it and/or modify
### it under the terms of the GNU Library General Public License as published by
### the Free Software Foundation; version 2 only
###
### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU Library General Public License for more details.
###
### You should have received a copy of the GNU Library General Public License
### along with this program; if not, write to the Free Software
### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
### Copyright 2004-2007 Dag Wieers <dag@wieers.com>


from __future__ import generators


try:
    import sys, os, time, sched, re, getopt
    import types, resource, getpass, glob, linecache
    except KeyboardInterrupt:
pass


VERSION = '0.7.2'
theme = { 'default': '' }
if sys.version_info < (2, 2):
    sys.exit('error: Python 2.2 or later required')

### Workaround for python <= 2.2.1

dsata如果不加选项默认选项是-a或cdngy选项

上面的输出结果:

  1. CPU统计数据:用户(usr)进程的CPU使用情况,系统(sys)进程,以及空闲(idl)和等待(wai)进程数,硬中断(hiq)和软中断(siq)。
  2. 磁盘统计信息:磁盘上的读取(读取)和写入(写入)操作的总数。
  3. 网络统计:网络接口上接收(recv)和发送(发送)的总字节数。
  4. 分页统计信息:信息被复制到内存中(内)和外出(外出)的次数。
  5. 系统统计信息:中断数(int)和上下文切换(csw)。

要显示提供的信息vmstat,请使用-v--vmstat选项:

  1. 进程统计:运行(run),阻塞(blk)和新(new)生成进程的数量。
  2. 内存统计:使用(used),缓冲(buff),缓存(cach)和剩余(free)内存的数量。
Dstat进阶操作
  1. -c – CPU使用率
  2. --top-cpu – 使用大多数CPU的过程
  3. -dn – 磁盘和网络统计信息
  4. --top-mem – 消耗最多内存的进程
dstat -c --top-cpu -dn --top-mem

我们可以通过启用--output选项,将dstat的输出存储在文件中,以便在以后进行分析。

示例:显示时间,CPU,内存,系统负载统计数据,每隔1秒刷新一次,捕捉5次结果后退出dstat。

dstat --time --cpu --mem --load --output report.csv 1 5

显示每个CPU的详细信息(包括cpu0,cpu1等)和总使用情况。它显示每个CPU(用户时间,系统时间,空闲时间,和等待时间)活动进程

dstat -C 0,1,2,total

显示有关特定磁盘的磁盘利用率(读取和写入)和磁盘I / O(读取和写入)利用率的详细信息。如果要检查总磁盘利用率和I / O,请使用dstat --disk --io

显示特定网络利用率(数据接收和数据发送)的详细信息。如果要显示所有以太网利用率,请使用dstat --net

dstat --net -N eno16777728

显示有关top cpu,top cputime(使用最多CPU时间(以ms为单位)的进程),top磁盘I / O活动,top磁盘块I / O活动,top memory和top latency usage的详细信息。

dstat --top-cpu --top-cputime --top-io --top-bio --top-mem --top-latency

显示有关(CPU,磁盘,内存,进程,负载和网络)使用情况的详细信息,这对于服务器负载过高时的基本故障排除非常常见。

dstat --cpu --mem --proc --load --disk --net

显示网络有关tcp(listen,established,syn,time_wait,close),udp(listen,active)和socket(total,tcp,udp,raw,ip-fragments)用法的详细信息。

dstat --tcp --udp --socket

nginx反向代理后响应200但是没有返回数据


2019年3月13日 15:09:00   5,701 次浏览

最近公司在上线新的项目,原来的环境都是每个项目配置一个独立的域名。因微信回调域名添加有限制貌似最多只能添加5个,新项目又急着上线,注册新的微信公众号资料繁琐且时间紧张,只能改造公司内部的项目了,一台服务器要配置一个独立域名通过多个目录形式访问不同的多个前端项目,这时候nginx开始上场了 。单个项目还好说,如下修改nginx的nginx.conf配置文件

前端打包react的文件后的dist目录,然后使用nginx反向代理

网上大多数的文章都是这样配置的,单个项目

try_files $uri $uri/ /index.html;

多个项目配置

try_files $uri $uri/ /Aproject/index.html;
try_files $uri $uri/ /Bproject/index.html;

然而这样配置后页面都是200状态接口依旧还是没有返回数据

// 访问这里的接口是正常的,后台接口是用node.js写的,返回的是json格式

location /style {
 proxy_pass   http://localhost:80808;      
 proxy_set_header  Host       $host;
 proxy_set_header  X-Real-IP  $remote_addr;
 proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;

}
  1. // 访问这里的接口会返回200,但是没有响应体
  2. // 去掉下面的rewrite会显示404
location /api {
 rewrite  ^/api/?(.*)$ /$1 break;
 add_header backendIP $upstream_addr;
 add_header backendCode $upstream_status;
 proxy_pass http://xxxx;

}

修改node项目的路由代码将browserHistory改成history模式

删除process.env.API_ENV == ‘dev’ ? “/” :

package.json文件增加homepage

修改静态资源调用代码

最后nginx配置如下

server
{
   listen 1080;
   server_name 192.168.1.36;
       root   /data/apps-data/h5/;
       index index.php index.html index.htm default.html default.htm default.php;
       error_page      404  /errors/404.htm;
       error_page      403  /errors/403.html;
       location /flight {
               alias   /data/apps-data/h5/flight/;
               try_files $uri $uri/ /flight/index.html;
               proxy_set_header   Host             $host;
               proxy_set_header   X-Real-IP        $remote_addr;
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto  $scheme;
                 }
               location /flight/flightList/static/ {
               alias   /data/apps-data/h5/flight/static/;
               }
       location /hotel {
               alias   /data/apps-data/h5/hotel/;
               try_files $uri $uri/ /hotel/index.html;
               proxy_set_header   Host             $host;
               proxy_set_header   X-Real-IP        $remote_addr;
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto  $scheme;
               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection $connection_upgrade;
   }
       location /auth {
               alias   /data/apps-data/h5/auth/;
               try_files $uri $uri/ /auth/index.html;
               proxy_set_header   Host             $host;
               proxy_set_header   X-Real-IP        $remote_addr;
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto  $scheme;
       }
       }

最后配置二层代理线上代理线下的nginx服务

server
{
   listen 80;
   server_name hello.com;
   location / {
       proxy_redirect ~^http://work.baidu.com:1018/(.*) http://hello.com/$1;
       proxy_connect_timeout 600;
       proxy_read_timeout 600;
       proxy_send_timeout 600;
       proxy_buffer_size       64k;
       proxy_buffers           4 64k;
       proxy_busy_buffers_size 128k;
       proxy_temp_file_write_size 128k;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_pass http://work.baidu.com:1018/;
       expires -1;
       }
   access_log logs/hotel.log;
   error_log  logs/hotel-error.log;
}