360个人网站怎么推广,中国建设银行官网站,网站开发的报告,合肥网站建设 卫来网络一、引言 最近公司在海外上云服务器#xff0c;作者自己也搞了云服务器去搭建部署系统#xff0c;方便了解整体架构和系统的生命周期#xff0c;排查解决问题可以从原理侧进行分析实验。虽然用的云不是同一个#xff0c;但是原理都是相通的。
二、选型 作者选用的是腾讯云…一、引言 最近公司在海外上云服务器作者自己也搞了云服务器去搭建部署系统方便了解整体架构和系统的生命周期排查解决问题可以从原理侧进行分析实验。虽然用的云不是同一个但是原理都是相通的。
二、选型 作者选用的是腾讯云没别的原因就是便宜加牌子大。 阿里云肯定是更好一些的不管是服务售后还是服务器内核和操作系统都是比较活跃的毕竟作者以前公司用的就是阿里云了解一些。 不过以前都是和运维沟通排查问题作者自己只能看到一些服务器监控和运维的截图这对于了解整个云服务架构体系的生命流程是不太友好的。 操作系统选择了CentOS7.6-Docker20毕竟linux的底层是必须的目前的容器环境也是服务的基础。 基本参数如下没必要太好
CPU - 2核 内存 - 4GB系统盘 - SSD云硬盘 60GB管理快照流量包 - 500GB/月带宽5Mbps
三、系统搭建部署 作者准备把springboot用Maven打包jar包拿到docker容器运行
3.1、后端 后端是SpringBootSSM框架代码就不贴了作者写了个小程序给家里人用的。
3.2、打包 这一步很麻烦打出来的包很小作者当时还没意识到问题本地java -jar运行一下报错了。显示no main manifest attribute, in /**.jar问了一下chatGpt这就很扯做了这么久的SpringBoot他里面的application怎么可能不是字段设置为主类的呢。 作者有找了网上的一些文章有的说是打包的时候没有设置入口类pom的build重新设置一下。
buildplugins!-- maven-compiler-plugin 插件配置 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.8.1/versionconfigurationsource1.8/sourcetarget1.8/target/configuration/plugin!-- maven-jar-plugin 插件配置 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-jar-plugin/artifactIdversion3.2.0/versionconfigurationarchivemanifestaddClasspathtrue/addClasspathmainClass**.Application/mainClass/manifest/archive/configuration/plugin!-- 其他插件... --/plugins/build 然后出现了新的错误Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) at java.lang.ClassLoader.loadClass(ClassLoader.java:351) 跟chatgpt拉扯了许久还是没找到正确的pom又找了朋友看以前做的项目其实很简单的po完全依赖spring自动打包发现
buildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build 打包之后有60几M大小之前只有几百k所以很明显了再次本地运行java -jar显示成功通过Localhost也可以访问里面的接口 3.3 部署 部署系统jar之前需要先把数据库部署好不然根本运行不起来。
1、部署mysql 这里安装的的是mysql5.7习惯了这个版本 下载MySQL 5.7的Docker镜像docker pull mysql:5.7 下载完成后可以运行以下命令来创建并运行MySQL容器docker run --name mysql -e MYSQL_ROOT_PASSWORDpassword -p 3306:3306 -d mysql:5.7 创建一个名为mysql的容器并将MySQL的默认端口3306映射到主机的3306端口。将password替换密码。 检查MySQL容器是否正在运行docker ps -a 如果看到mysql容器正在运行说明MySQL已经成功安装并运行在Docker中。 如果MySQL容器未运行启动它docker start mysql 登录到MySQLdocker exec -it mysql mysql -u root -p 检查MySQL服务器的运行状态service mysql status 启动它service mysql start 作者在这中间还走了一些弯路一开始不想设置用户名密码结果导致他自动生成了一串作者还不知道密码是什么又进去修改密码最后还生成了两个root账号一个权限是*一个是localhost导致后面jar运行出了问题。
2、部署服务 腾讯云界面上有个SFTP的文件可视化作者一开始不知道还准备搞市面上的一些文件传输软件毕竟jar包需要传输到远程服务器。 首先要创建一个Dockerfile这个文件没有后缀的在服务器窗口建好文件夹之后 输入vi Dockerfile 从vi界面搭建i编辑自动创建文件写完内容之后点击esc退出编辑状态再点击:wq退出文件并且保存。 Dockerfile里面内容
# 基础镜像使用java
FROM openjdk:8-jdk-alpine
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
ADD test-provider-service-0.0.1.jar /test-provider-service.jar
ENTRYPOINT [java,-Djava.security.egdfile:/dev/./urandom,-jar,/test-provider-service.jar]
1. FROM openjdk:8-jdk-alpine指定使用OpenJDK 8的Alpine Linux作为基础镜像。 2. VOLUME /tmp指定将主机的/var/lib/docker目录与容器的/tmp目录进行挂载用作临时文件目录。 3. ADD test-provider-service-0.0.1.jar /test-provider-service.jar将当前目录下的test-provider-service-0.0.1.jar文件复制到容器的根目录并将其重命名为test-provider-service.jar。 4. ENTRYPOINT [java,-Djava.security.egdfile:/dev/./urandom,-jar,/test-provider-service.jar]指定容器启动时要执行的命令。这里是运行Java应用程序的命令使用java命令执行test-provider-service.jar文件。 然后把jar传入服务器jar要和Dockerfile在一个文件夹里面。 创建docker镜像docker build -t ** . 这个.是指使用当前文件夹所以要先cd到jar所在的文件夹**就是指容器的名字。 运行容器docker run -d -p 5006:5006** 用的是宿主机5006端口容器的5006也是作者springboot用的端口默认springboot是用8080的这个要在配置文件设一下
3、问题排查解决
3.1、root拒绝 docker ps -a看一下容器状态诶嘿退出来了exit说明jar有问题但是docker logs ** 有看不到日志那就加个日志打印。
public class Application {public static void main(String[] args) {try{SpringApplication.run(Application.class, args);} catch (Throwable t) {System.out.println(t);throw t;}}
} 先得把之前的容器和镜像删除然后重新生成删除容器需要用容器id或者名称在docker ps -a中可以看到docker rm ** 删除镜像docker rmi ** 爆出来的是access denied for user rootip (using password: YES) 一开始还以为是配置错了账号密码在本地又跑了一下但是很明显没有问题 看了一下mysql在MySQL的user表中每个用户都有一个唯一的组合键由用户名User和主机名Host组成。这意味着即使用户名相同只要主机名不同就会被视为不同的用户。我猜测的是root这个%会拦截所有的root访问因为在本地用workBench去链接显示的也是拒绝。但是%的root不是我设置的密码所以得加一个新的用户密码。
root | localhost root | % 创建一个具有相同权限的新用户但允许从任何主机访问MySQL服务器 CREATE USER new_user% IDENTIFIED BY password;GRANT ALL PRIVILEGES ON *.* TO new_user% WITH GRANT OPTION;
3.2、链接mysql失败 再次运行镜像爆出了不一样的错误
Unsatisfied dependency expressed through bean property sqlSessionFactory; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name sqlSessionFactory defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Unsatisfied dependency expressed through method sqlSessionFactory parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name dataSource defined in class path resource [com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.class]: Invocation of init method failed; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure 很明显是mysql的链接问题但是为什么会出现这种问题问一下chatgot 说的很官方没有什么实际作用但是原理是相同的要么是驱动程序问题要么是网络问题如果是驱动程序应该不可能出现本地运行成功服务器失败。 那么就要思考服务器的docker容器和本地运行到底有什么区别作者想到的是mysql和服务jar运行在两个容器当中本地访问服务器的mysql是通过公网ip那么在服务器jar里面的配置是使用127.0.0.1localhost去链接mysql那么是不是不能直接使用localhost去链接。 因为云服务器的容器不一定在同一个宿主机上面即使在同一个宿主机分配端口维度也可能是容器这个就看每个云厂商怎么设置的规则了。 带着这样的猜测作者把配置文件改为使用内网ip结果成功了。 四、总结 通过自己安装部署云服务器上的系统作者对于整个系统架构有了更多了解实践出真知对于技术工具实验和底层原理排查都有帮助。