在阅读SpringBoot的源码时,框架运用了大量的函数式编程。可以说,业务代码你可以不使用函数式编程,但是上升到框架层面,函数式编程是基础。
微服务网关,是一个微服务体系的门户,是多有流量的入口和出口。这样重要的地位就代表了网关需要很高的稳定性。而动态路由就是Spring Cloud Gateway高可用的一种解决方案。
在文章《SpringCloudGateway源码解析(3)- 路由的装配》中,我们了解了网关路由的相关实现,这一章节,主要讲解下SpringCloudGateway中handler包实现,其中最核心的两个类FilteringWebHandler和RoutePredicateHandlerMapping。
在文章《SpringCloudGateway源码解析-揭开SpringCloudGateway神秘面纱》中,我们从宏观上了解了Spring Cloud Gateway的整体架构和思想,本篇文章就是要带着大家了解网关的一等公民”路由”的前世和今生。
反应式编程,作为一种新的思想,以函数式编程为基础,受到越来越多的开发人员欢迎,Spring5作为行业的标准,也全面拥抱了Reactor框架。
Spring Cloud Gateway是Spring官方自己推出的网关组件,基于Spring5,Spring Boot 2.0 和 Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的API路由管理方式,作为Spring Cloud全家桶替代Zuul的产品。想一探它的神秘面容嘛?学习源码会收获哪些?想知道的话,就跟我走吧
在SpringBoot构建完之后,会在resource目录下创建一个application.properties文件,这是一个空文件。SpringBoot应用默认就会读取application.properties文件,但我们可以修改为application.yml,个人建议使用yml,因为YMAL的风格会更加适合配置文件。两者的功能上是一致的,只是语法不同,本文不重点介绍语法。
##2.实战
1 |
|
1 | spring: |
以上代码实现用yml文件,映射到类GatewayProperties中。最终的打印结果是
1 | {"routes":[{"id":"yml-id","order":-1,"predicates":[{"args":{"arg0":"1","arg1":"2"},"name":"predicatesName"}],"uri":"www.baidu.com"}]} |
细心的同学可能会注意到@EnableConfigurationProperties、@ConfigurationProperties(prefix = “spring.cloud.gateway”)、@Validated 这三个很重要的注解。是的,如果想实现配置文件直接映射成Bean,@EnableConfigurationProperties和@ConfigurationProperties是必须要配置的,prefix=”spring.cloud.gateway”代表从spring.cloud.gateway开始采集配置。
@Validated 是校验配置的工具注解,除了代码中应用到的注解外,其它常见注解:
1 | - Path=/echo |
这行代码有些不好理解,其实就是RouteDefinition 有两个构造函数,这句配置的意思是调用了有参数的构造函数来定义RouteDefinition对象,使得构建网关的配置更加简洁。
##3.总结
以上的内容,是通过阅读SpringCloudGateway源代码,发现实现方式很优雅,便总结下来。利用好SpringBoot的配置,可以写出很优雅的代码,提高维护性。
在说SpringCloud之前,首先要陈述一下单体应用架构和微服务架构。
一个归档包,包含所有功能的应用程序叫单体应用。在系统初期或者系统本身的复杂度不高,采用单体应用架构是合理的。它比较容易部署、维护、测试,大多数功能的实现,采用函数本地调用,所以说从架构合理性和性能角度考量,都是一个合理的方案。
但随着系统的复杂度越来越高,引入越来越多的功能,技术团队扩张,越来越多的人加入到系统的研发过程中。慢慢的,单体应用变得越来越臃肿,可维护性、灵活性逐渐降低,如果没有良好的编程规范约束和工程规范,一定会留下不少的技术债务(俗称”埋雷”),以上这些问题(当然还有其他的问题)共同导致了维护成本越来越高。
以上这些问题,相信大家在工作中,一定会经常碰到。那么如何解决单体应用架构的问题呢?微服务应运而生,微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务都运行在自己的进程中,服务间采用轻量级通信机制,一系列独立运行的微服务共同构建起整个系统。
微服务虽然有很多吸引人的地方,但它并不是免费的午餐,使用它是有代价的。
1、运维成本较高:更多的服务,意味着更多的运维投入。在单体架构中,只需要保证一个应用的正常运行。而在微服务中,需要保证几十甚至几百个服务正常运行与协作,这给运维带来了很大的挑战。
2、分布式固有的复杂性:使用微服务架构即是分布式系统。对于一个分布式系统,系统容错、网络延迟、分布式事务等都会带来巨大的挑战。
3、接口调整成本高:微服务之间通过接口通信,如果修改某一个微服务的API,可能所有使用了该接口的微服务都需要做调整。
4、重复劳动:很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会开发这一功能,从而导致代码重复。
虽然微服务有如上的缺点,但是瑕不掩瑜,为了更好的应用微服务,可以选择SpringCloud作为开发框架。
上一章讲述了微服务的产生背景和微服务的优势和劣势,本章讲述应用SpringCloud生态,如何合理的搭建一套健壮,好维护的微服务的系统。
SpringCloud是基于SpringBoot构建的,因此它延续了SpringBoot的契约模式以及开发方式。SpringBoot的出现,解决了Java应用配置繁杂的缺点,整合了最优秀的中间件,使得基于Java的应用开发和部署十分简单。
没有服务中心,那么服务的调用必须采用硬编码的模式,那么每次服务的扩容,缩容,新的服务上线,都需要所有的服务上线,这显然是不合理的。
Eureka是一款开源的服务发现组件,https://github.com/Netflix/eureka
Eureka的功能:
1、Eureka集群
2、Eureka用户认证
3、Eureka自我保护模式
4、Eureka健康检查
如下图所示,要关注如下的参数
Renews threshold: 这个指标的计算是应用的数量int(count 2 0.85),图中实例正好是三个eureka-server实例,故而结果为5。
Renews(last min): 这个指标的含义是一分钟内接收到的心跳数量。如果renews(last min) < Renews threshold,则会触发Eureka的自我保护机制。
Instances currently registered with Eureka: 展示此时注册中心管理的应用及实例数量
Ceneral Info:最重要的是registered-replicas,available-replicas, 正常情况下unavailable-replicas是不应该有值的,如果有值,说明有replica不能使用。
1 | server: |
Ribbon是Netflix发布的负载均衡器。Ribbon的github地址,https://github.com/Netflix/ribbon
在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。
Feign是Netflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit,JAXRS-2.0以及WebSocket。Feign可帮助我们更加便捷、优雅的调用HTTP API。https://github.com/OpenFeign/feign
Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性和容错性。
https://github.com/spring-cloud/spring-cloud-gateway
https://github.com/ctripcorp/apollo