我们需要在项目中增加一个服务网关模块shop-gateway,在服务网关模块中实现网关的能力。此时,我们的项目中就会有用户微服务、商品微服务、订单微服务和服务网关。
在项目中新建shop-gateway模块,新增网关模块后项目的结构如下图所示。
(1)在服务网关shop-gateway模块的pom.xml文件中添加如下依赖。
org.springframework.cloud
spring-cloud-starter-gateway
(2)在服务网关shop-gateway模块的resources目录下新建application.yml文件,并在文件中添加如下配置信息。
server:
port: 10001
spring:
application:
name: server-gateway
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowCredentials: true
allowedHeaders: "*"
routes:
- id: user-gateway
uri: http://localhost:8060
order: 1
predicates:
- Path=/server-user/**
filters:
- StripPrefix=1
- id: product-gateway
uri: http://localhost:8070
order: 1
predicates:
- Path=/server-product/**
filters:
- StripPrefix=1
- id: order-gateway
uri: http://localhost:8080
order: 1
predicates:
- Path=/server-order/**
filters:
- StripPrefix=1
我们重点来看下 spring.cloud.gateway 节点下的配置。
(3)在服务网关shop-gateway模块的io.binghe.shop包下新建GatewayStarter类,表示服务网关的启动类,源码如下所示。
/**
* @author binghe (公众号:冰河技术)
* @version 1.0.0
* @description 服务网关启动类
*/
@SpringBootApplication
public class GatewayStarter {
public static void main(String[] args){
SpringApplication.run(GatewayStarter.class, args);
}
}
(4)由于之前项目中整合了Nacos和Sentinel,所以,在启动项目前,要分别启动Nacos和Sentinel。
startup.cmd -m standalone
进入Sentinel Jar包所在的目录,输入如下命令启动Sentinel。
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.4.jar
(5)分别启动用户微服务、商品微服务、订单微服务和服务网关。
(6)通过服务网关访问用户微服务,在浏览器中输入http://localhost:10001/server-user/user/get/1001,如下所示。
用户微服务返回的原始数据如下所示。
{
"id": 1001,
"username": "binghe",
"password": "c26be8aaf53b15054896983b43eb6a65",
"phone": "13212345678",
"address": "北京"
}
可以看到,通过服务网关能够正确访问到用户微服务。
(7)通过服务网关访问商品微服务,在浏览器中输入http://localhost:10001/server-product/product/get/1001,如下所示。
商品微服务返回的原始数据如下所示。
{
"id": 1001,
"proName": "华为",
"proPrice": 2399,
"proStock": 100
}
可以看到,通过服务网关能够正确访问到商品微服务。
(8)通过服务网关访问订单微服务,在浏览器中输入http://localhost:10001/server-order/order/test_sentinel,如下所示。
可以看到,通过服务网关能够正确访问到订单微服务。
在初步整合SpringCloud Gateway中,我们在服务网关模块的application.yml文件中硬编码配置了服务转发的地址,如下所示。
uri: http://localhost:8060
uri: http://localhost:8070
uri: http://localhost:8080
这里,我们将网关整合Nacos实现从Nacos注册中心获取转发的服务地址。
(1)在服务网关shop-gateway模块的pom.xml文件中继续添加如下依赖。
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
(2)在服务网关shop-gateway模块的启动类io.binghe.shop.GatewayStarter上添加@EnableDiscoveryClient注解,如下所示。
/**
* @author binghe (公众号:冰河技术)
* @version 1.0.0
* @description 服务网关启动类
*/
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayStarter {
public static void main(String[] args){
SpringApplication.run(GatewayStarter.class, args);
}
}
(3)将application.yml备份一份,命名为application-simple.yml,并修改application.yml配置文件,修改后的文件如下所示。
server:
port: 10001
spring:
application:
name: server-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowCredentials: true
allowedHeaders: "*"
discovery:
locator:
enabled: true
routes:
- id: user-gateway
uri: lb://server-user
order: 1
predicates:
- Path=/server-user/**
filters:
- StripPrefix=1
- id: product-gateway
uri: lb://server-product
order: 1
predicates:
- Path=/server-product/**
filters:
- StripPrefix=1
- id: order-gateway
uri: lb://server-order
order: 1
predicates:
- Path=/server-order/**
filters:
- StripPrefix=1
上述配置中增加了Nacos相关的配置,如下所示。
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
新增了让SpringCloud Gateway可以发现Nacos中的服务配置,如下所示。
Spring:
cloud:
gateway:
discovery:
locator:
enabled: true
另外,将硬编码的服务转发地址修改成从Nacos中按照名称获取微服务地址,并按照负载均衡策略分发。
uri: lb://server-user
uri: lb://server-product
uri: lb://server-order
其中,lb指的是从Nacos中按照微服务的名称获取微服务地址,并按照负载均衡的策略分发。使用lb从Nacos中获取微服务时,遵循如下的格式。
lb://微服务名称
微服务的名称就是各个微服务在application.yml文件中配置的服务名称。
spring:
application:
name: 服务名称
(4)分别启动用户微服务、商品微服务、订单微服务和服务网关。
(5)通过服务网关访问用户微服务,在浏览器中输入http://localhost:10001/server-user/user/get/1001,如下所示。
用户微服务返回的原始数据如下所示。
{
"id": 1001,
"username": "binghe",
"password": "c26be8aaf53b15054896983b43eb6a65",
"phone": "13212345678",
"address": "北京"
}
可以看到,通过服务网关能够正确访问到用户微服务。
(6)通过服务网关访问商品微服务,在浏览器中输入http://localhost:10001/server-product/product/get/1001,如下所示。
商品微服务返回的原始数据如下所示。
{
"id": 1001,
"proName": "华为",
"proPrice": 2399,
"proStock": 100
}
可以看到,通过服务网关能够正确访问到商品微服务。
(7)通过服务网关访问订单微服务,在浏览器中输入http://localhost:10001/server-order/order/test_sentinel,如下所示。
可以看到,通过服务网关能够正确访问到订单微服务。
SpringCloud Gateway整合Nacos后,可以不用手动指定其他微服务的名称来从Nacos中获取微服务的地址。接下来,我们就来实现SpringCloud Gateway网关整合Nacos的最简配置。
(1)将application.yml备份一份,命名为application-nacos.yml,并修改application.yml配置文件,修改后的文件如下所示。
server:
port: 10001
spring:
application:
name: server-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowCredentials: true
allowedHeaders: "*"
discovery:
locator:
enabled: true
可以看到,在application.yml文件中,去掉了spring.cloud.gateway.routes 节点及其下面的所有配置。
(2)分别启动用户微服务、商品微服务、订单微服务和服务网关。
(3)通过服务网关访问用户微服务,在浏览器中输入http://localhost:10001/server-user/user/get/1001,如下所示。
用户微服务返回的原始数据如下所示。
{
"id": 1001,
"username": "binghe",
"password": "c26be8aaf53b15054896983b43eb6a65",
"phone": "13212345678",
"address": "北京"
}
可以看到,通过服务网关能够正确访问到用户微服务。
(4)通过服务网关访问商品微服务,在浏览器中输入http://localhost:10001/server-product/product/get/1001,如下所示。
商品微服务返回的原始数据如下所示。
{
"id": 1001,
"proName": "华为",
"proPrice": 2399,
"proStock": 100
}
可以看到,通过服务网关能够正确访问到商品微服务。
(5)通过服务网关访问订单微服务,在浏览器中输入http://localhost:10001/server-order/order/test_sentinel,如下所示。
可以看到,通过服务网关能够正确访问到订单微服务。
注意:SpringCloud Gateway整合Nacos最简配置时,通过网关访问微服务的格式如下所示。
http(s)://网关IP:网关端口/访问的目标微服务名称/接口地址
Sentinel从1.6.0版本开始,提供了SpringCloud Gateway的适配模块,并且可以提供两种资源维度的限流,一种是route维度;另一种是自定义API分组维度。
(1)在服务网关shop-gateway模块的pom.xml文件中添加如下依赖。
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
com.alibaba.cloud
spring-cloud-alibaba-sentinel-gateway
org.springframework.cloud
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.csp
sentinel-spring-cloud-gateway-adapter
(2)在服务网关shop-gateway模块中新建io.binghe.shop.config包,并在包下新建GatewayConfig类。基于Sentinel 的Gateway限流是通过其提供的Filter来完成的,使用时只需注入对应的SentinelGatewayFilter实例以及 SentinelGatewayBlockExceptionHandler 实例即可。
GatewayConfig类的源代码如下所示。
/**
* @author binghe (公众号:冰河技术)
* @version 1.0.0
* @description 网关配置类
*/
@Configuration
public class GatewayConfig {
private final ListviewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
@Value("${spring.cloud.gateway.discovery.locator.route-id-prefix}")
private String routeIdPrefix;
public GatewayConfig(ObjectProvider> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
/**
* 初始化一个限流的过滤器
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
@PostConstruct
public void init() {
this.initGatewayRules();
this.initBlockHandlers();
}
/**
* 配置初始化的限流参数
*/
private void initGatewayRules() {
Setrules = new HashSet<>();
/**
* Sentinel整合SpringCloud Gateway使用的API类型为Route ID类型,也就是基于route维度时,
* 由于Sentinel为SpringCloud Gateway网关生成的API名称规则如下:
* 生成的规则为:${spring.cloud.gateway.discovery.locator.route-id-prefix}后面直接加上目标微服务的名称,如下所示。
* ${spring.cloud.gateway.discovery.locator.route-id-prefix}目标微服务的名称
* 其中,${spring.cloud.gateway.discovery.locator.route-id-prefix}是在yml文件中配置的访问前缀
*
* 为了让通过服务网关访问目标微服务链接后,请求链路中生成的API名称与流控规则中生成的API名称一致,以达到启动项目即可实现访问链接的限流效果,
* 而无需登录Setinel管理界面手动配置限流规则,可以将
* resource参数设置为${spring.cloud.gateway.discovery.locator.route-id-prefix}目标微服务的名称
*
* 当然,如果不按照上述配置,也可以在项目启动后,通过服务网关访问目标微服务链接后,在Sentinel管理界面的请求链路中找到对应的API名称所代表的请求链路,
* 然后手动配置限流规则。
**/
// //用户微服务网关
// rules.add(this.getGatewayFlowRule("user-gateway"));
// //商品微服务网关
// rules.add(this.getGatewayFlowRule("product-gateway"));
// //订单微服务网关
// rules.add(this.getGatewayFlowRule("order-gateway"));
//用户微服务网关
rules.add(this.getGatewayFlowRule(getResource("server-user")));
//商品微服务网关
rules.add(this.getGatewayFlowRule(getResource("server-product")));
//订单微服务网关
rules.add(this.getGatewayFlowRule(getResource("server-order")));
//加载规则
GatewayRuleManager.loadRules(rules);
}
private String getResource(String targetServiceName){
if (routeIdPrefix == null){
routeIdPrefix = "";
}
return routeIdPrefix.concat(targetServiceName);
}
private GatewayFlowRule getGatewayFlowRule(String resource){
//传入资源名称生成GatewayFlowRule
GatewayFlowRule gatewayFlowRule = new GatewayFlowRule(resource);
//限流阈值
gatewayFlowRule.setCount(1);
//统计的时间窗口,单位为
gatewayFlowRule.setIntervalSec(1);
return gatewayFlowRule;
}
/**
* 配置限流的异常处理器
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
/**
* 自定义限流异常页面
*/
private void initBlockHandlers() {
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public MonohandleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Map map = new HashMap<>();
map.put("code", 1001);
map.put("codeMsg", "接口被限流了");
return ServerResponse.status(HttpStatus.OK).
contentType(MediaType.APPLICATION_JSON_UTF8).
body(BodyInserters.fromObject(map));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
}
GatewayConfig类的源代码看上去比较多,但是都是一些非常简单的方法,冰河在这里就不再赘述了。
这里有个需要特别注意的地方:
Sentinel1.8.4整合SpringCloud Gateway使用的API类型为Route ID类型时,也就是基于route维度时,由于Sentinel为SpringCloud Gateway网关生成的API名称规则如下:
生成的规则为:${spring.cloud.gateway.discovery.locator.route-id-prefix}后面直接加上目标微服务的名称,如下所示。
{spring.cloud.gateway.discovery.locator.route-id-prefix}目标微服务的名称。其中,${spring.cloud.gateway.discovery.locator.route-id-prefix}是在yml文件中配置的访问前缀。
为了让通过服务网关访问目标微服务链接后,请求链路中生成的API名称与流控规则中生成的API名称一致,以达到启动项目即可实现访问链接的限流效果,而无需登录Setinel管理界面手动配置限流规则,可以将生成GatewayFlowRule对象的resource参数设置为${spring.cloud.gateway.discovery.locator.route-id-prefix}目标微服务的名称
当然,如果不按照上述配置,也可以在项目启动后,通过服务网关访问目标微服务链接后,在Sentinel管理界面的请求链路中找到对应的API名称所代表的请求链路,然后手动配置限流规则。
(3)将服务网关shop-gateway模块的application.yml文件备份一份名称为application-nacos-simple.yml的文件,并将application.yml文件的内容修改成如下所示。
server:
port: 10001
spring:
application:
name: server-gateway
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel:
transport:
port: 7777
dashboard: 127.0.0.1:8888
web-context-unify: false
eager: true
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowCredentials: true
allowedHeaders: "*"
discovery:
locator:
enabled: true
route-id-prefix: gateway-
其中:
(4)在IDEA中配置启动服务网关shop-gateway模块的参数-Dcsp.sentinel.app.type=1,如下所示。
如果是在命令行启动网关服务的Ja
网站栏目:服务网关:项目整合SpringCloudGateway网关
网站URL:http://www.csdahua.cn/qtweb/news35/353985.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网