头像

我真的菜的要死了

某不知名医科大学




离线:38分钟前


最近来访(424)
用户头像
Renaissance_0
用户头像
yekkkk1
用户头像
宇宙有边
用户头像
01.
用户头像
su尔
用户头像
白日梦Q
用户头像
玺一喵
用户头像
覆暮北城歌
用户头像
acwing_49062
用户头像
yi生守护你
用户头像
大秦洛阳
用户头像
希尔维亚
用户头像
BlankScript
用户头像
γχc
用户头像
方_35
用户头像
yxc
用户头像
种花家的虎式坦克
用户头像
Bug自动机
用户头像
藏锋守拙
用户头像
lorendw7


接下来的这一部分,是实现acapp端。将前端做出适应性修改,以能够适应acapp窗口。

因为这整个项目是一个前后端分离的项目,同样的一个后端可以有多个前端
QQ图片20221201094213.jpg

实现acapp端,其实与实现上述的前端是类似的。
因为在前端项目完成后,打包说白了就是些cssjs文件,在打包时可以设置是打包成多少个cssjs文件。
任何一个能调用这两类文件的地方,都可以去运行代码(App,小程序,浏览器)

要想能够适应不同页面的不同窗口,就需要对前端进行重新的规划与布局。
另外在上线的时候,将应用打包成两个文件,在上线acapp端的时候,填下cssjs地址与类名。

项目地址地址

实现

一.铺垫:

1.首先要先检查下vue版本

如果vue版本较低,会导致在开发中出现问题。
输入:vue-version查看vue版本
如果版本大于@vue/cli 5.0.8,那么就说明没有问题

2.重新配置nginx

(现在y总提供的nginx就是已经解决了跨域问题的nginx,因此不用再去修改。)

二.创建acapp

如果之前创建的vue中有vue.config.js那么就不需要重新创建。
首先先安装插件(先安装,后面为了防止被污染去掉他)

vue-router;
vuex

安装依赖:

bootstap
properjs/core
vue3-ace-editor
jquery

2.配置vue.config.js

将讲义中的配置粘贴进来
默认将项目分成若干个文件,去分包处理。
配置内容在讲义。
通过这个配置,希望整个前端项目只打包成一个文件,因为配置作用是让打包的数量为1

接下来把web端的src放进acapp端文件夹.

3.首先先将整个项目打包成acapp

首先先点build然后运行


关于备案:国内要是想上线一个东西,网站基本上离死不远了
问题在于行政审批


dist文件夹下如果有一个js文件与一个css文件,则说明打包成功。
打包成功.png

接下来,就可以把这两个文件传递到云端。
nginx配置可知,路径放在了

/kob/acapp/

将文件放进相应的文件夹:

scp js/*.js springboot:kob/acapp/

同理将css文件传过去。然后给文件重命名为app.jsapp.css

如果想给在已经上了域名的网站中访问app.js的方法为:
在链接的路径后面添加/acapp/app.js即可
打开app.js,如果看到里面是一堆代码,则说明配置成功。
这样就可以将css地址与js地址填到对应的地方上去。
填写的表单样式如下所示:
QQ截图20221201142119.png

其中的主类名需要自己去设置:
大体的方法为:在app.js中,有一串很长的代码,是一个匿名函数,将匿名函数挂载到#app上。
主类名的形式就是将这个文件封装成一个类,然后返回一个类名。

3.1 生成主类名:

首先先将这一堆代码变成一个函数。
然后传过去appidmyappid
然后将常量#app替换成appid,并且删掉函数执行。
在删除后,引入讲义中的Game
引入的Game类.png

解析:export出去主类名,传入id,调用函数,将整个app挂载到appid上面去
完成后,将前端再次传到云端,再重复整个过程。

3.1.1写一个脚本,简化执行流程。

因为整个修改的过程需要不断的删除云端jscss文件,然后再把新的jscss文件传进去。
因此可以写一个脚本,用脚本去执行这个操作。
首先,在本地的服务器的acapp文件夹里,创建文件rename.sh
这个文件的主要作用就是将文件删除,并且将传过来的文件重命名

rm app.js app.csss
mv *.js app.js
mv *.css app.css

然后给这个脚本添加上可执行权限

chmod +x rename.sh

在本地的acapp文件夹里,再创建一个文件。uoload.sh这个文件主要是负责上传 文件到服务器
以及能够执行云端脚本

scp dist/js/*.js springboot:kob/acapp/
scp dist/css/*.css springboot:kob/acapp/

ssh springboot 'cd kob/acapp &&./rename.sh'

然后赋予可执行权限
在本地的终端中执行这个文件:

sh uoload.sh

这样的话,而米处要更改代码的时候,就可以先去执行脚本。。


完成了之后就可以去准备保存了。
主类名就是刚刚上传的那个主类名,Game
选择头像然后提交安装再打开应用。

此时的acapp,页面背景的格局都发生了改变,改变的原因就是传过来的文件里自带了样式:bootstrap与acwing的样式是冲突发发,因此需要删掉第三方依赖,自己重写一遍。

注意:自己写的样式是不带scopedscoped的作用是不去影响别的样式。因此去掉了scoped可能会对别的组件产生影响,

三.修改前端,使其自适应acapp


因为在acapp里,如果切换页面,那么链接也会发生变化,按理说,需要的是在切换页面的时候,acapp不能跳转变化的链接。因此除了换掉vue自带的bootstrapvue自带的router也应该换掉。

在调试阶段,选择采用一个默认静态的token数据来先进行登陆操作。以切换跳过登录是否有用户的判断。


本地网页的登录的token在哪能够查找到:
当打开控制台,选择应用,存储大项的第一个项中的第一个小项,即可看到token,如下图所示:
token的位置.png


1.前期工作

首先先修改下App.vuegame-bodygame-window的大小
因为项目是跑在一个框里的,
因此可以给整个项目画一个框。

<div>

并且设定其宽度与高占满。项目的界面在这个大框里面的小框里,就像下图这样:
QQ图片20221201212200.jpg
整个游戏要占满整个内部框,设定宽高都为100%。写法如下
20221201212401.png

2.正式改造

首先要先把router去掉
但是去掉router有一个问题,他会影响url,但是url是不能修改的。
因此解决方法就是手写一个router

2.1手写router

整个项目一个有的页面为:Menu,pk,record,record-content,ranklist,user-bot这几个页面。
首先,这每一个页面都是一个组件,用一个全局变量,并通过判断,以控制当前页面应该显示哪一个组件,
登录注册,因为后续采用的是第三方授权登录,因此不需要这两个组件。router路由与报错error删掉,NavBar因为后面会换成一个菜单页,因此也要删掉。

store中定义2全局变量:router.js
其中的变量:router_name表示当前应该在哪个页面下,默认的页面为菜单页面。
定义更新的方法:updateRouter(state,router_name)

接下来,创建组件MenuView.vue,然后在App.vue中,将所有的组件都import进去。
然后引入到App.vue

通过v-if来判断控制router页面的切换。写法如下:
QQ截图20221201215726.png

注:改成:v-else-if之后,就不要每个都判断一遍,加快了速度

2.2 实现菜单页面

定义一个类名为menu<div>
菜单中有很多项,每项叫menu-item一共4项,分别是对战,对战列表,排行榜,我的Bot
整个菜单要展示在整个屏幕的正中间的位置。
实现这样的布局,可以选择用flex
水平居中样式:justify-content:center
竖直居中样式:align-items:center

把宽度与高度设置成100%,然后设置下其他的类样式。比如菜单内容的样式:
具体实现如下所示:
QQ截图20221201225841.png
当点击某个按钮,要实现能够跳转到对应的事件

2.2.1 实现跳转页面

修改页面,修改全局变量,全局变量位于store里面。需要把store引入进来。
接下来需要定义四种行为
clcik_pk_handler调整pk页面的Router的名字
click_record_handler调整record页面的Router的名字
click_ranklist_handler调整ranklist页面的Router的名字
click_user_bot_handler调整我的Bot页面的Router的名字。
代码如下:
QQ截图20221201233533.png

将函数返回,最后在组件里,绑定@click点击操作。

接下来,就需要给每一个被跳转的页面,添加一个返回按钮,因为四个界面都需要一个返回按钮。
因此要需要一个公共组件来呈现。

目前有一个废弃的公共组件:ContentField

2.2.2 改造contentfield

首先设置content-field的宽高都设置成100%
然后将所有的页面都用content-field括起来。
接下来就可以添加一个返回按钮。
返回按钮的位置可以在任意的地方,不做硬性的要求。
设置按钮的样式之后,并且添加鼠标悬浮的形状
QQ截图20221202101855.png

接下来,给这个按钮添加行为click_go_back_handler
使其能够点击之后,就能够跳转到菜单页面,并且将行为绑定到组件上。
QQ截图20221202102450.png

接下来,就是对单一的组件进行处理。

3.改造pk页面

对于pk页面来说 ,重点改造的应该是matching匹配。

关于MatchGround的修改,只涉及样式,不涉及功能。

首先先用一个大的<div>名为matchground-field,把整个结构给括起来

在括起来之后,整个的匹配框就被放在了左上角
需要调整样式把他放到中间去

选用flex布局,写法如下:

div.matchground-field
   display:flex;
   jsutify-content:center;
   align-items:center;
   width:100%;
   height:100%

由于bootstrap会污染其他的样式与页面,因此需要把bootstrap从根源删掉,以及与bootstrap相关的属性也需要删掉

3.1 将页面恢复到bootstrap之前的样式

对决双方的信息,以及select框要均匀的分布在这一行上。
均匀分布也可以采用flex布局。
定义<div>class类为matchground-head
因为是水平均匀分布而不是居中,因此可以设计为:

justify-content:space-around

要注意:类user-photouser-username其实应该是一个整体,因此也应该用<div>括起来,以方便flex布局

因为前端要跑在acapp里,因此需要将头像、字体等做适应性修改。
中间区域下拉框过小,也需要适当的放大以及添加圆角处理。
QQ截图20221202111936.png


此时在调试的时候的显示并不是100%全窗口显示
页面显示不呈现100.png
因为body具有一个margin
因此可以先把margin先强行关掉。


修改完上面的选择框之后,接下来就可以修改下面的button来做适应性改造
定义类为start-match-button,修改按钮的颜色大小,以及点击的悬浮操作。
写法如下:
QQ截图20221202113004.png

在写一段时间之后,尝试打包进行调试。

打包完成后,进入dist文件夹,再执行一开始打包上云的操作

注:在运行前,每次都一定要记得清缓存,ctrl+shift+r清除缓存,每次更新代码也需要清除缓存再打开网页


在运行时,发现acapp里的显示没有呈现100%全面显示
运行时不能做到100%.png
解决的方法是:
div.widow组件去掉,把scoped加上
(每次想要在acapp下运行的时候,就需要执行上面的操作)

----------

对于一个成熟且面向大众的应用,如何每次更新版本后给用户能够强制的清除缓存
解决方法就是,每次都把路径换一下,这样浏览器就一定没有缓存
修改的方式是:在云服务器每次上云的时候,给文件名中加一个后缀,每次更新版本后,修改cssjs地址,这样就能够保证用户每次用的都是最新版本


3.2 调整:为了能够适应acapp,对匹配界面进行重新的布局

(在进行改动的之前,为了方便调试,把div.windowscoped加上与去掉)
主要的改动在于matchgrounddiv组件,改为flex布局,设置布局方向为竖直方向。环绕方式改为space-around
把按钮组件去掉:padding
将玩家的信息设置成space-around环绕方式。
然后删掉div.window加上scoped
重新打包重新上传查看效果

QQ截图20221202161113.png

问题描述

由于chrome插件的原因,可能打开的时候,页面会一直卡在白色页面
出现这样的问题:主要是scale属性的问题。导致加载缓慢,可以将scale属性修改成下面的写法:transform:scale(1,2)







项目的毛坯版本的最终效果如下所示:

登录页面与注册页面:

QQ截图20221129133650.png
QQ截图20221129133555.png

对战页面与匹配页面

对战页面.png
匹配页面.png

对局列表页面

对局列表页面.png

排行榜页面

排行榜页面.png

我的Bot页面

我的bot页面.png

以上的页面样式/动效/甚至功能都相对简陋且毛坯,待后续有时间将会对页面样式进行重新的设计,对后端功能进行丰富与完善。

项目github地址

网页传送门

本次笔记记录的是最后整个项目部署到云服务器,并且上线到云端的过程。由于整个笔记已经做了拆分,关于服务器的选择购买以及服务器的配置可以查看下面链接

关于服务器选择过程的全记录看这里

关于服务器的配置过程看这里

项目部署的步骤

一.完善本地项目,使其能够传到后端

在之前运行的代码是通过函数把数据传过去。如果在云端,可以用docker沙箱来作为运行环境,

关于docker沙箱:docker沙箱中一般是通过文件来传参数,一般来说会更加灵活且能够支持更多的语言。

1.首先,先将函数参数的传递方式更改为文件形式

大体方法为用bot.getInput()这种输入把他写进文件里,然后再把它读取出来。

首先修改下Consumer类(消费者进程)
首先先定义一个File,然后把File读入进文件里。
然后接下来,用一个try..catchbot.getInput读入到文件里。
输出之后,记得去清空下缓存区。
这样就不需要BotInterface这个接口了将接口更换成Supplier<Integer>
具体代码如下所示:
第一段代码.png

注:关于这个接口:函数中有一个参数get,这个函数是不能传参数的,用来返回一个数值direction,相应的前端控制的代码Bot也需要做一个相应修改,使其能够读到操作指令。通过重载一个Get()方法以实现。

1.1 重载Get方法

首先先从文件里把相关的信息读入进来。

File file =new File("input.txt")

然后定义一个Scanner
之后调用下nextMove函数,去把这个代码给进行前端覆盖。
重载get方法.png

除了这个以外,代码添加随机字符串的逻辑部分也需要更换接口
更换接口.png

2.第二个不妥情况

匹配成功之后,不知道自己是A蛇还是B蛇(也就是不知道自己是左下位置还是右上位置)
如果不标注的话,对于一名用户有50%的概率选择对,如果两名用户就是25%的概率才能让比赛正常进行。

PkIndexView中,添加<div>用来判断

$store.state.user.id === $store.state.pk.a_id

这样写是不会有显示的。
原因是因为这两个等号边的Id不一定都是整数类型(虽然数据上是,但是逻辑判断时函数背后的逻辑不一定是)
因此为了能够统一,把这两个数都统一成整数类型。
或者把===改成==
并且要保证双方的对战状态为playing以保证比赛结束重开之后不会再显示。

3.后端:面向前端的API设置统一的格式。

这个项目里,有9个API分布在ranklist/record/account/bot/
为了方便配nginx,统一给API链接加上/api
然后修改在securityConfig放行接口

通过以上的操作,已经做好了能够让前后端都上线的准备

二.打包项目上线后端

1.首先给后端添加一个配置

打开三个子模块的pom
首先先加上<package>
然后再加上<build>,(<build>的内容在讲义里有)
(要记得<build>里面的<mainclass>要换成对应的main文件所在路径)

2.将项目整体打包

点击Maven,然后把最大的那个模块backendcloud点击生命周期,点击clean
clean完之后,有一个pacakge选项,点击即可打包
QQ截图20221129155756.png

关于在后端打包时遇到的一系列问题,可以查看下面的分享:

关于Maven打包出现的一些问题与解决方法

3.传文件

将打包好的三个文件:
上传到云端.png
首先打开文件所在的backend文件夹。
输入命令:

scp 文件名 服务器名

接下来,为了方便管理,在云端创建几个文件夹
kob,以及在kob中创建的bakcendcloudwebacapp
三个文件夹对应后端、前端、acapp端。
首先先进到bakcend文件夹,把这三个jar包传进去。

cp ~/*.jar

传进去之后,启动它即可。

4.启动后端

tmux中,输入接下来的命令,以打开后端3000,3001,3002端口。

java -jar  文件名

注意:如果对一个后端项目做了修改,那么就把这个模块重新打包,然后重新上传,比如:

scp springboot -1.0-SNAPSHOT

三.打包前端

在打包前端之前,首先要给IP绑定一个域名

1.绑定域名:

对于一个开发者,如果想要一个域名,需要经过如下的几个过程
租一个域名->备案->等待审批通过->获得证书

但是Acwing已经帮助申请好了域名。
类似这样的样式.png

图片仅供参考。,起一个标题,把服务器的IP放进去,保存,这样IP就绑定到了域名上

2.配置nginx

目前的网站是http的,http的由于cookie的问题会导致弹出不安全。
为了能够安全,改为https
在上面的acapp的应用创建页面里,有一个acapp.key
去到终端,在/etc/nginx/里创建cert文件夹,在里面创建acapp.key
同样创建acapp.pem,将相应的代码放进去,然后再配置nginx.conf
(在这之前先给sudo配置上三件套文件:.bashrc .vimrc .tmux.conf )

接下来启动nginx

sudo /etc/init.d/nginx start

输入命令如果等待看到这个代码,则说明没问题
nginx启动成功.png

如果能够看到403 Forbidden的页面,则说明没有问题
QQ截图20221125221716.png

如果nginx的配置有问题,可以打开error.log来查看原因。


关于nginx.conf的解析为:
如果是地址以/api开头,则导流到Springboot后台。
/websocket 开头,则导流到SpringBoot后台
/开头,则导流到前端项目


3.部署前端

通过快捷键ctrl+shift+f,定位寻找 需要修改的链接的位置。
(ws也要改,只是ws改成wss)

3.2打包前端项目:

vue的图形化界面的脚手架中,点击build开始运行,这是会看到本地文件中出现了dist文件夹。
这个dist文件夹就是已经打包好的项目
将这个dist文件夹传到云端就可以了

scp -r dist springboot:/kob/web/

接下来,把dist文件夹内容复制出来

mv dist/* .

如果后续前端需要修改,首先先将全部的文件都删除

rm css -r
rm js -r
rm img -r
rm favicon.ico
rm index.html

然后重新打包,重新scp上传,再移出dist文件夹。

这样整个项目,就部署好了。

问题描述与解决方法:

问题一.在上传完成后,注册报500

原因:服务器的mysql与配置文件properties的端口不一致,因为当时用的两个mysql,因此设置的是3307
修改方案有两个:一个是重新修改后端,另一个是直接修改服务器的mysql端口.
具体可以查看下面的链接:

服务器的mysql修改端口的方法

问题二.在将代码pushgit时出现报错

出现的报错为:
QQ截图20221129224227.png
之前用的还好好的,但是这次就不行了,
于是去百度查询解决方案:
参考了如下的几个参考方法后,最终解决问题:
参考方法1
参考方法2
参考方法3
基本方法为:重新生成一遍ssh密钥,然后给git代码库加上新生成的ssh
输入命令:
ssh-keygen -t git关联的邮箱
生成之后,去系统的用户文件夹找到id_rsa.pub
复制ssh密钥,粘贴到git上,
最终解决问题
项目上传到git.png




前传

由于SpringBoot框架课的项目需要上线部署到云端,并且需要赋予域名,需要租一台云服务器,祖云服务器以及选择云服务器的过程可以查看下面的链接:

云服务器的选择与配置过程传送门

在购买完服务器之后,接下来就需要配置服务器了,如何配置服务器,方法如下:

正式配置服务器

首先在刚刚购买完服务器之后,在Terminal里可以尝试登录一下:

ssh 用户名@IP

输入密码之后,如果能够登录成功则说明购买成功
打开说明正常购买成功.png

一.配置一下这个服务器

在这事先声明,本人所使用的服务器为华为云,由y总的几个讲义来看,华为云、腾讯云、阿里云,基本的配置流程大致是相同的,只是在细节上有出入,接下来以华为云嗯对配置方法举例,如果后续再买到其他云的时候,再来更新

因为如果使用root根用户配置服务器的话,权限太高可能导致误操作从而导致文件删除,因此首先未来在操纵服务器的时候不要在根用户下操作。就需要首先先添加一个用户。

1.创建一个非root用户

创建命令为:

adduser 用户名

接下来输入密码,输入密码之后一直按回车,即可
创建用户.png

接下来,给新建的用户添加一个sudo权限

usermod -aG sudo acs

2.将常用的配置传入服务器

常用的配置三件套:

.bashrc 。vimrc .tmux.conf

再添加这些常用的配置之前,首先先配置免密登录

2.1 配置免密登录

在配置免密登录之前,首先先配置一个别名,以防止IP太长记不住
配置别名的位置在ssh下的config文件
写内容格式为:

Host 服务器别名/域名
    HostName:IP地址
    User:自己的用户名

比如写为:

Host:springboot
    HostNameL:120,46.201.37
    User:acs

然后输入以下命令配置免密登录:

ssh-copy-id 服务器别名

输入刚刚给用户设置的密码
免密登录.png

这样就配好了免密登录。
登录到服务器,将这三个文件传进服务器

2.2将文件传进服务器

输入下面命名:

scp. bashrc .vimrc .tmux.config springboot_server:

注意:一定要记得加上最后那一个:
配置文件传递.png

3.去服务器里装一下tmuxdocker

首先先更新下apt

sudo apt-get update

接下来安装tmux

sudo apt-get install tmux

安装tmux.png
至此云服务器基本配置完成。

3.1 安装docker容器

在安装docker的时候,时间程序会比较长,因此最好是在tmux里装,这样在即使退出掉Terminal之后,依旧不会断掉。
docker的安装有相关的教程,在docker的官网

docker官方文档传送门

docker教程里去按照步骤复制,在复制完之后,输入:

sudo apt-get  update

对代码进行更新。之后输入dokcer,如果能够弹出东西,像下图所示,那么说明安装成功
docker安装成功.png

4.配置docker

首先先配置一下dockersudo权限
输入下面命令;

sudo usermod -aG docker $USER

检验的命令为docker images
退出服务器后,再输入这个命令,出现下面的内容,就说明拥有了sudo权限


问题:再多次输入命令,甚至是重新配置了docker之后发现依旧没有sudo权限。
解决方法参考链接1
解决方法参考链接2

解决的方法大体为:可能有占用正在运行的tmux,因此先把tmux杀掉,然后输入docker ps/docker images,以解决问题。


镜像出来了.png

4.1 安装镜像

在之前的djangoLinux基础课上存在AC Terminal里有相关的镜像,可以直接拿过来用。


下一步就是在ssh文件夹下的config文件,配置本地终端的免密登录

首先先给本地终端生成一个ssh密钥(如果有的话就不用生成)

然后创建一个文件config
在里面输入上面配置免密登录时的内容。
最后输入

ssh-copy-id springboot_server

配置完免密登录之后,接下来,把docker镜像解压出来。
解压的命令为

docker load -i

整个的解压的过程中需要一段时间


小贴士:最好不要一台服务器上两个项目,原因的瓶颈不在服务器上。
因为未来项目做大了之后,一个服务器都跑不起来。
所以根本不会出现一个服务器因为自己项目多而不够用
而且,同一个服务器,80端口都是一样的,因此不同的项目在同一个服务器还需要做特殊处理,很麻烦


4.2 把docker跑起来

要想让docker跑起来,需要用到一些端口映射
用到的端口有:
20000:容器用ssh端口登录的端口
(22端口被服务器本身占用)
443:https
三个微服务的端口:
3000、3001、3002
给容器取一个名字:kob_server
输入如下命令

docker run  -p 20000:22 -p 443:443 80:80 -p 3000:3000 -p 3001:3001 -p 3002:3002 -itd --name kob_server django_lesson:1.0

这样容器就创建好了,出现下图则说明运行成功
跑起来镜像.png
输入下面的命令进入到docker容器中

docker attach kob_server

进来之后,把刚刚创建用户时给用户赋予权限等等操作再重复的做一遍。

4.3 配置docker容器

输入下面的命令,首先先创建容器中的用户:

adduser acs
usermod -acs sudo acs

接下来,就是把容器挂载,挂载容器用ctrl+Pctrl+q,输入ctrl+d关闭容器
容器挂载.png

然后去云平台,将用到的端口都打开
22打开:否则ssh登录不上
20000打开:是负责容器的登录
443打开:https协议
80:http协议
3000、3001、3002是在服务器内部访问,在外面不要打开。
华为云的安全组配置在哪呢:
华为的安全组在哪.png
位置如上图所示。华为云的服务器的默认的安全组只有一个

Sys-WebServer

华为的位置2.png
在华为云的服务器里打开一个端口的方法为:
打开一个端口.png

4.4 配置容器的免密登录\

打开容器的.ssh/config
添加一个新的表名:

Host:Springboot
   HostName:IP与服务器的一样
   User:与服务器的用户名一致
   Port:200000

接下来配置容器免密登录
在这可以简单的解释下:容器:服务器中创建的一个虚拟服务器

ssh-copy-id: springboot

如果在重新运行的时候出现Bad Configuration
一般是自己的Config有地方写错了,比如说:port写成了post
报错Bad configuration.png


接下来在本地也要配置下容器(服务器中的虚拟操作)
在vim中添加服务器里一样的配置内容,然后同样再次输入命令配置免密登录。


服务器为何要与本地同步、
云端的作用;课上的很多配置位于AC Termina中
本地:文件项目在本地
因此云端与本地需要进行同步


5.配置mysql

在配置mysql之前,首先需要补啊.bashrc .vimrc .tmux.conf传给容器
再给容器添加完配置之后,接下来,就是在本地去运行了。

首先先安装一下mysql

sudo apt-get install mysql0server

然后执行更新

sudo apt-get update

然后再安装一遍mysql

这样,mysql就安装完成了,下一步启动mysql

sudo serivce mysql start

检验:输入top
如果能够看到mysqldmysqld_safe则说明登陆成功
表示启动成功.png

5.1设置mysql

首先先连接登录下mysql

sudo mysql -uroot 

在进来的时候首先先设置下密码:

ALTER USER 'root'@'localhost' INDENTIFIED WITH caching_sha2_password BY '要设置的密码'

再次登录进去,查看数据库,初始的状态下,项目数据库kob是不会随着后端项目所迁移的
数据库里是没有kob的.png
因此就需要先创建。
在创建完数据库之后,同理会发现也没有表。
那么就需要把这三个表从本地后端传上云端。

5.2 在云端重新创建表

由于表是在idea中的图形化界面创建的,找到相关命令的方式为:在idea右键->sql脚本->将DDL复制到剪切板
然后在云端创建文件。

vim crerate_table.sql

既然怒粘贴模式,把这三个表的SQL语句都粘贴进来。
mysql中输入这个脚本

source /home/acs/文件名

6.安装Java8

安装Java8的命令为:

sudo apt-get install openjdk-8-jdk

检验是否安装成功,输入:

Java-version

如果能够看到版本呢号,则说明安装成功。
看到版本号说明安装成功.png

通过上述操作,就可以配置好一台能够部署Springboot项目的云服务器




问题一.

maven打包时出错.png
出错的问题在于,刚刚加载进来用来生成项目的<build>没有Springboot版本
解决方法就是:添加上版本号就行。
QQ截图20221126162838.png

问题二.

jar包打包不全.png

在解决了上面的问题之后发现打包不全,有的模块没打包,有的模块只打包了一部分。
但是一开始找不出问题来,于是决定对部分模块单独打包,
但是单独打包后报错。

第二次打包出错.png

而且其实一直来说有一个问题,当我点开之前的backend文件夹的时候,里面是已经加载好了jar包。这也就说明,其实现在的bakcend模块是独立于父模块之外的,那么matchingsystem的模块同理也是这个问题。
点开父项目的配置文件,果不其然,在<Module>里面只有BotRunningSystem,这也就是为什么我的项目里只有BotRunningSysytem是子项目。
修改这个配置
解决许多模块没加入进父模块中.png
点击Maven然后重新加载,然后开始打包。

问题三.

在打包的过程中又出现了新的问题
新问题.png
解决方法:切换成跳过测试模式,这样即可实现打包。

上传到云端.png




前情提要

刚刚上线在云端服务器上的项目打开后注册账户结果报了500错误,如下图所示:
500错误.png
其实500错误挺常见,大概也许是后端的问题,于是回去检查了下后端代码,发现后端代码并没有什么问题。

问题查找:

就去视频下面的评论区翻评论,看到了两个佬的回复:
QQ图片20221126154000.jpg

由这两个回复不难看出出现500的错误一般错误的原因要么在于nginx的部署要么在于后端代码的配置文件与服务器的配置是否一致。

经过多次检查后发现nginx的配置是没有问题的,问题出在了application.properties上。
由于给出的回复里仅仅说了要保证mysql的密码与application.properties的密码一致,于是在检查时的重心一直放在了密码上。

始终没有想到端口号的问题

于是就跑去洗澡了(洗澡是一个好的思考方式)
然后突然在过整个配置文件的时候想到,properties里的端口是3307(因为我有两个mysql在电脑上),而我的mysql装的端口是默认端口没有修改过,依旧是3307
安装端口为3306,与3307不对应.png

因此问题可能出现在端口上。

问题解决:

关于给Linux修改端口,网上那些方法似乎都不大准,尤其是对于系统是Ubuntu
他们给出的解决方法都是在my.cnf里修改还说没有就直接添加,但是这样会直接报错
修改端口号,没有就新增.png

于是在整个路径下查找真正的解决入口:
QQ截图20221126155633.png
在这里面有一个mysql.conf.d文件夹

进入这个文件夹之后,有两个文件:
QQ截图20221126161113.png
打开那个`mysqld,conf,打开之后,有一行是port=3306`
但是这一行是注释掉的,因此需要把注释拿走。(改了这里好几次发现都没有,原来是这个问题hh)
华为云格外特殊.png

最后输入:

sudo service mysql restart

解决问题.
QQ截图20221126161405.png







前情提要

之前租了一台服务器,用来给我的SpringBoot项目部署到云端来用。要部署到云端需要先配置一下服务器,需要部署一下docker,在给服务器的acs用户配置sudo权限的时候,按照Linux基础课的讲义来配置项目但是却始终没有配置成功。显示的错误如下所示:
重启后没有权限.png

问题出现的原因:

docker的守护线程绑定的是unix socket,而不是TCP端口,这个套接字默认属于root,其他用户访问的是需要sudo去访问这个套接字。所以docker的服务进程,都是以root账户运行。

解决方法:

一开始尝试重新配置docker,但是尝试完之后始终不能够解决这个问题。去搜索引擎查找到的有效的解决方案如下: [ 解决方法1
解决方法2
首先输入cat group|grep docker来检查有无用户组。
没有用户组.png
发现确实没有用户组。
于是输入命令开始创建用户组

sudo groupadd docker 

结果显示用户组存在,可能就决定解决方法有问题,于是换了解决方法2(但其实解决方法1是没有问题的)

选择用解决方法2,以此输入如下命令:

sudo groupadd docker     #添加docker用户组
sudo gpasswd -a $USER docker     #将登陆用户加入到docker用户组中
newgrp docker     #更新用户组
docker ps    #测试docker命令是否可以使用sudo正常使用

解决方法.png
此时输入docker versiondocker images后,如上图所示,没有发生问题。
于是关掉服务器再次重启,再次输入docker images发现问题依旧存在。

那么就需要再输入一遍

sudo usermod -aG docker $USER

这样的话,在不进入tmux的情况下,就能够正常的打开docker
最终成功.png

但是进入tmux中不行。

原因在于: 根据官方文档:tmux keeps all its state in a single main process, called the tmux server. This runs in the background and manages all the programs running inside tmux and keeps track of their output.
tmux是client-server架构,后台有一个tmux server进程管理所有程序的运行状态。(英语好的可以自行翻译hh~)

解决方法很简单:
首先:杀掉tmux进程

pkill -f tmux

然后再打开tmux,输入docker images最终成功。
QQ截图20221123175932.png

参考方法1
参考方法2




本次课程的大部分内容主要是前端部分,后续会对页面的动效以及动画进行更新,敬请期待~

这一次同样的也是把整个部分分成逻辑以及问题部分。

项目地址

一.基本逻辑

(一).前传与补充:更新天梯积分

要让排行榜能够有效,就需要把天梯积分在每局比赛之后进行更新,规定赢者加分,输者减分,平局不扣分。

基本的逻辑为:在backend模块下的Game类里,有一个SendToDatabase()函数,这个函数是用来与record数据库进行数据获取与交互,在这个数据库里对对战双方的天梯积分进行计算更新。人为定义,胜者+3分,输者-3,平局不变分。

更新数据需要定义辅助函数UpdateUserRating,更新信息需要用到Mapper来调用数据库操作。
首先先取出玩家的Id,然后调用Pojo层的rating变量自有的函数setRating来取出新的函数,最后update来更新函数

在往数据库存储更新前,首先需要往sendTpDatabase()中取出天梯积分:

Integer ratingA =WebSocketServer.userMapper.selectById(playerA.getId()).getRating

然后判断当前的loser是谁,如果是A则给B加3分,如果是B则给A加3分。对于这方面最好是写成:

常量.equals()

否则的话当处于平均状态时会出现异常。
最后调用函数来更新天梯积分,总体的逻辑如下所示:

QQ截图20221122112240.png

重启后查看是否能够更新天梯积分:
天梯积分的更新.png

(二).实现对局列表页面

依旧是需要serviceimplcontroller三件套

在这里要注意:如果对局列表的信息很多,展示在一个页面会导致加载很慢,因此要需要分页。
实现分页功能,需要新的COnfig配置,内容在讲义(当然也可以去百度搜),创建一个新的Config类,MybatisConfig类接下来就是写三件套了。

1.Service

backend模块的service中添加一个包为record,同理在recordimpl中添加一个包为record

1.1 service

定义类名为GetRecordListService,定义一个JSONObject返回一个对局列表的list,需要传入一个页面的编号,因为是按照分页来返回,因此返回list的时候就需要返回当前是第几页的编号。
定义一个参数:Integer page.

1.2impl实现这个接口

(这个在后面展示页面信息中)

1.3 controller

定义Java类为GetRecordListontroller,与之前一样的方法,添加注解@Service
添加映射,由于映射只需要获取数据而不对数据库做修改,因此用到Get方法,映射到链接:/record/getlist/里面
调用接口里的getList函数,因为需要传入页面page参数,因此需要用到@RequestMapping.
getlist里,首先将page数据取出来

Integer page =Integer.parseInt(data.get("page"));

然后解析出来所有的page里面的列表信息。

return getRecord(listService.getList(page));

具体写法如下:
QQ截图20221122141222.png

2.展示某个页面的信息(也就是实现接口)

在实现接口的时候首先就需要将页面信息返回回来,假定一个页面展示20条记录,定义一个k,用来标识第几页,当k=1,则展示前20条记录,以此类推,当超出范围的时候则返回空。
实现逻辑:
实现这个功能,对于Mybatis来说需要用到APIIPage.
IPage的用法为:

IPage<Record>recordIPage =new Page<>(page,页中有多少条目)

因为需要从数据库里拿用户的信息以及记录的信息,因此把Mapper注入进来。

定义一个排序的Wrapper,来让列表倒序排列。

QueryWrapper<Record>queryWrapper =new QueryWrapper

对于Wrapper来说,有API可以决定是升序还是降序

orderByAsc()递增
orderByDesc()降序
queryWrapper.orderByDesc("列的名称/id")

为什么选择的排序条件是按照Id,因为Id是递增顺序放进的数据库,当两个bot时间相同时能够按照Id来排序,以此来保证排序的顺序唯一。
最后将查询的结果存到List里,
接下来就是将信息返回给前端;返回到前端用的是一个JSONObject,要返回到前端展示的是:用户名、头像、记录以及对战的结果。对战记录是存在于List里面,
因此名称以及头像需要现查现求。
QQ截图20221122145509.png
**在这里做一下补充:如果希望只能看到自己的对局记录,那么在查询的Mapper语句里添加.eq()的查询条件即可** 判断输赢方,并且给result结果赋值: ![QQ截图20221122145821.png](https://cdn.acwing.com/media/article/image/2022/11/22/109718_0fdbe45f6a-QQ截图20221122145821.png) 最后将这四个数据打包放进itemList`中。

以上的这些操作放进一个循环里,循环中不断的取出每一个对局的用户的Id,然后存储用户的相关信息,用一个Json把所有的信息都put进去,放进最后的大的List里面,最终存进JSONrecords中。

最后记得给前端在返回信息的时候,返回一个所有List的总数,以方便分页。
对于返回全部的总数,也有一个API,名为:

"records_count",recordMapper.selectCount(null)

最后返回resp

关于数据库的注入:对于三件套的注入数据库,直接注入Mapper,第三方类的需要写一个Set函数,再加上一个static,再注入一个Autowired.

2.1前端页面:

首先在前端页面中定义一个函数:puul_page,写一个ajax请求需要把page数据传进去。定义current_page变量,以表示当前页面,初始为1,与page相同。最后记得把这个函数再调用下:

2.1.1把列表显示在页面上:

首先先定义一个变量为:ref
定义一个变量,用来存储所有获取到的value值。

let records =ref([])

因为返回的值都在resprecords里面,因此直接赋值就行。
为了方便计算翻页,需要定义变量以存储有多少个对局。

let total_record =0;

将变量返回即可。

写法见下图:

QQ截图20221122152215.png

接下来就是要把页面展示到前端的网页上了
首先先把之前负责Bot的那个table拿过来。
在内容上:第一页展示A玩家,第二列展示B玩家,第三列展示对战结果,第四列展示对战时间,第五列展示操作,也就是点开能够看到回放的那个按钮。

把这些信息展开展示到页面上,需要在前端组件中添加循环。循环以id作为参照。取出id从最初后端的record中取出来:

record.record.id

第一个record是返回的条目。第二个是条目中的record,第三个是条件中是数值Id。
在整个列表里,第一列输出A用户的头像与用户名,
第二列输出B用户的头像与用户名,
第三列是对战结果,在判断完成之后从前端提取结果
第四列是按钮,用来查看录像

在两个标签的前端显示的时候添加&nbsp以添加空格。

2.1.2 实现录像查看

为了方便展示录像,需要存一些全局信息。
创建一个store,名为record.js
record.js中需要的变量有:
是不是录像is_record:因为录像页面的组件与对战页面的组件是一个组件Gamemap.js
两名玩家的走法记录:a_steps,b_steps
map:由一维数组存储的字符串变成一个[13][14]的二维数组绘制到地图上

注:mutatios里面的update只能传一个参数,如果有多个参数,需要将参数放进字典。

因为需要当点击录像按钮之后需要跳转到新的页面,跳到新的view里。
因此需要定义新的页面组件:RecordContentView.vue,只需要一个componenntsPlayGround
将这个组件的页面加进路由:这个路由需要带参数,因为不同的页面的id展示的内容不一样。
将加进去的路由中添加参数的方法为:/路由名/:参数名/
具体写法为:
QQ截图20221122162652.png

如何跳转到一个新的页面:
RecordIndexView中有一个函数名为open_record_content,这个函数需要一个参数,参数名为recordId,函数由点击button来进行触发。首先在record找出任意一个records,更新IsRecord,表示接下来要打开的是回放页面,

记得当切换回PK页面的时候切换回去,也就是在PkIndexView中添加状态,否则的话一进来就会放录像。
想要实现跳转到某个页面,则直接将router引进来,通过API把里面传入名字与参数:

router.push()

通过这个参数就可以跳转到对应名字的按钮。
QQ截图20221122174911.png

在跳转页面之前,首先先把游戏信息、每一步的操作信息、最后的输赢信息都取出来

注意:在record.js中,key的命名全都是小写的形式,因此注意调用时的写法。

将一维函数转化成二维数组line,用到函数stringTo2D
在实现了这个函数之后,调用函数把他存到updateGame里面,以及将AB两名玩家的id以及坐标都传过去。
这一部分的写法如下所示:
QQ截图20221122181502.png
QQ截图20221122181521.png
信息通过这样的方式已经全都传到录像页面了

接下来就是要对录像以及具体的操作做一下具体详细的区分,
当判断应该是播放录像的时候播放录像,当判断是要播放录像的时候则播放录像,否则则鼠标聚焦棋盘,执行蛇的移动操作。
add_listening_events函数中,判断的逻辑为:

if(this.store.state.record.is_record)

因为移动的操作就是原来的操作,因此直接用就行,关于录像的操作,是需要详细的逻辑来写。

具体的基本逻辑为:通过存储的一步步的操作的移动步骤,将每一步操作回放出来。
在此前已经将一步步的移动存到了updateSteps,

这样在回放的时候为了保证正常,设置整个逻辑的执行时间为300ms,其中200ms用作蛇的移动,100ms用作方向取出以及设定。

GameMap.js中定义APIsetInterval,因为后面在时间结束的时候会把这个API取消掉,因此需要先将它的Id存下来。
定义k,用来标记这是第几步移动指令。在之前已经确定,蛇的移动用到的改变方向的函数是set_direction


关于判断:if(k>=a.steps.length-1)
为什么要-1,是因为整个比赛最后的最后一步其实是不算的,因为两个蛇的最后一步有一步是非法是操作,肯定有一个因为非法操作已经死亡了。因此双方的最后一步都不要复现,直接停止录像复现就行。


因为需要标注输赢,以及蛇的输赢的死亡情况,因此还需要在全局变量record中定义新的变量为:record_loser
Gamemap.js中定义变量loser,用来帮助哦按段显示的逻辑
关于输赢判断最后导致整个对局结束的逻辑与在PkIndexView.vue中的相关判断是一致的。因此直接拿过来即可。

最后在整个录像视频播放结束之后,取消/退出掉300ms的移动循环

clearInterval(interval_id)

写法如下:
QQ截图20221122202753.png

记得每一次循环完成之后都去更新一下k

3.实现对局列表分页功能

bootstrap里面找一个Pagination,调整一下样式,
如果想让鼠标放上去之后这个按钮变蓝,需要给class添加一个active

接下来需要实现的行为是:当前页为返回页,且当前页码变蓝,另外在页面栏里面把当前页前后的两页页码展示出来,如果不足则不予以展示。点击每一个编号会打开相应的页面。

首先先定义一个辅助函数update_pages(),用来记录能展示出来的分页有多少个。

在实现函数之前首先先定义变量max_pagess用来计算一共有多少个pages

let max_pages=parseInt(Math.ceil(total_records/20))

定义一个数组new_pages,用这个数组动态的存储所有在分页栏中的代码。

函数的具体实现:
枚举这个页的前后两页,如果这一页上有内容,则在分页栏中展示这一页

这样的话从前端每次返回完信息之后,都需要更新下代码。
最后将动态数组new_pages里面的值赋值给已经定义好的pages中。
pagesupdatepages返回。

此外还需要判断当前点击的这个pages是哪一个页面。
因此需要给new_pages中新存一个对象,其编号是i,对象名为number,
i===current_page的逻辑表达式来判断当前的页码是不是应该变成蓝色。

然后把分页符中的页码以循环的形式展示出来:

v-for ="page in pages" :key="page.number"

<li>的判断里判断添加是否要加一个active
写法为:

<li :class="'page-item ' + page.is_active" v-for="page in pages" :key="page.number" ">

注意:'page-item '+page.is_activepage-item一定要在后面加一个
空格,因为is_active这个返回值是没有空格的,如果page-item也不加,那么类名就变了。
基本写法如下所示:
QQ截图20221122222613.png

3.1添加行为使得每次点击页码跳转到对应的页面。

定义一个辅助函数:click_page,需要传入page的编号。对于所有的页码框,规定当页面为-2的时候为前一页,当为-1的时候为下一页。其他的页,page与按钮的页数相对应就行。

通过判断,给每一个分页栏的按钮分配相对应的页面。
首先求一下当前的page的页数,max_page,当页数page在页数范围内的时候,就可以添加开一个新的页面承载这些列表
具体的实现的方法如下:
QQ截图20221122224234.png

(三).实现排行榜页面

1.实现后端页面

实现排行榜页面的后端依旧是三件套。serviceimplcontroller

1.1 定义接口GetRanklistService

在里面定义一个JSON,并且定义一个分页page
QQ截图20221122225520.png

1.2 实现这个接口impl

快捷键添加这个接口的实现(至于详细的实现在实现查询排行榜页面中部分)

1.3 调用接口controller

定义类:GetRankListController,添加注解:@RestController
将接口注入进来,
因为只需要获取数据,同样的,只要用Get方法就行了。映射的链接为/ranklist/getlist/
JSON方法中传入页面分页编号的参数。
QQ截图20221122231250.png

注:关于controller调用参数的类型选择,其实只有在注解是Resttemplate才会用MultivalueMap,否则不会用

2.实现查询排行榜

首先先注入用户数据库usermapper.个人定义一页展示5个用户。
定义Wrapper进行查询操作。
规定排序按照天梯积分降序排序:

queryWrapper.orderByDesc("rating")

将查询的结果存到名为userList中。
在返回的时候需要反悔呢一个总数。用来帮助分页.

resp.put("users_count",userMapper.selectCount(null))

尽管要把2整个数据库的信息全反悔呢给前端,但是因为users中的密码是加密且保密的,因此需要在向前端传递数据的时前去,清空密码项,以防止泄密。

for(user user:users)
  user.setPassword("");

QQ截图20221122232737.png

3.前端页面

前端页面的样式与对战列表的样式是类似的,因此是可以拿过来直接用的
包括前端的一些功能,比如翻页,获取信息(只需要获取用户名、头像以及天梯积分)等。直接拿过来用
其中一些的变量名的改动如下:

let records =>users
total_records=>total_users

总之records全部替换成users

小问题:如果想要给选择BotBot列表分列,但是其实并不是特别的好分

谨记一个原则:在开发的时候不要为难自己,给用户增加限制、增加麻烦来解决问题
Bot数量在AddServiceImpl中添加限制。并且添加判断,当SelectCount大于限定的数量的时候,直接返回限制信息,并且不能够添加Bot数量。
QQ截图20221122233436.png

二.开发遇到的问题

1.老问题:参数的名称错误:有数据但是没有页面展示:

目前能够成功返回数据.png
于是开始进行大量的输出。页面提取信息的部分没有问题。那么就有可能是判断页面类型的判断有问题,发现原因是把thjs.store.state.state.is_record写成了resord,导致没有判断成功。

2.问题二。在加上判断之后无法显示页码:

在加上循环之后无法返回页码.png
但是在去掉if判断之后就可以显示代码了,只是范围不能确定:
去掉if判断能够显示.png
在对下面这些对象参数输出之后发现:

 console.log(new_pages.number);
       console.log(new_pages.is_active);
       console.log(pages.value.number);
       console.log(pages.value.is_active);

activenumber都没有返回甚至没有存储在neew _pages
一直是没有找到问题,其中说明一点,max_page尽管输出NaN但是确实是不会有数据的,结果这成了找到问题的突破口。
max_page没有数据,但是max_page是基于total_records计算而来,total_records又是从resp取出来的
因此最终的问题在于从resp中数据集获取record_count时,写成了records_count,导致total_records没有得到数据,因此计算为NaN.




前情提要,关于服务器的配置以及使用可以查看任意一节工程课。如果想要更为详细使用全流程,可以报名AcWing的Linux基础课hh

进一步的前情提要:由于众所周知的行业寒冬,11.1-11.30期间正处在双十一的优惠活动期间,但是并没有多少的优惠力度,因此很多人推荐的等待节假日和购物节购买薅羊毛的时代已经不复存在了。

在这提醒:对于一个项目来说,服务器并不是一成不变的,在项目的每个阶段可以综合考虑项目需求性能、服务器的配置、价格多方面因素,综合考虑与升级选择自己的服务器

本文的篇幅较长且啰嗦,一共会分成两个部分:前传与正式购买

还望能够耐心看完

相关讲义以及企业链接

阿里云
腾讯云
华为云
Linux基础课讲义

前传:

阿里云:

一.关于服务器的选择

在听了y总以及众多大佬的建议下,可以有如下的结论:抛开钱不谈,优先考虑阿里云,如果考虑钱,谁钱少买谁,综合考虑阿里云>腾讯云>华为云

二.配置一个阿里云服务器的具体流程。

首先说明,关于云服务器,价格根据节假日以及市场保有量从而呈现不同程度的波动。一般双十一或者节假日有巨大的优惠活动,新人也具有优惠(以前还有学生优惠的,现在没有了)
首先打开阿里云,点击购买云服务ECS
会打开下面的一个页面:
ECS云服务器的页面.png

如果点击创建ECS,会弹出下面这个界面,(注意这个界面,后续会用到它)
第二个页面.png

如果你刚好财力雄厚,或者赶上了相关优惠,点击下面的不试用,立即购买,那么就进入了自己想要购买的配置选择页面。
自定义购买页面.png
服务器规格选择.png
(按照自己想要的配置进行选择)

需要注意的一点是,这个地域以及可选区,需要遵顼就近原则,但也不一定一定要遵循就近原则,遵循就近原则的话,服务器会更快速,而为什么不用遵循就近原则,比如说山东,就近选择青岛,价格会很贵而且可以选择的项也很少,对于华北区来说,强烈建议选择北京

下面是青岛当时服务器的价格:
青岛服务器规格过高且价格贵.png

至于下面,就是每一步需要配置的配置了,这个可以根据个人需求而定,在这里展示下我的个人所需的配置(主要是用作SpringBoot课程的上线)
配置选择.png
选择配置2.png
配置3.png
配置4.png
在一切配置完成后,下一步就是进入付款界面了

三.给你的阿里云服务器进行付款

点击下面的提交订单就可以购买支付你的服务器了。
可以看到支付的价格为80一个月,如果租一年的话就是12*80=960,这对于一个个人甚至说一个学生开发者来说可吃不消,又根据很多人提供的购买的信息以及价格来看,根本不需要支付这么昂贵的价格,在某些优惠甚至某些促销的叠加下,可能达到打一折的效果。于是就去开始寻找优惠

1.新人优惠的使用:

对于新人优惠,在这里要说明的是,只要你不买,那就一直享有新人优惠,这个情况无需担心。
回到首页,点击个人头像,下面弹出的框中有选项为新人优惠
IMG_1638.PNG

新人优惠页面有着如下的福利:
IMG_1640.PNG

尝试在这个页面配置后无果,

但其实始终没有找到真正的福利购买入口,入口在这:
新人专享入口.png
点开进入购买页面:
新人专享页面.png

因为目前新人优惠提供的服务器配置里,是没有这一款的,因此不适用。下面是当时所推出的限时优惠的服务器
现在服务器就这些没有ecs的等有活动再买.png
但是不排除后续应该会有,在根据下面这篇文章中收到了启发与猜测,在此感谢:

参考文章

2.学生优惠:

其实学生优惠已经是没有了,属于是去年的事情,但是在购买的时候并不知情。
学生优惠现在在开发者计划的成长计划页面里,也就是下图:
IMG_1642.PNG
很明显,目前已经不提供学生优惠了。

既然学生优惠没了,新人优惠又没有力度,但是项目上线又是必须的,经过一下午的思考与斗争,在查看了腾讯:135,华为还没配置完就100了之后,最终决定,先暂时临时试用一个月:

暂时先租用服务器.png

经过纠结了很久以及受到高人的启发,由于众所周知的行业寒冬,时代已经大变了,再也不会有机会搞到像曾经那么便宜的服务器了hh~,因此能搞优惠券下单入手就入手吧

待后续有了大的优惠甚至说有羊毛可以薅了之后,再去选择购买,此时也会实时更新分享hh~

正式购买

尽管在阿里云上选择了免费试用一个月,但是这并不是长久之计,如果需要能够始终保证项目的稳定运行且始终保持域名的时候的话,还是去选择购买一个服务器相对合适。

根据个人的需求以及对于整个SprinBoot框架课的规模进行分析,包括在咨询了众多大佬之后,尽管y总在Linux基础课上并不推荐购买轻量级的服务器,但是轻量级的服务器在规格配置等方面完全能够满足我的项目需求。此外轻量级的服务器在配置上已经完全的配置好,对于我这种初学者来书简单易上手。毕竟我的需求仅仅是把项目后端部署到云上,并且获得一个域名而已。

接下来就是服务器的选择了

在综合价格以及配置的综合选择,选择了下面三个平台的三款服务器,接下来进行逐一的解析:

阿里云

首先还是去看了下y总课上选择配置的那个服务器,果不其然依旧没有优惠,甚至说没有去年那么大力度的折扣。于是就去考虑轻量级的服务器。幸好的是,在新人优惠中,有对于轻量级服务器的优惠。价格非常的美丽:
阿里的轻量服务器.png

但是要注意的是,这个美丽的价格的镜像是WordPress,且有且仅有镜像是WordPress,如果更换一个系统的镜像,价格就会发生大变
配置后60一个月.png


2022.11.23更新
今天再次打开阿里云去查看后,发现依旧是在这种套路之下:
QQ截图20221123095338.png
1.png
大概也许可能是我找不到新客有优惠的入口吧hh
于是选择果断放弃阿里云


腾讯云:

关于腾讯云的购买,最好的购买的优惠渠道应该对于学生来说应该是----学生优惠
学生优惠入口链接
在学生优惠中,服务器大多是轻量级的服务器,基本的价格如下:
腾讯的学生轻量服务器.png
如果稍微配置一下的话,价格也并没有变化,相对较为良心
其实对于一个这种项目的量级一个轻量的就够用.png

接下来就去看一下华为云:

华为云

华为云有一个特色的产品:云耀HECS服务器,具体的介绍我也没看出与ECS服务器区别在哪,大体可能优势在于轻量化容易搭建。
滑到下面有一些关于华为云的秒杀活动,
QQ截图20221123103417.png

综合的这些配置来看,第二个1核2G的云服务器是完全够用的。可以将其考虑在内

华为云与腾讯云的产品的比较

选择的华为云的产品价格低,但是1核2G带宽1M,隔壁的腾讯云2核2G,带宽4M,价格贵30.

在这里就不得不说明一个原则了:所有的服务器里,不差钱优先选择阿里云,如果差钱,就在能够满足自己配置需求的情况下那个便宜买那个

本着这个项目以学习为目的,且以能用为基本要求,在综合考虑价格以及配置的情况下,最终决定选择华为云的轻量级服务器:
华为云服务器配置.png

最后要说明的是,对于一个项目来说,并不是一个服务器就一成不变了,随着线程的增加,流量的扩大,对服务器的需求也会不断的变化,当需求以及要求的配置不断的提升的时候,综合考虑性价比去选择最适合自己项目的服务器。