文章目录
- 一,通过域名访问商城架构设计
- 二,配置
- 三,记录2个问题
-
- 1,网关路由匹配实现
- 2,网关路由配置前后顺序导致的问题
- [3,nginx.conf upstream配置缺少端口](#3,nginx.conf upstream配置缺少端口)
一,通过域名访问商城架构设计
1,为什么nginx要将请求转发给网关
上一节实现通过Nignx将域名gulimall.com的请求直接转发给产品服务,这样的设计有比较大的缺陷:
- 管理复杂性:如果需要更改服务的路由规则或负载均衡策略,可能需要在多个地方更新配置。
- 安全性风险:直接暴露服务的IP地址可能会增加安全风险。
更好的方式是nginx将请求转发给网关,由网关实现路由转发和负载均衡。转发给网关的优势如下:
- 统一入口:Nginx作为反向代理服务器,提供了一个统一的入口点,所有外部请求首先到达Nginx。
- 安全性:隐藏了后端服务的真实IP地址,增加了系统的安全性。
- 灵活性:可以在Nginx层面进行请求的路由、负载均衡、SSL终端等操作。
- 可扩展性:易于添加新的服务或修改现有服务的路由规则,而不需要更改客户端的访问方式。
2,架构设计
根据图片,当我们在浏览器输入gulimall.com
,nginx将这个请求转发给网关,原理如下:
-
本地DNS解析(hosts文件):
- 在Windows系统的hosts文件中配置域名与虚拟机IP的映射关系。例如,
gulimall.com
、search.gulimall.com
、item.gulimall.com
和member.gulimall.com
都被指向同一个虚拟机IP地址。这样,当在浏览器中输入这些域名时,系统会将它们解析到指定的虚拟机IP。
- 在Windows系统的hosts文件中配置域名与虚拟机IP的映射关系。例如,
-
Nginx作为网关:
- Nginx被配置为一个网关,用于接收来自上述域名的所有请求。
-
server块配置:
- 在Nginx配置中,定义了一个server块来监听域名
gulimall.com
的80端口。这意味着所有HTTP请求都会首先到达这个server块。
- 在Nginx配置中,定义了一个server块来监听域名
-
反向代理配置(location块):
- 在server块中,定义了一个location块,用于匹配根路径
/
的请求。使用proxy_pass
指令将请求转发到内部网络的特定服务上,这里是转发到http://192.168.56.1:10000
,即商品服务所在的地址。
- 在server块中,定义了一个location块,用于匹配根路径
-
请求处理:
- 当用户访问
gulimall.com
时,请求首先被发送到配置在hosts文件中的虚拟机IP。 - 虚拟机上的Nginx监听80端口,接收到请求后,根据配置的location块,将请求转发到内部的商品服务。
- 当用户访问
二,配置
1,nginx配置
nginx修改两处配置:
- 在nginx全局配置文件nginx.conf中配置服务器地址
- 在server块配置文件gulimall.conf中配置负载均衡配置
1.1 nginx.conf
在nginx.conf中做如下配置。
dart
upstream gulimall{
server 192.168.56.1:88;
}
1.2 gulimall.conf
在conf.d目录下的gulimall.conf做如下配置。
dart
location / {
proxy_pass http://gulimall;
}
注意,配置完成要重启docker容器。
1.3 配置原理
-
location / { ... }:
- 这个
location
块定义了对于根路径/
的请求的处理方式。location
块可以包含在server
块内,用于匹配特定的URI或路径。 location /
表示匹配所有以根路径开始的请求。
- 这个
-
proxy_pass http://gulimall;:
proxy_pass
指令用于设置请求的代理转发目标。这里它指定了请求应该被转发到名为gulimall
的上游服务器组(upstream)。注意,这里的http://
是可选的,因为proxy_pass
默认就是HTTP代理。
-
upstream gulimall { ... }:
upstream
块定义了一个服务器组的名称和一组后端服务器的地址。在这个例子中,gulimall
是服务器组的名称。- 在
upstream gulimall
块内,使用server
指令来指定后端服务器的地址和端口。这里的server 192.168.56.1;
表示将请求代理到IP地址为192.168.56.1
的服务器。默认情况下,如果没有指定端口,则使用80端口。
这两段配置是如何起作用的:
- 当一个请求到达Nginx,并且请求的URI是根路径
/
时,Nginx会根据配置的location /
块来处理这个请求。 - 在
location /
块中,proxy_pass
指令告诉Nginx将请求转发到名为gulimall
的上游服务器组。 - Nginx查找
upstream gulimall
块,找到后端服务器的列表。在这个例子中,只有一个服务器,即IP地址为192.168.56.1
的服务器。 - Nginx将请求转发到这个后端服务器,由它来处理请求并返回响应。
这种配置方式允许Nginx作为一个反向代理服务器,将请求分发到不同的后端服务。使用upstream
可以方便地进行负载均衡和故障转移等操作,而proxy_pass
则定义了具体的请求转发行为。
2,网关配置
在网关服务的配置文件中,增加如下配置。
dart
- id: gulimall-index-route
uri: lb://gulimall-product
predicates:
- Host=**.gulimall.com
这段配置的作用是:
- 当API网关接收到一个HTTP请求时,它会检查请求的Host头部。
- 如果Host头部匹配
**.gulimall.com
的模式(即任何子域名的gulimall.com
),则这个请求将被路由到名为gulimall-product
的服务。 - 请求将通过负载均衡器发送到后端服务实例,以实现请求分发和故障转移。
配置完成重启网关。
三,记录2个问题
1,网关路由匹配实现
在网关中配置工具域名来进行路由转发,测试发现并未生效,原因是nginx转发请求会丢失域名信息,需要在nginx的server块配置文件gulimall.conf中配置中重设请求头域名信息,配置如下。
dart
location / {
proxy_set_header Host $host;
proxy_pass http://gulimall;
}
2,网关路由配置前后顺序导致的问题
如果将下列配置放在路由配置的最前面,将会出现一些问题。
路由规则gulimall-index-route
使用Host
谓词匹配所有以.gulimall.com
结尾的请求。
如果这个规则gulimall-index-route
放在最前面,可能出现的问题包括:
-
匹配优先级问题:
- 路由规则是从上到下匹配的,一旦匹配成功,就不会再考虑下面的规则。如果
gulimall-index-route
放在最前面,所有.gulimall.com
的请求都会被这个规则捕获,即使这些请求的路径可能更适合下面的某个Path
谓词规则。
- 路由规则是从上到下匹配的,一旦匹配成功,就不会再考虑下面的规则。如果
-
路径路由失效:
- 由于
gulimall-index-route
会捕获所有.gulimall.com
的请求,其他基于特定API路径(如/api/search/**
、/api/coupon/**
等)的路由规则将不会生效,因为请求在到达这些规则之前已经被gulimall-index-route
匹配并路由了。
- 由于
-
服务发现问题:
- 如果
gulimall-product
服务不能处理所有可能的API请求(例如,它不包含搜索、优惠券、库存等API的实现),那么将所有请求都路由到这个服务将导致错误或不期望的响应。
- 如果
3,nginx.conf upstream配置缺少端口
重启nginx和网关后,仍然不能正常访问页面,查看nginx日志,发现转发到80端口,而网关是在88端口,说明配置nginx.conf
中upstream
配置缺少端口。
如下图修改之后,即能正常访问。