# huaweicloud-go-quickstart-shop
**Repository Path**: HuaweiCloudDeveloper/huaweicloud-go-quickstart-shop
## Basic Information
- **Project Name**: huaweicloud-go-quickstart-shop
- **Description**: huaweicloud-go-quickstart-shop
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master-dev
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-10-31
- **Last Updated**: 2022-11-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# go-shop-demo
本项目是基于Gin+Gorm开发的一个基础商品订单功能的Go入门Web项目,采用前后端分离实现,并能在华为云上实现部署,帮助开发者实现基于Go的基础Web应用云上部署的一套经典流程。
## 1 Web项目说明
### 1.1 项目环境
- Go 1.16
- RDS for MySQL
- Goland\(推荐\)
- Node.js
- Git
### 1.2 技术选型
### 1.3 项目介绍
1. 项目代码结构目录
- app
- common:通用方法 error、middleware、db、config等。
- controller:api,参数校验。
- dto:接收参数模型
- service: 业务处理
- dao:数据库处理
- model:业务模型
- routers:路由初始化
- consts:枚举常量
- vue\_demo:前端项目
2. 项目架构

3. 项目业务模块功能
本项目中主要有三大接口模块,分别是用户模块,商品模块,订单模块
- 用户模块实现功能:注册登录功能
```
userGroup := r.Group("/user")
{
//注册
userGroup.POST("/register", controller.Register)
//登录
userGroup.POST("/login", controller.Login)
}
```
- 商品模块实现功能:商品添加,删除,展示
```
//商品相关
goodsGroup := r.Group("goods")
{
//商品添加
goodsGroup.POST("/add", controller.AddGoodser)
//商品列表
goodsGroup.GET("/list", controller.GetGoods)
//商品删除
goodsGroup.DELETE("/delete", controller.DeleteGoods)
//单个商品信息
goodsGroup.GET("/single", controller.GetSingleGoods)
}
```
- 订单模块实现功能:订单创建,删除,详情,支付
```
//订单相关
orderGroup := r.Group("/order")
{
//订单创建
orderGroup.POST("/add", controller.AddOrder)
//订单删除
orderGroup.DELETE("/delete", controller.DeleteOrder)
//订单详情
orderGroup.GET("/detail", controller.DetailOrder)
//订单支付
orderGroup.PUT("/pay", controller.Payer)
}
```
## 2 项目环境搭建
### 2.1 项目初始化
前提条件:本地安装如下环境
- [安装Git](http://git-scm.com/downloads)
- [安装Node.js](https://nodejs.org/zh-cn/download/)
安装完成后步骤
1. 执行如下命令,克隆项目到本地。
```
git clone https://codehub-dg-g.huawei.com/p30036525/go-shop-demo.git
```
2. 执行如下命令,打开项目并更新依赖。
```
go mod tidy
```
3. 修改前端IP代码
>**说明:**
>必须把图中白框的baseUrl修改为自己要部署的服务器IP。如http://Your IP:8080/
>
4. 执行如下命令,编译前端代码
1. 打开cmd窗口,进入vue\_demo目录下,执行如下命令,安装vue包
```
npm i --force
```
2. 执行如下编译命令,在当前目录生成dist目录,dist内部文件如下图
```
npm run build
```

### 2.2 前端的两种部署方式
在前端代码编译生成dist目录后,部署前端代码有两种方式
- GO后端加载静态文件
1. 把dist里的static目录移至app目录下,同时把index.html移至app目录的templates目录下
2. 根据静态文件路径添加的GO代码
```
//加载index.html文件
r.LoadHTMLFiles("./app/templates/index.html")
//映射静态文件路径
r.Static("/static", "./app/static")
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)
})
```
3. 后续参考[ECS+RDS部署](#ECS+RDS部署)
- Nginx部署前端代码
1. 将dist文件单独传入服务器
>**说明:**
>由于Nginx默认监听80端口,所以此时前端编译代码前将端口改为80。如http://Your IP:80/
>
2. 后续参考[ECS+RDS+Nginx部署](#ECS+RDS+Nginx部署)
## 3 ECS+RDS部署
云数据库 RDS是一种基于云计算平台的即开即用、稳定可靠、弹性伸缩、便捷管理的在线云数据库服务,ECS+RDS实现高可靠的部署方案。本节介绍如何将Go Web 应用部署到[华为云 ECS](https://www.huaweicloud.com/product/ecs.html)上,并采用[云数据库RDS](https://support.huaweicloud.com/rds/index.html),示例应用使用Go入门Web项目。
前提条件:[项目环境搭建](#项目环境搭建)
1. 购买华为云ECS
配置需要Linux操作系统。
具体购买过程请参考[购买并登录Linux弹性云服务器](https://support.huaweicloud.com/basics-ecs/ecs_01_0103.html)
2. 购买RDS for MySQL
具体购买过程请参考[购买实例](https://support.huaweicloud.com/qs-rds/rds_02_0008.html)
3. 连接RDS数据库并新建数据库
1. 采用[DAS连接](https://support.huaweicloud.com/qs-rds/rds_02_0007.html)RDS for MySQL并登录

2. 新建数据库,输入数据库名称,字符集选择utf8mb4

4. 修改配置文件并交叉编译上传
1. 修改项目的配置文件application.yml
```
port: "8080"
db:
name: "RDS的用户名"
password: "RDS的密码"
host: "RDS的内网地址"
port: "3306"
database: "test_goods"
```
2. 在windows平台上交叉编译项目,在当前目录生成go-shop-demo二进制文件
```
D:\go-shop-demo> go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64
D:\go-shop-demo> go build
```
3. 使用CloudShell上传文件到服务器,上传本地go-shop-demo项目文件夹到ECS的home目录
5. 部署项目
1. 执行如下命令,给二进制文件赋予权限
```
chmod -R 777 /home/go-shop-demo/go-shop-demo
```
2. 执行如下命令,在后台启动二进制go程序,并记录日志到app.log
```
nohup ./go-shop-demo > app.log 2>&1 &
```
3. 执行如下命令,查看日志,显示如图正常运行

```
cat app.log
```
4. 通过服务器公网ip调用接口进行访问,显示如图

## 4 ECS+RDS+Nginx部署
在需要负载均衡、多应用部署、前后端分离等场景下,我们可以搭配第三方的web服务器Nginx来部署我们的程序。本节介绍如何采用Nginx进行前后端分离部署到[华为云 ECS](https://www.huaweicloud.com/product/ecs.html)上,示例使用Go入门Web项目。
前提条件:[项目环境搭建](#项目环境搭建)
架构流程图:

1. 启动GO服务
参照[ECS+RDS部署](#ECS+RDS部署)
2. 单独上传前端编译目录dist到RDS的home目录下
3. 安装并启动Nginx
1. 执行如下命令,安装Nginx
```
yum -y install nginx
```
2. 执行如下命令,启动Nginx
```
systemctl enable nginx
systemctl start nginx
```
4. 修改Nginx配置
1. 执行如下命令,打开配置文件
```
vi /etc/nginx/nginx.conf
```
2. 默认监听80端口,将server模块设置为如下内容:
```
server {
listen 80;
server_name localhost;#本机ip
# 静态文件请求
location ~ .*\.(gif|jpg|jpeg|png|js|css|eot|ttf|woff|svg|otf)$ {
access_log off;
expires 1d;
root /home/dist; #前端打包文件目录
}
# index.html页面请求
# 因为是单页面应用这里使用 try_files 处理一下,避免刷新页面时出现404的问题
location / {
root /home/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
# 匹配域名后以user开头的请求,转发请求至http://localhost:8080/user
location ^~ /user {
proxy_pass http://localhost:8080/user;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 匹配域名后以goods开头的请求,转发请求至http://localhost:8080/goods
location ^~ /goods {
proxy_pass http://localhost:8080/goods;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 匹配域名后以order开头的请求,转发请求至http://localhost:8080/order
location ^~ /order {
proxy_pass http://localhost:8080/order;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
```
3. 执行如下命令,重启nginx
```
nginx -s reload
```
4. 输入公网ip访问页面

## 5 CCI+RDS部署
[华为云CCI](https://support.huaweicloud.com/cci/index.html)是基于Kubernetes的Serverless容器服务,兼容K8s和Docker原生接口。用户无需关注集群和服务器,简单配置即可快速创建容器负载,实现秒级计费
1. 参考[使用云容器实例](https://support.huaweicloud.com/qs-cci/cci_qs_0001.html)做准备工作
2. 将项目打包为tar.gz文件并上传到服务器
1. 本地压缩文件

2. 执行如下命令,解压文件到/var目录
```
tar -xzf /home/go-shop-demo.tar.gz -C /var
```
3. 参照[购买RDS for MySQL实例](https://support.huaweicloud.com/qs-rds/rds_02_0008.html),并修改数据库配置文件
1. 执行如下命令,打开配置文件
```
vi /var/go-shop-demo/application.yml
```
2. 将host修改为mysql的服务器ip地址
```
port: "8080"
db:
name: "RDS的用户名 "
password: "RDS的密码"
#修改为本地的私网ip
host: "your IP"
port: "3306"
database: "test_goods"
```
4. Dockerfile构建镜像并上镜像仓库
1. 参照[构建镜像并上传镜像仓库](https://support.huaweicloud.com/qs-cci/cci_qs_0003.html),采用下面Dockerfile文件构建镜像并上传:
```
FROM golang:1.16 as build-stage
WORKDIR /go-shop-demo
COPY . .
# 设置环境变量
RUN go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64
RUN go env -w GOPROXY=https://goproxy.cn,direct
RUN go mod tidy
# 编译go文件
RUN go build
FROM alpine as production-stage
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY --from=build-stage /go-shop-demo /go-shop-demo
WORKDIR /go-shop-demo
ENTRYPOINT ["./go-shop-demo"]
```
>**说明:**
>Dockerfile使用多阶段构建,减少镜像的大小
2. 执行如下命令,构建Docker镜像命令
```
cd /var/go-shop-demo
#镜像为go-shop-demo:v1
docker build --force-rm -t go-shop-demo:v1 .
```
5. 创建实例步骤参照[创建命名空间和负载](https://support.huaweicloud.com/qs-cci/cci_qs_0004.html)
6. [访问负载](https://support.huaweicloud.com/qs-cci/cci_qs_0006.html)
1. 在访问配置找到公网ip地址

2. 在浏览器中访问公网ip地址,显示如图

## 6 ECS+RDS+OBS+CDN\(静态网站托管)部署
[OBS](https://support.huaweicloud.com/obs/index.html)服务允许在桶上托管静态网站,支持索引页、错误页展示和页面跳转。您可以将静态网站文件上传至OBS的桶中,并对这些文件赋予匿名用户可读权限,然后将该桶配置成静态网站托管模式,就可以实现在OBS上托管静态网站了。
本项目采用OBS服务的静态网站托管并配置[CDN](https://support.huaweicloud.com/cdn/index.html)网站加速功能。
>**说明:**
>华为云对象存储服务OBS禁止通过OBS的默认域名使用静态网站托管功能,所以目前通过自定义域名使用静态网站托管功能。自定义域名需要提前完成[ICP备案](https://support.huaweicloud.com/qs-icp/icp_07_0002.html)。
架构流程图:

1. 客户在CDN控制台配置加速域名。
2. 终端用户通过浏览器发出请求数据,经DNS解析转向CDN节点。
3. CDN节点从OBS桶中拉取静态数据,OBS返回数据。
4. 另一终端用户访问同一数据,通过浏览器发出请求数据,经DNS解析转向CDN节点。
5. 经过上一终端用户的访问,CDN节点有缓存数据,直接返回所需数据至当前终端用户。
方案部署优势
- OBS安全、高可靠且低成本,可以节省存储费用。
- 通过分布在各个区域的CDN节点,将静态资源内容扩展到距离终端用户较近的地方,用户可以享受更加流畅的网站加载速度。
- 华为云CDN与华为云OBS通过内网连接,节省带宽费用。
部署步骤
1. 购买华为云资源
- 购买[华为云 ECS](https://www.huaweicloud.com/product/ecs.html)上,具体购买过程请参考[购买并登录Linux弹性云服务器](https://support.huaweicloud.com/basics-ecs/ecs_01_0103.html)
- 购买[云数据库RDS](https://support.huaweicloud.com/rds/index.html),具体购买过程请参考[购买实例](https://support.huaweicloud.com/qs-rds/rds_02_0008.html)
- 购买[对象存储服务OBS](https://support.huaweicloud.com/obs/index.html),具体购买过程请参考[快速入门](https://support.huaweicloud.com/qs-obs/obs_qs_1000.html),华为云提供[六种使用方式](https://support.huaweicloud.com/ugobs-obs/obs_41_0002.html)对OBS资源进行管理,本项目使用[控制台功能](https://support.huaweicloud.com/usermanual-obs/obs_03_0054.html)
2. 参照[项目初始化](项目初始化.md),准备前端静态资源和后端代码。
3. 部署后端代码
1. 连接RDS数据库并新建数据库,采用[DAS连接](https://support.huaweicloud.com/qs-rds/rds_02_0007.html)RDS for MySQL并登录

2. 新建数据库,输入数据库名称,字符集选择utf8mb4

3. 修改项目的配置文件application.yml
```
port: "8080"
db:
name: "RDS的用户名"
password: "RDS的密码"
host: "RDS的内网地址"
port: "3306"
database: "test_goods"
```
4. 在windows平台上交叉编译项目,在当前目录生成go-shop-demo二进制文件
```
D:\go-shop-demo> go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64
D:\go-shop-demo> go build
```
5. 使用CloudShell上传文件到服务器,上传本地go-shop-demo二进制文件到ECS的home目录
>**说明:**
>此处只须上传编译后的二进制文件,其他文件不需要上传至ECS
6. 执行如下命令,给二进制文件赋予权限
```
chmod -R 777 /home/go-shop-demo/go-shop-demo
```
7. 执行如下命令,在后台启动程序,并记录日志到app.log
```
nohup ./go-shop-demo > app.log 2>&1 &
```
8. 执行如下命令,查看日志,显示如图正常运行
```
cat app.log
```

4. 上传前端静态资源到OBS
1. [登录OBS管理控制台](https://support.huaweicloud.com/usermanual-obs/obs_03_0305.html)并[创建桶](https://support.huaweicloud.com/usermanual-obs/obs_03_0306.html),成功后如下图所示

>**说明:**
>创建桶需选择公共读选项,避免别人无法访问读取桶内资源。
2. 上传前端编译生成的dist目录里的文件到桶里,参考[上传文件](https://support.huaweicloud.com/usermanual-obs/obs_03_0307.html),结果如下图所示

5. 参考[配置静态网站托管](https://support.huaweicloud.com/usermanual-obs/zh-cn_topic_0045829093.html),将index.html配置为默认首页,如下图所示

6. 参考[绑定自定义域名](https://support.huaweicloud.com/usermanual-obs/obs_03_0032.html),该域名需要备案。左侧导航栏选择“域名管理”,单击“绑定用户域名”,绑定自定义域名到桶域名

7. 配置[CDN](https://support.huaweicloud.com/cdn/index.html)域名加速,CDN[快速入门](https://support.huaweicloud.com/qs-cdn/cdn_01_0072.html)
1. 返回到OBS域名管理处,点击“管理CDN加速”

2. 将需要加速的域名添加到CDN,添加成功后,点击设置,系统显示会为该域名分配对应的CNAME域名

8. 回源配置
1. 点击源站配置编辑,进入编辑页面,选择OBS桶域名,找到当前桶域名。
2. 勾选静态网站托管后,点击确定。

9. 登录CDN控制台的“域名管理”界面,在相应域名的“高级配置”中添加“Content-Disposition”响应头,取值为“inline”。

10. 配置CNAME解析
1. 登录华为云控制台,在控制台首页选择“网络 \> 云解析服务 DNS”,进入云解析服务页面
2. 在左侧菜单栏中,选择“公网域名”,进入域名列表页面
3. 待添加记录集的域名所在行,单击“域名”列的域名名称
4. 单击“添加记录集”,进入“添加记录集”页面,把CNAME域名添加到此处值

11. 验证CNAME配置是否生效,
1. 打开Windows操作系统中的cmd程序,输入如下指令:
```
nslookup -qt=cname 桶绑定的自定义域名
```
2. 开启CDN加速:如果回显CDN分配的CNAME域名,则表示CNAME配置已经生效

12. 输入自定义域名访问页面
