Spring中的ThreadPoolTaskExecutor的参数:corePoolSize、maxPoolSize、queueCapacity分别是什么意思

问题:

今天线上爆出了一个问题,很多的异步线程都跑的非常慢

多线程使用的是Spring的ThreadPoolTaskExecutor

配置如下

1
2
3
corePoolSize: 5
maxPoolSize: 500
queueCapacity: 100

错误逻辑

之前以为的逻辑(错误逻辑):
corePoolSize:默认创建线程数量:5个,

maxPoolSize:如果线程数量超过5个后,在maxPoolSize大小内继续增加线程,直到线程数量到达500个,

queueCapacity:线程数量到达maxPoolSize以后,再添加线程,将会进入queueCapacity进行等待,当等待队列超过queueCapacity设定的值,抛出异常。

可是。。。。现实狠狠的抽了我一巴掌

因为线上发现,线程执行的速度非常慢,很多线程创建了以后并没有执行,而且可以确定线程没有超过500个

百度了一堆,都没有找到这几个参数的正确解释,直到最终看了看源码,发现正确的逻辑是这样的:

正确逻辑

corePoolSize:当线程数小于corePoolSize个的时候,正常创建线程

queueCapacity:当线程大于corePoolSize个的时候,将线程放入queueCapacity大小的队列

maxPoolSize:当queueCapacity队列已满,将会继续创建线程,直到线程数超过maxPoolSize的大小,将抛出异常

于是线上的问题就找到了,实际上,线程在跑的一直只有5个,所以导致线程一直不执行

解决办法:

也简单,把corePoolSize的大小增大到500即可。

dmesg命令查看java程序突然挂掉的原因

最近做项目,总是发现项目突然挂掉,但是java的日志又没有显示任何内容。

网上搜索了一波才知道了这个命令

1
2
3
4
5
# 按时间格式显示
dmesg -T

# 显示跟java 有关的日志
dmesg -T | grep "(java)"

最终打印的信息如下

1
2
[Wed May  8 09:40:57 2019] Out of memory: Kill process 5348 (java) score 125 or sacrifice child
[Wed May 8 09:40:57 2019] Killed process 5348 (java) total-vm:6105560kB, anon-rss:1032792kB, file-rss:0kB, shmem-rss:0kB

看来的确是因为内存不足导致的进程被杀

mongodb用户管理以及连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 使用帐户名连接
mongo -u 用户名 -p 密码 --host 数据库地址

# 创建账户
# 创建超级管理员,角色:root
db.createUser({user:"用户名",pwd:"密码",roles:["root"]})

# 创建账户管理员
db.createUser({user:"用户名",pwd:"密码",roles:["userAdminAnyDatabase"]})

# 创建名为test的数据库拥有者账户
# 先切换到需要创建的数据库
use test
db.createUser({user:"用户名",pwd:"密码",roles:[{role:"dbOwner",db:"test"}]})

#查看用户
show users

#删除单个用户
db.system.users.remove({user:"用户名"})

# 创建数据库
use 数据库名
# 如果不存在该数据库,就会创建一个

mongodb后台运行

完成安装mongodb(略)

创建数据目录:
mkdir /data/db

创建配置文件

1
2
3
4
5
6
# vi /data/db/mongodb.cnf
dbpath=/data/db/
logpath=/data/db/mongo.log
logappend=true
fork=true
port=27017

或者:不创建配置文件通过mongod参数启动也可以

配置文件方式启动mongo
mongod -f /data/db/mongodb.cnf

nginx防止被其他域名恶意解析

在nginx对应配置文件中增加以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80 default_server;
listen 443 ssl default_server;
ssl_certificate 证书路径;
ssl_certificate_key 证书路径;
ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
server_name _;
access_log off;
return 403;
}

redis批量删除key

redis-cli -h ipaddress -p redis端口 keys "key前缀*" |xargs redis-cli -h ipaddress -p redis端口 del

elasticsearch安装时遇到的问题

1. 提示:max file descriptors [4096] for elasticsearch process is too low

max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
解决方法如下:

编辑/etc/security/limits.conf文件
vi /etc/security/limits.conf

在文件的末尾处加上以下内容并保存

1
2
elasearch soft nofile 65536
elasearch hard nofile 65536

2. 提示:max virtual memory areas vm.max_map_count [65530] is too low

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

解决方法如下:

执行:
vi /etc/sysctl.conf
在里面最后一行加入:
vm.max_map_count=655360
再执行下面命令使配置生效
sysctl -p
再使用以下命令查看是否已经生效
sysctl -a | grep "vm.max_map_count"
生效即可

kibana安装配置以及授权访问

最近工作中使用了elasticsearch,每次都敲命令行实在是不方便,kibana则可以很方便的管理elasticsearch

1.下载安装包

我用的是5.4.2的elasticsearch,所以下载5.4.2版本的kibana
wget https://artifacts.elastic.co/downloads/kibana/kibana-5.4.2-linux-x86_64.tar.gz

2.解压

tar zxvf kibana-5.4.2-linux-x86_64.tar.gz

3.配置kibana配置文件

配置kibana配置文件config/kibana.yml
具体配置:

1
2
3
4
5
6
7
8
9
10
11
#kibana启动端口
server.port: ""

#kibana启动主机
#设为127.0.0.1则为本机访问
#设为内网ip则为只能内网访问
#设为外网ip则可外网访问
server.host: ""

#elasticsearch的访问路径
elasticsearch.url: ""

一般知道这几个参数就行了

4.后台启动kibana

nohup bin/kibana log.txt 2>&1 &

5.关闭外网访问5601端口

略……

6.生成密码文件

htpasswd -c /usr/local/nginx/httpdwd kibana

7.nginx设置转发,并且加上授权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
#将kibana的访问端口设置为15601,
listen 15601;
server_name 你的服务器ip或者域名;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_redirect off;
proxy_pass http://127.0.0.1:5601;
auth_basic "客官,输个密码呗~";
auth_basic_user_file /usr/local/nginx/httpdwd;
access_log off;
}
}

linux下crontab的使用方式

查看所有定时任务:
crontab -l

编辑定时任务:
crontab -e

定时任务格式:
0 23 * * 6 /opt/nginx-1.10.2/sbin/nginx -s stop #每周六晚上11点停止nginx服务

nginx部署https反向代理tomcat

上次部署https时没有记录,这次专门记录一下

首先申请证书……略

nginx配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
server {
listen 80;
# 监听443端口
listen 443 ssl;
#这里是填你的域名
server_name stonewuu.com www.stonewuu.com;
#charset koi8-r;
#这里为证书路径以及证书的配置
ssl_certificate /etc/letsencrypt/live/stonewuu.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/stonewuu.com/privkey.pem;
ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
#301重定向,将所有http请求重定向为https
if ($scheme = http) {
return 301 https://$host$request_uri;
}
#这里为lets encrypt证书需要的验证文件
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /opt/tomcat-8.5.9/blog_data;
}

#这里防止用户访问到lets encrypt验证文件的目录
location = /.well-known/acme-challenge/ {
return 404;
}
# 反向代理,指向tomcat的地址
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8080;
}

}