货币交易项目-IAAS 基础服务的搭建和开发 (三)-gateway-server 网关服务的搭建-01
一、IAAS简介
IaaS(Infrastructure as a Service基础设施即服务)是指把IT基础设施作为一种服务通过网络对外提供。
二、API网关介绍
API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。
网关应当具备以下功能:
- 性能:API高可用,负载均衡,容错机制。
- 安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
- 日志:日志记录(spainid,traceid)一旦涉及分布式,全链路跟踪必不可少。
- 缓存:数据缓存。
- 监控:记录请求响应数据,api耗时分析,性能监控。
- 限流:流量控制,错峰流控,可以定义多种限流规则。
- 灰度:线上灰度部署,可以减小风险。
- 路由:动态路由规则。
目前,比较流行的网关有:Nginx 、 Kong 、Orange等等,还有微服务网关Zuul 、Spring Cloud Gateway等等。
三、Spring Cloud Gateway介绍
既然有Nginx这样成熟的网关,那为什么还需要Gateway呢?
-
像Nginx这类网关,性能肯定是没得说,它适合做那种门户网关,是作为整个全局的网关,是对外的,处于最外层的;而Gateway这种,更像是业务网关,主要用来对应不同的客户端提供服务的,用于聚合业务的。各个微服务独立部署,职责单一,对外提供服务的时候需要有一个东西把业务聚合起来。
-
像Nginx这类网关,都是用不同的语言编写的,不易于扩展;而Gateway就不同,它是用Java写的,易于扩展和维护
-
Gateway这类网关可以实现熔断、重试等功能,这是Nginx不具备的
-
Spring Cloud已经放弃Netflix Zuul了。现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是基于过滤器的,是阻塞IO,不支持长连接。Zuul 2.x版本跟1.x的架构大一样,性能也有所提升。既然Spring Cloud已经不再集成Zuul 2.x了,那么是时候开始使用Spring Cloud Gateway了。
四、使用Spring Cloud Gateway
4.1 在gateway-server里面添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
4.2 在gateway-server里面添加启动类
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayServerApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServerApplication.class,args) ;
}
}
4.3 在gateway-server里面添加配置文件
创建 src/main/resources/application.yml
文件:
server:
port: 80
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 启用gateway 服务发现功能
lower-case-service-id: true # 启用小驼峰的服务名称访问服务
routes: # 自定义路由机制
- id: test-router
uri: https://www.baidu.com
predicates:
- Query=url,baidu
- id: admin-service-router # /admin/**--->admin-service
uri: lb://admin-service
predicates:
- Path = admin/**
- id: member-service-router # /member/**--->member-service
uri: lb://member-service
predicates:
- Path = member/**
- id: finance-service-router # /finance/**--->finance-service
uri: lb://finance-service
predicates:
- Path = finance/**
- id: chan-service-router # /chan/**--->chan-service
uri: lb://chan-service
predicates:
- Path = chan/**
- id: statistics-service-router # /statistics/**--->statistics-service
uri: lb://statistics-service
predicates:
- Path=statistics/**
- id: match-service-router # /match/**--->match-service
uri: lb://match-service
predicates:
- Path=match/**
- id: exchange-service-router # /exchange/**--->exchange-service
uri: lb://exchange-service
predicates:
- Path=match/**
nacos:
server-addr: nacos-server:8848
4.4 修改本机的hosts文件
在 C:\Windows\System32\drivers\etc
目录下,修改 hosts
文件:
#################### coinexchange ##################
98.142.123.144 nacos-server
4.5 启动访问测试
在启动服务的时候,报了这样一个错误:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-04-02 23:48:50.015 ERROR 9644 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.cloud.gateway.config.GatewayAutoConfiguration$NettyConfiguration.reactorNettyWebSocketClient(GatewayAutoConfiguration.java:738)
The following method did not exist:
org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient.setHandlePing(Z)V
The method's class, org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient, is available from the following locations:
jar:file:/C:/developer/environment/java/maven/repository/org/springframework/spring-webflux/5.2.3.RELEASE/spring-webflux-5.2.3.RELEASE.jar!/org/springframework/web/reactive/socket/client/ReactorNettyWebSocketClient.class
It was loaded from the following location:
file:/C:/developer/environment/java/maven/repository/org/springframework/spring-webflux/5.2.3.RELEASE/spring-webflux-5.2.3.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient
Disconnected from the target VM, address: '127.0.0.1:52003', transport: 'socket'
Process finished with exit code 1
版本:
spring-boot 2.2.13.RELEASE
springcloud version Hoxton.SR3
SpringCloud若选用: Hoxton.SR3
支持的SpringBoot版本: 2.2.5.RELEASE
SpringCloud官网:https://spring.io/projects/spring-cloud
原来是maven的配置有问题,导致拉取不了包:
重新做了一些配置,改为默认配置。
启动gateway-server,观察Nacos注册中心:
五、Spring Cloud Gateway集成Sentinel
Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。
参考文档:
https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81
5.1 限流规则的维度
5.1.1 网关维度
代表网关访问该服务时的限流规则
粒度粗--全局的配置
5.1.2 Api分组维度
代表网关访问该接口时的限流规则
粒度细--局部配置
5.2 添加依赖
coin-exchange/coin-iaas/gateway-server/pom.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
5.3 修改配置文件
server:
port: 80
spring:
application:
name: gateway-server
cloud:
nacos:
discovery:
server-addr: nacos-server:8848 # 修改本机的host 文件
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true # admin-service ADMIN-SERVICE /admin-service/** -> 微服务(ADMIN-SERVICE)
routes:
- id: amdin-service_router
uri: lb://admin-service # 转发到那个目的地
predicates:
- Path=/admin/**
- id: test_router
uri: http://www.aliyun.com
predicates:
- Path=/product
sentinel:
filter:
enabled: true
datasource:
ds1.file:
file: classpath:router-flow.json
ruleType: gw-flow
ds2.file:
file: classpath:api-flow.json #api-flow.json 接口的分组
ruleType: gw_api_group
规则配置具体参考:
GatewayFlowRule:网关限流规则,针对 API Gateway 的场景定制的限流规则,可以针对不同 route 或自定义的 API 分组进行限流,支持针对请求中的参数、Header、来源 IP 等进行定制化的限流。
ApiDefinition:用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合。比如我们可以定义一个 API 叫 my_api,请求 path 模式为 /foo/** 和 /baz/** 的都归到 my_api 这个 API 分组下面。限流的时候可以针对这个自定义的 API 分组维度进行限流。
其中网关限流规则 GatewayFlowRule 的字段解释如下:
resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
resourceMode:规则是针对 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID)还是用户在 Sentinel 中定义的 API 分组(RESOURCE_MODE_CUSTOM_API_NAME),默认是 route。
grade:限流指标维度,同限流规则的 grade 字段。
count:限流阈值
intervalSec:统计时间窗口,单位是秒,默认是 1 秒。
controlBehavior:流量整形的控制效果,同限流规则的 controlBehavior 字段,目前支持快速失败和匀速排队两种模式,默认是快速失败。
burst:应对突发请求时额外允许的请求数目。
maxQueueingTimeoutMs:匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效。
paramItem:参数限流配置。若不提供,则代表不针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换成热点规则。其中的字段:
parseStrategy:从请求中提取参数的策略,目前支持提取来源 IP(PARAM_PARSE_STRATEGY_CLIENT_IP)、Host(PARAM_PARSE_STRATEGY_HOST)、任意 Header(PARAM_PARSE_STRATEGY_HEADER)和任意 URL 参数(PARAM_PARSE_STRATEGY_URL_PARAM)四种模式。
fieldName:若提取策略选择 Header 模式或 URL 参数模式,则需要指定对应的 header 名称或 URL 参数名称。
pattern:参数值的匹配模式,只有匹配该模式的请求属性值会纳入统计和流控;若为空则统计该请求属性的所有值。(1.6.2 版本开始支持)
matchStrategy:参数值的匹配策略,目前支持精确匹配(PARAM_MATCH_STRATEGY_EXACT)、子串匹配(PARAM_MATCH_STRATEGY_CONTAINS)和正则匹配(PARAM_MATCH_STRATEGY_REGEX)。(1.6.2 版本开始支持)
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)