传送门
spring cloud alibaba系列之nacos:(1)安装
spring cloud alibaba系列之nacos:(2)单机模式支持mysql
spring cloud alibaba系列之nacos:(3)服务注册发现
spring cloud 系列之openfeign:(4)集成openfeign
spring cloud 系列之openfeign:(5)openfeign的高级用法
spring cloud 系列之openfeign:(6)openfeign的链路追踪
spring cloud 系列之openfeign:(7)链路追踪sleuth+zipkin
spring cloud 系列之openfeign:(8)链路追踪续
短暂的回顾
在谈网关之前,回顾了一下springcloud系列文章。从写下第一篇博客spring cloud alibaba系列(1)之:nacos安装时,时间是2022-06-12,距离现在已经过去快2年了。而如果要从真正从接触微服务(主要指springcloud全家桶)写下的第一博客《spring cloud系统架构的淘宝客之一》
算起,时间应该是2018-01-10,过去了整整6年。在此期间,微服务蓬勃发展、遍地开花,几乎成了现在java开发的首选和项目框架选型的标配。但是这几年间我并没有一直在使用它,原因是中间去福报厂呆了几年(为此还产生了,当然也留下了一个大坑没填)。
一般的大公司都有自己封装的一套所谓xx框架,比如sofa这种rpc框架。当时在里面要适应做toc业务及整天精神高度紧张,导致并没有持续关注springcolud。等从互联网出来转到做tob业务时,又有了什么spring cloud alibaba,那是不是还得学?所以有了这个系列的文章,当时也没有过多想法。现在细想起来,至少有以下3方面原因:
- 1是做为学习的一个记录,及归纳总结。也希望能帮助到其它需要的java boy
- 2是心态上的一个转变,从以前追逐各种框架中逐渐解脱出来,开始回归到计算机基础的学习上。比如网络(主要是http协议簇)、计算机组成原理、数据结构(不断开始/放弃的循环中)、jvm等学习上
- 3是深度上,现在更多是尽量深入到源码级别来学习:阅读各种框架的源码比如nacos,xxl-job的《分布式定时任务系列8:xxl-job源码分析之远程调用》,不过现在博客里面很少具体体现出来怕误导别人
但是工欲善其事,对于项目的开发及实际框架的使用,了解它的相关用法、特性还是很有必要。所以会继续这个系列下去,这次会切入微服务中另一个重要的基础组件:网关gateway
什么是网关
对于网关这个概念来说,在传统架构的模式下,可能感知并不是很强烈。特别是单体架构可能都没有网关这个组件或服务:
无网关架构
一个极简的单体架构,可以是如下图(假设在内网,不考虑防火墙安全等非业务功能):
- 1台物理机,有1个对应的ip
- 在物理机上面运行1个tomcat实例,并部署对应的服务a,设置对应的端口port
- 系统架构采用springmvc,前后端打包在一块部署1个实例
- 用户直接通过浏览器访问系统:https://ip:port/xx,xx为服务a暴露的请求url
在这样的架构下,会发现其实是没有网关这个组件的。当然一般面向互联网的可能还会在前面挂一个域名,但是也不会对上述网关的定位有涉及。
负载均衡架构
但是一般大型一些的系统,出于高可用的需要会采用集群部署:即对后端服务进行同一个服务多个副本部署,并搭载对应的负载均衡器做统一路由,比如硬件层面的f5,软件层面的nginx等。
这里给各个单体系统的副本分发流量的负载均衡器(f5或nginx),其实就承担着内部服务与外部调用之间的网关角色。
微服务架构
不过在微服务环境中,网关的存在感就极大地增强了,甚至成为微服务集群中必不可少的设施之一,重要性不比服务发现(eureka/nacos)、配置中心(config/nacos)、负载均衡(ribbon/loadbalacer)低!
因为在微服务的理念下,不仅对系统架构有冲击要进行服务拆分,甚至可能对组织架构也有冲击导致研发团队按服务拆分。
如果每个服务节点都由不同的团队负责,它们有自己独立的、各不相同的能力,所以如果服务集群没有一个统一对外交互的代理人角色,那外部的服务消费者就必须知道所有微服务在集群中的精确坐标(各个后端服务的地址)。所以,微服务中网关的首要职责
所以网关gateway拥有路由基本职责与能力。但是如果仅仅这一点,与其它老牌的负载均衡器f5、nginx有什么区别呢?直接用负载均衡器不就好了,搞一个什么网关轮子出来干啥?其实原因有如下几点:
- 微服务架构下的网关除了路由能力外,还需要提供一些比如安全、认证、授权、限流、监控、缓存的额外能力
- 另外通过spring提供原生的gateway组件,能更好的适配springcloud生态,做大做强
- 通过代码解析请求url的一些特征,能更方便的制定路由策略及方便边缘功能的扩展
基于上述原因,gateway网关还提供了过滤器实现代码层级的精细控制:
gateway入门
以之前的tsm项目为例,若为它增加一个微服务模块-网关!这样整个项目的后端入口就不再是直接请求到各个微服务模块了,而是所有请求都先到gateway然后由它路由到对应的微服务去。
- 这里要注意一点是:网关建议使用默认的8080端口,这样就不用单独开放了
- 若其它服务占用了此端口,建议调整,如上图的auth服务
引入pom
先新建一个gw服务做为网关。要使用gateway组件的话,需要引入专门的starter包:
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-gateway</artifactid>
</dependency>
这里还要注意,因为gateway使用的reactor,需要排除web的包
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
或者启用配置
spring:
main:
web-application-type: reactive
- 注意这里也要将gw注册到服务发现中心nacos,通过服务发现来做服务发现(还有负载均衡-loadbalancer)
配置路由
这里配置一个最简单的路由,将auth、cipher服务的请求通过gw转发到对应的微服务去:
server:
port: 8080
spring:
main:
web-application-type: reactive
application:
name: gw
cloud:
gateway:
routes:
- id: auth-service
uri: http://localhost:8083
predicates:
- method=get
- id: cipher-service
uri: http://localhost:8081
predicates:
- method=get
- 这里配置了2个路由策略:auth-service、cipher-service,并分别将对应的请求转发到auth服务(端口8083)cipher服务(端口8081)
- 只转发get请求
测试
通过上述配置,可以来测试一下gw的功能。auth服务有个接口:
@requestmapping(value = "/echo/{str}", method = requestmethod.get)
public string echo(@pathvariable string str)
{
log.info("echo init begin..........tid:{}", mdccontext.gettraceid());
// return resttemplate.getforobject("http://cipher-service/echo/" + str, string.class);
return authfeignclient.echo(str);
}
分别请求网关地址和直接请求auth服务:
http://localhost:8080/echo/gate-test-for-auth
http://localhost:8083/echo/gate-test-for-auth
得到结果一致,至此gw的功能成功,最简化的的一个gw就完成了。
后面会在下一节里面,重点讨论一下gw的相关配置基本用法,并了解过滤器的用法及具体原理。
发表评论