首页系统综合问题springcloud微服务实战:服务网关,Gateway

springcloud微服务实战:服务网关,Gateway

时间2023-04-22 11:28:18发布分享专员分类系统综合问题浏览132

今天小编给各位分享gateway的知识,文中也会对其通过springcloud微服务实战:服务网关,Gateway和Spring Cloud Zuul 微服务网关等多篇文章进行知识讲解,如果文章内容对您有帮助,别忘了关注本站,现在进入正文!

内容导航:

  • springcloud微服务实战:服务网关,Gateway
  • Spring Cloud Zuul 微服务网关
  • 生产级基于SpringCloud微服务架构性能优化实战,建议收藏
  • 【SpringCloud-Alibaba系列教程】13.gateway网关结合Sa-token进行登录鉴权
  • 一、springcloud微服务实战:服务网关,Gateway

    服务网关: Spring Cloud Gateway

    前面已经介绍了基于Spring Cloud搭建微服务框架所需要的必需组件,利用这些组件再配合客户端就可以构建出一个完整的系统。但在实际应用场景中,每一个微服务都会部署到内网服务器中,或者禁止外部访问这些端口,这是对应用的一种安全保护机制。因此,我们如果想通过互联网来访问这些服务,需要一个统一的入口,这就是本章将介绍的微服务的又一大组件——服务网关。

    我们需要服务网关,还有一些很重要的因素,比如服务网关会对接口进行统一拦截并做合法性校验,一个服务可以启动多个端口,利用服务网关进行负载均衡处理等。

    目前市面上有很多产品可以实现服务网关这一功能,如 Nginx、Apache、Zuul以及 Spring CloudGateway等。Spring Cloud集成了Zuul和Gateway,我们可以很方便地实现服务网关这一功能。

    Gateway简介

    关于Gateway,其官网是这样描述的:

    This project provides a library for building an API Gateway on top of Spring MVC.Spring CloudGateway aims to provide a simple, yet effective way to route to APIs and provide cross cuttingconcerns to them such as: security, monitoring/metrics, and resiliency.

    这个项目提供了一个在Spring MVC之上构建的API网关库,Spring Cloud Gateway致力于提供一个简单而有效的方法来由路由到API,并为它们提供跨领域的关注点,如安全、监控/度量和弹性。

    Gateway是由Spring Cloud官方开发的一套基于WebFlux实现的网关组件,它的出现是为了替代Zuul。Gateway 不仅提供统一的路由方式,还基于Filter Chain供了网关的基本功能,例如安全、监控、埋点和限流等。

    创建服务网关

    本节中,我们将开始创建服务网关,进一步优化我们的微服务架构。

    (1)创建一个子工程,命名为gateway并添加以下依赖:

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>< / dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</ artifactId></ dependency><dependency><artifactId>common</artifactId><groupId>com.lynn.blog</groupId><version>1.e-SNAPSHOT</version>< / dependency>

    前面提到,Spring Cloud Gateway基于WebFlux,因此需要添加 WebFlux依赖,注意不能引入Web依赖,否则无法正常启动gateway工程;此外,为了启用服务网关功能,还需要添加spring-cloud-starter-gateway依赖。

    (2)在Git仓库创建一个配置文件gateway.yml,并添加以下内容:

    server:port: 8088spring:application:name: gatewaycloud:#Spring Cloud Gateway路由配置方式gateway:#是否与服务发现组件进行结合,通过serviceId(必须设置成大写)转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据serviceId创建路由的功能discovery:#路由访问方式:http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问locator:enabled: truelogging:#配置网关日志策略level:org.springframework.cloud.gateway : traceorg.springframework.http.server.reactive: debugorg.springframework.web.reactive: debugreactor.ipc.netty: debugfeign:hystrix:#开启熔断器enabled: true

    在上述配置中spring.cloud.gateway.discovery.locator.enabled默认为false,设置为true,我们就可以通过注册中心的 serviceId 请求路由地址,路由访问格式为http://Gateway_HOST:Gateway_PORT/serviceId/**,其中微服务应用名默认大写;logging.level配置的是服务网关日志策略。

    (3)在gateway工程下创建bootstrap.yml配置文件,并添加以下内容:

    spring:cloud :config:name: eurekaclient,gatewaylabel: masterdiscovery :enabled: trueserviceId: configusername: adminpassword: admineureka:client:serviceUrl:defaultzone: http: // admin :admin123@localhost:8101/eureka/

    上述配置通过spring.cloud.config.name指定要拉取的文件,除了gateway还多了eurekaclient文件。eurekaclient 用于配置Eureka客户端。由于每个微服务都应注册到Eureka服务端中,所以每个服务都需要拉取eurekaclient配置,该配置内容如下:

    spring:cloud:inetutils:preferred-networks : 127.0.e.1eureka:instance:prefer-ip-address: trueclient:register-with-eureka: truefetch-registry: true#开启熔断器feign:hystrix:enabled: true

    这些配置前面已经讲解,这里不再重复。

    (4)创建应用启动类GatewayApplication,代码和前面讲的人口程序类似,此处省略具体的代码。

    这样一个最简单的服务网关组件就搭建完成了。

    接下来,分别启动register、config、test、 gateway工程并访问localhost:8080/TEST/test,如果出现如图9-1所示的内容,说明服务网关搭建成功。

    在以上地址中,8080为网关启动端口,TEST为服务注册名 (Spring Cloud默认为大写),test为服务的restapi3地址。

    利用过滤器拦截API请求

    使用服务网关还有一个很重要的原因是我们需要对外提供统一的HTTP入口,便于我们管理各个服务接口,尤其是在鉴权R方面。假如没有服务网关进行拦截,就需要在每个服务下都实现拦截代码,而微服务系统的鉴权逻辑往往是一样的,代码也是一样的,所以这样做不利于维护和扩展。因此,我们可以利用Spring Cloud Gateway统一过滤外来请求。

    服务网关提供了多种过滤器( filter )供大家选择,如GatewayFilter和 GlobalFilter等,不同过滤器的作用是不一样的,GatewayFilter处理单个路由的请求,而GlobalFilter根据名字就能知道,它是一个全局过滤器,可以过滤所有路由请求。本文以全局过滤器GlobalFilter为例,讲解如何通过过滤器过滤API请求,达到鉴权的目的。

    (1)创建ApiGlobalFilter类,并实现GlobalFilter:

    @Componentpublic class ApiGlobalFilter implements GlobalFilter {@Overridepublic Mono<Void>filter(ServerwebExchange exchange,GatewayFilterChain chain){String token = exchange.getRequest().getQueryParams().getFirst("token");if ( StringUtils.isBlank( token)) iServerHttpResponse response = exchange.getResponse();3SONObject message = new JSONObject();message.put( ""status", -1);message.put( "data","鉴权失败");byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory( ).wrap(bits);response. setStatuscode(HttpStatus. UNAUTHORIZED);response.getHeaders().add("content-Type", "text/json;charset=UTF-8");return response.writewith(Mono.just(buffer));}return chain.filter( exchange);}}

    上述代码的意思是过滤所有请求路由,从参数中提取token并通过chain.filter方法执行目标路由,如果没有token,则提示鉴权失败,并通过writewith方法返回。

    Spring Cloud Gateway依赖WebFlux,而WebFlux通过Mono对象返回数据,因此上述过滤器也返回了Mono对象。我们注意到,filter方法返回的是 Mono<Void>,读者可以将Void类理解为同Java的void关键字一样的功能,它其实就是void关键字的包装类,同int和 Integer的区别一样。该Mono并不返回任何数据,我们如果将它想象成普通的定义方法,就应该是void filter()。

    (2)启动gateway 工程,访问localhost:8080/TEST/test,得到以下结果,如图9-2所示。说明全局过滤器对路由做了过滤处理。将地址加上 token参数后,将会得到如图9-1所示的结果。

    请求失败处理

    如果要调用的服务出现异常或者宕机了,那么Gateway请求失败,必然会返回错误。这时停止 test工程并访问网关地址,可以看到如图9-3所示的界面。

    这种500 错误对用户是不友好的,需要对服务网关进行统一的异常处理并给客户端返回统一的JSON数据,让客户端具有友好的体验,具体步骤如下。

    (1)创建异常处理类JsonExceptionHandler,它继承自DefaultErrorwebExceptionHandler:

    public class JsonExceptionHandler extends DefaultErrorwebExceptionHandler{public JsonExceptionHandler(ErrorAttributes errorAttributes,ResourcePropertiesresourceProperties, ErrorProperties errorProperties,ApplicationContextapplicationcontext) {super(errorAttributes,resourceProperties,errorProperties, applicationContext);)@overrideprotected Map<String, 0bject> getErrorAttributes(ServerRequest request,booleanincludeStackTrace) iint code = 508;Throwable error = super.getError(request);if (error instanceof org.springframework.cloud.gateway. support.NotFoundException){code = 404;}return response(code,this.buildMessage(request,error));}@overrideprotected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributeserrorAttributes) {return RouterFunctions.route(RequestPredicates.all(), this:: renderErrorResponse);}@overrideprotected HttpStatus getHttpStatus(Map<String,object> errorAttributes){int statuscode =(int) errorAttributes.get( "code" );return Httpstatus.valueOf(statuscode);}private String buildMessage(ServerRequest request,Throwable ex){StringBuilder message = new StringBuilder("Failed to handle request [");message.append(request.methodName());message. append(" ");message. append(request.uri());message. append("]");if (ex != null){message. append(": ");message.append(ex.getMessage();}return message.toString();}public static Map<String,0bject> response(int status,String errorMessage){Map<String,object> map = new HashMap<>();map.put( "code", status);map.put( "message" , errorMessage);map.put( "data" , null);return map;}}

    SpringBoot提供了默认的异常处理类DefaultErrorwebExceptionHandler,显示效果如图9-3所示,这显然不符合我们的预期。因此,需要重写此类,并返回JSON格式。

    Spring Cloud Gateway进行异常处理的原理是,当出现请求服务失败(可以是服务不可用,也可以是路由地址404等)的情况,首先会调用getRoutingFunction方法,该方法接收ErrorAttributes对象,即接收具体的错误信息,然后调用getErrorAttributes方法获得异常属性,通过该方法判断具体的错误码,最终将错误信息放到Map 并返回客户端。

    (2)覆盖默认异常,具体的实现如下:

    @SpringBootConfiguration@EnableConfigurationProperties({ServerProperties.class,ResourceProperties.class})public class ErrorHandlerConfiguration {private final ServerProperties serverProperties;private final ApplicationContext applicationContext;private final ResourceProperties resourceProperties;private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecconfigurer;public ErrorHandlerconfiguration(ServerProperties serverProperties,ResourceProperties resourceProperties,0bjectProvider<List<ViewResolver>>viewResolversProvider,ServerCodecConfigurer serverCodecConfigurer,Applicationcontext applicationcontext) {this.serverProperties = serverProperties;this.applicationContext = applicationContext;this.resourceProperties = resourceProperties;this.viewResolvers = viewResolversProvider.getIfAvailable(Collections: :emptyList);this.servercodecConfigurer = servercodecConfigurer;}@Bean@order(ordered.HIGHEST_PRECEDENCE)public ErrorwebExceptionHandler errorwebExceptionHandler(ErrorAttributeserrorAttributes) {JsonExceptionHandler exceptionHandler = new 3sonExceptionHandler(errorAttributes,this.resourceProperties,this.serverProperties.getError(),this.applicationContext);exceptionHandler.setViewResolvers(this.viewResolvers);exceptionHandler.setMessagewriters(this.serverCodecConfigurer.getwriters());exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());return exceptionHandler;}}

    以上代码最核心的部分是errorlwebExceptionHandler方法,因此上述类添加了@SpringBoot-Configuration注解,并且 errorWwebExceptionHandler声明了@Bean。gateway工程启动时就会执行errorwebExceptionHandler方法且需要返回ErrorWwebExceptionHandler对象,方法内可以实例化sonExceptionHandler对象并返回。这样gateway在发生异常时就会自动执行JsonExceptionHandler而不会执行其默认类了。

    (3)重新启动gateway并停止 test,访问地址 localhost:8080/TEST/test就可以得到如图9-4所示的结果。

    小结

    本文介绍了Spring Cloud的另一大组件:服务网关,它是外部通信的唯一入口。在实际项目中,我们需要对接口进行安全性校验,而一套微服务架构可能存在成千上万个服务,不可能对每个服务都单独实现安全机制,而应通过服务网关统一拦截。Spring Cloud Gateway默认实现了负载均衡,一个服务可以部署到多台服务器,通过其负载均衡机制,.可以有效地提升系统的并发处理能力。

    本文给大家讲解的内容是springcloud实战:服务网关,SpringCloudGateway下篇文章给大家讲解的是springcloud实战:网站功能开发;觉得文章不错的朋友可以转发此文关注小编;感谢大家的支持!

    一、Spring Cloud Zuul 微服务网关

    Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application.

    Zuul 是从设备和网站到后端应用程序或服务的所有请求的入口,为内部服务提供了可配置的对外URL到服务的映射关系。

    Zuul 网关提供了如下功能:

    1、路由转发:接收一切外界请求,转发到后端的微服务上去;

    2、过滤器Filter:在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成(其实路由转发也是通过过滤器实现的)。

    Zuul Server 工程中需要引入的依赖项

    如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务

    在Spring Boot主函数上通过注解 @EnableZuulProxy 来开启网关路由功能,这样可以将请求转发到对应的服务。 按照约定, 一个ID为"client"的服务会收到 /client 请求路径的代理请求(前缀会被剥离)。

    Zuul使用Ribbon定位服务注册中的实例, 并且所有的请求都在hystrix的command中执行, 所以失败信息将会展现在Hystrix Dashboard中, 并且一旦断路器打开, 代理请求将不会尝试去链接服务。

    如下是Eureka,Zuul,Ribbon 交互图:

    二、生产级基于SpringCloud微服务架构性能优化实战,建议收藏

    本文将从 Tomcat性能优化,SpringCloud开启重试机制,Zuul网关性能参数优化,Ribbon性能参数优化,Feign与Hystrix性能优化等 五个方面分享在生产环境如何做好SpringCloud性能优化。

    一般基于SpringCloud的微服务能够脱离传统的tomcat,独立跑起来,SpringBoot功不可没,其原理是SpringBoot内嵌了tomcat(当然可以换成其他servlet容器,如jetty),能够以java -jar形式就能跑起来。

    所以针对每个springboot服务,我们需要对tomcat的一些参数进行优化,以下是楼主项目组优化的tomcat参数配置,供大家参考。

    tomcat参数说明:

    maxThreads,acceptCount参数应用场景

    场景一

    场景二

    场景三

    maxThreads调优

    一般说服务器性能要从两个方面说起:

    1、cpu计算型指标

    2、io密集型指标

    所以大部分情况下,tomcat处理io型请求比较多,比如常见的连数据库查询数据进行接口调用。

    另外,要考虑tomcat的并发请求量大的情况下,对于服务器系统参数优化,如虚拟机内存设置和linux的open file限制。

    maxThreads设置多大合适?

    我们知道线程过多,会导致cpu在线程切换时消耗的时间随着线程数量的增加越来越大;线程太少,服务器的请求响应吞吐量会急剧下降,所以maxThreads的配置绝对不是越大越好。

    实际情况是设置maxThreads大小没有最优解,要根据具体的服务器配置,实际的应用场景不断的调整和优化。

    acceptCount设置多大合适?

    尽量与maxThreads的大小保持一致 这个值应该是主要根据应用的访问峰值与平均值来权衡配置的。

    当使用URL进行路由时,则需要对zuul.host.connect-timeout-millis和zuul.host.socket-timeout-millis参数控制超时时间。

    请求连接的超时时间

    请求处理的超时时间

    对所有操作请求都进行重试

    对当前实例的重试次数,针对同一个服务实例,最大重试次数(不包括首次调用)

    对下个实例的重试次数,针同其它的服务实例,最大重试次数(不包括首次server)

    注意Hystrix断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试

    Feign和Ribbon在整合了Hystrix后,首次调用失败的问题?

    目前楼主的强烈做法是: 禁用Hystrix的超时时间,设为false

    还有一种是官方提倡的是 设置超时时间。

    在实际的项目中亲测,这种方式也有不好的地方, 如请求时间超过5s会出现请求数据时有时无的情况 ,给用户的感觉是 系统不稳定,要求整改

    另外,禁用hystrix,官方不推荐

    hystrix超时设置原则

    问题:一个http请求,如果feign和ribbon都配置了重试机制,异常情况下一共会请求多少次?

    请求总次数 n 为feignClient和ribbon配置参数的笛卡尔积:

    n(请求总次数) = feign(默认5次) * (MaxAutoRetries+1) * (MaxAutoRetriesNextServer+1)

    其中+1是代表ribbon本身默认的请求。

    其实二者的重试机制相互独立,并无联系。但是因为用了feign肯定会用到ribbon,所以feign的重试机制相对来说比较鸡肋,一般会关闭该功能。ribbon的重试机制默认配置为0,也就是默认是去除重试机制的,建议不要修改。

    三、【SpringCloud-Alibaba系列教程】13.gateway网关结合Sa-token进行登录鉴权

    在介绍 【SpringCloud-Alibaba系列教程】10.gateway网关 的时候文章末尾简单说了一下实现的鉴权功能,本文结合比较火的 sa-token 权限框架,进行整合,实现登录逻辑。看到本文,建议按照发文顺序阅读,方便理解我写的部分以及内容,本文实现的需求就是,首先进行统一在网关登录,然后调用shop-auth,然后在进行访问商品微服务shop-product,如果没登录,就查询不到进行相关提示,如果登录了就可以查询到了,现在我们开始。

    首先我们再次借用上次的图。

    下面就是网关了。

    关于gateway的问题,通过《生产级基于SpringCloud微服务架构性能优化实战,建议收藏》、《【SpringCloud-Alibaba系列教程】13.gateway网关结合Sa-token进行登录鉴权》等文章的解答希望已经帮助到您了!如您想了解更多关于gateway的相关信息,请到本站进行查找!

    爱资源吧版权声明:以上文中内容来自网络,如有侵权请联系删除,谢谢。

    gateway
    零成本造字,百度输入法AI造字体验,人人都是造字大师 设置双屏显示器的技巧