分布式架构:根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务:
优点:降低服务耦合
有利于服务升级拓展
微服务:
是一种经过良好架构设计的分布式架构方案,微服务架构特征:
●单一职责:微服务拆分粒度更小,每-一个服务都对应唯- -的业务能力,做到单一职责,避免重复业务开发。
●面向服务:微服务对外暴露业务接口
●自治: 团队独立、技术独立、数据独立、部署独立
SpringCloud:是目前国内使用最广泛的微服务框架。官网地址: Spring Cloud.
服务拆分及远程调用:
注意事项:1.不同的微服务,不能重复开发相同业务
2.微服务数据独立,不访问其他微服务的数据库
3.微服务将自己的业务暴露接口,供其他微服务调用
跨服务远程调用:
案例:
根据订单ID查询订单的功能:根据订单id查询订单的同时,将订单的用户信息一起返回
学会远程调用方式:
如何在java代码中发送HTTP请求:
在application文件中写@Bean,创建一个RestTemplate工具,创建即可。
微服务远程调用:
提供者和消费者
服务提供者: 一次业务中,被其它微服务调用的服务。( 提供接口给其它微服务) 服务消费者: 一次业务中,调用其它微服务的服务。( 调用其它微服务提供的接口)
提供者和消费者,得看相对而言(一个服务既可以是生产者也可以是消费者)
Eureka注册中心:
作用:
如果其中一个端口挂掉,则直接排除。
案例:
搭建服务步骤如下:
注册User-service
再order-service完成服务拉取:
Ribbon负载均衡:
流程:
代码参考:
Gitee:cloudcode: Java微服务技术学习指南 - Gitee.com
GitHub:cloudcode/05-cloud-nacos at master · lexinhu/cloudcode · GitHub
SpringCloudAlibaba 推出了一个名为 Nacos 的注册中心,在国外也有大量的使用。
解压启动 Nacos,详细请看 Nacos安装指南
startup.cmd -m standalone
访问:http://localhost:8848/nacos/
这里上来就直接服务注册,很多东西可能有疑惑,其实 Nacos 本身就是一个 SprintBoot 项目,这点你从启动的控制台打印就可以看出来,所以就不再需要去额外搭建一个像 Eureka 的注册中心。
引入依赖
在 cloud-demo 父工程中引入 SpringCloudAlibaba 的依赖:
com.alibaba.cloud spring-cloud-alibaba-dependencies 2.2.6.RELEASE pom import
然后在 user-service 和 order-service 中的pom文件中引入 nacos-discovery 依赖:
com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery
配置nacos地址
在 user-service 和 order-service 的 application.yml 中添加 nacos 地址:
spring: cloud: nacos: server-addr: 127.0.0.1:8848
项目重新启动后,可以看到三个服务都被注册进了 Nacos
浏览器访问:http://localhost:8080/order/101,正常访问,同时负载均衡也正常。
一个服务可以有多个实例,例如我们的 user-service,可以有:
127.0.0.1:8081
127.0.0.1:8082
127.0.0.1:8083
假如这些实例分布于全国各地的不同机房,例如:
127.0.0.1:8081,在上海机房
127.0.0.1:8082,在上海机房
127.0.0.1:8083,在杭州机房
Nacos就将同一机房内的实例,划分为一个集群。
微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。例如:杭州机房内的 order-service 应该优先访问同机房的 user-service。
接下来我们给 user-service 配置集群
修改 user-service 的 application.yml 文件,添加集群配置:
spring: cloud: nacos: server-addr: localhost:8848 discovery: cluster-name: HZ # 集群名称 HZ杭州
重启两个 user-service 实例后,我们再去启动一个上海集群的实例。
-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH
查看 nacos 控制台
Ribbon的默认实现 ZoneAvoidanceRule
并不能实现根据同集群优先来实现负载均衡,我们把规则改成 NacosRule 即可。我们是用 orderservice 调用 userservice,所以在 orderservice 配置规则。
@Bean public IRule iRule(){ //默认为轮询规则,这里自定义为随机规则 return new NacosRule(); }
另外,你同样可以使用配置的形式来完成,具体参考上面的 Ribbon 栏目。
userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #负载均衡规则
然后,再对 orderservice 配置集群。
spring: cloud: nacos: server-addr: localhost:8848 discovery: cluster-name: HZ # 集群名称
现在我启动了四个服务,分别是:
orderservice - HZ
userservice - HZ
userservice1 - HZ
userservice2 - SH
访问地址:http://localhost:8080/order/101
在访问中我们发现,只有同在一个 HZ 集群下的 userservice、userservice1 会被调用,并且是随机的。
我们试着把 userservice、userservice2 停掉。依旧可以访问。
在 userservice3 控制台可以看到发出了一串的警告,因为 orderservice 本身是在 HZ 集群的,这波 HZ 集群没有了 userservice,就会去别的集群找。
实际部署中会出现这样的场景:
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求。但默认情况下 NacosRule 是同集群内随机挑选,不会考虑机器的性能问题。
因此,Nacos 提供了权重配置来控制访问频率,0~1 之间,权重越大则访问频率越高,权重修改为 0,则该实例永远不会被访问。
在 Nacos 控制台,找到 user-service 的实例列表,点击编辑,即可修改权重。
在弹出的编辑窗口,修改权重
另外,在服务升级的时候,有一种较好的方案:我们也可以通过调整权重来进行平滑升级,例如:先把 userservice 权重调节为 0,让用户先流向 userservice2、userservice3,升级 userservice后,再把权重从 0 调到 0.1,让一部分用户先体验,用户体验稳定后就可以往上调权重啦。
如果权重调为0时,就不会响应。
Nacos 提供了 namespace 来实现环境隔离功能。
Nacos 中可以有多个 namespace
namespace 下可以有 group、service 等
不同 namespace 之间相互隔离,例如不同 namespace 的服务互相不可见
默认情况下,所有 service、data、group 都在同一个 namespace,名为 public(保留空间):
我们可以点击页面新增按钮,添加一个 namespace:
然后,填写表单:
就能在页面看到一个新的 namespace:
给微服务配置 namespace 只能通过修改配置来实现。
例如,修改 order-service 的 application.yml 文件:
spring: cloud: nacos: server-addr: localhost:8848 discovery: cluster-name: HZ namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间ID
重启 order-service 后,访问控制台。
public
dev
此时访问 order-service,因为 namespace 不同,会导致找不到 userservice,控制台会报错: