Linux从0到1部署SpringCloud项目

之前弄了个Linux虚拟机准备自己捣鼓捣鼓,可惜一直没时间,再加上不是很适应纯命令行的操作方式,导致一拖再拖。正好最近不是很忙,过一遍SpringBoot+SpringCloud项目的部署流程,查漏补缺一下,也确实是发现了很多问题。

部署步骤

  1. 安装项目运行所需要的所有依赖。安装依赖很好理解,没有他们项目也运行不了,全程能用yum就用yum(因为懒)。
  2. 确保远程机器能够访问到Linux服务器。这个远程访问的主要目的有两个:第一是项目部署好后远程机器要能访问到项目,不然没有任何意义;其次是大部分MySQL和Redis等中间件都是部署在服务器上的,如果不能远程连接也会造成很多麻烦,所以必须确保远程访问。
  3. 本地项目打包发布到Linux上并启动。这个里面有很多细节,也遇到了许多障碍,后面会一一描述。
  4. 远程机器访问服务器上的项目,查看是否能够正常调试接口。这一步如果没有问题,就说明整个过程成功了。

下面就一步一步复现整个过程。

准备工作

  • 开发环境:CentOS-7  Java Development Kit-1.8.0.342
  • 开发框架:SpringBoot  SpringCloud
  • 中间件:MySQL-5.7.39  Redis-3.2.12  Nacos-1.4.1
  • 其他工具:IDEA  Maven

上面是需要在Linux中安装的基本依赖,几种安装软件的途径,yum/wget/tar包/rpm,之前的一篇文章里介绍过各自的优缺点,在这里不作赘述。原则就是能用yum就用yum,全程yum -y install还是很方便的;yum如果没有,就安装一个EPEL(Extra Packages for Enterprise Linux),相当于扩充了你的yum源;如果这样还不行,那就用tar包安装吧。

在用yum之前记得要设置一下国内的镜像源,之前用网易的感觉不是很理想,换到阿里以后下载速度1M每秒吧,还凑合。大概步骤如下:

//记得先把原配置文件备份一下
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

//下载新的阿里镜像源配置文件,注意要对应系统版本号
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

//更新一下缓存
yum clean all
yum makecache

依赖安装

在这之前我打算先试试能不能让本机访问到Linux虚拟机,就先顺手安个Nginx。

yum -y install nginx

然后用whichis nginx找安装的目录,去启动一下。在本机访问虚拟机IP看看效果(看IP用ifconfig,没有的话用yum安装):

 

 OK,松一口气,没什么奇怪的问题出现。

1.JDK 1.8安装

yum -y install java-1.8.0-openjdk-devel.x86_64

等屏幕不闪了调用一下 java -version,能正常显示信息即可,然后去修改一下环境变量信息,vim /etc/profile后在后面追加:

//注意这里的openjdk-***,要和你安装的信息保持一致,可以调用下whereis java看看安装的目录名称
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.342.b07-1.el7_9.x86_64
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar

2.MySQL 5.7安装

yum源没找到MySQL 5.7,所以只能先获取到rpm包,再进行安装:

//下载rpm包到本地
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

//安装
yum -y install mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql-community-server

安装碰到了一个奇怪的问题,提示我“公钥尚未安装”,去搜索了一下要去先获取公钥才行,所以先调用获取一下公钥再进行安装即可:

rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

安装好后 systemctl start mysqld.service启动MySQL服务,status查看运行状态,如果为“active(running)”则说明运行成功。之后就需要登录一下MySQL,默认生成的密码我们需要去安装的日志里查看一下,这时就涉及第一个常用命令的扩展知识点:grep

grep是个很常用的正则搜索命令,一般日志查询和定位都要用到它。一般用法如下,更复杂点的正则匹配可以自己再去了解。

//这里的na作用为:显示行数+不忽略二进制数据
grep -na "搜索内容" /路径/路径

//此处的用法
grep -an "password" /var/log/mysqld.log

2022-08-30T02:33:52.142942Z 1 [Note] A temporary password is generated for root@localhost: le-d16iLpco5

然后用这个密码登录进MySQL,修改密码后操作数据库,由于MySQL对密码强度有一定的要求,在设置简单的纯数字密码时会提示密码强度太低。所以我们先设置一个复杂点的密码,进入系统修改密码策略后,再设置一个简单密码。其实是不建议这样做,但是由于只是用于个人学习,搞个简单点的密码比较好。

步骤主要如下:

//降低密码强度策略
set global validate_password_policy=0;

//降低密码最小长度
set global validate_password_length=1;

//然后修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';

//最后记得刷新权限,不然不生效
flush privileges;

最后去配置一下远程连接,MySQL默认是不支持的,还需要关闭一下selinux或者防火墙,或者开放3306端口。增加权限的语句如下:

grant all privileges on *.* to root@'%' identified by '密码';

flush privileges;

之后就可以在本机用可视化工具来操作SQL,用Navicat把表结构和数据都复制进去,MySQL环境就准备好了。

3.Redis 3.2安装

Redis安装倒是很简单,直接 yum -y install redis就行,主要是要学习如何开启Redis的远程访问。和MySQL相同,Redis也是默认不允许远程访问的,可以去修改以下配置:

//找到redis.conf的位置
whereis redis.conf

//修改如下几个配置项
bind 0.0.0.0 或 本机ip

//关闭保护模式
protected-mode no

//设置为守护进程,用于后台启动
daemonize yes

设置完上述配置项后,可以用RedisDesktopManager试一试能不能连接上,能连上就说明Redis已经成功运行且配置文件生效。如果连不上,说明可能是Redis没有正常启动,或者配置项没有生效。可以先查Redis进程是否启动成功,或者直接查6379端口号有没有被监听;使用 ps -ef|grep redis 查进程,修改配置如果不生效就杀进程再启动;或者 netstat -an|grep 6379,查询6379端口是否被监听,或是 netstat -ntlp查看所有端口监听情况。

4.Nacos 1.4安装

由于要部署的是一个微服务项目,用Nacos作为注册和配置中心,因此还需要先安装好Nacos才能实现服务注册和配置管理。

Nacos是用tar包安装的,先去官网下载好 nacos-server-1.4.1.tar.gz,用WinSCP扔到虚拟机上直接解压启动即可。要注意的一点是,由于tar包解压不属于常规的安装方法,在rpm和yum中是无法查询到的,只能查文件夹所在位置。

解压完毕后cd到bin目录,输入 sh startup.sh -m standalone &,意为单体模式,加上“&”让他后台运行。运行后可以输入 netstat -ntlp看看所有端口的监听情况,如下图:

可以看到3306/6379/8848端口都已监听,且最后面显示了程序的名称,说明MySQL、Redis、Nacos都已正常运行。可以去本机访问一下ip:8848/nacos,如果能正常登录就说明没问题。

至此,所有项目运行所需的依赖都已经安装完毕,下面只需要把项目正常打包并运行在Linux上即可。

代码打包

由于是一个Maven父子工程,所以只需要把整个父工程先Clean再Install即可。把整个工程Install完之后,每个子工程下会生成一个Target目录,里面的Jar包就是我们需要的。

将单个工程拖进Linux准备运行一下,在运行 java -jar xxxxx.jar后,连SpringBoot启动的日志都没看到,直接报出“no main manifest attribute in xxx.jar”。分析一下这个报错,是由于当前Jar包中没有指定主入口,简单来说就是没指定主启动Main方法。

经过查阅一些资料,发现这些信息是在Jar包的“MANIFEST.MF”中指定的,这个清单说明了该工程的所有信息。用压缩包形式打开我打包的Jar包,在/META-INF下确实有这么个MANIFEST,打开看了看其中的内容:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: 52Hz
Created-By: Apache Maven 3.5.2
Build-Jdk: 1.8.0_311

这看着确实是少了点什么,资料说少了下面几个东西:

  • Main-Class:SpringBoot自定义的类加载器。
  • Start-Class:主启动类,也就是Main方法。
  • Spring-Boot-Classes:类路径,包括编译后的Class文件和配置文件,打包后都会放在这个目录中。
  • Spring-Boot-Lib:所有依赖的打包路径。

要把这些信息打包进去,那肯定要从Maven下手了,因为包管理都是靠Maven实现的。需要做的就是在pom.xml的<build>标签中加入SpringBoot打包插件:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

要注意的是,首先要设置 repackage属性,它才会重写MANIFEST,否则有时会无法生效。 

其次这个插件不能放在父工程中,因为使用他的前提是当前工程必须有主启动类,才能正常打包,否则就会报错。一开始我为了偷懒直接放在父工程,让每个子工程获取他,对父工程调用Install后发现,总是到某个子工程就会报错。经过排查后发现,报错的子工程没有主启动类和Main方法,只是作为一个依赖存在。把父工程的插件去掉,再给有主启动类的子工程挨个加上,对父工程Install就正常了。

现在再来看看正常的MANIFEST文件内容:

Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Archiver-Version: Plexus Archiver
Built-By: 52Hz
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.blog.BlogApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.7.3
Created-By: Apache Maven 3.5.2
Build-Jdk: 1.8.0_311
Main-Class: org.springframework.boot.loader.JarLauncher

这次就齐活了,下一步就是把项目扔到Linux启动。 

项目运行

让项目运行起来,听起来是很简单,直接java -jar不就行了吗?但实际上还是有很多问题可以探讨的。

1.后台运行

首先第一点,如何让程序在后台运行?因为我们部署的是一个微服务项目,需要同时启动非常多服务,都前台执行是不现实的,Ctrl+C就直接退出去了。

前面我们提到过一个“&”,可以让程序后台运行,这里我们的第一种实现方式就是“java -jar xxxx.jar &”。这种方式对大部分情况是够用的,但当窗口或账户退出时,程序也会自动退出,这就不是很理想了。

针对这种想让程序一直在后台挂着的情况,我们可以用nohup(no hang up)不挂断模式,具体指令为“nohup java -jar my-blog-1.0-SNAPSHOT.jar &”。这种方式可以在账户退出或终端退出时,仍然让程序运行。

但其实还不够,运行日志在程序问题和Debug排查过程中,是一个非常重要的工具,这两种方法无疑是看不到日志的。我们可以针对nohup指令,再改进一下。

2.日志输出 

nohup还有一个很重要的扩展功能,就是可以自动输出日志。在“nohup java -jar my-blog-1.0-SNAPSHOT.jar &”这种情况下,我们没有指定输出的日志文件,他就会自动将日志输出到当前目录下的 nohup.out文件中。可是每个文件夹都有一个 nohup.out是一件很诡异的事,你要如何区分哪个是哪个的日志呢?这些也可以指定。

可以使用“nohup java -jar my-blog-1.0-SNAPSHOT.jar >>/home/Shelter/log/blog.log 2>&1 &”,这段指令的总体意思是“将my-blog程序后台运行,并将其运行日志输出到blog.log文件中”,我们来分段解释一下:

nohup java -jar my-blog-1.0-SNAPSHOT.jar >>/home/Shelter/log/blog.log 2>&1 &

//前面这段就是挂起执行Jar包
nohup java -jar my-blog-1.0-SNAPSHOT.jar

//显示指定要输出的日志文件路径,前面的“>>”意为追加写入,如果是“>”则为覆盖
>>/home/Shelter/log/blog.log

//将 标准错误输出2 重定向到 标准输出&1,再将 &1 重定向到指定的log文件中
2>&1

//后台运行
&

在启动程序后,可以用“tail -f blog.log”查看日志的实时输出。

总结

将所有微服务启动后去Nacos查看,所有服务都被成功注册,在本机调用接口和Feign也都能正常得到结果。说明这次部署就圆满完成啦,确实是捣鼓了半天,不过是有意义的。学会了很多常用的指令和排查问题的方法,比如ps查进程号kill了重开,netstat查端口监听情况。还有最好用的reboot指令,出啥问题了解决不了就reboot,以后谁问电脑问题统一建议重启。

下面是一些常用指令的总结:

  • grep:内容查询。示例为“grep -na 'debug' /home/Shelter/log/log.log”,查询“debug”在log.log中出现的位置和行数。
  • ps:查进程。示例为“ps -ef|grep redis”,寻找redis的进程号。
  • kill:杀进程,配合ps使用。示例为“kill -9 5555”,意为关闭pid为5555的进程。
  • netstat:查看端口监听情况。示例为“netstat -an|grep 6379”,查询6379是否被监听,或是“netstat -ntlp”查看所有端口监听情况。
  • jobs:查看后台启动程序。比如后台挂起的Jar包就可以从jobs中看到。
  • nohup:后台挂起。示例为“nohup java -jar my-blog-1.0-SNAPSHOT.jar >>/home/Shelter/log/blog.log 2>&1 &”,可以将项目后台启动并输出日志到指定文件。
  • tail:动态查看,默认显示最后10行。示例为“tail -f log.log”,动态查看日志文件尾部。
  • whereis/which/find:寻找文件所在位置。
  • &:后台启动,加在启动程序指令的后面。
  • reboot:重启大法好。
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值