# dtse-practice
**Repository Path**: HuaweiCloudDeveloper/dtse-practice
## Basic Information
- **Project Name**: dtse-practice
- **Description**: 采用springboot 框架,集成华为云OBS和RDS,实现用户登陆、图片上传、更新等功能,并在云端部署,配置日志采集监控等内容。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: dev1
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 4
- **Forks**: 1
- **Created**: 2021-11-24
- **Last Updated**: 2022-08-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 基于华为云开发实战操作指导手册
---
## 实验目的
- 使用IDEA、Vscode开发工具,基于springboot、VUE.js框架开发和测试单元编写
- 能够集成 OBS-Java-SDK 和 RDS for MySQL 进行业务开发
- 了解用户鉴权、用户信息查询以及用户数据更新等业务实现逻辑
## 项目实战要求
- 在华为云上创建OBS桶 和 RDS for MySQ 并初始化数据库
- IDEA工具导入Springboot项目,集成 OBS SDK 和数据库RDS开发环境
- 查看华为云官方SDK文档,实现“OBSservice”类中 uploadOneFile 和 deleOneFile 方法
- 能够编写junit测试类,实现接口数据测试
- 使用VScode工具加载前端代码,输入用户名密码后,查看profile 图片,并修改图片
## 实战项目介绍
本实践是一个前后端分离的项目,通过集成华为云OBS Java SDK 和华为云RDS数据库,实现用户中心个人图片上传、更新功能。
#### 业务流程图

#### 部署架构图

#### 项目实战技术栈
本项目是一个前后端分离项目,涉及:
- 开发工具:后端开发工具 IntelliJ IDEA 、前端开发工具 VScode
- 开发技术栈:springboot 、vue.js 、jwt、mybatis-plus、OBS Java-SDK
- 应用部署技术栈:ECS、EIP 、 RDS(MySQL)、OBS、华为云CodeHub
- 运维技术栈:云日志服务 LTS
## 前置条件
- 已注册华为云账号,完成实名认证,同时账号不能处于欠费或冻结状态;
- 账户需有足够的余额或代金券;
- 工具安装:安装好IDEA以及VScode。
- 获取源代码:gitee上获取
## 创建并配置云端环境
#### 创建用户访问秘钥
- 登录华为云,进入控制台,点击用户名下“我的凭证”,点击访问秘钥,进入秘钥管理界面,点击新建访问秘钥。

- 新建秘钥后下载在本地,后续可继续进行使用。
- 参考:https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html?utm_campaign=ua&utm_content=ca&utm_term=console
#### 创建OBS桶
- 登录华为云,进入控制台,进入OBS管理界面,点击“创建桶”按钮,进入创建界面。

- 参数配置:
存储策略:标准存储;
桶策略:公共读写;
其余参数可自定义输入。
- 参考:https://support.huaweicloud.com/usermanual-obs/zh-cn_topic_0045829088.html
#### 创建RDS数据库
- 登录华为云,进入控制台,进入RDS管理界面,点击“购买数据库实例”,进入创建界面。

- 参数配置:
计费模式,数据库引擎,数据库版本,实例类型,规格参数等根据个人需求进行选择;
- 参考:https://support.huaweicloud.com/qs-rds/rds_02_0008.html
#### 数据库配置公网IP
- 登录华为云,进入控制台,进入EIP管理界面,点击“购买弹性公网IP”,进入创建界面。

- 参数配置:
区域:选择与RDS同一个区域;其他参数根据个人需求进行选择;
- 参考:https://support.huaweicloud.com/usermanual-eip/eip_0008.html
- 数据库配置公网IP,进入数据库详情界面,点击“连接管理”,进入连接管理控制台,点击“绑定”按钮,选择新建的EIP;

- 参考:https://support.huaweicloud.com/qs-rds/rds_02_0025.html
## 后端代码调试
### 代码调试
#### pom.xml 配置OBS SDK、MySQL驱动等依赖
```
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.7.RELEASE
org.example
obs-sdk
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
org.springframework.boot
spring-boot-starter-data-jpa
mysql //数据库依赖
mysql-connector-java
com.baomidou //mybatis
mybatis-plus-boot-starter
3.3.1
com.huaweicloud //OBS SDK
esdk-obs-java-bundle
[3.21.8,)
org.projectlombok
lombok
com.fasterxml.jackson.core
jackson-annotations
2.10.0
io.jsonwebtoken
jjwt-api
0.11.2
io.jsonwebtoken
jjwt-impl
0.11.2
runtime
io.jsonwebtoken
jjwt-jackson
0.11.2
runtime
org.springframework.boot
spring-boot-configuration-processor
true
com.google.code.findbugs
annotations
3.0.1
org.springframework.boot
spring-boot-maven-plugin
org.apache.maven.plugins
maven-javadoc-plugin
3.0.0
```
#### 修改配置项
```
server:
port: 9090 #服务端口
spring:
application:
name: dtse-practice-demo
#数据库配置参数
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://IP(数据库绑定的公网IP):3306/dtse?useUnicode=true&characterEncoding=utf8 #数据库连接地址
username: root
password: ************** #数据库密码
jpa:
open-in-view: off
security:
oauth2:
resourceserver:
jwt:
issuer-uri:
logging:
level:
root: info
com.huaweicloud: debug
jwt:
config:
ttl: 360000
##OBS 配置信息
obs:
config:
bucketname: ***** ##OBS桶名称
#objectname: dtsetraining/Dtest
endPoint: https://obs.cn-north-4.myhuaweicloud.com ##访问桶,概述页面获取
ak: **** ##访问秘钥AK
sk: **** ##访问秘钥SK
```
#### 实现OBSService类的 uploadOneFile 和 deleteOneFile 方法
```
package com.huaweicloud.dtse.service;
import com.huaweicloud.commons.config.OBSParams;
import com.huaweicloud.commons.response.Result;
import com.huaweicloud.commons.response.ResultCode;
import com.huaweicloud.dtse.service.impl.IOBSService;
import com.obs.services.ObsClient;
import com.obs.services.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/**
* OBS service接口
*/
@Service
public class OBSService implements IOBSService {
@Autowired
OBSParams obsParams;
/**
* @param inputStream 上传至OBS数据流参数
* @return 返回存入OBS请求参数
*/
@Override
public String uploadOneFile(InputStream inputStream) {
//1、从obsParams中获取OBS 访问配置参数
String endPoint = obsParams.getEndPoint();
String ak = obsParams.getAk();
String sk = obsParams.getSk();
String bucketname = obsParams.getBucketname();
String objectname = obsParams.getObjectname();
//2、创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
//3、使用obsClient 的putObject方法,将数据存储至对象存储 OBS
PutObjectResult putObjectResult = obsClient.putObject(bucketname, objectname, inputStream);
return putObjectResult.getObjectUrl();
}
/**
* @param deleobjectname 需要删除对象的请求参数
* @return 返回删除状态
*/
@Override
public Result deleteOneFile(String deleobjectname) {
//1、从obsParams中获取OBS 访问配置参数
String endPoint = obsParams.getEndPoint();
String ak = obsParams.getAk();
String sk = obsParams.getSk();
String bucketname = obsParams.getBucketname();
//2、创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
//3、使用obsClient 的deleteObject方法,删除OBS中对象
try {
obsClient.deleteObject(bucketname, URLDecoder.decode(deleobjectname, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new Result(ResultCode.SUCCESS);
}
}
```
#### Test类,初始化数据
```
package com.huaweicloud;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.huaweicloud.commons.pojo.User;
import com.huaweicloud.dtse.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest()
public class test {
User user = new User();
@Autowired
private UserService userService;
@Test
public void saveUser() {
//1、初始化对象参数
String id = (String) IdWorker.getIdStr();
String mobile = "15927356938";
String username = "dtse";
String password = "dtse";
user.setId(id);
user.setMobile(mobile);
user.setUsername(username);
user.setPassword(password);
//2、调用UserService 的save方法保存对象至数据库中。
userService.save(user);
}
}
```
### 项目打包
- IDEA项目打包

- 项目目录target查看生成的jar包

### 项目部署
- jar包上传到服务器

- 运行jar包

## 前端服务调试
### 项目导入以及参数配置
点击 :point_right: **[前端代码获取](https://gitee.com/DTSEDeveloper/dtse-practice-frontEnd/tree/dev/)**
- 下载插件 npm install

- 修改后端服务配置,修改文件 /project/vue.conf.js
```
let proxyObj = {}
proxyObj['/'] = {
//websocket
ws:false,
//目标地址
target:'http://IP:9090', //后端服务地址
//发送请求头中host会设置成target
changeOrigin:true,
//不重写请求地址
pathRewrite:{
'^/':'/'
}
}
module.exports = {
devServer:{
host:'localhost',
port:8080,
proxy:proxyObj
}
}
```
- 修改后端文件上传接口配置,修改文件 /project/src/views/profile.vue
```
点击上传
```
### 项目打包
- VScode执行命令 npm run build

- 打包成功

### 项目部署
- 静态资源包上传

- 安装 nginx 并进行配置
```
user root;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 8080; //前端访问端口
listen [::]:8080;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / { //前端静态资源配置
root /root/dist;
index index.html;
}
location /login { //后端路由配置
proxy_pass http://localhost:9090;
}
location /profile { //后端路由配置
proxy_pass http://localhost:9090;
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
```

## LTS日志接入
#### 配置LTS
- 登录华为云,进入控制台,进入LTS管理界面,进入“日志接入”模块,点击“接入日志”按钮选择主机接入,进入配置界面。

- LTS-step1 选择日志组以及日志流 (若不存在主机组以及日志流,点击新建即可)

- LTS-step2 新建主机组,主机安装 ICagent 后选择主机并进行下一步


- LTS-step3 日志采集配置,当前采集nginx 日志为例,配置完成点击提交即可

- 参考:https://support.huaweicloud.com/usermanual-lts/lts_04_1031.html
#### LTS 日志查看
- 控制台进入日志管理界面,点击对应的日志组以及日志流查看原始日志以及实时日志。


#### LTS日志转储
- 控制台进入日志转储界面,选择转储对象后点击配置转储

- 参考:https://support.huaweicloud.com/usermanual-lts/lts_04_0041.html
- 查看转储
