Spring Boot 使用 spring-boot-devtools 实现热加载时出现类型转换异常

热加载问题

网上有给出了许多解决热加载的方法,比如:

在resource目录下创建META-INF/spring-devtools.properties文件

里面的内容为类似下面的内容:

1
2
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar

网上能给出的答案一般也就这些,可是作为观众我们自然是表示一脸懵逼啊,这两行啥玩意?

那么现在给出下我的解决办法:

现在大部分的项目在eclipse中基本都是多个项目的形式,在intellij idea中则是多个module的形式

其中,web项目引用了faced项目,没有引用service项目,因为service项目是个独立的dubbo provider(提供者),web项目则为consumer(消费者)

web项目中的controller中有这么一行代码:

1
UserInfo info = userService.findInfo();

其中UserInfo来自faced项目,userService则通过dubbo的reference注入

项目引入spring-boot-devtools了以后,如果改动了web项目中的代码,则下次web项目中运行到了上面这行代码,则会出现如下报错
java.lang.ClassCastException: com.xxx.UserInfo cannot be cast to com.xxx.UserInfo
为啥明明显示的是同一个类,却给我显示类型转换异常?

那么这就要从spring-boot-devtools的工作原理说起

工作原理

spring-boot-devtools的热加载其实是这么工作的

当你启动web项目的时候,你的web项目中的代码都会交给spring-boot-devtools的restart加载器去进行加载,而jar包,则基本会交给base加载器去加载

当项目中的代码有改动时,devtools检测到代码变动,restart加载器就会被扔掉重建,这个时候,所有restart加载器加载的代码都会重新部署,而base加载器则维持不变

因为jar包的内容基本都不会变,所以用base加载器不会有什么问题

但是由于web项目中引用了faced项目,于是你引用的faced的所有代码也会被restart加载器重新加载,此时,刚刚加载的UserInfo则跟项目刚开始启动的UserInfo就是两个类了,java中判断两个类是否为同一个类不仅仅是通过包名+类名去识别,还会去看两个类的加载器是否一致,如果不一致,则识别为两个类,所以就会出现我们之前看到的转换异常

那么解决办法呢?

解决方案

首先我们需要确定我们出现转换异常的类在哪个项目中,我的则是platform-faced项目

那么回到最初的方法,我们需要在resource目录下创建META-INF/spring-devtools.properties文件

里面的内容填写:
restart.exclude.faced=/platform-faced
如果你有多个face项目,且项目名开头都是这个,那么可以使用如下的配置
restart.exclude.faced=/platform-faced[\\w-]+
网上给的答案后面有带上.jar,但是由于我们开发的时候的引用方式是项目引用,后面是不带jar的,所以我们不需要带上.jar

restart.exclude.faced这个键中的faced是可以自己命名的,只需要保证在这个配置文件中唯一即可

文件配置好后,我们可以在项目已启动状态下修改web项目中的代码,可以看到控制台有显示项目重新加载,继续访问到之前触发转换异常的地方,发现已经不会异常了,完美!

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;
}

}

MariaDB远程访问IP授权

授权
GRANT ALL PRIVILEGES ON *.* TO 'root'@'你的IP' IDENTIFIED BY '密码' WITH GRANT OPTION;

删除
delete from mysql.user where User = 'root' and Host = 'IP'; FLUSH PRIVILEGES;

在centos7上安装git客户端

首先需要安装依赖包:

1
2
yum -y install zlib-devel openssl-devel perl cpio expat-devel gettext-devel 
yum install autoconf

下载git源码包

1
wget xxxxxxxxxxxxxx

解压源码包

1
tar zxvf xxxxxxxx.tar.gz

编译安装

1
2
3
4
5
cd  git(源码目录)
autoconf
./configure --with-curl=/usr/local/git(安装目录)
make
make install

编译的时候有可能会报Can’t locate ExtUtils/MakeMaker.pm的错误

解决方式:

1
yum install perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker