首页 文章详情

Spring Cloud Gateway 的简单搭建

码农UP2U | 311 2021-10-20 01:22 0 0 0
UniSMS (合一短信)


早期文章




        在 《服务注册、发现和远程调用》 这篇文章中介绍关于服务注册、发现和远程调用的一个 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.cloud</groupId>        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>        <version>2.2.6.RELEASE</version>    </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>2.2.0.RELEASE</version> </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 的文档。


更多文章



good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter