DinosaurStore

Dinosaur Store

恐龙商城是一个B2C模式的电商平台,销售自营商品给客户。

-.png

介绍

1 微服务

把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程,并使用轻量级通信机制(通常是HTTP API)。

2 集群&分布式

集群是个物理形态,分布式(多个业务运行在不同的机器,所有业务构成一个大型的业务)是个工作方式。

3 远程调用(RPC)

分布式系统中,各个服务可能处于不同的主机,但是服务之间不可避免相互调用。 (?Java PRC的dubbo是不是也是呢?注册中心)

SpringCloud中使用HTTP+JSON的方式完成远程调用,比如订单服务给商品模块发送HTTP请求。

4 负载均衡

不能让每一台服务器太忙或者太闲。

轮询

最小连接

散列

5 服务注册/发现&注册中心

A调用B,但是A不知道B服务当前有多少台,那些正常,所以引入注册中心。

dubbo这个Java RPC框架使用zookeeper注册中心

6 配置中心

每个服务可能部署在多机器,让每个服务从配置中心中获取自己的配置。

7 服务熔断&服务降级

服务之间依赖,一个不可用,导致其他的可能也不可用。

熔断:设置服务超时时间,若经常超时到达某个阈值,开启短路,就其他服务不在调用这个服务。

降级:整体把控,高峰,资源紧张期间,让非核心业务降级,简单处理,返回null,返回异常等等

8 API网关

整体架构的重要组件,抽象了微服务中都需要的公共功能,同时提供了客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流控制,日志统计等丰富的功能,帮助我们解决很多API管理难题。

整体服务框架

-.png

项目中的数据表,都没有使用外建,因为数据量很大,每添加,删除都要检查外建太麻烦了。

每一个微服务有自己的数据库注意是单独的数据库,不是单独的表。

管理系统的前后端,使用了码云上的人人开源,在vscode中运行npm install升级的时候,会有错误,所以我尝试使用了tyarn

1
2
tyarn install
tyarn run dev

逆向工程开发(根据数据库,开发出他的代码),也使用人人上的代码。

分布式系统搭建,SpringCloud

此处使用SpringCloud Alibaba

Spring Cloud Alibaba

alibaba/spring-cloud-alibaba

Screen-Shot-2022-06-23-at-12.22.52.png

Mysql

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
# 先创建
mkdir -p /mydata/mysql/conf.d
# 在创建文件
vim /mydata/mysql/conf.d/my.cnf
[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
default-time_zone = '+8:00'

# 注意,上面的文件也可以先随便创建一个容器,然后从里面拿出来文件,然后再进行下面的挂载
# 不过要知道的是,首先要知道这些配置文件在容器的哪里

docker run -p 3306:3306 \
--name mysql \
--privileged=true \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf.d:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=971707 \
--restart=always \
-d mysql:5.7

Nacos Server

nacos注册中心服务器

Spring Cloud Alibaba Nacos Discovery

可以使用docker启动

1
2
3
4
5
6
7
8
9
sudo docker run --restart=always -e MODE=standalone --name nacos-test -p 8848:8848 -d nacos/nacos-server:2.0.3
# 账号密码都是nacos

http://124.222.48.192:8848/nacos

# 在Docker容器退出时,默认容器内部的文件系统仍然被保留,以方便调试并保留用户数据。
# 因此,可以通过--rm命令,让容器在退出时,自动清除挂在的卷,以便清除数据

# 通过命令lsof -i:8443 查看占用端口号的进程号

然后application.yml中配置

需要有该服务的应用名字

Nacos配置中心

Spring Cloud Alibaba Nacos Config

需要在bootstrap.properties中配置,这个配置文件优先于application.tml文件。

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
/**
* 如何使用nacos作为配置中心
*
* 1 引入依赖
*
* 2 创建bootstrap.properties,1当前应用名字,2配置中心服务器地址
*
* 3 在配置中心中添加一个默认的数据集(DataID)DinosaurStore-coupon.properties,
* 默认规则,应用名.properties(本地跟配置中心的,优先使用配置中心)
* 4 给 应用名.properties添加任何配置
* 5 动态获取并刷新配置 @RefreshScope @Value("${配置项的名字}")
*
* 二、细节
* 1 命名空间:做配置隔离
* 默认public(保留空间)
* 1、开发,测试,生产环境。所以可以创建新的名称空间,比如test、dev、prod
* 然后bootstrap.properties中配置需要使用哪个命名空间下的配置
* spring.cloud.nacos.config.namespace=6b0baddd-4fa5-4e72-8586-3477d5dd0b8b
* 2、每一个微服务之间互相隔离配置,每一个微服务创建一个自己的命名空间只加载自己命名空间下的配置文件
* 2 配置集:所有的配置的集合
* 3 配置集ID:类似于配置文件名,即:应用名.properties
* 4 配置分组
* 默认所有的配置集都属于:DEFAUL_TGOURP
* 比如,双十一、双十二的时候,分别用不同的组名
* 使用的时候,在bootstrap.properties中加入spring.cloud.nacos.config.group=group名字
*/

整体使用:每个微服务创建自己的命名空间,使用配置分组区分环境,dev、test、prop

Open Feign

一个声明式的HTTP客户端

会员服务(里面引入openfeign,那么就有远程调用别的服务的能力)先从注册中心看优惠券服务在哪几台机器,然后注册中心返回在的机器,然后会员服务从里面挑一台,发送请求。

1
2
3
4
5
6
7
8
9
/**
* openfeign
* 远程调用别的服务
*
* 1.引入openfeign
* 2.编写一个接口,告诉SpringCloud这个接口需要调用远程服务(见feign包下的service代码,首先@FeignClient中的回去注册中心找,然后找里面的方法)
* 声明借口的每一个方法都是调用哪个远程服务的哪个请求
* 3. 开启远程调用功能@EnableFeignClients,然后指定远程调用服务的接口在哪个包里面(此处在feign下)
*/

网关

Spring Cloud Gateway

路由:ID,目的地,集合filters

断言:让开发人员匹配当次请求的任何信息。断言成功,就能到达目的地。

过滤器:请求或者相应都可以被修改,在请求抵达目标或者请求到达响应之后。

请求到达网关,网关利用断言判断这次请求是否符合某个路有规则,若符合,则按照路有规则路由到指定地方,但是到达前需要经过一系列过滤器。

SpringCloud的Gateway,是所有请求的入口

1 比如,同一个服务,一个机器挂了,改到另一个机器;一个状态改到另一个状态;端口改到另一个端口。

所以,给任何服务发送的请求,都先发送给网关,然后动态路由到指定位置。

2 每一个请求过来,可能要加权限,限流,日志输出,把功能加载每个服务上,太多

注意

要让网关转发的服务,需要在注册中心中注册,然后uri的时候写在注册中心注册的应用名,如下面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
spring:
cloud:
gateway:
routes:
- id: baidu_route
uri: https://www.baidu.com
predicates:
- Query=url, baidu
- id: qq_route
uri: https://www.qq.com
predicates:
- Query=url, qq

- id: admin_route
# 注意,下面这个lb是负载均衡的意思,后面的那个是去注册中心找的
uri: lb://DinosaurStore-renrenfast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}

比如 http://localhost:88/api/asdasd.jpg 先到(uri作用) http://DinosaurStore-renrenfast:8080/api/asdasd.jpg (这个8080是在注册中心找到该应用名的服务然后写上去的,此处的DinosaurStore-renrenfast也会变成该应用注册的ip的吧?) 再到(filter)http://DinosaurStore-renrenfast:8080/renren-fast/asdasd.jpg

前端

Screen-Shot-2022-06-24-at-08.51.59.png

ES6

ECMAScript6.0是浏览器语言的规范、标准,而js是实现。好比jdbc是标准,mysql是实现。

Vue

MVVM

M:Model,模型,包含数据和一些基本操作

V:View,视图,渲染结果

VM:ViewModel,模型与视图之间的双向操作(无需开发人员干预)

  • 只要model发生改变,view上自然表现出来(VM中封装的一些指令操作,自动的改View界面
  • 视图界面比如表单等内容改变,自动到Model中(View中的DOM Listeners自动监听)

Vue

Vue很强大,也有计算属性,和监听(监控一个数值的变化,从而做出相应的反应,swift里面类似的语法)

组件化

页面可以划分成很多部分,不同页面也会有相同的部分,比如相同的头部导航。所以吧页面的不同部分拆分成独立的组建,然后在不同的页面就能够共享这些组件,避免重复开发。

DOM

(Document Object Model文档对象模型),网页中的用来表示文档中对象的标准模型,通过javascript可以对网页中的所有DOM对象进行操作。

IMG_52600B450F20-1.jpg

IMG_7F7DD77281F7-1.jpg

IMG_FA4459E5E175-1.jpg

Element-ui

是一款vue的组件库,一套为开发者、设计师和产品经理准备的基于Vue2.0的桌面端组件库。比如单选框、多选框等很多组件。

IMG_5EAC21F6555D-1.jpg

导入其他的组件库,使用也是类似

Babel

是一个js编译器,可以使用es的最新语法变成,而不用担心浏览器兼容问题,它会自动转化为浏览器兼容的代码。

Webpack

自动化项目构建工具。gulp也是同类产品。

后台管理系统项目

跨域

浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的。同源策略,指协议,域名,端口都要相同,其中有一个不能就会产生跨域。

注意,带src属性的资源不受跨域限制,比如图片验证码等等。简单请求跨域也没关系。

Screen-Shot-2022-06-24-at-22.44.14.png

解决跨域

  1. 使用nginx转化为同一个域。

Screen-Shot-2022-06-24-at-22.47.22.png

  1. 服务器告诉他,能跨域
Screen-Shot-2022-06-24-at-22.49.10.png

前端vue的增删改查和后台的增删改查,都可以逆向生成,人人工程。

OSS

把图片先传给后台,后台再传到OSS,这样做带宽占用太大。

1
2
3
4
5
/**
* 1 引入oss的client
* 2 配置key,endpoint等相关信息
* 3 使用OSSClient进行相关操作
*/

所以考虑:用户向应用服务器请求上传policy,应用服务器给出签名数据,然后用户直接上传数据到OSS

关于校验

在前端,表单输入的数据需要进行校验,不能为空,只能首字母等等,

但是在后端还是要继续校验的,因为如果绕过前端,直接提交,就会出问题了呀,比如使用postman

此处前端校验,使用的是Vue中的功能 validator验证器件。

此处,后端校验,使用的是JSR303

关于抛出异常

可以使用一个controller来处理所有的异常,这个时候抛出的错误code(不只是404这种)是什么意思就很重要了(公司文档统一规定)。

状态码写成枚举类型,放在common的BizCodeEnum枚举中。

Screen-Shot-2022-06-26-at-20.31.12.png

@ControllerAdvice可以集中处理所有异常。

@Slf4j记录日志,就可以使用log.err()来进行打印了。

java中for、foreach、stream性能比较

最终总结:如果数据在1万以内的话,for循环效率高于foreach和stream;如果数据量在10万的时候,stream效率最高,其次是foreach,最后是for。另外需要注意的是如果数据达到100万的话,parallelStream异步并行处理效率最高,高于foreach和for。

各个微服务功能

前端:使用Vue框架,使用的是renrenfast-ui这个基础框架

后端:

每一个微服务都可以独立部署,运行,升级,独立自治(数据库、技术、架构、业务等都自治)

​ 1、 renren-fast:提供登录、sidebar侧边栏的增删改、账户管理等一些基础服务

​ 2、store-third-party:提供OSSpolicy签名、

​ 3、store-common:提供一些公共服务,其他微服务会依赖该服务,比如配置中心、注册中心、mysql驱动、lombok等等,校验分组的组别,异常枚举类

​ 4、store-product:商品的三级分类(增删改、拖动等等)、品牌管理(OSS图片上传、后台数据校验)、发布商品、商品维护、商品规格维护等等。

​ SPU商品、SKU商品规格(比如不同颜色,不同之间内存的组合),一个spuid下可能有多个sku,然后根据spuid的到的attrlist是一个list,每一个sku对应一个list,每一个list里面有该sku的attr。

​ 5、store-ware:商品库存,商品采购,采购单入库,添加到库存。比如,添加采购需求,然后添加采购单(关联人员),然后采购单和采购需求相关联,关联分配后人员在自己的手机app上领取该采购需求和采购单。(采购单一旦领取,采购需求就不能再重新分配了),采购完成后,采购人员在自己的app上点击完成。 此处采购人员点击领取(采购单变成已领取,采购项目变成正在购买),采购人员点击完成(采购单完成,勾选了的采购项目显示完成),这两个任务由postman模拟实现,后台都是实现了的。代码中PurchaseDetailEntity是采购项,采购需求;PurchaseEntity是采购单,里面包含了多个采购项目。

​ 6、store-search:主要是对es进行操作,将数据存放到es中,从里面查询等等,目前实现的是,将如果商品上架,那么将商品存储到es中去。

基础课程总结

分布式基础课

微服务

注册中心,Nacos,放在application.yaml,商品服务可能要调用会员服务以及库存服务等等,所以需要注册中心,而且网关转发的时候,也是指定服务的注册应用名字。 在应用程序上加上@EnableDiscoveryClient。

配置中心,Nacos,放在bootstra.properties,在线上可以直接更改配置文件,而不用重新运行代码

远程调用,使用OpenFeign实现,此处的远程调用,是本服务使用feign给其他服务发送一个远程调用(),首先要开启远程调用(被调用的服务注册到注册中心),导入feign的依赖,开启远程调用功能@EnableFeighClients(basePackages=这里写那个被调用的服务的接口包(里面的每一个类指定那个服务的哪个接口方法,接口上面@FeignClient(“应用名”),里面写被调用服务的controller的方法接口))。

网关,application.yaml中配置路有规则,还有网关出统一的配置,跨域解决。

基础开发

SpringBoot2.0、SpringCloud(开启服务的注册发现,开启feign的远程调用以及接口编写)、Mybatis-Plus(配置简单的包扫描@MapperScan等等)、Vue组件化、阿里云OSS对象存储(第三方使用:申请开通、拿到权限、调用人家的SDK)

环境

Vagrant(快速创建启动虚拟机)、Linux、Docker、MySQL、Redis、逆向工程&人人开源

开发规范

1 数据校验JSR303、全局异常处理(写在store-product中的@RestControllerAdvice(basePackages = “com.jcwang.store.product.controller”))、全局统一返回(R对象)、全局跨域处理(网关中)

2 枚举状态(全部在common中)、业务状态码、VO与TO与PO的划分、逻辑删除@TableLogic(value = “1”, delval = “0”),0表示删除

3 Lombok中,@Data自动生成getset方法,@Slf4j后log.error()就能用了;

还有如果要mysql中的语句进行打印,

1
2
3
logging:
level:
com.jcwang.store: debug

Elasticsearch

分布式的开源搜索和分析引擎,(MySQL CRUD好,但是搜索在大数据下还是承受不了的)

  • 分布式的实时文件存储,每个字段都被索引并可被搜索

  • 分布式的实时分析搜索引擎–做不规则查询

  • 可以扩展到上百台服务器,处理PB级结构化或非结构化数据

Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

ES是存储在内存中的。

某个 索引 下, 某种 类型 的一个文档,文档是JSON格式的 ,属性

某个 数据库 下, 某个 的一行**数据 **

Screen-Shot-2022-06-28-at-10.13.47.png

倒排索引

先将整个句子拆分为单词,然后维护 哪个单词哪些记录 里面有。搜索得到之后按照得分概念排序返回,该搜索的几个单词总共命中多少个记录。

全文检索字段用 match其他非 text 字段匹配用 term

分词器,比如,whitespace tokenizer 遇到空白字符时分割文本。要分中文,需要自己安装一个ik分词器。

ik分词器

analyzer”: “ik_smart” analyzer”: “ik_max_word”,

1
2
3
4
5
6
7
8
9
sudo docker exec -it d18aaabceba2 /bin/bash
cd plugins

cd /mydata/elasticsearch/plugins # 由于自己-v映射了文件,所以在外面操作即可,不需要再进入容器里面
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
sudo unzip elasticsearch-analysis-ik-7.4.2.zip
rm –rf *.zip
sudo chmod -R 777 ik/
sudo docker restart d18aaabceba2

安装

elasticsearch:7.4.2

kibana:7.4.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
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
sudo mkdir -p /mydata/elasticsearch/config 
sudo mkdir -p /mydata/elasticsearch/data
sudo echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml


sudo chmod -R 777 /mydata/elasticsearch/

sudo docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
--restart=always \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2

docker logs elasticsearch # 可以查看容器的日志

http://124.222.48.192:9200 # 下面可访问


sudo docker run --name kibana -e ELASTICSEARCH_HOSTS=http://124.222.48.192:9200 -p 5601:5601 \
-d kibana:7.4.2


# 如果一开始没有写开机自动启动,那么
sudo docker update adwqrqwrqw --restart=always


# 安装nginx,为了给ik可以访问到并使用最新的自定义的词库
sudo mkdir -p /mydata/nginx/conf
cd /mydata/nginx/conf
sudo docker container cp nginx:/etc/nginx . # 首先随便启动一个,为了拿到里面的配置

sudo docker run -p 80:80 --name nginx \
--restart=always \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
sudo docker update 4838c6db7b2b --restart=always
#然后
cd /mydata/nginx/html
vim index.html
mkdir es
cd es
vim fenci.txt
# 可访问 http://124.222.48.192/es/fenci.txt
# 然后配置elasticsearch
cd /mydata/elasticsearch/plugins/ik/config
sudo vim /mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml
# 重启es


sudo docker run -p 80:80 --name nginx \
-v /Users/dinosaur/mydockerdata/nginx/html:/usr/share/nginx/html \
-v /Users/dinosaur/mydockerdata/nginx/logs:/var/log/nginx \
-v /Users/dinosaur/mydockerdata/nginx/conf:/etc/nginx \
-d nginx:1.10

PUT和POST区别是,PUT一定要带id,而POST可以不带,自动生成唯一的id。

GET是查询,其中有一个愿数据“_seq_no”,是给乐观锁用的,若一样,这次才修改。修改完之后 _seq_no+1,我们存储的数据在元数据” _source”下面。

1
http://124.222.48.192:9200/customer/external/2?if_seq_no=3&if_primary_term=1

前端访问页面项目

之前的后台管理系统,是Vue前端,所以做到了 前后端分离

搭建域名访问环境

此处前台网页使用了nginx的渲染

nginx作为反向代理(另外的功能有负载均衡,还有前面的ik分词器),反向代理给网关,网关的好处是可以做统一鉴权认证以及限流工作等等

而加上nginx之后,每一个微服务自己里面的页面,页面需要的静态资源,可以都搬家到nginx里面,做到了部署期间的 动静分离。静态资源(图片,js,css等以实际文件存在的方式)直接由nginx返回,而动态请求发送给微服务拿到动态资源。

正向代理:如科学上网,隐藏客户端的信息,就是被访问到的服务器看到的我的信息是代理的信息。

反向代理:屏蔽内网服务器信息,也就是屏蔽了运行微服务的服务器信息,负载均衡访问。请求商城的时候先来到nginx,由nginx转交给后台对应的服务集群。

Screen-Shot-2022-06-29-at-20.13.20.png

注意,下面的操作我是在macOS下做的

1 更改本地hosts,让它知道域名

1
2
3
4
5
6
7
8
9
10
sudo vim  /etc/hosts
# 注意,下面是为了项目,我自己写的
124.222.48.192 zijifuwuqi
127.0.0.1 dinosaurstore.com
127.0.0.1 search.dinosaurstore.com
127.0.0.1 item.dinosaurstore.com
127.0.0.1 auth.dinosaurstore.com
127.0.0.1 cart.dinosaurstore.com
127.0.0.1 order.dinosaurstore.com
127.0.0.1 member.dinosaurstore.com
Screen-Shot-2022-06-29-at-20.14.35.png

2 docker安装nginx,配置反向代理

2.1 在/Users/dinosaur/mydockerdata/nginx/conf/nginx.conf加入上游服务器,指定有多少

1
2
3
4
5
http {    
upstream dinosaurstore {
server 192.168.1.102:88; # 反向代理到DinosaurStore-gateway网关
}
}

2.2 然后写/Users/dinosaur/mydockerdata/nginx/conf/conf.d/dinosaurstore.conf文件,使得nginx进行反向代理

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name dinosaurstore.com;

location / {
proxy_set_header Host $host;
proxy_pass http://dinosaurstore; # 总配置文件里面配置了上游服务器地址upstream,所以此处写这个即可
}
}
Screen-Shot-2022-06-29-at-20.59.14.png

3 在store-gateway中的application.yaml配置网关的路由规则

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
# 注意,这一条,需要放到最后面,不然的话,前面的也会被匹配走,以至于访问不到下面的子域名
- id: admin_route
# 注意,下面这个lb是负载均衡的意思,后面的那个是去注册中心找的
uri: lb://DinosaurStore-product
predicates:
- Host=**.dinosaurstore.com

压力测试(压测)

postman用来测试服务。

jmeter用来做性能测试。

jconsole 堆内存的监控、CPU占用率等等。

jvisualvm一样,可以下载插件,查看GC。

Screen-Shot-2022-06-29-at-23.26.58.png

优化问题

thyemeleaf开缓存,给数据库加索引,多次查询变一次批量查询,redis缓存,es检索,动静分离静态资源直接从nginx中拿到,若多了从nginx到网关再到tomcat这两步也会增加响应时间。

动静分离

首先将idea中的static下面的放到nginx的html/static下面,然后修改idea中的index中的一些资源的路径(加上/static/)

然后配置nginx,让访问的静态资源,都到nginx自己的目录下面找。就是跟反向代理一样的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name dinosaurstore.com;

location /static/ {
root /usr/share/nginx/html; # 注意,因为用的是docker运行nginx并且挂在到外面的文件,所以只需要写容器里面的html的路径即可
# root /Users/dinosaur/mydockerdata/nginx/html; # root表示所有的资源都去这里面找,而不是反向代理到网关去找了
}

location / {
proxy_set_header Host $host;
proxy_pass http://dinosaurstore; # 总配置文件里面配置了上游服务器地址upstream,所以此处写这个即可
}
}

Author: Jcwang

Permalink: http://example.com/2022/06/22/%E9%A1%B9%E7%9B%AEDinosaurStore/