社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
环境:
Spring Cloud版本 | Spring Boot版本 | JAVA | IDE |
Greenwich.SR1 | 2.1.6.RELEASE | 1.8 | IDEA |
为模拟实际开发,本篇教程除alh-tms外,所有的参数均从远程配置中心读取,若是不用远程配置中心,请在本地应用直接写各项参数即可。
涉及项目:
alh-config-server(6001): 保持启动状态,本篇不涉及修改
alh-eureka-server(6000):保持启动状态,本篇不涉及修改
alh-tms(8001):保持8001实例启动状态,本篇不涉及修改
alh-gateway(7000)
完整教程全部章节目录:https://blog.csdn.net/tuoyun6647/article/details/93501029
首先先提出几个问题:
Q1:微服务架构中,我们会有很多服务,比如访问服务1的时候,可以直接去访问服务1,访问2的时候直接去2,但是如果在我们的服务如果部署在“容器”中,容器内部是个“局域网”环境,内部可以相互调用,但是对外只能映射一个端口,只能提供一个入口怎么办?
Q2:为了避免接口“裸奔” ,服务被调用时需要做权限验证,如果我们有50个微服务,如果每个服务都做权限认证,当需要改变认证方式技术实现时,我们需要去改50个微服务,此时我们怎么保证效率?怎么保证准确性?怎么保证不失控?
Q3:如果需要一个界面,监控所有的API流量,或者统一采集接口调用日志信息,要怎么做?
Q4:如果要进行统一限流,统一熔断要在哪里做,怎么做?
为了实现以上几个需求,于是就有了微服务体系中的网关,网关是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,微服务网关具备以下几个基本功能:
(1)路由转发
(2)统一权限认证
(3)统一监控
(4)限流、熔断
准备工作:
1、启动远程配置中心alh-config-server(6001)
2、启动注册中心alh-eureka-server(6000)
3、启动服务alh-tms(8001)
本章需创建alh-gateway项目,远程配置中心alh-config-server先增加alh-gateway的配置文件,提交至git
创建alh-gateway项目
(引入Web )
创建配置文件bootstrap.properties,内容如下:
# 和git里的文件名对应
spring.application.name=alh-gateway
# 远程仓库的分支
spring.cloud.config.label=master
# dev开发环境、test测试环境、pro正式环境
spring.cloud.config.profile=dev
# 配置服务中心的安全认证账号密码
csname=kcsm
cspwd=kcsm111
# 指明配置服务中心的网址
spring.cloud.config.uri= http://${csname}:${cspwd}@localhost:6001/
application配置文件中会配置各服务的转发地址,为了方便配置使用yml格式,将配置文件命名为application.yml。yml与properties可以用转换工具转换:https://www.bejson.com/devtools/properties2yaml/
application.yml内容如下:
spring:
application:
name: alh-gateway
server:
port: ${server.port}
eureka:
client:
service-url:
defaultZone: ${default-zone}
启动项目,发现启动失败
原因:在类路径上找到了SpringMVC,此时它与Spring Cloud Gateway不兼容。需删除Spring Boot Starter Web依赖项。pom中移除spring-boot-starter-web依赖,即可成功启动。
完整pom如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kcsm.alh</groupId>
<artifactId>alh-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>alh-gateway</name>
<description>Gateway</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml配置如下,具体配置说明注释里已经描述,其中整合Eureka时,uri格式如下所示,如果调用的服务没有注册在注册中心,直接填写地址就可以,例如uri: "http://www.baidu.com"
# 服务名称
spring:
application:
name: alh-gateway
# 路由配置
cloud:
gateway:
routes:
- id: alh-tms
#lb:lb代表从注册中心获取服务,后面接需要转发到的服务名称,这个服务名称必须跟eureka中的对应
uri: lb://alh-tms
predicates:
- Path=/tms/**
filters:
- StripPrefix=1
# StripPrefix=1,此处配置为去除前一个后缀之后,例如tms/application/csinfo转发为/application/csinfo
# 如http://localhost:7000/tms/application/csinfo转发为http://localhost:8001/application/csinfo(该资源的实际路径),只有去除tms前缀才能正确调用服务
# Eureka Server 配置
eureka:
client:
service-url:
defaultZone: ${default-zone}
此种配置方式有个弊端,就是每一个需要转发的微服务都要进行配置,例如有两个微服务,则两个都需要配置
启动alh-gateway(7000),启动后访问http://localhost:7000/tms/application/csinfo,即可访问alh-tms服务的方法,由于配置文件中设置了StripPrefix=1(除去前一个后缀,tms被除去)此路径相当于http://localhost:8001/application/csinfo
先介绍一下Zuul,Zuul与Gateway都是网关工具,Zuul构建于 Servlet 2.5,兼容 3.x,使用的是阻塞式的 API,不支持长连接,比如 websocket。Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,Spring Cloud Gateway构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API它支持 websocket,和 Spring 框架紧密集成,开发体验相对来说更不错。虽然目前新出的Zuul 2.x 在底层上有了很大的改变,使用了异步无阻塞式的 API,性能改善明显,不过截止至2019年6月Spring Cloud 没集成 Zuul 2.x。由于公司的项目使用到websocket,所以从Zuul转为Gateway。
Zuul路由配置很简单,注册到Eureka的服务Zuul默认全部可进行转发,在访问路径上指定要访问的服务即可。Gateway也提供类似Zuul的配置方式,使用此种配置方式,当新增服务时无需增加配置内容即可进行转发。
配置文件如下,注意两种配置方式只能使用一种,便于管理:
# 服务名称
spring:
application:
name: alh-gateway
# 路由配置方式一(方式一与方式二只能使用一种)
# 方式一配置开始- - - - - - - - - - - - - - - - -
# cloud:
# gateway:
# routes:
# - id: alh-tms
# #lb:lb代表从注册中心获取服务,后面接需要转发到的服务名称,这个服务名称必须跟eureka中的对应
# uri: lb://alh-tms
# predicates:
# - Path=/tms/**
# filters:
# - StripPrefix=1
# 方式一配置结束- - - - - - - - - - - - - - - - -
# StripPrefix=1,此处配置为去除前一个后缀之后,例如tms/application/csinfo转发为/application/csinfo
# 如http://localhost:7000/tms/application/csinfo转发为http://localhost:8001/application/csinfo(该资源的实际路径),只有去除tms前缀才能正确调用服务
# 方式一访问地址为:http://网关uri:网关端口/Path配置值/**
# 路由配置方式二(方式一与方式二只能使用一种)
# 方式二配置开始- - - - - - - - - - - - - - - - -
cloud:
gateway:
discovery:
locator:
enabled: true
#服务名小写有效,如果不配置,只能用大写服务名作为路径
lowerCaseServiceId: true
# 方式二配置结束- - - - - - - - - - - - - - - - -
# 方式二访问地址为:http://网关uri:网关端口/服务名称(小写)/**
# Eureka Server 配置
eureka:
client:
service-url:
defaultZone: ${default-zone}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!