部署部署项目上线
星恒title:
date:
updated:
tags:
categories:
keywords:
description:
top_img:
comments:
cover:
toc:
toc_number:
toc_style_simple:
copyright:
copyright_author:
copyright_author_href:
copyright_url:
copyright_info:
mathjax:
katex:
aplayer:
highlight_shrink:
aside:
swiper_index: 1
top_group_index: 1
background: “#fff”


服务器准备
服务器购买与初始化
- 购买链接:https://cloud.tencent.com/act/pro/Featured?from=22872

其他平台也可以,总之就是购买轻量级服务器!
- 重置密码:

点击右上角重置密码,设置服务器“操作”密码
宝塔面板配置和使用
就是对服务器图形化界面,类似我们平时看到的电脑桌面。在面板上,我们可以更易安装,管理和使用一些环境(mysql,redis)。
- 服务器开放防火墙的宝塔端口8888
我们之后再服务器上安装的任何环境都需要将其的端口的防火墙打开
- 拿到宝塔面盘登录初值账号密码

在这里我们可以看到宝塔面板的界面浏览器地址,在浏览器上输入地址就可以访问<font style="color:rgba(0, 0, 0, 0.9);">http://106.54.227.250:8888/tencentcloud</font>
点击登录链接,即可跳转到命令行界面,输入sudo /etc/init.d/bt default,即可获得面板的初始账号和密码

- 访问地址,使用获取到的账号密码登录即可

- 进入后改一下账号和密码(用自己熟悉的,之后用的时候就方便了)

在服务器上安装我们需要的环境
node
- 点击安装,直接安装node

- 点即Node版本管理器,选择一个LTS(稳定版)安装即可

mysql
同理,点击弹出来的安装即可()
redis



第三方连接
用户名默认为:default
Java

maven

服务部署梳理
前端:http://ip
后端:http://ip/api,实际运行在8120端口
nginx:80端口(识别到api,然后转发到8120端口)
数据库:3306
redis:6379
java
maven
对象存储:第三方
前端部署


1 2 3
| location / { try_files $uri $uri/index.html /index.html; }
|
后端部署
后端部署上线真的是难啊,真的不简单
- 配置线上环境
**application-prod.yml**
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| # 线上配置文件 server: port: 8101 spring: # 数据库配置 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql: username: xingdada password: 123456 # Redis 配置 redis: database: 1 host: 106.54.227.250 port: 6379 password: redis # 分库分表配置(开源代码部署可忽略) shardingsphere: #数据源配置 datasource: # 多数据源以逗号隔开即可 names: xingdada xingdada: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql: username: xingdada password: 123456 # 规则配置 rules: sharding: # 分片算法配置 sharding-algorithms: # 自定义分片规则名 answer-table-inline: ## inline 类型是简单的配置文件里面就能写的类型,其他还有自定义类等等 type: INLINE props: algorithm-expression: user_answer_$->{appId % 2} tables: user_answer: actual-data-nodes: xingdada.user_answer_$->{0..1} # 分表策略 table-strategy: standard: sharding-column: appId sharding-algorithm-name: answer-table-inline mybatis-plus: configuration: # 生产环境关闭日志 log-impl: '' # 接口文档配置 knife4j: basic: enable: true username: root password: 123456 # AI配置 ai: apiKey: 318a5c7d0deb4350aa49b8acf98e7ae0.1Q2SDxDhWVS8vl07
|
- 打包
1)点击idea右侧边栏Maven,点击1按钮禁用测试(打包他会先将你的测试给运行),然后点击package打包即可
注:如果其中出现报错,不要着急,按照他的步骤一步一步改就行,大部分都是简单的文件/依赖多余的问题)

2)查看包位置

- 上传文件

将jar包拖入,然后点击上传按钮即可上传!

- 部署
1)点击左边栏网站按钮,然后点击左侧Java项目,接着点击添加Java项目



1 2
| /www/server/java/jdk1.8.0_371/bin/java -jar -Xmx512M -Xms256M /www/wwwroot/xingdada-backend-0.0.1-SNAPSHOT.jar --server.port=8101 --spring.profiles.active=prod
|
2)– 成功就不看这一步 –
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
| mysql -u root -p
DROP USER 'xingdada'@'localhost'; DROP USER 'xingdada'@'%';
CREATE USER 'xingdada'@'localhost' IDENTIFIED BY 'YourStrongPassword'; CREATE USER 'xingdada'@'%' IDENTIFIED BY 'YourStrongPassword';
GRANT ALL PRIVILEGES ON *.* TO 'xingdada'@'localhost' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON *.* TO 'xingdada'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
SELECT Host, User, Grant_priv FROM mysql.user WHERE User = 'xingdada'; # 权限检验:如果出现 Y ,即成功了 SHOW GRANTS FOR 'xingdada'@'localhost';
SELECT User, Host FROM mysql.user; mysql> SELECT User, Host FROM mysql.user WHERE User = 'xingdada'; +----------+-----------+ | User | Host | +----------+-----------+ | xingdada | % | | xingdada | localhost | +----------+-----------+
|
- 成功!



nginx

1 2 3 4 5 6 7 8
| location /api { proxy_pass http://127.0.0.1:8101; proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering off; proxy_set_header Connection ""; }
|

绑定域名
前端项目访问:
用户输入网址 => 域名解析服务器(把网址解析为ip地址/交给其他的域名解析服务) => 服务器 => nginx接受请求,找到对应的文件,返回文件给前端 => 前端加载文件 => 前端加载到浏览器 => 渲染页面
后端项目访问:
用户输入网址 => 防火墙 => 域名解析服务器 => 服务器 => 后端项目(8080端口)
前端绑定

后端绑定
nginx反向代理:替服务器接受请求,转发请求



跨域
浏览器为了用户的安全,仅允许同域名、同端口的服务器发送请求
解决方法:
- 把域名改成相同的
- 网关支持Nginx
让服务器告诉浏览器,允许跨域(返回cross-origin-allow响应头)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| location ^~ /api/ { proxy_pass http://127.0.0.1:8101/api/; add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Credentials' 'true'; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers '*'; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } }
|
- 修改后端服务
- 配置@CrossOrigin注解
- 添加web全局请求拦截器
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
| package com.xingheng.xingdada.config;
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/** * 全局跨域配置 * */ @Configuration public class CorsConfig implements WebMvcConfigurer {
@Override public void addCorsMappings(CorsRegistry registry) { // 覆盖所有请求 registry.addMapping("/**") // 允许发送 Cookie .allowCredentials(true) // 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突) .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .exposedHeaders("*"); } }
|
- 定义新的corsFilter Bean
数据库总是自动停止解决
1 2 3 4 5
| pgrep -x mysqld &> /dev/null if [ $? -ne 0 ];then bash /www/server/panel/script/rememory.sh /etc/init.d/mysqld start fi
|


106.54.227.250
不要的代码
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 29 30 31 32 33 34 35 36 37 38 39 40 41
| package com.xingheng.xingdada;
import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.xingheng.xingdada.model.entity.UserAnswer; import com.xingheng.xingdada.service.UserAnswerService; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest public class UserAnswerShardingTest {
@Resource private UserAnswerService userAnswerService;
@Test void test() {
UserAnswer userAnswer1 = new UserAnswer();
userAnswer1.setAppId(1L); userAnswer1.setUserId(1L); userAnswer1.setChoices("1"); userAnswerService.save(userAnswer1);
UserAnswer userAnswer2 = new UserAnswer(); userAnswer2.setAppId(2L); userAnswer2.setUserId(1L); userAnswer2.setChoices("2"); userAnswerService.save(userAnswer2);
UserAnswer userAnswerOne = userAnswerService.getOne(Wrappers.lambdaQuery(UserAnswer.class).eq(UserAnswer::getAppId, 1L)); System.out.println(JSONUtil.toJsonStr(userAnswerOne));
UserAnswer userAnswerTwo = userAnswerService.getOne(Wrappers.lambdaQuery(UserAnswer.class).eq(UserAnswer::getAppId, 2L)); System.out.println(JSONUtil.toJsonStr(userAnswerTwo)); } }
|
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 29 30 31 32
| package com.xingheng.xingdada;
import com.xingheng.xingdada.controller.QuestionController; import com.xingheng.xingdada.model.dto.question.AiGenerateQuestionRequest; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest public class QuestionControllerTest { @Resource private QuestionController questionController;
@Test void aiGenerateQuestionSSETest() throws InterruptedException { AiGenerateQuestionRequest aiGenerateQuestionRequest = new AiGenerateQuestionRequest(); aiGenerateQuestionRequest.setAppId(3L); aiGenerateQuestionRequest.setQuestionNumber(10); aiGenerateQuestionRequest.setOptionNumber(2);
questionController.aiGenerateQuestionSSETest(aiGenerateQuestionRequest, false); questionController.aiGenerateQuestionSSETest(aiGenerateQuestionRequest, false); questionController.aiGenerateQuestionSSETest(aiGenerateQuestionRequest, true);
Thread.sleep(1000000L); } }
|
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 29 30
| package com.xingheng.xingdada;
import io.reactivex.Flowable; import io.reactivex.schedulers.Schedulers; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.TimeUnit;
@SpringBootTest public class RxjavaTest { @Test public void test() throws InterruptedException { Flowable<Long> flowable = Flowable.interval(1, TimeUnit.SECONDS) .map(i -> +i) .subscribeOn(Schedulers.io());
flowable .observeOn(Schedulers.io()) .doOnNext(item -> System.out.println(item.toString())) .subscribe();
Thread.sleep(10000L); }
}
|
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package com.xingheng.xingdada;
import com.fasterxml.jackson.core.JsonProcessingException; import com.zhipu.oapi.ClientV4; import com.zhipu.oapi.Constants; import com.zhipu.oapi.service.v4.model.ChatCompletionRequest; import com.zhipu.oapi.service.v4.model.ChatMessage; import com.zhipu.oapi.service.v4.model.ChatMessageRole; import com.zhipu.oapi.service.v4.model.ModelApiResponse; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource; import java.util.ArrayList; import java.util.List;
@SpringBootTest public class ZhiPuAiTest { @Resource private ClientV4 clientV4; @Test public void test() {
List<ChatMessage> messages = new ArrayList<>(); ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), "作为一名营销专家,请为智谱开放平台创作一个吸引人的slogan"); messages.add(chatMessage);
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder() .model(Constants.ModelChatGLM4) .stream(Boolean.FALSE) .invokeMethod(Constants.invokeMethod) .messages(messages) .maxTokens(100) .build();
ModelApiResponse invokeModelApiResp = clientV4.invokeModelApi(chatCompletionRequest); System.out.println("model output:" + invokeModelApiResp.getData().getChoices().get(0)); } }
|
