从零搭建基于 Java 的服务器生产环境
之前的文章介绍了我最近开发的一款工具软件 移动工具箱,然而安装包放在华为应用市场上面,如果不安装华为应用市场就无法下载软件,无奈,只能自己从零搭建一个服务器来进行应用的宣传和下载。搭建一个服务器是很简单的,这里我们将服务器的要求提高一些,以对标 “生产” 的标准进行要求,要做的东西比较多,故作此文,加以记录。
首先说下环境,腾讯云,CentOS 7.5 64 位,服务器采用 Java 完成,具体来说就是 Springboot. 大致罗列下要做的事情:
- 介绍服务器远程连接方式
- 进行基础的服务器安全配置
- 禁止 root 用户直接登录服务器
- 关闭 22 登录端口
- 警惕空密码账户
- 设置密码过期时间
- 设置密码复杂度要求
- 禁止 ping 服务器
- 最重要的,防止 rm -rf
- 搭建生产服务器环境
- 安装 ftp 服务
- 连接 ftp 服务器
- 安装 JDK
- 搭建 Springboot 环境
- 发布应用
- 在服务器中启动 Springboot 程序
- 指定虚拟机启动参数
- 编写服务器启动脚本程序
- 配置域名
1、介绍服务器远程连接方式
对于腾讯云,一种连接方式是直接使用腾讯云提供的在线的 webshell 进行登录,这种登录方式提供的是 ssh 登录。假如我们进行 ftp 登录来上传文件的话比较不方便。腾讯云的 webshell 还是比较好用的,不过一般我们推荐使用 Xshell 进行 ssh 登录,使用 xftp 进行 ftp 登录。可以到我的公众号后台回复 【服务器连接软件】 获取我打包好的软件。
拿到一个新的服务器,我们要做的第一件事情就是到控制台里去重置密码。对于密码,为了系统安全起见,应该选择比较复杂的口令,例如最好使用 8 位长的口令,口令中包含有大写、小写字母和数字,不应该包含单词,应该与姓名、生日等不相同。
按照上面的介绍重置密码之后就可以进行登录了,这里使用 Xshell 进行登录,登录方式比较简单,此处略过。
2、进行基础的服务器安全配置
2.1 禁止 root 用户直接登录服务器
为啥要禁止 root 登录呢?首先,root 这个用户是众所周知的,使用 root 用户增加了被攻击的风险。其次,root 权限比较高,不论是服务器拥有者还是服务器的协同开发都不应该直接使用 root 操作服务器。使用 root 用户,一旦出现操作意外,就可能会给服务器带来致命的危害。
禁止 root 登录之前先添加一个新的管理员用户,
# Step 1: 创建新用户 admin
adduser the_xxx_admin
# Step 2: 修改用户密码,密码也应该满足上述要求哦
passwd the_xxx_admin
# Step 3: 赋予该用户 su 执行权限
gpasswd -a the_xxx_admin wheel
这里增加了一个名为 the_xxx_admin (用户名不要太大众化)的管理员用户,并将其用户组设置为 wheel. wheel 在 linux 中是一个特殊的用户组,这个组被设计用来解决 su 指令的授权问题。也就是只有在 wheel 组里面的成员才能使用 su 切换到 root 用户。如果一个用户不在 wheel 组里面,即使使用 su 指令并正确地输入了密码也无法切换到 root 用户。wheel 用户组不仅具有 su 指令的权限,也具有 sudo 的权限,可以通过浏览 /etc/sudoers
文件来了解。
增加了新的用户之后并赋予 sudo 权限之后,我们就可以禁止 root 用户登录了:
- 修改
/etc/ssh/sshd_config
文件将#PermitRootLogin yes
修改为PermitRootLogin no
; - 使用
service sshd restart
重启 ssh 服务并验证登录效果即可。
此处修改文件的时候可以使用 vim /etc/ssh/sshd_config
命令,然后输入 /PermitRootLogin
定位到 #PermitRootLogin yes
所在的一行,输入 a
进入编辑模式,修改完毕之后使用 :wq!
退出即可。
重启之后再使用 root 进行登录,立刻显示 “服务器拒绝 ssh 连接”,然后使用新增的用户进行登录即可。
2.2 关闭 22 登录端口
主要是因为 22 端口登录已经是众所周知的了,如果我们使用其它端口实现 22 端口的功能可以减少被攻击的风险。修改登录端口需要修改 /etc/ssh/sshd_config
文件。在该文件中,我们先新增一个端口,推荐使用 10000 号以上的端口。注意这里应该先保留 22 端口,设置完毕并验证新的端口可以登录之后再删除 22 端口。还有需要注意的地方,验证新的接口是否可以登录之前一定要先打开防火墙,防火墙关闭的时候端口可以直接使用,而一旦防火墙打开,而你又没有使用防火墙打开该端口,那么防火墙可能会直接屏蔽该端口,导致你无法登录自己的服务器。
这里直接使用 vim 编辑 /etc/ssh/sshd_config
文件的时候应该会出现 Permission Denied
。此时,可以通过 sudo 命令来完成,
sudo vim /etc/ssh/sshd_config
与 sudo 类似的还有 su 命令。sudo
和 su
功能类似,区别在于 sudo
命令需要输入当前用户的密码,su
命令需要输入要切换到的用户的密码。 sudo
比 su
更合理一些,因为,比如如果希望某个用户切换到 root 用户,使用 su
的方式要求执行者必须知道 root 账户的密码,密码被很多人知道显然不安全。而 sudo
只要求确认当前执行者的身份,如果当前执行的用户在 sudoers
中被授予过访问 root 的权限,则它可以切换到 root 用户,这样我们既赋予了该用户切换到 root 的权限,又无需告知该他 root 账户的密码。此外,我们还可以通过在 sudoers
文件中进行配置来限制用户的权限,记录更多的用户日志等。
进入编辑模式之后找到 Port 22
并在下面新增一行 Port 10022
:
Port 22
Port 10022
然后,我们需要按照上述管理端口的逻辑开放 10022 端口。然后,重启 ssh 服务:
systemctl restart sshd # 或者 service sshd restart
如果验证登录成功,再将上面的 Port 22
注释掉,重启 ssd 服务然后再使用 22 端口登录,验证是否已经禁止。
此时,我再使用 22 端口进行登录,提示 Connection failed
,表明禁止 22 端口登录成功。
2.3 警惕空密码账户
空密码账户会增加系统的安全风险。使用如下指令查询:
cat /etc/shadow | awk -F: '($2==""){print $1}'
另外,可以通过修改 ssh 配置文件 /etc/ssh/sshd_config
来禁止空密码账户进行登录:
PermitEmptyPasswords no
2.4 设置密码过期时间
设置和查询密码有效期会用到指令 chage,该指令格式如下:
chage [参数] [数值]
常用参数:
- -m : 密码可更改的最小天数。为零时代表任何时候都可以更改密码。
- -M : 密码保持有效的最大天数。
- -W : 用户密码到期前,提前收到警告信息的天数。
- -E : 帐号到期的日期。过了这天,此帐号将不可用。
- -d : 上一次更改的日期。
- -I : 停滞时期。如果一个密码已过期这些天,那么此帐号将不可用。
- -l : 例出当前的设置。由非特权用户来确定他们的密码或帐号何时过期。
一般的使用示例如下。
首先查询用户密码的有效期:
chage -l admin
显示信息如下:
Last password change : Apr 07, 2020
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
我们可以使用 chage 指令来修改密码的过期时间,比如使用如下指令将密码的最大有效期设置为 99 天:
chage -M 99 admin
2.5 设置密码复杂度要求
有两种方式来设置密码复杂度。
一种方式是修改 /etc/login.defs
文件,这里面几个比较重要的选项。可以通过修改选项的值来设置对密码对要求:
PASS_MAX_DAYS 90 #密码最长过期天数
PASS_MIN_DAYS 80 #密码最小过期天数
PASS_MIN_LEN 10 #密码最小长度
PASS_WARN_AGE 7 #密码过期警告天数
另外一个方法是,修改 /etc/pam.d/system-auth
文件。编辑该文件,在下面这行进行配置即可:
password required pam_pwquality.so dcredit=-1 ucredit=-1 ocredit=-1 lcredit=0
配置的可选参数可以参考 /etc/security/pwquality.conf
文件。常用的参数如下:
- retry=N:定义登录/修改密码失败时,可以重试的次数;
- Difok=N:定义新密码中必须有几个字符要与旧密码不同。但是如果新密码中有1/2以上的字符与旧密码不同时,该新密码将被接受;
- minlen=N:定义用户密码的最小长度;
- dcredit=N:定义用户密码中必须包含多少个数字;
- ucredit=N:定义用户密码中必须包含多少个大写字母;
- lcredit=N:定义用户密码中必须包含多少个小写字母;
- ocredit=N:定义用户密码中必须包含多少个特殊字符(除数字、字母之外);
2.6 禁止 ping 服务器
禁止 ping 后,不让别人通过域名 ping 到你的 ip. 禁用后,你在 ping 自己的域名会给你返回服务商的 IP 并提示超时,这样你就可以减少 IP 暴露,增加一点安全。
实现的方式是:编辑 /etc/sysctl.conf
里面配置,如果没有添加上下面一行配置:
net.ipv4.icmp_echo_ignore_all=1
然后使用如下命令使配置生效:
sysctl -p
这样就禁止了对服务器的 ping 操作。如果要解除,只需要将上面的 1 换成 0 即可。
配置完毕之后在本地的命令行里输入 ping 你的ip
地址,如果显示请求超时,则说明配置成功。
2.7 最重要的,防止 rm -rf
rm -rf
这个梗想必大家都了解,这节我们不是要教你如何在服务器上面执行该操作,来观察它带来的喜剧效果,而是如何避免该操作带来的负面影响。需要注意的地方:下面的操作会使用 source 命令,这个指令也是万分危险的指令,必须慎重! 这个指令用来修改类似于 windows 中的环境变量,假如 source 出现问题,可能会导致几乎所有的命令都无法使用,非常危险。
实现的原理是对 rm
命令进行改写,将其关联到一个自定义脚本。首先,我们在 ~
目录下面一个隐藏的 .trash
文件和 .tools
文件夹,
# 创建 .trash 文件夹
mkdir .trash
# 创建 .tools 文件夹
mkdir .tools
# 检查创建结果
ls -al
然后,在 .tools
文件夹中创建一个名称为 remove.sh
的脚本,编辑其内容如下:
#!/bin/sh
trash_dir=~/.trash/`date +%Y%m%d`if [ ! -d ${trash_dir} ] ;thenmkdir -p ${trash_dir}
fifor i in $*
dosuffix=`date "+%H%M%S"`if [ ! -d "${i}" ]&&[ ! -f "${i}" ];then # 首先判断是否是合法的文件或者文件夹if [[ "${i}" != "-rf" && "${i}" != "-f" ]];then # 这里对-rf进行处理,因为mv指令后面没有-rf,-f参数echo "[${i}] do not exist"fielsefile_name=`basename $i` # 取得文件名称mv ${i} ${trash_dir}/${file_name}_${suffix}_${RANDOM}echo "[${i}] delete completed"fi
done
这里简单解释下这个脚本文件的内容吧。这个脚本文件按照文件名拼接的规则,在文件名中增加了日期信息(用来对同名文件进行区别),然后使用 mv 命令将指定对文件夹移动到 ~/.trash
目录下面。应该注意这里对 -rf
参数的处理。之前也看过一些博客的脚本,没有对这两个参数做处理,导致 mv
命令无法执行。
然后,我们修改 ~/.bashrc
文件,在末尾追加下面一行代码。将 rm 命令关联到指定的 Shell 文件:
alias rm='sh ~/.tools/remove.sh'
然后,使用如下命令来使我们对修改生效,
source ~/.bashrc
最后,在用户根目录下面创建文件夹,并使用 rm -rf 文件夹
指令测试效果。
这里本质上是把要删除的目录移动到了 .trash
目录下面。然后根据操作的日期对移除对文件夹进行管理。这无疑地会导致我们的文件夹越来越大,所以,我们要定期对该文件夹进行删除。这里,我们使用脚本来实现这个目标。
这里我们创建一个定时任务来执行删除操作。在 .tools
文件夹下面添加一个脚本文件 clean.sh
,编辑内容如下。其作用是找到回收站中修改日期大于 3 天的文件,执行真正的删除操作:
#!/bin/sh
trashdir=~/.trash
find ${trashdir} -mtime +3 -exec 'rm' -rf {} \;
然后,我们将该任务添加到 crontab 任务中。
使用 crontab -e
命令进入定时任务编辑界面,在最后面加入
0 3 * * * sh ~/.tools/clean.sh #每天 3:00 执行清理回收站的脚本
使用 service crond restart
重启 crontab 服务,使用 crontab -l
命令如果可以看到刚才添加的那段话,则证明添加成功。这里使用了一段 cron 表达式,Linux 的 cron 表达式和 Springboot 中的表达式起始单位有些不同,需要注意下。
另外,注意到上文中需要使用 source ~/.bashrc
才能使配置的 bash 文件生效。当用户重新登录的时候也必须这么做才能使我们的配置再次生效。作为程序员,这当然是无法容忍的。于是,我们可以用下面的方法来解决这个问题,来让每次登录服务器之后我们的配置自动生效,
# 编辑 .profile 文件
vim .profile# 在文件中增加如下的配置
if [ -s ~/.bashrc ]; thensource ~/.bashrc;
fi# 或者直接增加下面的代码也行,不过简单粗暴了点
source ~/.bashrc
这样配置之后,每次启动重新登录的时候我们的配置就可以自动生效了。
最后的一个问题,如果用户目录下面不存在 .bashrc
或者 .profile
文件,那么可以从 /etc/skel
文件下面将其拷贝到用户目录下面,然后再做上面的配置即可。
3、搭建生产服务器环境
上面的配置已经做到了安全性的基本要求。下面着手搭建服务器生产环境。既然是基于 Java 的生产环境,那么要求安装的东西不多,一个必备的 ftp 服务,一个 JDK 环境即可。当然,正式的话还有数据库 MySQL, Redis,以及常用的中间件 MQ、ES 等。这里我们先搭建一个基础的 Java 环境,能运行起 Springboot 即可,所以 JDK 就够了。
3.1 安装 ftp 服务
Ftp 还是比较重要的,我一般使用 ftp 上传要发布的 jar 包。另外,个别软件的安装包比较大,而且存在网络连接问题,导致下载速率比较低,因此,有时候会选择本地下载完成安装包之后通过 ftp 上传到服务器再进行安装。所以,ftp 是非常重要的一个环节。
先安装 vsftpd,
yum install -y vsftpd
安装之后会生成 /etc/vsftpd/
和 /var/ftp/
,其中
/etc/vsftpd/
目录下面包含四个文件:ftpusers
指定了哪些用户不能访问 ftp 服务user_list
当 vsftpd 里userlist_deny=NO
时,只允许这里的用户访问 ftp 服务;当 vsftpd 里userlist_deny=YES
(默认) 时,不允许这里的用户 访问 ftp 服务vsftpd.conf
是 vsftpd 的核心配置文件vsftpd_conf_migrate.sh
是 vsftpd 操作的一些变量和设置脚本
/var/ftp/
是匿名访问 ftp 服务器的时候能够访问的目录
使用 vim vsftpd.conf
编辑配置文件,比较重要的配置项说明:
# 是否允许匿名登录,默认 YES,为了安全起见,我们应该将其关闭
anonymous_enable=NO
# 是否允许本地账号(系统账号)登录
local_enable=YES
# 是否运行上传操作,如果要运行上传那么就要开启这个配置
write_enable=YES
# 是否以独立运行的方式监听服务,ftp 服务的运行模式,NO 时表示 xinetd 模式;YES 时表示 standlone 模式
listen=NO
# 控制 user_list 的功能,允许 user_list 列表用户登录ftp
userlist_enable=YES
# 控制 user_list 的功能,不允许 user_list 列表用户登录ftp
userlist_deny=YES
# 这个指令应该谨慎!!因为当其设置为 YES 的时候,虽然可以登录服务器,但是登录的 ftp 用户可以访问上级目录
chroot_local_user=NO
# 不受限制的用户列表,在 vsftpd 目录下面建立 chroot_list 文件,写入指定的用户名即可
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
allow_writeable_chroot=YES # 这句必须有
其他配置还可以选择:
# 地址:设置监听f t p服务的ip地址,默认监听所有IP地址
listen_address=IP
# 设置监听ftp服务的端口号
listen_port=21
# 允许下载权限
download_enable=YES
# 用户切换进入目录时显示 “.message”文件(如果已存在)的内容
dirmessage_enable=YES
# 启用xferlog日志,默认记录到 /var/log/xferlog
xferlog_enable=YES
# ftp日志格式
xferlog_std_format=YES
# 数据连接端口号默认20
connect_from_port_20=YES
# 禁止被动模式连接;默认允许被动模式连接
pasv_enable=NO
# 起始端口号
pasv_max_port=21600
# 结束端口号
pasv_min_port=21700
# 开启PAM验证
pam_service_name=vsftpd
# 限制多个客户端同时连接(0为无限制)
max_clients=0
# 允许相同IP地址访问ftp连接次数(0为无限制)
max_per_ip=0
# ftp的访问控制列表提升安全性使用
tcp_wrappers=YES
配置完成之后就可以使用以下命令开启服务:
service vsftpd start
另外还需要配置 系统的安全模块 SELinux:
# Step 1: 打开 SELinux 文件进行编辑:
vim /etc/sysconfig/selinux# Step 2: 将 SELINUX=1 修改为 disabled
然后,我们需要添加一个独立的用户来进行 ftp 访问,并且限制 ftp 用户只能进行 ftp 连接,不能进行服务器登录,不应该将 ftp 用户和登录用户混为一谈,以此来进一步保障服务器的安全性:
# Step 1: 添加用户,语法是 useradd [-mMnr][-c <备注>][-d <登入目录>][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-s <shell>][-u <uid>][用户帐号]
# 用户登录终端设为 /sbin/nologin,即使之不能登录系统,只能访问 ftp
useradd ftpuser -d /home/ftpuser -s /sbin/nologin# Step 2: 修改用户密码
passwd ftpuser# Step 3: 设置用户权限,/path/you/set 为刚刚设定的该用户 ftp 的根目录
chown -R ftpuser /home/ftpuser# Step 4: 再到 /etc/vsftpd 目录下新建(或者修改) chroot_list 文件 并添加允许访问的用户# Step 5: 重启 ftp 服务
service vsftpd restart# Step 6: 若出现无法上传或者读取目录情况,设置之前指定的目录的读写权限
chmod 777 /home/ftpuser
3.2 连接 ftp 服务器
1. 远程连接 ftp
在 Mac 上面,可以使用 finder 连接 ftp 服务器,缺点是只能下载不能上传。参考文章 《Mac自带FTP工具用法》 进行连接即可,另外还可以使用 iterm2 连接。iterm2 是 Mac 上的终端神奇。其安装和配置可以参考 《MAC终端神器iterm2——告别黑白》,然后需要在 Mac 上面安装 ftp,参考 《Mac ftp 命令安装即使用》。至于 Windows 上面,直接使用 Xftp 即可。可以到我的公众号后台回复 【服务器连接软件】 获取我打包好的软件。
2. 连接 ftp 服务器的问题
用 xftp 连接提示无法打开,无法显示远程文件夹:选择 “属性->选项->将使用被动模式” 选项去掉即可。
3.3 安装 JDK
需要注意:Java SDK 和 ElasticSearch 等其他的中间件的版本对应关系,一般来说 JDK 8+ 可以满足大部分需求。
到官方网站 JDK 官方下载地址 下载 JDK 即可。在官网下载之前需要先进行用户登录,获取到下载链接之后使用 wget 命令进行下载即可:
wget http://download.oracle.com/otn-pub/java/jdk/8u171-b11/512cd62ec5174c3487ac17c61aaa89e8/jdk-8u171-linux-x64.tar.gz?AuthParam=1531155951_4e06a4d17c6c1dbfb8440352e19dd2ae
注意下载后缀中包含 AuthParam
参数,如果链接不包含这个参数,下载之后可能无法使用。
如果从官网下载速度比较慢,可以尝试从华为镜像下载:华为 JDK 镜像。
进行安装:
# Step 1: 创建安装目录
mkdir /usr/local/java/# Step 2: 解压至安装目录
tar -zxvf jdk-8u171-linux-x64.tar.gz -C /usr/local/java/
设置环境变量:
# Step 1:打开 profile 编辑模式
vim /etc/profile# Step 2:在 profile 文件末尾追加环境变量
export JAVA_HOME=/usr/local/java/jdk1.8.0_171
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH# Step 3:使 profile 生效
source /etc/profile# Step 4:添加软链接
ln -s /usr/local/java/jdk1.8.0_171/bin/java /usr/bin/java# Step 5: 检测是否安装成功
java -version
3.4 搭建 Springboot 环境
如果仅仅是提供一个下载服务的话,还是比较简单的,直接使用 Springboot 的 web 和模板引擎构建一个 html 页面,apk 放到 static 目录下即可。也有问题需要注意下,即如果这样简简单单地搭建的一个服务是不安全的,因为没有做限流处理。而一般我会使用 Redis 做限流,但是这样就要介绍如何安装 Redis 以及 Redis 的各种安全配置等……所以,目前先不做,当前能够展示应用详情,并且能够给用户提供下载渠道即可。
4、发布应用
4.1 在服务器中启动 Springboot 程序
Springboot 应用开发完毕,直接在项目根目录执行 mvn install
编译打包即可。打出来的包,通过 ftp 上传到服务器。
对于 jar 包,如果想要在后台启动,可以使用如下指令,
nohup java -jar target/包名.jar --spring.profiles.active=lt &
也就是使用 nohup
并且末尾追加了一个 &
。如果不使用 nohup
只追加一个 &
,也可以后台启动,但是这种方式在 ssh 会话结束之后程序就会停止。
按照上面 nohup
的启动方式,会在当前目录下面生成一个名为 nohup.out
的文件,终端的内容会被写入到这个文件当中。使用这种启动方式的时候终端不会显示启动过程,所以我们只能通过获取 nohup.out
的内容来判断程序是否启动成功。动态获取文件的内容可以使用指令 tail -f nohup.out
来获取。当然,如果希望将输出人日志重定向到某个具体的文件或者不输出日志(重定向到 /dev/null
)也是可以的。比如下面的命令用来将日志重定向到 catalina.out 文件:
nohup java -jar xxx.jar > catalina.out 2>&1 &
查看 Springboot 工程的进程使用如下命令,
ps aux | grep "java -jar" | grep -v "grep"
上述显示的内容中包含了进程的 pid,如果要杀掉某个进程,直接输入下面的命令即可:
kill -9 pid
4.2 指定虚拟机启动参数
1. 远程连接虚拟机
首先,我们需要远程连接上我们的应用来观察虚拟机的状况。不论是排查线上问题还是项目启动之前虚拟机参数调整,这个都比较重要。常用的连接工具有 jconsole 和 jvisualvm 两个。让我们的虚拟机可以被远程监控,需要我们做小小的配置。
首先,我们需要修改虚拟机远程连接的密码。进入 jre 安装目录下面的 management 目录中,比如我的 jdk1.8.0_181/jre/lib/management
。然后,复制 jmxremote.password.template
并将其重命名为 jmxremote.password
,然后注释掉最后两行的注释,这里的 monitorRole 就是默认的远程连接的登录账号,紧随其后的就是登录密码。需要把默认的密码修改掉,增加服务器的安全性。
然后,我们需要在项目的启动参数中增加几个参数来配置并启用远程连接,比如我的设置了之后的参数如下:
nohup java -jar -Djava.rmi.server.hostname=23.123.122.31 -Dcom.sun.management.jmxremote.port=11162 -Dcom.sun.management.jmxremote.rmi.port=11163 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true $portal_app_jar > portal.out 2>&1 &
这里我们的参数配置及其含义如下:
java.rmi.server.hostname
:远程连接的时候的 ip,就是你的服务器的真实 ip 地址;com.sun.management.jmxremote.port
:远程连接的时候的端口,不能和应用的端口相同;com.sun.management.jmxremote.rmi.port
:远程 rmi 连接的时候的端口,不能和应用的端口相同;com.sun.management.jmxremote.ssl
:是否使用 ssl 连接方式;com.sun.management.jmxremote.authenticate
:是否启用身份认证功能,这个应该启用,否则就别人不需要输入密码就可以直接连接并查看你的虚拟机了。
这样配置完成之后开发上面填写的两个端口,然后重新启动应用。
本地远程连接虚拟机的时候使用 jconsole 和 jvisualvm 皆可。这两个可执行文件放在 jdk 的 bin 目录下面。双击打开之后直接连接即可。
2. 应用启动参数配置
首先是一些官方的参考资料
- Springboot 核心配置参数的官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#core-properties
- Oracle 上面的虚拟机参数调优文章,包括虚拟机版本、垃圾收集器选择、设置堆大小等方面的调优提示:https://docs.oracle.com/middleware/11119/wls/PERFM/jvm_tuning.htm#i1146060
常用的参数:
-XX:MetaspaceSize=128m (元空间默认大小)
-XX:MaxMetaspaceSize=128m (元空间最大大小)
-Xms1024m (堆默认大小也是最小的大小)
-Xmx1024m (堆最大大小)
-Xmn256m (新生代大小)
-Xss256k (棧最大深度大小)
-XX:SurvivorRatio=8 (新生代分区比例 8:2)
-XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,这里使用CMS收集器)
-XX:+PrintGCDetails (打印详细的GC日志)
具体取值多少要根据自己的应用的类型、并发量和服务器环境综合分析,可以结合上面的一些文档为自己的程序指定参数。
4.3 编写服务器启动脚本程序
当然了,指定服务器启动参数还是比较繁琐的,所以,通常我们会编写启动脚本,然后通过执行脚本来启动和终止程序。下面是一段参考代码,
#!/bin/bash
# 程序运行脚本程序
# 作者:王守恒
# 定义要启动的程序的 Jar 文件,不指定 Jar 文件的版本
app_jar=box.jar# 脚本文件使用说明
usage() {echo "|====================================================================="
echo "| 脚本文件用法说明 |"
echo "|====================================================================="
echo "| sh 脚本名称.sh [start|stop|restart|status] [prev] |"
echo "| |"
echo "| 参数说明 |"
echo "| |"
echo "| start: 启动程序 |"
echo "| stop: 停止程序 |"
echo "| restart: 重新启动程序 |"
echo "| status: 程序状态 |"
echo "| |"
echo "| prev: 可选参数,如果指定该参数,则会将程序的运行日志输出到指定 |"
echo "| 的文件中,否则不输出,建议项目正式发布的时候不启用该选项 |"
echo "|====================================================================="
}# 程序启动函数
# 函数体内使用 $ 获取的参数是函数调用的时候传入的参数,
# 而不是整个脚本被调用的时候传入的参数
start() {# 运行portal程序vm_opt='-XX:NewSize=216m -XX:MaxNewSize=216m -XX:SurvivorRatio=8 -Xms1024m -Xmx2048m -XX:+PrintGCDetails -Djava.rmi.server.hostname=你的ip -Dcom.sun.management.jmxremote.port=你的端口 -Dcom.sun.management.jmxremote.rmi.port=你的端口 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true'if [[ $1 == "prev" ]]; then# 预览nohup java -jar $vm_opt $app_jar > box.out 2>&1 &echo "box[prev] start succeed"elsenohup java -jar $vm_opt $app_jar > /dev/null &echo "box app start succeed"fi
}# 程序停止函数
stop() {# 获取程序的pid并kill之
is_exist $app_jar
if [ $? -eq "0" ]; thenkill -9 $pidecho "Box was killed with pid ${pid}"
elseecho "Box is NOT running"
fi
}# 程序状态函数
status() {is_exist $app_jar
if [ $? -eq "0" ]; thenecho "Box is running with pid ${pid}"
elseecho "Box is NOT running"
fi
}# 程序重新启动函数
restart() {stop $app_jarstart $app_jar
}# 判断指定的进程存不存在
is_exist() {pid=`ps -ef | grep $1|grep -v grep | awk '{print $2}'`
if [ -z "${pid}" ]; thenreturn 1
elsereturn 0
fi
}# 根据用户输入参数选择执行的函数
case "$1" in
"start")
start $2
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac# End
# =========================================================================
这里我区分了预览和正式环境,因为有时候应用启动之前就因为某些配置错误无法启动,此时如果使用正式环境的话,日志会按照我们上述的配置被丢掉,从而无法配查问题。可以通过启动的时候指定一个 prev 参数将启动过程中的日志重定向到当前的目录下的指定文件中。这里主要有几个功能吧:启动、重启、判断是否启动以及指令说明。
4.4 配置域名
按照上面的配置我们已经可以可以使用 ip 地址进行访问了,但是我们还是要配置一下域名。这里我使用的是之前的一个子域名。当然,除了配置域名之外还要配置一下 CDN,配置了 CDN 之后的访问逻辑如下:
box.meiyan.tech -> CDN 域名 -> CDN 域名指定的 ip 地址或者 ip 地址加端口号
配置 CDN 比直接使用域名映射到 ip 地址的方式还有一个好处,就是在 ping 指定的域名的时候不会直接暴露 ip 地址,这样可以阻挡一步分流量攻击。
总结
这里介绍了搭建服务器和服务器安全配置相关的知识,也涉及到了一些 linux 指令,因篇幅的原因,上面仅仅介绍了一部分,更无法详细进行介绍。此外,我写了完整的十几篇文章,从基础的 linux 指令到各种常用的中间件安全配置等详细的知识,感兴趣的话关注下吧。这里提到的 移动工具箱 是我最近开发的一款 Android 工具软件,非常实用,其中包含了很多对开发者非常实用的功能,感兴趣可以下载尝试。
从零搭建基于 Java 的服务器生产环境相关推荐
- 从零搭建webpack的react开发/生产环境
一.初始化项目 在命令行中敲入如下命令: mkdir Webpack-react && cd Webpack-react && npm init -y 然后你就可以在你 ...
- VituralBox从零搭建基于CentOS 7(64位)的Kubernetes+docker集群
VituralBox从零搭建基于CentOS 7(64位)的Kubernetes+docker集群 1. 下载CentOS 7官方minimal镜像 2. 安装VituralBox(Windows 1 ...
- 测试小白基于java的selenium自动化测试环境搭建
本人是一个软件测试小白,自己在研究自动化测试时,真的入了不少坑,直到现在,才勉强将环境搭建了起来. 在此,我随随便便总结了一下基于java的selenium自动化测试环境搭建,送给正在学习软件测试的你 ...
- 从零搭建一个java开发环境: 二、下载安装mysql数据库
前言 这是从零搭建一个java开发环境的第二篇,这篇文章将介绍mysql数据库的下载安装.在关系型数据库中,使用较多的是mysql和oracle,我自己用一般装mysql.oracle占用内存太大,自 ...
- 从零搭建符合自己需求的开发环境
从零搭建符合自己需求的开发环境 本文长期持续更新中,保持和自己实际开发环境一致,欢迎关注交流讨论! 前言 这篇文章,一是总结自己,二是给新上道的小白一些思路,三是 何时能重组大学时的EXplosion ...
- 15分钟从零开始搭建支持10w+用户的生产环境(三)
上一篇文章介绍了这个架构中,选择MongoDB做为数据库的原因,及相关的安装操作. 原文地址:15分钟从零开始搭建支持10w+用户的生产环境(二) 三.WebServer 在SOA和gRPC大行其 ...
- 15分钟从零开始搭建支持10w+用户的生产环境(二)
上一篇文章,把这个架构的起因,和操作系统的选择进行了详细说明. 原文地址:15分钟从零开始搭建支持10w+用户的生产环境(一) 二.数据库的选择 对于一个10W+用户的系统,数据库选择很重要. 一 ...
- 15分钟从零开始搭建支持10w+用户的生产环境(四)
上一篇文章,介绍了这个架构中,WebServer的选择,以及整个架构中扩展时的思路. 原文地址:15分钟从零开始搭建支持10w+用户的生产环境(三) 五.架构实践 前边用了三篇文章,详细介绍了这个 ...
- 基于Java技术的Web环境下分布式数据库互操作性的实现
作者:李炽明 莫倩 徐明 1 JDBC工作原理 JDBC(Java Database Connectivity)是1个Sun公司注册了的商标,代表用来执行SQL语句的Java语 ...
最新文章
- 【机器学习PAI实践八】用机器学习算法评估学生考试成绩
- C#工业物联网和集成系统解决方案的技术路线
- 属于服务器端运行的程序_生信分析云平台产品开发 - 5 生信分析pipeline服务器端运行...
- mysql hy093_请问SQLSTATE [HY093]:参数号无效:未定义参数
- 曲面化原理创新设计_曲面丝印机会给我们带来什么样的美丽
- 如何用命令行运行python程序_如何使用运行python代码命令行.exe从C应用程序?
- 移动磁盘故障,如何在Mac修复?
- 爬虫实例十一 全国城市房价排行
- linux 重启mysql_Grafana+Prometheus 监控 MySql服务
- 关于天猫魔盒tmb100系列 开机灯亮显示器无反应的问题分析
- 将url编码数据转换为简单字符串
- java 右下角_java实现桌面右下角弹窗效果
- 微信小程序:选择图片、上传图片(应用:切换用户头像)及过程中遇到的问题
- 大学生就业的三方协议基本概述
- 2022年秋招总结暨acm退役记
- ubuntu16.04对比工具Meld安装和使用
- (附源码)springboot基于java的超市购物管理系统 毕业设计 271611
- docker 简单教程
- 基于神威·太湖之光的超大规模图计算系统“神图” 2019-12-16 14:10:29 作者:Fma
- 超融合过时?来看看超融合最时髦的应用场景
热门文章
- 【已收到Offer】小米前端实习面经(一、二面)
- 移动硬盘在计算机中不显示数据能恢复,移动硬盘在电脑上不显示怎么办?分享常用电脑知识...
- 调查问卷动态生成的一点探索
- 教你制作服务器中更高效率的刷怪塔,我的世界低耗材高效率凋零骷髅刷怪塔制作攻略...
- 想用自己电脑做服务器并且绑定域名建一个个人网站应该怎么做
- 怎样在服务器上放自己写的网页
- 《小狗钱钱》良句收录和读后感想
- OMCI协议二层功能的模型选择
- CPU降温软件测试自学,CPU降温软件真的有用吗工作原理是什么
- 有趣的巴什博弈(Bash Game)