Spring Cloud Gateway 的简单搭建

码农UP2U

共 5021字,需浏览 11分钟

 ·

2021-10-20 01:22


早期文章




        在 《服务注册、发现和远程调用》 这篇文章中介绍关于服务注册、发现和远程调用的一个 Demo,本文在这篇文章的基础上介绍如何使用 Spring Cloud Gateway 搭建一个网关。


一、问题

        在上篇文章中,分别创建了 service_user 和 service_dict 两个服务,两个服务分别使用了 8001 和 8002 两个端口。这样直接通过 PostMan 或浏览器调用其中的接口没什么问题,如下图所示。

        从上图可以看到,访问 user 使用了 8001 端口,访问 dict 使用了 8002 端口,如果要为这些服务提供一个页面,由于不同的服务使用了不同的端口号,那么在写前端页面时就会因为有多个端口而导致难以管理,使得开发变得复杂。为了解决该问题,那么此时,我们可以通过反向代理来进行完成,比如 Nginx。


二、使用 Nginx 的反向代理功能来完成请求的分发

        在上面抛出的问题中,我们可用使用 Nginx 的反向代理功能来进行解决,解决的方法也很容易。这里 Nginx 直接下载一个 Windows 版本的进行测试。对 Nginx 进行简单的配置,配置如下:

    server {        listen 9001;        server_name localhost;                         location ~ /user/ {            proxy_pass http://localhost:8001;        }         location ~ /dict/ {            proxy_pass http://localhost:8002;        }    }

        这里通过配置了两个 location 完成了服务的分发,并且可用使用统一的端口 9001,测试如下图所示。

        可用看到,通过访问 localhost 的 9001 端口可用正常的访问 service_user 和 service_dict 两个服务。接着,我们写一个页面,通过页面来调用 localhost 的 9001 来访问这两个服务。


三、编写简单的页面进行测试

        这里使用 vue-admin-template 来进行测试,我们直接在登录页进行测试,然后通过 F12 的调试窗口来进行观察。先添加接口调用的代码,代码如下:

export function getUser() {  return request({    url: 'http://localhost:9001/admin/user/getUser/1',    method: 'get'  })}

        然后再登录页面中进行调用,调用的代码如下:

getUsers() {  getUser().then(response => {    console.log(response)  }).catch(error => {    console.log(error)  })},

        最后我们让页面打开时就进行调用,代码如下:

created() {    this.getUsers()},

        然后我们来观察调用的请求,如下图所示。

        从两幅图中可用看出,接口并没有调用成功,因为发生了跨域的问题。我们可以在每个控制器上增加 @CrossOrigin 注解,也可以给每个服务添加一个配置类。同样,我们可以在两个服务前面增加一个网关,让网关来做路由分发和处理跨域的问题。


四、使用 Spring Cloud Gateway 网关

        网关的作用比较多,网关可以做鉴权、限流、日志等功能,这里只是使用它做一个路由分发和处理跨域的问题。

        在项目中创建一个子模块,命名为 gateway,接着来引入它的依赖,依赖如下:

<dependencies>    <dependency>        <groupId>com.alibaba.cloudgroupId>        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>        <version>2.2.6.RELEASEversion>    dependency>
<dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-gatewayartifactId> <version>2.2.0.RELEASEversion> dependency>dependencies>

        第一个依赖是做 Nacos 服务发现的,第二个就是网关的依赖。

        引入依赖之后,创建 config 包,然后写一个用于允许跨域的 Bean,代码如下:

@Configurationpublic class CorsConfig {    @Bean    public CorsWebFilter corsFilter() {        CorsConfiguration config = new CorsConfiguration();        config.addAllowedMethod("*");        config.addAllowedOrigin("*");        config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source); }}

        有了上面的代码就可以让前端完成跨域请求,这里需要注意,在网关有了上面的跨域配置,那么在实际服务的 Controller 类上面就不可用再使用 @CrossOrigin 注解了,否则会报错。

        创建一个 application.properties 文件,然后来配置路由分发,配置如下:

# 服务端口server.port=7000# 服务名spring.application.name=service-gateway# nacos服务地址spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#使用服务发现路由spring.cloud.gateway.discovery.locator.enabled=true
#设置路由idspring.cloud.gateway.routes[0].id=service-user#设置路由的urispring.cloud.gateway.routes[0].uri=lb://service-user#设置路由断言,代理servicerId为auth-service的/auth/路径spring.cloud.gateway.routes[0].predicates= Path=/*/user/**
#设置路由idspring.cloud.gateway.routes[1].id=service-dict#设置路由的urispring.cloud.gateway.routes[1].uri=lb://service-dict#设置路由断言,代理servicerId为auth-service的/auth/路径spring.cloud.gateway.routes[1].predicates= Path=/*/dict/**

        上面的配置文件中,主要看 spring.cloud.gateway.routes 的配置,这里是数组,分别配置了两个路由规则,一个用来转发给 service_user 服务,第二个用来转发给 service_dict 服务。

        同样要给 gateway 创建一个启动类,启动类的代码如下:

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

        这样就可以启动我们的 gateway 了,gateway 的端口号为 7000。


五、测试前端调用

        service-user、service-dict 和 service-gateway 已经启动并注册到了 Nacos 中,但是现在我们并不能测试我们的前端页面,原因是前端页面的地址使用的是 Nginx 的端口,而 Nginx 的规则仍然是直接转发给两个服务,我们需要修改 Nginx 的配置,修改如下:

    server {        listen 9001;        server_name localhost;                 location ~ /user/ {            proxy_pass http://localhost:7000;        }         location ~ /dict/ {            proxy_pass http://localhost:7000;        }    }

        可以看到,Nginx 将两个请求转发给了 localhost:7000,也就是转发给了我们的网关。那么,我们来测试我们的前端页面。通过 F12 的调试窗口来进行查看。如下图所示。

        可以看到,我们的请求同样成功了。前端页面请求 localhost:9001 也就是 Nginx 的端口号,然后 Nginx 转发给 网关,最后网关路由到具体的服务,这样就完成了一次前端请求服务的调用。如下图所示。

        同样的,我们可以让 Ajax 直接调用网关来访问服务,这里就不再进行演示了,大家可以自行测试。


六、总结

        本篇文章通过一个简单的 Demo 完成了一个简单的 网关功能,该网关具有 处理跨域请求 和 路由转发 的功能。当然了我们这个功能过于的简单,但是大家可以自己进行扩展。比如可以类似如下图所示。

        gateway、service_user 和 service_dict 同时部署多台,Nginx 通过负载均衡策略将请求转发到任意一台网关,网关再将请求分发到任意一台具体的服务上。如果是这样做,那么我们的 Demo 看起来就更有些意思了。



公众号内回复 【mongo】 下载 SpringBoot 整合操作 MongoDB 的文档。


更多文章



浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报