spring cloud gateway网关(一)之网关路由

1、gateway相关介绍

在微服务架构中,系统往往由多个微服务组成,而这些服务可能部署在不同机房、不同地区、不同域名下。这种情况下,客户端(例如浏览器、手机、软件工具等)想要直接请求这些服务,就需要知道它们具体的地址信息,例如 IP 地址、端口号等。这种客户端直接请求服务的方式存在很多的复杂问题。如:需要维护大量的服务地址、存在跨域请求的问题、每个微服务需要独立认证等。所以我们可以通过 API 网关(gateway)来解决这些问题。所有客户端请求都发生到网关,由网关统一转发到不同的地址。网关还可以 处理一些非业务功能的逻辑,例如权限验证、监控、缓存等。本篇主要讲解通过网关统一请求转发到不同微服务。

2、创建网关服务

首先创建maven项目新建网关模块:

pom导入网关相关依赖:

<dependencies><!--Eureka Client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--特别注意:在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错--><!-- Spring cloud gateway 网关依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
 <!-- LoadBalancer -->
<!-- 引入spring-cloud-loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!--ribbon Spring Cloud Ribbon 在高版本移除了 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>-->
<!-- <version>2.2.5.RELEASE</version>-->
<!-- </dependency>-->
</dependencies>

创建springboot启动类:

@SpringBootApplication
@EnableEurekaClient
public class GateWayApplication {
 public static void main(String[] args) {
 SpringApplication.run(GateWayApplication.class,args);
 }
}

启动类创建成功后,在resources资源目录下创建application.yml文件,用来配置gateway。首先设置服务端口和服务名称:

server:
 port: 8081
spring:
 application:
 name: gateway-server-one

在把网关注册到注册中心:

#客户端注册
eureka:
 instance:
 instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} #localhost
 hostname: localhost
 client:
 register-with-eureka: true #是否向注册中心注册自己 默认为true
 fetch-registry: true #是否需要检索服务 默认为true
 service-url:
 defaultZone: http://eternity:1234qwer@localhost:4405/eureka/

配置好之后,可以启动网关。查看网关服务是否可以正常启动以及是否在注册中心注册成功,如果注册成功然后在开始配置网关参数。

可以看到服务启动成功,我们看看注册中心是否成功:

eureka中心已经有了,说明启动成功。

3、配置gateway路由

spring:
 application:
 name: gateway-server-one
 cloud:
 loadbalancer:
 ribbon:
 enabled: false #使用LoadBalancer, Ribbon 在高版本移除了 切换到ReactiveLoadBalancerClientFilter
 gateway:
 discovery: 
 locator: #路由访问方式:http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问。
 enabled: true #开启通过名称找到服务器功能
 lower-case-service-id: true #使用小写service-id
 routes:
 - id: hibernate-server-one-route #路由的ID,没有固定规则,但要求唯一,建议与服务名对应
 uri: http://localhost:8800 #匹配后提供服务的路由地址
 predicates:
 #以下是断言条件,必选全部符合条件
 - Path=/admin/user/** #断言,路径相匹配的进行路由
 - Method=GET #只能时 GET 请求时,才能访问
 - id: xxl-job-server-one-route
# uri: http://localhost:8801 #可以设置为服务名
 uri: lb://XXL-JOB-SERVER-MODEL #可以设置为服务名
 predicates:
 - Path=/admin/user/** #断言,路径相匹配的进行路由, 注意:Path 中 P 为大写
 - After=2022-06-06T03:29:37.318-07:00 # [Asia/Shanghai] # after来进行设置,后面添加一个时间,就是指在什么时间之后这个服务才可以被访问,否则将无法被访问到
# - After=2030-01-20T17:42:47.789-07:00 # [America/Denver]

配置成功后再次启动网关,查看服务器是否转发成功。

通过网关gateway请求路径访问查找用户信息:

http://localhost:8081/admin/user/

通过postman测试接口,查询成功。

4、gateway负载均衡

通过在配置文件中配置路径的uri为注册中心服务器名称,可以实现gateway负载均衡。访问时通过服务名称去查找服务名下面的多个实例,根据配置的策略实现转发到不同实例服务。

uri: lb://XXL-JOB-SERVER-MODEL #可以设置为服务名

在通过服务名称转发的过程中,有可能转发失败。报找不到服务,接口报错:

查看网关控制台发现也报错:

java.net.UnknownHostException: failed to resolve 'xxl-job-server-model' after 4 queries 
 at io.netty.resolver.dns.DnsResolveContext.finishResolve(DnsResolveContext.java:1013) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
 Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
 |_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
 |_ checkpoint ⇢ HTTP POST "/admin/user/" [ExceptionHandlingWebHandler]
Stack trace:
 at io.netty.resolver.dns.DnsResolveContext.finishResolve(DnsResolveContext.java:1013) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
 at io.netty.resolver.dns.DnsResolveContext.tryToFinishResolve(DnsResolveContext.java:966) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
 at io.netty.resolver.dns.DnsResolveContext.query(DnsResolveContext.java:414) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]

没有找到服务名,刚开始以为是设置路由的服务名和注册中心的服务名不一致。经过查找发现是一致。最后查找发现是客户端微服务注册到注册中心的hostname配置错误,需要配置和注册中心一致的hostname。不然网关通过服务名找不到相关地址:

查看eureka服务注册地址:

所以需要配置客户端hostname:

hostname: localhost

再次重新运行系统,发现报错问题已经解决。

 

作者:sowler原文地址:https://www.cnblogs.com/eternality/p/17463553.html

%s 个评论

要回复文章请先登录注册