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