在vps上部署SpringMVC+Mysql+Tomcat动态网站

github仓库地址:https://github.com/lmtsunnie/forum

网站效果:https://bithelper.site/

vps安装组件

查看vps版本

1
2
3
4
5
6
root@VM-0-12-ubuntu:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial

安装mysql和redis

1
2
sudo apt install mysql-server
sudo apt install redis-server

安装tomcat

https://linuxize.com/post/how-to-install-tomcat-9-on-ubuntu-18-04/

1
2
3
4
cd /tmp
wget https://www-us.apache.org/dist/tomcat/tomcat-9/v9.0.16/bin/apache-tomcat-9.0.16.tar.gz
sudo tar xf /tmp/apache-tomcat-9*.tar.gz -C /opt/tomcat
sudo systemctl restart tomcat

打开127.0.0.1:8080页面发现是nginx页面并不是tomcat,查看端口发现8080端口被nginx占用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@VM-0-12-ubuntu:~# netstat -ltnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8009 0.0.0.0:* LISTEN 29907/java
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 29042/mysqld
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 26215/redis-server
tcp 0 0 0.0.0.0:2000 0.0.0.0:* LISTEN 20830/nginx -g daem
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 20830/nginx -g daem
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 20830/nginx -g daem
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 15376/sshd
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 20830/nginx -g daem
tcp 0 0 127.0.0.1:8005 0.0.0.0:* LISTEN 29907/java
tcp6 0 0 :::2000 :::* LISTEN 20830/nginx -g daem
tcp6 0 0 :::8080 :::* LISTEN 20830/nginx -g daem
tcp6 0 0 :::22 :::* LISTEN 15376/sshd

修改/opt/tomcat/apache-tomcat-9.0.16/conf/server.xml文件中tomcat端口为9000:

1
2
3
<Connector port="9000" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

如果修改了/etc/systemd/system/tomcat.service

1
2
systemctl daemon-reload
systemctl status tomcat.service

重启tomcat:

1
2
3
4
5
systemctl restart tomcat
或者
cd /opt/tomcat/apache-tomcat-9.0.16/bin
./shutdown.sh
./startup.sh

打开127.0.0.1:9090发现是tomcat页面,tomcat启动成功。

代码修改

将本地的数据库导入到vps上

生成本地df库的sql文件:

1
2
➜  ~ mysqldump -u root -p df > df.sql
Enter password:

在vps上导入数据库:

1
2
3
4
5
6
7
8
9
10
11
mysql> drop database df;
Query OK, 8 rows affected (0.38 sec)

mysql> create database df;
Query OK, 1 row affected (0.00 sec)

mysql> exit
Bye

root@VM-0-12-ubuntu:~# mysql -u root -p df < df.sql
Enter password:

设置mysql可通过外网IP访问

修改mysql配置文件/etc/mysql/mysql.conf.d/mysqld.cnf

bind-address = 127.0.0.1改成bind-address = 0.0.0.0

一开始mysql上写的是外网ip123.207.143.168,但是代码从外网无法访问mysql:

https://stackoverflow.com/questions/19101243/error-1130-hy000-host-is-not-allowed-to-connect-to-this-mysql-servers

默认只有localhost能作为root访问mysql,修改为所有ip都可以作为root访问mysql:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysql> SELECT host FROM mysql.user WHERE User = 'root';
+-----------+
| host |
+-----------+
| localhost |
+-----------+
1 row in set (0.00 sec)
mysql> update mysql.user set host = '%' where user = 'root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> SELECT host FROM mysql.user WHERE User = 'root';
+------+
| host |
+------+
| % |
+------+
1 row in set (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

设置redis可通过外网IP访问

修改redis配置文件/etc/redis/redis.conf

bind 127.0.0.1改成bind 0.0.0.0

查看redis状态:

1
systemctl status redis.service

重启redis:

1
2
3
/etc/init.d/redis-server restart
或者
systemctl restart redis

可以通过外网ip访问redis了:

1
redis-cli -h 123.207.143.168 -p 6379 -a password

设置redis密码

1
2
root@VM-0-12-ubuntu:~# redis-cli
127.0.0.1:6379> config set requirepass password

下次再登录redis的时候:

1
2
3
4
5
6
7
root@VM-0-12-ubuntu:~# redis-cli
127.0.0.1:6379> smembers 17:like
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth wangji1997
OK
127.0.0.1:6379> smembers 17:like
1) "39"

或者

1
root@VM-0-12-ubuntu:~# redis-cli -a password

设置完redis密码后可以在Intellij idea中安装Iedis插件:

重启redis/tomcat/mysql/nginx的方法

redis安装路径:/etc/redis

tomcat安装路径:/opt/tomcat/apache-tomcat-9.0.16/

mysql安装路径:/etc/mysql

nginx安装路径:/etc/nginx

方法1:systemctl restart …

1
systemctl restart redis/mysql/tomcat/nginx

方法2:service … restart

1
service redis/mysql/tomcat/nginx restart

方法3:找到安装路径手动重启

tomcat:

1
2
3
cd /opt/tomcat/apache-tomcat-9.0.16/bin
./shutdown.sh
./startup.sh

redis/mysql/nginx:

1
2
3
/etc/init.d/redis-server restart
/etc/init.d/mysql restart
/etc/init.d/nginx restart

项目代码IP修改

在项目中修改forum/src/main/resources/application.properties配置文件的ip:

1
2
mysql.url=jdbc:mysql://123.207.143.168:3306/df
redis.hostName=123.207.143.168

修改forum/src/main/java/com/limengting/common/Constant.java中发送激活邮件的ip:

1
public static final String DOMAIN_NAME = "http://123.207.143.168:9000/"; // change to your own IP

打包传送

打war包:

把本地war包传送上vps:

1
scp /Users/sunnie/git/forum/target/forum.war root@123.207.143.168:/opt/tomcat/apache-tomcat-9.0.16/webapps

外网访问

通过IP访问

访问 http://123.207.143.168:9000/forum 即可访问:

通过域名访问

申请域名

申请域名bithelper.site,设置转发规则:

申请SSL证书并传到vps上

阿里云域名Nginx服务器安装SSL证书指南:

https://help.aliyun.com/knowledge_detail/95491.html?spm=5176.2020520154.cas.41.69515LYl5LYlo9

证书申请成功后把证书的压缩包上传到vps上:

1
scp ~/Downloads/1910329_www.bithelper.site_nginx/* /etc/nginx/cert

nginx动态转发配置

/etc/nginx/conf.d路径下增加bithelper.conf配置:

nginx转发动态页面请求参考:https://blog.51cto.com/pynliu/1569060

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
server {
listen 80;
listen [::]:80;

server_name bithelper.site www.bithelper.site;
return 301 https://bithelper.site;
}

server {
listen 443 ssl http2;
root /opt/tomcat/apache-tomcat-9.0.16/webapps/forum;
server_name bithelper.site www.bithelper.site;
ssl on;
ssl_certificate /etc/nginx/cert/1910329_www.bithelper.site.pem;
ssl_certificate_key /etc/nginx/cert/1910329_www.bithelper.site.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/bithelper_access.log;
error_log /var/log/nginx/bithelper_error.log;
location / {
proxy_pass http://localhost:9000/forum/;
proxy_set_header X-Real-IP $remote_addr;
}
}

注意:静态转发和动态转发location设置不一样,静态转发设置root/index等,动态转发设置proxy_pass和proxy_set_header等。

nginx反向代理时session失效

参考:https://blog.csdn.net/joyous/article/details/79966593

登录以后会被再次拦截,证明session里面存的内容在反向代理后丢失,需要修改nginx配置:

增加proxy_cookie_path /forum /;

修改后的/etc/nginx/conf.d/bithelper.conf如下:

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
server {
listen 80;
listen [::]:80;

server_name bithelper.site www.bithelper.site;
return 301 https://bithelper.site;
}

server {
listen 443 ssl http2;
root /opt/tomcat/apache-tomcat-9.0.16/webapps/forum;
server_name bithelper.site www.bithelper.site;
ssl on;
ssl_certificate /etc/nginx/cert/1910329_www.bithelper.site.pem;
ssl_certificate_key /etc/nginx/cert/1910329_www.bithelper.site.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/bithelper_access.log;
error_log /var/log/nginx/bithelper_error.log;

location / {
proxy_pass http://localhost:9000/forum/;
proxy_cookie_path /forum /;
proxy_set_header X-Real-IP $remote_addr;
}
}

重启nginx

检测nginx配置:

1
2
3
root@VM-0-12-ubuntu:/etc/nginx/conf.d# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

重启nginx:

1
root@VM-0-12-ubuntu:/etc/nginx/conf.d# service nginx reload

远程调试设置

vps上添加tomcat的JVM启动参数(/opt/tomcat/apache-tomcat-9.0.16/bin/catalina.sh中添加下面这行,调试端口为10000):

1
JAVA_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=10000'

Intellij idea在启动配置中添加remote debug:

关闭tomcat后重启tomcat:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@VM-0-12-ubuntu:/opt/tomcat/apache-tomcat-9.0.16/bin# ./shutdown.sh
Using CATALINA_BASE: /opt/tomcat/apache-tomcat-9.0.16
Using CATALINA_HOME: /opt/tomcat/apache-tomcat-9.0.16
Using CATALINA_TMPDIR: /opt/tomcat/apache-tomcat-9.0.16/temp
Using JRE_HOME: /usr
Using CLASSPATH: /opt/tomcat/apache-tomcat-9.0.16/bin/bootstrap.jar:/opt/tomcat/apache-tomcat-9.0.16/bin/tomcat-juli.jar
Listening for transport dt_socket at address: 10000

root@VM-0-12-ubuntu:/opt/tomcat/apache-tomcat-9.0.16/bin# ./startup.sh
Using CATALINA_BASE: /opt/tomcat/apache-tomcat-9.0.16
Using CATALINA_HOME: /opt/tomcat/apache-tomcat-9.0.16
Using CATALINA_TMPDIR: /opt/tomcat/apache-tomcat-9.0.16/temp
Using JRE_HOME: /usr
Using CLASSPATH: /opt/tomcat/apache-tomcat-9.0.16/bin/bootstrap.jar:/opt/tomcat/apache-tomcat-9.0.16/bin/tomcat-juli.jar
Tomcat started.

bug修复

部署后发送邮件失效

云主机TCP 25 端口出方向被封禁:https://cloud.tencent.com/developer/ask/23866

本地部署后能发送激活邮件,但部署到服务器上就一直发不出,发现是阿里云/腾讯云都会默认将25端口封闭的原因:

mysql乱码问题

1
mysql> show variables like "%char%";

结果里有很多不是utf8的

关闭mysql进程后修改/etc/mysql/conf.d/mysql.cnf,在[mysql]后面加上default-character-set=utf8

1
2
3
root@VM-0-12-ubuntu:/etc/mysql/conf.d# cat mysql.cnf
[mysql]
default-character-set=utf8

修改/etc/mysql/mysql.conf.d/mysqld.cnf,在[mysqld]后面加上character-set-server=utf8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
# 加上下面这行
character-set-server=utf8

重启mysql:

1
service mysql restart

再次查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> show variables like "%char%";
+--------------------------------------+----------------------------+
| Variable_name | Value |
+--------------------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
| validate_password_special_char_count | 1 |
+--------------------------------------+----------------------------+
9 rows in set (0.00 sec)

查看网站解决乱码问题。

增加修改头像功能

七牛云官方文档:https://developer.qiniu.com/kodo/sdk/1239/java

forum/src/main/java/com/limengting/serviceimpl/QiniuServiceImpl.java中upload接口的实现:

https://github.com/lmtsunnie/forum/blob/master/src/main/java/com/limengting/serviceimpl/QiniuServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public String upload(byte[] localData, String remoteFileName) throws IOException {
//Response res = uploadManager.put(localData, remoteFileName, getUpToken());
// 打印返回的信息
//System.out.println(res.bodyString());
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
try {
Response response = uploadManager.put(localData, key, getUpToken());
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return putRet.hash;
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
return null;
}

forum/src/main/java/com/limengting/controller/UserController.java中的uploadUrl接口核心代码:

https://github.com/lmtsunnie/forum/blob/master/src/main/java/com/limengting/controller/UserController.java

1
2
3
4
5
6
7
String hash = qiniuService.upload(file.getBytes(), filename);
//更新数据库中头像URL
int uid = (int) session.getAttribute("uid");
String newHeadUrl = Constant.QINIU_IMAGE_URL + hash;
// 注意也要更新session中的headUrl
session.setAttribute("headUrl", newHeadUrl);
userService.updateHeadUrl(uid, newHeadUrl);

效果

点击这里查看效果

谢谢小天使请我吃糖果
0%