文章目录
- 概述
- 微服务技术对比
- Eureka
- 服务远程调用
- 服务提供者和消费者
- Eureka注册中心
- 搭建注册中心
- 服务注册
- 服务发现
- Ribbon负载均衡
- 负载均衡策略
- 饥饿加载
- Nacos
- Nacos与Eureka对比
- Nacos服务注册
- Nacos服务分集群存储
- NacosRule负载均衡
- 服务实例权重设置
- 环境隔离
- Nacos配置管理
- 配置热更新
- 多环境配置共享
- Nacos集群搭建
- Feign
- 简单使用
- 自定义配置
- Feign性能优化
- Feign最佳实践
- Gateway
- 搭建网关
- 路由断言工厂
- 过滤器工厂
- 全局过滤器
- 过滤器执行顺序
- 网关跨域问题处理
概述
微服务,又叫微服务架构,是一种软件架构方式。它将应用构建成一系列按业务领域划分模块的、小的自治服务。
在微服务架构中,每个服务都是自我包含的,并且实现了单一的业务功能。简单来说,就是将一个系统按业务划分成多个子系统,每个子系统都是完整的,可独立运行的,子系统间的交互可通过HTTP协议进行通信(也可以采用消息队列来通信,如RoocketMQ,Kafaka等)。
微服务技术对比
Eureka
服务远程调用
在一个服务模块中调用另一个服务,需要在服务中构建类似前端发出的http请求访问另外一个服务。
服务端可以基于RestTemplate发起http请求实现远程调用,步骤如下:
服务提供者和消费者
- 服务提供者:暴露接口给其他微服务调用
- 服务消费者:调用其他微服务提供的接口
- 服务者与消费者角色其实是相对的,一个服务可以同时是服务提供者和服务消费者。
Eureka注册中心
1、服务提供者向Eureka注册中心注册服务信息
2、服务消费者向Eureka注册中心拉取服务信息
3、如果有多个服务提供者,利用负载均衡算法,从服务提供者列表中选择一个。
4、服务提供者每隔30秒向EurekaServer发送心跳请求,报告健康状态,Eureka会更新记录服务列表信息,心跳不正常会被剔除。
搭建注册中心
EurekaServer本身就是一个单独的微服务组块。
配置文件yml中指定服务端口,服务名称,并将自身作为服务注册到Eureka服务器。
启动后:
服务注册
如果想让一个服务模拟多实例部署:
注意在environment的option选项中设置命令参数选项:-Dserver.port = 8082,其中-D指设置参数。
服务发现
Ribbon负载均衡
Ribbon对请求进行拦截,从Eureka-server拉取请求服务列表,Ribbon通过“轮询”等负载均衡手段,选择其中一个服务。
@LoadBalanced注解原理:
拦截请求:
请求被负载均衡拦截器拦截。由请求id,拉取服务列表:
动态服务列表负载均衡器从请求的url中获取服务id(服务名),向Eureka-server拉取服务列表。基于负载均衡策略,选择服务的ip + 端口:
动态服务列表负载均衡器基于IRule提供的负载均衡策略,选择服务列表中的某个服务的ip地址和端口号,并返回给负载均衡拦截器。替换服务id为真实的服务ip + 端口:
负载均衡拦截器将服务id(服务名)替换为真实的服务的ip + 端口号,向服务提供者发起真正的请求。
负载均衡策略
通过定义IRule实现可以修改负载均衡规则,有两种方式:
- 代码方式,配置IRule的Bean,针对服务消费者,即不管调用哪个微服务,都会采用你配置的IRule规则。
- 配置文件方式,在配置文件中先指定服务名称,再指定Ribbon负载均衡规则,针对服务提供者,即只对某个微服务(配置的服务名称)有效。
饥饿加载
Nacos
Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件,相比Eureka功能更加丰富,在国内受欢迎程度较高。
Nacos与Eureka对比
- Nacos中服务实例有临时实例和非临时实例之分,Eureka则没有。
- Nacos中所有实例默认是临时实例,临时实例与Nacos之间由实例主动发送心跳包,Nacos做心跳监测,如果监测不到心跳,则将其从服务列表剔除。
- 非临时实例则由Nacos主动询问实例是否存活。非临时实例如果询问时发现实例宕机,不会被Nacos剔除,只是会被标记为不健康,Nacos会等待其恢复上线。
- 主动询问的频次较高,而心跳监听的周期较长,所有临时实例从掉线到被发现的时间更长,非临时实例如果掉线很快就会被发现。
2 . Eureka与服务消费者之间,服务消费者是定时向Eureka拉取(pull)服务列表。Nacos支持服务列表变更的消息推送模式,服务列表更新就更加及时。
Nacos服务注册
Nacos服务分集群存储
- 1、一级是服务,一个服务有多个不同的实例。
- 2、二级是集群,例如地域中心
- 3、三级是实例,位于某个地域中心机房上运行的服务实例。
NacosRule负载均衡
- 配置文件中为服务指定负载均衡规则为NacosRule。
- 请求优先选择同集群服务实例列表,本地集群找不到提供者,才去找其他集群寻找,并且会报警告。
- 确定可用列表后,再采用随机负载均衡挑选实例。
服务实例权重设置
实际部署中会出现这样的场景:
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求
Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。
实例的权重控制
Nacos控制台可以设置实例的权重值,0~1之间同集群内的多个实例,权重越高被访问的频率越高,权重设置为O则完全不会被访问。
环境隔离
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用于做最外层隔离。
在namespace中又有Group的概念。
不同namespace下的服务互相是不可见的。
Nacos配置管理
Nacos除了用来做服务注册发现,还可以用于做服务的配置管理,并实现服务配置的热更新。
在Nacos添加配置信息:
没有Nacos配置时,配置获取的步骤如下:
有Nacos配置文件时:
先将Nacos服务器地址配置在优先级最高的bootstrap.yml文件中,然后读取Nacos中的配置文件,再读取本地application.yml中的配置文件,合并所有的配置。
实操步骤:
配置热更新
多环境配置共享
生产环境与开发环境可能会有很多相同的配置属性,那么就可以写一个公共的配置文件来记录这些共有的相同的配置属性,常用“服务名 + yaml”的格式来命名,而各个环境特有的属性,使用“服务名 + “-” + 环境名 + yaml”的格式来命名。
本地环境中可能已经配置了yaml文件,而Nacos中也有可能配置共享配置和环境配置,这些配置的优先级顺序是怎么样的呢?
考虑运维的便利性,在Nacos中配置的属性优先级是更高了,针对于某个特殊环境配置的属性又要高于共享配置属性,因此有:
服务名-profile.yaml > 服务名称.yaml > 本地配置
Nacos集群搭建
设置Nacos服务器集群ip和端口:
搭建集群:
为什么需要数据库呢?
Nacos配置信息是持久化到数据库中的,Nacos本身也是一个服务器,需要有自己的数据库。
Feign
Feign需要解决的问题:
Feign是一种声明式的http客户端,其作用就是帮助我们优雅的实现http请求。
简单使用
具体使用:
1、使用@FeignClient
注解一个接口UserClient
,参数指明服务名称,该接口中都是对注解指定的服务的调用。
2、接口中定义的调用方法是类似SpringMVC中的注解声明调用。
自定义配置
Feign允许我们在对http请求发送的各个阶段做自定义配置,包含请求发送响应日志、响应结果解码器、请求参数编码器、请求失败重试机制
等。
最常用的就是请求发送响应日志的配置,日志级别包含四种类型:
- NONE:无日志
- BASIC:基本日志,仅包含请求行、响应行信息。
- HEADERS:头部日志,包含请求行、请求头,响应行,响应头。
- FULL:包含全部的请求和响应信息。
Feign性能优化
主要优化两个点:
- 1、Feign底层http连接实现是不带连接池的,可以选择带连接池的http请求框架替换。
- 2、日志级别:日志会影响性能,最好使用basic或者默认的none。
怎么配置带有连接池的HttpClient?
Feign最佳实践
方式一是通过继承的方式:既然服务提供者和服务调用者都需要同样的API接口,那么可以只写一个,服务提供者和服务端调用者都继承这个接口。但是这样做可能导致紧耦合,而且SpringMVC中的路径参数映射也会失效。
方式二:将API接口以及接口所涉及的实体类、返回值对象类都抽取为一个公共模块,服务提供者和消费者都通过引用依赖的方式,加载这个模块。
Gateway
外部请求想要请求微服务资源,首先得经过统一的网关,网关实现的功能:
- 身份认证和权限校验
- 服务路由、负载均衡
- 请求限流
搭建网关
网关服务器本身也是一个微服务!
搭建网关服务的步骤:
1、创建新的module,引入SpringcloudGateway和Nacos服务发现依赖
2、配置Nacos地址以及路由规则
路由断言工厂
使用规则见spring官网
过滤器工厂
过滤器在路由规则之后,可以通过设置多个过滤器,构成过滤器链。
使用规则见spring官网
使用案例,给请求加响应头字段:
在响应接口处取出过滤器加的字段并打印出来:
如果想对所有服务的请求都加过滤器,可以在default-filter加过滤器工厂。
全局过滤器
全局过滤器与default-filter配置类似,对所有请求生效,全局过滤器不同的地方在于,过滤器的处理的逻辑需要自己写代码实现,定义方式是实现GlobalFilter接口。
使用案例:
为了让过滤器生效,首先还需要给过滤器加上Component和Order注解。
@Order注解,指定过滤器的优先级顺序,过滤器顺序也可以通过实现Orderd接口来指定,接口实现方法直接返回order顺序。
过滤器执行顺序
网关跨域问题处理